PostgreSQL Source Code  git master
trigger.c
Go to the documentation of this file.
1 /*-------------------------------------------------------------------------
2  *
3  * trigger.c
4  * PostgreSQL TRIGGERs support code.
5  *
6  * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group
7  * Portions Copyright (c) 1994, Regents of the University of California
8  *
9  * IDENTIFICATION
10  * src/backend/commands/trigger.c
11  *
12  *-------------------------------------------------------------------------
13  */
14 #include "postgres.h"
15 
16 #include "access/genam.h"
17 #include "access/htup_details.h"
18 #include "access/relation.h"
19 #include "access/sysattr.h"
20 #include "access/table.h"
21 #include "access/tableam.h"
22 #include "access/xact.h"
23 #include "catalog/catalog.h"
24 #include "catalog/dependency.h"
25 #include "catalog/index.h"
26 #include "catalog/indexing.h"
27 #include "catalog/objectaccess.h"
28 #include "catalog/partition.h"
29 #include "catalog/pg_constraint.h"
30 #include "catalog/pg_inherits.h"
31 #include "catalog/pg_proc.h"
32 #include "catalog/pg_trigger.h"
33 #include "catalog/pg_type.h"
34 #include "commands/dbcommands.h"
35 #include "commands/defrem.h"
36 #include "commands/trigger.h"
37 #include "executor/executor.h"
38 #include "executor/execPartition.h"
39 #include "miscadmin.h"
40 #include "nodes/bitmapset.h"
41 #include "nodes/makefuncs.h"
42 #include "optimizer/optimizer.h"
43 #include "parser/parse_clause.h"
44 #include "parser/parse_collate.h"
45 #include "parser/parse_func.h"
46 #include "parser/parse_relation.h"
47 #include "parser/parsetree.h"
48 #include "partitioning/partdesc.h"
49 #include "pgstat.h"
50 #include "rewrite/rewriteManip.h"
51 #include "storage/bufmgr.h"
52 #include "storage/lmgr.h"
53 #include "tcop/utility.h"
54 #include "utils/acl.h"
55 #include "utils/builtins.h"
56 #include "utils/bytea.h"
57 #include "utils/fmgroids.h"
58 #include "utils/inval.h"
59 #include "utils/lsyscache.h"
60 #include "utils/memutils.h"
61 #include "utils/rel.h"
62 #include "utils/snapmgr.h"
63 #include "utils/syscache.h"
64 #include "utils/tuplestore.h"
65 
66 
67 /* GUC variables */
69 
70 /* How many levels deep into trigger execution are we? */
71 static int MyTriggerDepth = 0;
72 
73 /* Local function prototypes */
74 static void SetTriggerFlags(TriggerDesc *trigdesc, Trigger *trigger);
75 static bool GetTupleForTrigger(EState *estate,
76  EPQState *epqstate,
77  ResultRelInfo *relinfo,
78  ItemPointer tid,
79  LockTupleMode lockmode,
80  TupleTableSlot *oldslot,
81  TupleTableSlot **newSlot);
82 static bool TriggerEnabled(EState *estate, ResultRelInfo *relinfo,
83  Trigger *trigger, TriggerEvent event,
84  Bitmapset *modifiedCols,
85  TupleTableSlot *oldslot, TupleTableSlot *newslot);
87  int tgindx,
88  FmgrInfo *finfo,
89  Instrumentation *instr,
90  MemoryContext per_tuple_context);
91 static void AfterTriggerSaveEvent(EState *estate, ResultRelInfo *relinfo,
92  int event, bool row_trigger,
93  TupleTableSlot *oldtup, TupleTableSlot *newtup,
94  List *recheckIndexes, Bitmapset *modifiedCols,
95  TransitionCaptureState *transition_capture);
96 static void AfterTriggerEnlargeQueryState(void);
97 static bool before_stmt_triggers_fired(Oid relid, CmdType cmdType);
98 
99 
100 /*
101  * Create a trigger. Returns the address of the created trigger.
102  *
103  * queryString is the source text of the CREATE TRIGGER command.
104  * This must be supplied if a whenClause is specified, else it can be NULL.
105  *
106  * relOid, if nonzero, is the relation on which the trigger should be
107  * created. If zero, the name provided in the statement will be looked up.
108  *
109  * refRelOid, if nonzero, is the relation to which the constraint trigger
110  * refers. If zero, the constraint relation name provided in the statement
111  * will be looked up as needed.
112  *
113  * constraintOid, if nonzero, says that this trigger is being created
114  * internally to implement that constraint. A suitable pg_depend entry will
115  * be made to link the trigger to that constraint. constraintOid is zero when
116  * executing a user-entered CREATE TRIGGER command. (For CREATE CONSTRAINT
117  * TRIGGER, we build a pg_constraint entry internally.)
118  *
119  * indexOid, if nonzero, is the OID of an index associated with the constraint.
120  * We do nothing with this except store it into pg_trigger.tgconstrindid;
121  * but when creating a trigger for a deferrable unique constraint on a
122  * partitioned table, its children are looked up. Note we don't cope with
123  * invalid indexes in that case.
124  *
125  * funcoid, if nonzero, is the OID of the function to invoke. When this is
126  * given, stmt->funcname is ignored.
127  *
128  * parentTriggerOid, if nonzero, is a trigger that begets this one; so that
129  * if that trigger is dropped, this one should be too. (This is passed as
130  * Invalid by most callers; it's set here when recursing on a partition.)
131  *
132  * If whenClause is passed, it is an already-transformed expression for
133  * WHEN. In this case, we ignore any that may come in stmt->whenClause.
134  *
135  * If isInternal is true then this is an internally-generated trigger.
136  * This argument sets the tgisinternal field of the pg_trigger entry, and
137  * if true causes us to modify the given trigger name to ensure uniqueness.
138  *
139  * When isInternal is not true we require ACL_TRIGGER permissions on the
140  * relation, as well as ACL_EXECUTE on the trigger function. For internal
141  * triggers the caller must apply any required permission checks.
142  *
143  * When called on partitioned tables, this function recurses to create the
144  * trigger on all the partitions, except if isInternal is true, in which
145  * case caller is expected to execute recursion on its own. in_partition
146  * indicates such a recursive call; outside callers should pass "false"
147  * (but see CloneRowTriggersToPartition).
148  */
150 CreateTrigger(CreateTrigStmt *stmt, const char *queryString,
151  Oid relOid, Oid refRelOid, Oid constraintOid, Oid indexOid,
152  Oid funcoid, Oid parentTriggerOid, Node *whenClause,
153  bool isInternal, bool in_partition)
154 {
155  int16 tgtype;
156  int ncolumns;
157  int16 *columns;
158  int2vector *tgattr;
159  List *whenRtable;
160  char *qual;
161  Datum values[Natts_pg_trigger];
162  bool nulls[Natts_pg_trigger];
163  Relation rel;
164  AclResult aclresult;
165  Relation tgrel;
166  Relation pgrel;
167  HeapTuple tuple = NULL;
168  Oid funcrettype;
169  Oid trigoid = InvalidOid;
170  char internaltrigname[NAMEDATALEN];
171  char *trigname;
172  Oid constrrelid = InvalidOid;
173  ObjectAddress myself,
174  referenced;
175  char *oldtablename = NULL;
176  char *newtablename = NULL;
177  bool partition_recurse;
178  bool trigger_exists = false;
179  Oid existing_constraint_oid = InvalidOid;
180  bool existing_isInternal = false;
181 
182  if (OidIsValid(relOid))
183  rel = table_open(relOid, ShareRowExclusiveLock);
184  else
186 
187  /*
188  * Triggers must be on tables or views, and there are additional
189  * relation-type-specific restrictions.
190  */
191  if (rel->rd_rel->relkind == RELKIND_RELATION)
192  {
193  /* Tables can't have INSTEAD OF triggers */
194  if (stmt->timing != TRIGGER_TYPE_BEFORE &&
195  stmt->timing != TRIGGER_TYPE_AFTER)
196  ereport(ERROR,
197  (errcode(ERRCODE_WRONG_OBJECT_TYPE),
198  errmsg("\"%s\" is a table",
200  errdetail("Tables cannot have INSTEAD OF triggers.")));
201  }
202  else if (rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE)
203  {
204  /* Partitioned tables can't have INSTEAD OF triggers */
205  if (stmt->timing != TRIGGER_TYPE_BEFORE &&
206  stmt->timing != TRIGGER_TYPE_AFTER)
207  ereport(ERROR,
208  (errcode(ERRCODE_WRONG_OBJECT_TYPE),
209  errmsg("\"%s\" is a table",
211  errdetail("Tables cannot have INSTEAD OF triggers.")));
212 
213  /*
214  * FOR EACH ROW triggers have further restrictions
215  */
216  if (stmt->row)
217  {
218  /*
219  * Disallow use of transition tables.
220  *
221  * Note that we have another restriction about transition tables
222  * in partitions; search for 'has_superclass' below for an
223  * explanation. The check here is just to protect from the fact
224  * that if we allowed it here, the creation would succeed for a
225  * partitioned table with no partitions, but would be blocked by
226  * the other restriction when the first partition was created,
227  * which is very unfriendly behavior.
228  */
229  if (stmt->transitionRels != NIL)
230  ereport(ERROR,
231  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
232  errmsg("\"%s\" is a partitioned table",
234  errdetail("Triggers on partitioned tables cannot have transition tables.")));
235  }
236  }
237  else if (rel->rd_rel->relkind == RELKIND_VIEW)
238  {
239  /*
240  * Views can have INSTEAD OF triggers (which we check below are
241  * row-level), or statement-level BEFORE/AFTER triggers.
242  */
243  if (stmt->timing != TRIGGER_TYPE_INSTEAD && stmt->row)
244  ereport(ERROR,
245  (errcode(ERRCODE_WRONG_OBJECT_TYPE),
246  errmsg("\"%s\" is a view",
248  errdetail("Views cannot have row-level BEFORE or AFTER triggers.")));
249  /* Disallow TRUNCATE triggers on VIEWs */
250  if (TRIGGER_FOR_TRUNCATE(stmt->events))
251  ereport(ERROR,
252  (errcode(ERRCODE_WRONG_OBJECT_TYPE),
253  errmsg("\"%s\" is a view",
255  errdetail("Views cannot have TRUNCATE triggers.")));
256  }
257  else if (rel->rd_rel->relkind == RELKIND_FOREIGN_TABLE)
258  {
259  if (stmt->timing != TRIGGER_TYPE_BEFORE &&
260  stmt->timing != TRIGGER_TYPE_AFTER)
261  ereport(ERROR,
262  (errcode(ERRCODE_WRONG_OBJECT_TYPE),
263  errmsg("\"%s\" is a foreign table",
265  errdetail("Foreign tables cannot have INSTEAD OF triggers.")));
266 
267  if (TRIGGER_FOR_TRUNCATE(stmt->events))
268  ereport(ERROR,
269  (errcode(ERRCODE_WRONG_OBJECT_TYPE),
270  errmsg("\"%s\" is a foreign table",
272  errdetail("Foreign tables cannot have TRUNCATE triggers.")));
273 
274  /*
275  * We disallow constraint triggers to protect the assumption that
276  * triggers on FKs can't be deferred. See notes with AfterTriggers
277  * data structures, below.
278  */
279  if (stmt->isconstraint)
280  ereport(ERROR,
281  (errcode(ERRCODE_WRONG_OBJECT_TYPE),
282  errmsg("\"%s\" is a foreign table",
284  errdetail("Foreign tables cannot have constraint triggers.")));
285  }
286  else
287  ereport(ERROR,
288  (errcode(ERRCODE_WRONG_OBJECT_TYPE),
289  errmsg("\"%s\" is not a table or view",
290  RelationGetRelationName(rel))));
291 
293  ereport(ERROR,
294  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
295  errmsg("permission denied: \"%s\" is a system catalog",
296  RelationGetRelationName(rel))));
297 
298  if (stmt->isconstraint)
299  {
300  /*
301  * We must take a lock on the target relation to protect against
302  * concurrent drop. It's not clear that AccessShareLock is strong
303  * enough, but we certainly need at least that much... otherwise, we
304  * might end up creating a pg_constraint entry referencing a
305  * nonexistent table.
306  */
307  if (OidIsValid(refRelOid))
308  {
309  LockRelationOid(refRelOid, AccessShareLock);
310  constrrelid = refRelOid;
311  }
312  else if (stmt->constrrel != NULL)
313  constrrelid = RangeVarGetRelid(stmt->constrrel, AccessShareLock,
314  false);
315  }
316 
317  /* permission checks */
318  if (!isInternal)
319  {
320  aclresult = pg_class_aclcheck(RelationGetRelid(rel), GetUserId(),
321  ACL_TRIGGER);
322  if (aclresult != ACLCHECK_OK)
323  aclcheck_error(aclresult, get_relkind_objtype(rel->rd_rel->relkind),
325 
326  if (OidIsValid(constrrelid))
327  {
328  aclresult = pg_class_aclcheck(constrrelid, GetUserId(),
329  ACL_TRIGGER);
330  if (aclresult != ACLCHECK_OK)
331  aclcheck_error(aclresult, get_relkind_objtype(get_rel_relkind(constrrelid)),
332  get_rel_name(constrrelid));
333  }
334  }
335 
336  /*
337  * When called on a partitioned table to create a FOR EACH ROW trigger
338  * that's not internal, we create one trigger for each partition, too.
339  *
340  * For that, we'd better hold lock on all of them ahead of time.
341  */
342  partition_recurse = !isInternal && stmt->row &&
343  rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE;
344  if (partition_recurse)
346  ShareRowExclusiveLock, NULL));
347 
348  /* Compute tgtype */
349  TRIGGER_CLEAR_TYPE(tgtype);
350  if (stmt->row)
351  TRIGGER_SETT_ROW(tgtype);
352  tgtype |= stmt->timing;
353  tgtype |= stmt->events;
354 
355  /* Disallow ROW-level TRUNCATE triggers */
356  if (TRIGGER_FOR_ROW(tgtype) && TRIGGER_FOR_TRUNCATE(tgtype))
357  ereport(ERROR,
358  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
359  errmsg("TRUNCATE FOR EACH ROW triggers are not supported")));
360 
361  /* INSTEAD triggers must be row-level, and can't have WHEN or columns */
362  if (TRIGGER_FOR_INSTEAD(tgtype))
363  {
364  if (!TRIGGER_FOR_ROW(tgtype))
365  ereport(ERROR,
366  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
367  errmsg("INSTEAD OF triggers must be FOR EACH ROW")));
368  if (stmt->whenClause)
369  ereport(ERROR,
370  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
371  errmsg("INSTEAD OF triggers cannot have WHEN conditions")));
372  if (stmt->columns != NIL)
373  ereport(ERROR,
374  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
375  errmsg("INSTEAD OF triggers cannot have column lists")));
376  }
377 
378  /*
379  * We don't yet support naming ROW transition variables, but the parser
380  * recognizes the syntax so we can give a nicer message here.
381  *
382  * Per standard, REFERENCING TABLE names are only allowed on AFTER
383  * triggers. Per standard, REFERENCING ROW names are not allowed with FOR
384  * EACH STATEMENT. Per standard, each OLD/NEW, ROW/TABLE permutation is
385  * only allowed once. Per standard, OLD may not be specified when
386  * creating a trigger only for INSERT, and NEW may not be specified when
387  * creating a trigger only for DELETE.
388  *
389  * Notice that the standard allows an AFTER ... FOR EACH ROW trigger to
390  * reference both ROW and TABLE transition data.
391  */
392  if (stmt->transitionRels != NIL)
393  {
394  List *varList = stmt->transitionRels;
395  ListCell *lc;
396 
397  foreach(lc, varList)
398  {
400 
401  if (!(tt->isTable))
402  ereport(ERROR,
403  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
404  errmsg("ROW variable naming in the REFERENCING clause is not supported"),
405  errhint("Use OLD TABLE or NEW TABLE for naming transition tables.")));
406 
407  /*
408  * Because of the above test, we omit further ROW-related testing
409  * below. If we later allow naming OLD and NEW ROW variables,
410  * adjustments will be needed below.
411  */
412 
413  if (rel->rd_rel->relkind == RELKIND_FOREIGN_TABLE)
414  ereport(ERROR,
415  (errcode(ERRCODE_WRONG_OBJECT_TYPE),
416  errmsg("\"%s\" is a foreign table",
418  errdetail("Triggers on foreign tables cannot have transition tables.")));
419 
420  if (rel->rd_rel->relkind == RELKIND_VIEW)
421  ereport(ERROR,
422  (errcode(ERRCODE_WRONG_OBJECT_TYPE),
423  errmsg("\"%s\" is a view",
425  errdetail("Triggers on views cannot have transition tables.")));
426 
427  /*
428  * We currently don't allow row-level triggers with transition
429  * tables on partition or inheritance children. Such triggers
430  * would somehow need to see tuples converted to the format of the
431  * table they're attached to, and it's not clear which subset of
432  * tuples each child should see. See also the prohibitions in
433  * ATExecAttachPartition() and ATExecAddInherit().
434  */
435  if (TRIGGER_FOR_ROW(tgtype) && has_superclass(rel->rd_id))
436  {
437  /* Use appropriate error message. */
438  if (rel->rd_rel->relispartition)
439  ereport(ERROR,
440  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
441  errmsg("ROW triggers with transition tables are not supported on partitions")));
442  else
443  ereport(ERROR,
444  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
445  errmsg("ROW triggers with transition tables are not supported on inheritance children")));
446  }
447 
448  if (stmt->timing != TRIGGER_TYPE_AFTER)
449  ereport(ERROR,
450  (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
451  errmsg("transition table name can only be specified for an AFTER trigger")));
452 
453  if (TRIGGER_FOR_TRUNCATE(tgtype))
454  ereport(ERROR,
455  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
456  errmsg("TRUNCATE triggers with transition tables are not supported")));
457 
458  /*
459  * We currently don't allow multi-event triggers ("INSERT OR
460  * UPDATE") with transition tables, because it's not clear how to
461  * handle INSERT ... ON CONFLICT statements which can fire both
462  * INSERT and UPDATE triggers. We show the inserted tuples to
463  * INSERT triggers and the updated tuples to UPDATE triggers, but
464  * it's not yet clear what INSERT OR UPDATE trigger should see.
465  * This restriction could be lifted if we can decide on the right
466  * semantics in a later release.
467  */
468  if (((TRIGGER_FOR_INSERT(tgtype) ? 1 : 0) +
469  (TRIGGER_FOR_UPDATE(tgtype) ? 1 : 0) +
470  (TRIGGER_FOR_DELETE(tgtype) ? 1 : 0)) != 1)
471  ereport(ERROR,
472  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
473  errmsg("transition tables cannot be specified for triggers with more than one event")));
474 
475  /*
476  * We currently don't allow column-specific triggers with
477  * transition tables. Per spec, that seems to require
478  * accumulating separate transition tables for each combination of
479  * columns, which is a lot of work for a rather marginal feature.
480  */
481  if (stmt->columns != NIL)
482  ereport(ERROR,
483  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
484  errmsg("transition tables cannot be specified for triggers with column lists")));
485 
486  /*
487  * We disallow constraint triggers with transition tables, to
488  * protect the assumption that such triggers can't be deferred.
489  * See notes with AfterTriggers data structures, below.
490  *
491  * Currently this is enforced by the grammar, so just Assert here.
492  */
493  Assert(!stmt->isconstraint);
494 
495  if (tt->isNew)
496  {
497  if (!(TRIGGER_FOR_INSERT(tgtype) ||
498  TRIGGER_FOR_UPDATE(tgtype)))
499  ereport(ERROR,
500  (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
501  errmsg("NEW TABLE can only be specified for an INSERT or UPDATE trigger")));
502 
503  if (newtablename != NULL)
504  ereport(ERROR,
505  (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
506  errmsg("NEW TABLE cannot be specified multiple times")));
507 
508  newtablename = tt->name;
509  }
510  else
511  {
512  if (!(TRIGGER_FOR_DELETE(tgtype) ||
513  TRIGGER_FOR_UPDATE(tgtype)))
514  ereport(ERROR,
515  (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
516  errmsg("OLD TABLE can only be specified for a DELETE or UPDATE trigger")));
517 
518  if (oldtablename != NULL)
519  ereport(ERROR,
520  (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
521  errmsg("OLD TABLE cannot be specified multiple times")));
522 
523  oldtablename = tt->name;
524  }
525  }
526 
527  if (newtablename != NULL && oldtablename != NULL &&
528  strcmp(newtablename, oldtablename) == 0)
529  ereport(ERROR,
530  (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
531  errmsg("OLD TABLE name and NEW TABLE name cannot be the same")));
532  }
533 
534  /*
535  * Parse the WHEN clause, if any and we weren't passed an already
536  * transformed one.
537  *
538  * Note that as a side effect, we fill whenRtable when parsing. If we got
539  * an already parsed clause, this does not occur, which is what we want --
540  * no point in adding redundant dependencies below.
541  */
542  if (!whenClause && stmt->whenClause)
543  {
544  ParseState *pstate;
545  ParseNamespaceItem *nsitem;
546  List *varList;
547  ListCell *lc;
548 
549  /* Set up a pstate to parse with */
550  pstate = make_parsestate(NULL);
551  pstate->p_sourcetext = queryString;
552 
553  /*
554  * Set up nsitems for OLD and NEW references.
555  *
556  * 'OLD' must always have varno equal to 1 and 'NEW' equal to 2.
557  */
558  nsitem = addRangeTableEntryForRelation(pstate, rel,
560  makeAlias("old", NIL),
561  false, false);
562  addNSItemToQuery(pstate, nsitem, false, true, true);
563  nsitem = addRangeTableEntryForRelation(pstate, rel,
565  makeAlias("new", NIL),
566  false, false);
567  addNSItemToQuery(pstate, nsitem, false, true, true);
568 
569  /* Transform expression. Copy to be sure we don't modify original */
570  whenClause = transformWhereClause(pstate,
571  copyObject(stmt->whenClause),
573  "WHEN");
574  /* we have to fix its collations too */
575  assign_expr_collations(pstate, whenClause);
576 
577  /*
578  * Check for disallowed references to OLD/NEW.
579  *
580  * NB: pull_var_clause is okay here only because we don't allow
581  * subselects in WHEN clauses; it would fail to examine the contents
582  * of subselects.
583  */
584  varList = pull_var_clause(whenClause, 0);
585  foreach(lc, varList)
586  {
587  Var *var = (Var *) lfirst(lc);
588 
589  switch (var->varno)
590  {
591  case PRS2_OLD_VARNO:
592  if (!TRIGGER_FOR_ROW(tgtype))
593  ereport(ERROR,
594  (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
595  errmsg("statement trigger's WHEN condition cannot reference column values"),
596  parser_errposition(pstate, var->location)));
597  if (TRIGGER_FOR_INSERT(tgtype))
598  ereport(ERROR,
599  (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
600  errmsg("INSERT trigger's WHEN condition cannot reference OLD values"),
601  parser_errposition(pstate, var->location)));
602  /* system columns are okay here */
603  break;
604  case PRS2_NEW_VARNO:
605  if (!TRIGGER_FOR_ROW(tgtype))
606  ereport(ERROR,
607  (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
608  errmsg("statement trigger's WHEN condition cannot reference column values"),
609  parser_errposition(pstate, var->location)));
610  if (TRIGGER_FOR_DELETE(tgtype))
611  ereport(ERROR,
612  (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
613  errmsg("DELETE trigger's WHEN condition cannot reference NEW values"),
614  parser_errposition(pstate, var->location)));
615  if (var->varattno < 0 && TRIGGER_FOR_BEFORE(tgtype))
616  ereport(ERROR,
617  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
618  errmsg("BEFORE trigger's WHEN condition cannot reference NEW system columns"),
619  parser_errposition(pstate, var->location)));
620  if (TRIGGER_FOR_BEFORE(tgtype) &&
621  var->varattno == 0 &&
622  RelationGetDescr(rel)->constr &&
623  RelationGetDescr(rel)->constr->has_generated_stored)
624  ereport(ERROR,
625  (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
626  errmsg("BEFORE trigger's WHEN condition cannot reference NEW generated columns"),
627  errdetail("A whole-row reference is used and the table contains generated columns."),
628  parser_errposition(pstate, var->location)));
629  if (TRIGGER_FOR_BEFORE(tgtype) &&
630  var->varattno > 0 &&
631  TupleDescAttr(RelationGetDescr(rel), var->varattno - 1)->attgenerated)
632  ereport(ERROR,
633  (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
634  errmsg("BEFORE trigger's WHEN condition cannot reference NEW generated columns"),
635  errdetail("Column \"%s\" is a generated column.",
636  NameStr(TupleDescAttr(RelationGetDescr(rel), var->varattno - 1)->attname)),
637  parser_errposition(pstate, var->location)));
638  break;
639  default:
640  /* can't happen without add_missing_from, so just elog */
641  elog(ERROR, "trigger WHEN condition cannot contain references to other relations");
642  break;
643  }
644  }
645 
646  /* we'll need the rtable for recordDependencyOnExpr */
647  whenRtable = pstate->p_rtable;
648 
649  qual = nodeToString(whenClause);
650 
651  free_parsestate(pstate);
652  }
653  else if (!whenClause)
654  {
655  whenClause = NULL;
656  whenRtable = NIL;
657  qual = NULL;
658  }
659  else
660  {
661  qual = nodeToString(whenClause);
662  whenRtable = NIL;
663  }
664 
665  /*
666  * Find and validate the trigger function.
667  */
668  if (!OidIsValid(funcoid))
669  funcoid = LookupFuncName(stmt->funcname, 0, NULL, false);
670  if (!isInternal)
671  {
672  aclresult = pg_proc_aclcheck(funcoid, GetUserId(), ACL_EXECUTE);
673  if (aclresult != ACLCHECK_OK)
674  aclcheck_error(aclresult, OBJECT_FUNCTION,
675  NameListToString(stmt->funcname));
676  }
677  funcrettype = get_func_rettype(funcoid);
678  if (funcrettype != TRIGGEROID)
679  ereport(ERROR,
680  (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
681  errmsg("function %s must return type %s",
682  NameListToString(stmt->funcname), "trigger")));
683 
684  /*
685  * Scan pg_trigger to see if there is already a trigger of the same name.
686  * Skip this for internally generated triggers, since we'll modify the
687  * name to be unique below.
688  *
689  * NOTE that this is cool only because we have ShareRowExclusiveLock on
690  * the relation, so the trigger set won't be changing underneath us.
691  */
692  tgrel = table_open(TriggerRelationId, RowExclusiveLock);
693  if (!isInternal)
694  {
695  ScanKeyData skeys[2];
696  SysScanDesc tgscan;
697 
698  ScanKeyInit(&skeys[0],
699  Anum_pg_trigger_tgrelid,
700  BTEqualStrategyNumber, F_OIDEQ,
702 
703  ScanKeyInit(&skeys[1],
704  Anum_pg_trigger_tgname,
705  BTEqualStrategyNumber, F_NAMEEQ,
706  CStringGetDatum(stmt->trigname));
707 
708  tgscan = systable_beginscan(tgrel, TriggerRelidNameIndexId, true,
709  NULL, 2, skeys);
710 
711  /* There should be at most one matching tuple */
712  if (HeapTupleIsValid(tuple = systable_getnext(tgscan)))
713  {
714  Form_pg_trigger oldtrigger = (Form_pg_trigger) GETSTRUCT(tuple);
715 
716  trigoid = oldtrigger->oid;
717  existing_constraint_oid = oldtrigger->tgconstraint;
718  existing_isInternal = oldtrigger->tgisinternal;
719  trigger_exists = true;
720  /* copy the tuple to use in CatalogTupleUpdate() */
721  tuple = heap_copytuple(tuple);
722  }
723  systable_endscan(tgscan);
724  }
725 
726  if (!trigger_exists)
727  {
728  /* Generate the OID for the new trigger. */
729  trigoid = GetNewOidWithIndex(tgrel, TriggerOidIndexId,
730  Anum_pg_trigger_oid);
731  }
732  else
733  {
734  /*
735  * If OR REPLACE was specified, we'll replace the old trigger;
736  * otherwise complain about the duplicate name.
737  */
738  if (!stmt->replace)
739  ereport(ERROR,
741  errmsg("trigger \"%s\" for relation \"%s\" already exists",
742  stmt->trigname, RelationGetRelationName(rel))));
743 
744  /*
745  * An internal trigger cannot be replaced by a user-defined trigger.
746  * However, skip this test when in_partition, because then we're
747  * recursing from a partitioned table and the check was made at the
748  * parent level. Child triggers will always be marked "internal" (so
749  * this test does protect us from the user trying to replace a child
750  * trigger directly).
751  */
752  if (existing_isInternal && !isInternal && !in_partition)
753  ereport(ERROR,
755  errmsg("trigger \"%s\" for relation \"%s\" is an internal trigger",
756  stmt->trigname, RelationGetRelationName(rel))));
757 
758  /*
759  * It is not allowed to replace with a constraint trigger; gram.y
760  * should have enforced this already.
761  */
762  Assert(!stmt->isconstraint);
763 
764  /*
765  * It is not allowed to replace an existing constraint trigger,
766  * either. (The reason for these restrictions is partly that it seems
767  * difficult to deal with pending trigger events in such cases, and
768  * partly that the command might imply changing the constraint's
769  * properties as well, which doesn't seem nice.)
770  */
771  if (OidIsValid(existing_constraint_oid))
772  ereport(ERROR,
774  errmsg("trigger \"%s\" for relation \"%s\" is a constraint trigger",
775  stmt->trigname, RelationGetRelationName(rel))));
776  }
777 
778  /*
779  * If it's a user-entered CREATE CONSTRAINT TRIGGER command, make a
780  * corresponding pg_constraint entry.
781  */
782  if (stmt->isconstraint && !OidIsValid(constraintOid))
783  {
784  /* Internal callers should have made their own constraints */
785  Assert(!isInternal);
786  constraintOid = CreateConstraintEntry(stmt->trigname,
788  CONSTRAINT_TRIGGER,
789  stmt->deferrable,
790  stmt->initdeferred,
791  true,
792  InvalidOid, /* no parent */
793  RelationGetRelid(rel),
794  NULL, /* no conkey */
795  0,
796  0,
797  InvalidOid, /* no domain */
798  InvalidOid, /* no index */
799  InvalidOid, /* no foreign key */
800  NULL,
801  NULL,
802  NULL,
803  NULL,
804  0,
805  ' ',
806  ' ',
807  ' ',
808  NULL, /* no exclusion */
809  NULL, /* no check constraint */
810  NULL,
811  true, /* islocal */
812  0, /* inhcount */
813  true, /* noinherit */
814  isInternal); /* is_internal */
815  }
816 
817  /*
818  * If trigger is internally generated, modify the provided trigger name to
819  * ensure uniqueness by appending the trigger OID. (Callers will usually
820  * supply a simple constant trigger name in these cases.)
821  */
822  if (isInternal)
823  {
824  snprintf(internaltrigname, sizeof(internaltrigname),
825  "%s_%u", stmt->trigname, trigoid);
826  trigname = internaltrigname;
827  }
828  else
829  {
830  /* user-defined trigger; use the specified trigger name as-is */
831  trigname = stmt->trigname;
832  }
833 
834  /*
835  * Build the new pg_trigger tuple.
836  *
837  * When we're creating a trigger in a partition, we mark it as internal,
838  * even though we don't do the isInternal magic in this function. This
839  * makes the triggers in partitions identical to the ones in the
840  * partitioned tables, except that they are marked internal.
841  */
842  memset(nulls, false, sizeof(nulls));
843 
844  values[Anum_pg_trigger_oid - 1] = ObjectIdGetDatum(trigoid);
845  values[Anum_pg_trigger_tgrelid - 1] = ObjectIdGetDatum(RelationGetRelid(rel));
846  values[Anum_pg_trigger_tgparentid - 1] = ObjectIdGetDatum(parentTriggerOid);
847  values[Anum_pg_trigger_tgname - 1] = DirectFunctionCall1(namein,
848  CStringGetDatum(trigname));
849  values[Anum_pg_trigger_tgfoid - 1] = ObjectIdGetDatum(funcoid);
850  values[Anum_pg_trigger_tgtype - 1] = Int16GetDatum(tgtype);
851  values[Anum_pg_trigger_tgenabled - 1] = CharGetDatum(TRIGGER_FIRES_ON_ORIGIN);
852  values[Anum_pg_trigger_tgisinternal - 1] = BoolGetDatum(isInternal || in_partition);
853  values[Anum_pg_trigger_tgconstrrelid - 1] = ObjectIdGetDatum(constrrelid);
854  values[Anum_pg_trigger_tgconstrindid - 1] = ObjectIdGetDatum(indexOid);
855  values[Anum_pg_trigger_tgconstraint - 1] = ObjectIdGetDatum(constraintOid);
856  values[Anum_pg_trigger_tgdeferrable - 1] = BoolGetDatum(stmt->deferrable);
857  values[Anum_pg_trigger_tginitdeferred - 1] = BoolGetDatum(stmt->initdeferred);
858 
859  if (stmt->args)
860  {
861  ListCell *le;
862  char *args;
863  int16 nargs = list_length(stmt->args);
864  int len = 0;
865 
866  foreach(le, stmt->args)
867  {
868  char *ar = strVal(lfirst(le));
869 
870  len += strlen(ar) + 4;
871  for (; *ar; ar++)
872  {
873  if (*ar == '\\')
874  len++;
875  }
876  }
877  args = (char *) palloc(len + 1);
878  args[0] = '\0';
879  foreach(le, stmt->args)
880  {
881  char *s = strVal(lfirst(le));
882  char *d = args + strlen(args);
883 
884  while (*s)
885  {
886  if (*s == '\\')
887  *d++ = '\\';
888  *d++ = *s++;
889  }
890  strcpy(d, "\\000");
891  }
892  values[Anum_pg_trigger_tgnargs - 1] = Int16GetDatum(nargs);
893  values[Anum_pg_trigger_tgargs - 1] = DirectFunctionCall1(byteain,
894  CStringGetDatum(args));
895  }
896  else
897  {
898  values[Anum_pg_trigger_tgnargs - 1] = Int16GetDatum(0);
899  values[Anum_pg_trigger_tgargs - 1] = DirectFunctionCall1(byteain,
900  CStringGetDatum(""));
901  }
902 
903  /* build column number array if it's a column-specific trigger */
904  ncolumns = list_length(stmt->columns);
905  if (ncolumns == 0)
906  columns = NULL;
907  else
908  {
909  ListCell *cell;
910  int i = 0;
911 
912  columns = (int16 *) palloc(ncolumns * sizeof(int16));
913  foreach(cell, stmt->columns)
914  {
915  char *name = strVal(lfirst(cell));
916  int16 attnum;
917  int j;
918 
919  /* Lookup column name. System columns are not allowed */
920  attnum = attnameAttNum(rel, name, false);
921  if (attnum == InvalidAttrNumber)
922  ereport(ERROR,
923  (errcode(ERRCODE_UNDEFINED_COLUMN),
924  errmsg("column \"%s\" of relation \"%s\" does not exist",
925  name, RelationGetRelationName(rel))));
926 
927  /* Check for duplicates */
928  for (j = i - 1; j >= 0; j--)
929  {
930  if (columns[j] == attnum)
931  ereport(ERROR,
932  (errcode(ERRCODE_DUPLICATE_COLUMN),
933  errmsg("column \"%s\" specified more than once",
934  name)));
935  }
936 
937  columns[i++] = attnum;
938  }
939  }
940  tgattr = buildint2vector(columns, ncolumns);
941  values[Anum_pg_trigger_tgattr - 1] = PointerGetDatum(tgattr);
942 
943  /* set tgqual if trigger has WHEN clause */
944  if (qual)
945  values[Anum_pg_trigger_tgqual - 1] = CStringGetTextDatum(qual);
946  else
947  nulls[Anum_pg_trigger_tgqual - 1] = true;
948 
949  if (oldtablename)
950  values[Anum_pg_trigger_tgoldtable - 1] = DirectFunctionCall1(namein,
951  CStringGetDatum(oldtablename));
952  else
953  nulls[Anum_pg_trigger_tgoldtable - 1] = true;
954  if (newtablename)
955  values[Anum_pg_trigger_tgnewtable - 1] = DirectFunctionCall1(namein,
956  CStringGetDatum(newtablename));
957  else
958  nulls[Anum_pg_trigger_tgnewtable - 1] = true;
959 
960  /*
961  * Insert or replace tuple in pg_trigger.
962  */
963  if (!trigger_exists)
964  {
965  tuple = heap_form_tuple(tgrel->rd_att, values, nulls);
966  CatalogTupleInsert(tgrel, tuple);
967  }
968  else
969  {
970  HeapTuple newtup;
971 
972  newtup = heap_form_tuple(tgrel->rd_att, values, nulls);
973  CatalogTupleUpdate(tgrel, &tuple->t_self, newtup);
974  heap_freetuple(newtup);
975  }
976 
977  heap_freetuple(tuple); /* free either original or new tuple */
979 
980  pfree(DatumGetPointer(values[Anum_pg_trigger_tgname - 1]));
981  pfree(DatumGetPointer(values[Anum_pg_trigger_tgargs - 1]));
982  pfree(DatumGetPointer(values[Anum_pg_trigger_tgattr - 1]));
983  if (oldtablename)
984  pfree(DatumGetPointer(values[Anum_pg_trigger_tgoldtable - 1]));
985  if (newtablename)
986  pfree(DatumGetPointer(values[Anum_pg_trigger_tgnewtable - 1]));
987 
988  /*
989  * Update relation's pg_class entry; if necessary; and if not, send an SI
990  * message to make other backends (and this one) rebuild relcache entries.
991  */
992  pgrel = table_open(RelationRelationId, RowExclusiveLock);
993  tuple = SearchSysCacheCopy1(RELOID,
995  if (!HeapTupleIsValid(tuple))
996  elog(ERROR, "cache lookup failed for relation %u",
997  RelationGetRelid(rel));
998  if (!((Form_pg_class) GETSTRUCT(tuple))->relhastriggers)
999  {
1000  ((Form_pg_class) GETSTRUCT(tuple))->relhastriggers = true;
1001 
1002  CatalogTupleUpdate(pgrel, &tuple->t_self, tuple);
1003 
1005  }
1006  else
1008 
1009  heap_freetuple(tuple);
1010  table_close(pgrel, RowExclusiveLock);
1011 
1012  /*
1013  * If we're replacing a trigger, flush all the old dependencies before
1014  * recording new ones.
1015  */
1016  if (trigger_exists)
1017  deleteDependencyRecordsFor(TriggerRelationId, trigoid, true);
1018 
1019  /*
1020  * Record dependencies for trigger. Always place a normal dependency on
1021  * the function.
1022  */
1023  myself.classId = TriggerRelationId;
1024  myself.objectId = trigoid;
1025  myself.objectSubId = 0;
1026 
1027  referenced.classId = ProcedureRelationId;
1028  referenced.objectId = funcoid;
1029  referenced.objectSubId = 0;
1030  recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
1031 
1032  if (isInternal && OidIsValid(constraintOid))
1033  {
1034  /*
1035  * Internally-generated trigger for a constraint, so make it an
1036  * internal dependency of the constraint. We can skip depending on
1037  * the relation(s), as there'll be an indirect dependency via the
1038  * constraint.
1039  */
1040  referenced.classId = ConstraintRelationId;
1041  referenced.objectId = constraintOid;
1042  referenced.objectSubId = 0;
1043  recordDependencyOn(&myself, &referenced, DEPENDENCY_INTERNAL);
1044  }
1045  else
1046  {
1047  /*
1048  * User CREATE TRIGGER, so place dependencies. We make trigger be
1049  * auto-dropped if its relation is dropped or if the FK relation is
1050  * dropped. (Auto drop is compatible with our pre-7.3 behavior.)
1051  */
1052  referenced.classId = RelationRelationId;
1053  referenced.objectId = RelationGetRelid(rel);
1054  referenced.objectSubId = 0;
1055  recordDependencyOn(&myself, &referenced, DEPENDENCY_AUTO);
1056 
1057  if (OidIsValid(constrrelid))
1058  {
1059  referenced.classId = RelationRelationId;
1060  referenced.objectId = constrrelid;
1061  referenced.objectSubId = 0;
1062  recordDependencyOn(&myself, &referenced, DEPENDENCY_AUTO);
1063  }
1064  /* Not possible to have an index dependency in this case */
1065  Assert(!OidIsValid(indexOid));
1066 
1067  /*
1068  * If it's a user-specified constraint trigger, make the constraint
1069  * internally dependent on the trigger instead of vice versa.
1070  */
1071  if (OidIsValid(constraintOid))
1072  {
1073  referenced.classId = ConstraintRelationId;
1074  referenced.objectId = constraintOid;
1075  referenced.objectSubId = 0;
1076  recordDependencyOn(&referenced, &myself, DEPENDENCY_INTERNAL);
1077  }
1078 
1079  /*
1080  * If it's a partition trigger, create the partition dependencies.
1081  */
1082  if (OidIsValid(parentTriggerOid))
1083  {
1084  ObjectAddressSet(referenced, TriggerRelationId, parentTriggerOid);
1085  recordDependencyOn(&myself, &referenced, DEPENDENCY_PARTITION_PRI);
1086  ObjectAddressSet(referenced, RelationRelationId, RelationGetRelid(rel));
1087  recordDependencyOn(&myself, &referenced, DEPENDENCY_PARTITION_SEC);
1088  }
1089  }
1090 
1091  /* If column-specific trigger, add normal dependencies on columns */
1092  if (columns != NULL)
1093  {
1094  int i;
1095 
1096  referenced.classId = RelationRelationId;
1097  referenced.objectId = RelationGetRelid(rel);
1098  for (i = 0; i < ncolumns; i++)
1099  {
1100  referenced.objectSubId = columns[i];
1101  recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
1102  }
1103  }
1104 
1105  /*
1106  * If it has a WHEN clause, add dependencies on objects mentioned in the
1107  * expression (eg, functions, as well as any columns used).
1108  */
1109  if (whenRtable != NIL)
1110  recordDependencyOnExpr(&myself, whenClause, whenRtable,
1112 
1113  /* Post creation hook for new trigger */
1114  InvokeObjectPostCreateHookArg(TriggerRelationId, trigoid, 0,
1115  isInternal);
1116 
1117  /*
1118  * Lastly, create the trigger on child relations, if needed.
1119  */
1120  if (partition_recurse)
1121  {
1122  PartitionDesc partdesc = RelationGetPartitionDesc(rel, true);
1123  List *idxs = NIL;
1124  List *childTbls = NIL;
1125  ListCell *l;
1126  int i;
1127  MemoryContext oldcxt,
1128  perChildCxt;
1129 
1131  "part trig clone",
1133 
1134  /*
1135  * When a trigger is being created associated with an index, we'll
1136  * need to associate the trigger in each child partition with the
1137  * corresponding index on it.
1138  */
1139  if (OidIsValid(indexOid))
1140  {
1141  ListCell *l;
1142  List *idxs = NIL;
1143 
1145  foreach(l, idxs)
1146  childTbls = lappend_oid(childTbls,
1148  false));
1149  }
1150 
1151  oldcxt = MemoryContextSwitchTo(perChildCxt);
1152 
1153  /* Iterate to create the trigger on each existing partition */
1154  for (i = 0; i < partdesc->nparts; i++)
1155  {
1156  Oid indexOnChild = InvalidOid;
1157  ListCell *l2;
1158  CreateTrigStmt *childStmt;
1159  Relation childTbl;
1160  Node *qual;
1161 
1162  childTbl = table_open(partdesc->oids[i], ShareRowExclusiveLock);
1163 
1164  /* Find which of the child indexes is the one on this partition */
1165  if (OidIsValid(indexOid))
1166  {
1167  forboth(l, idxs, l2, childTbls)
1168  {
1169  if (lfirst_oid(l2) == partdesc->oids[i])
1170  {
1171  indexOnChild = lfirst_oid(l);
1172  break;
1173  }
1174  }
1175  if (!OidIsValid(indexOnChild))
1176  elog(ERROR, "failed to find index matching index \"%s\" in partition \"%s\"",
1177  get_rel_name(indexOid),
1178  get_rel_name(partdesc->oids[i]));
1179  }
1180 
1181  /*
1182  * Initialize our fabricated parse node by copying the original
1183  * one, then resetting fields that we pass separately.
1184  */
1185  childStmt = (CreateTrigStmt *) copyObject(stmt);
1186  childStmt->funcname = NIL;
1187  childStmt->whenClause = NULL;
1188 
1189  /* If there is a WHEN clause, create a modified copy of it */
1190  qual = copyObject(whenClause);
1191  qual = (Node *)
1193  childTbl, rel);
1194  qual = (Node *)
1196  childTbl, rel);
1197 
1198  CreateTrigger(childStmt, queryString,
1199  partdesc->oids[i], refRelOid,
1200  InvalidOid, indexOnChild,
1201  funcoid, trigoid, qual,
1202  isInternal, true);
1203 
1204  table_close(childTbl, NoLock);
1205 
1206  MemoryContextReset(perChildCxt);
1207  }
1208 
1209  MemoryContextSwitchTo(oldcxt);
1210  MemoryContextDelete(perChildCxt);
1211  list_free(idxs);
1212  list_free(childTbls);
1213  }
1214 
1215  /* Keep lock on target rel until end of xact */
1216  table_close(rel, NoLock);
1217 
1218  return myself;
1219 }
1220 
1221 
1222 /*
1223  * Guts of trigger deletion.
1224  */
1225 void
1227 {
1228  Relation tgrel;
1229  SysScanDesc tgscan;
1230  ScanKeyData skey[1];
1231  HeapTuple tup;
1232  Oid relid;
1233  Relation rel;
1234 
1235  tgrel = table_open(TriggerRelationId, RowExclusiveLock);
1236 
1237  /*
1238  * Find the trigger to delete.
1239  */
1240  ScanKeyInit(&skey[0],
1241  Anum_pg_trigger_oid,
1242  BTEqualStrategyNumber, F_OIDEQ,
1243  ObjectIdGetDatum(trigOid));
1244 
1245  tgscan = systable_beginscan(tgrel, TriggerOidIndexId, true,
1246  NULL, 1, skey);
1247 
1248  tup = systable_getnext(tgscan);
1249  if (!HeapTupleIsValid(tup))
1250  elog(ERROR, "could not find tuple for trigger %u", trigOid);
1251 
1252  /*
1253  * Open and exclusive-lock the relation the trigger belongs to.
1254  */
1255  relid = ((Form_pg_trigger) GETSTRUCT(tup))->tgrelid;
1256 
1257  rel = table_open(relid, AccessExclusiveLock);
1258 
1259  if (rel->rd_rel->relkind != RELKIND_RELATION &&
1260  rel->rd_rel->relkind != RELKIND_VIEW &&
1261  rel->rd_rel->relkind != RELKIND_FOREIGN_TABLE &&
1262  rel->rd_rel->relkind != RELKIND_PARTITIONED_TABLE)
1263  ereport(ERROR,
1264  (errcode(ERRCODE_WRONG_OBJECT_TYPE),
1265  errmsg("\"%s\" is not a table, view, or foreign table",
1266  RelationGetRelationName(rel))));
1267 
1269  ereport(ERROR,
1270  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
1271  errmsg("permission denied: \"%s\" is a system catalog",
1272  RelationGetRelationName(rel))));
1273 
1274  /*
1275  * Delete the pg_trigger tuple.
1276  */
1277  CatalogTupleDelete(tgrel, &tup->t_self);
1278 
1279  systable_endscan(tgscan);
1280  table_close(tgrel, RowExclusiveLock);
1281 
1282  /*
1283  * We do not bother to try to determine whether any other triggers remain,
1284  * which would be needed in order to decide whether it's safe to clear the
1285  * relation's relhastriggers. (In any case, there might be a concurrent
1286  * process adding new triggers.) Instead, just force a relcache inval to
1287  * make other backends (and this one too!) rebuild their relcache entries.
1288  * There's no great harm in leaving relhastriggers true even if there are
1289  * no triggers left.
1290  */
1292 
1293  /* Keep lock on trigger's rel until end of xact */
1294  table_close(rel, NoLock);
1295 }
1296 
1297 /*
1298  * get_trigger_oid - Look up a trigger by name to find its OID.
1299  *
1300  * If missing_ok is false, throw an error if trigger not found. If
1301  * true, just return InvalidOid.
1302  */
1303 Oid
1304 get_trigger_oid(Oid relid, const char *trigname, bool missing_ok)
1305 {
1306  Relation tgrel;
1307  ScanKeyData skey[2];
1308  SysScanDesc tgscan;
1309  HeapTuple tup;
1310  Oid oid;
1311 
1312  /*
1313  * Find the trigger, verify permissions, set up object address
1314  */
1315  tgrel = table_open(TriggerRelationId, AccessShareLock);
1316 
1317  ScanKeyInit(&skey[0],
1318  Anum_pg_trigger_tgrelid,
1319  BTEqualStrategyNumber, F_OIDEQ,
1320  ObjectIdGetDatum(relid));
1321  ScanKeyInit(&skey[1],
1322  Anum_pg_trigger_tgname,
1323  BTEqualStrategyNumber, F_NAMEEQ,
1324  CStringGetDatum(trigname));
1325 
1326  tgscan = systable_beginscan(tgrel, TriggerRelidNameIndexId, true,
1327  NULL, 2, skey);
1328 
1329  tup = systable_getnext(tgscan);
1330 
1331  if (!HeapTupleIsValid(tup))
1332  {
1333  if (!missing_ok)
1334  ereport(ERROR,
1335  (errcode(ERRCODE_UNDEFINED_OBJECT),
1336  errmsg("trigger \"%s\" for table \"%s\" does not exist",
1337  trigname, get_rel_name(relid))));
1338  oid = InvalidOid;
1339  }
1340  else
1341  {
1342  oid = ((Form_pg_trigger) GETSTRUCT(tup))->oid;
1343  }
1344 
1345  systable_endscan(tgscan);
1346  table_close(tgrel, AccessShareLock);
1347  return oid;
1348 }
1349 
1350 /*
1351  * Perform permissions and integrity checks before acquiring a relation lock.
1352  */
1353 static void
1355  void *arg)
1356 {
1357  HeapTuple tuple;
1358  Form_pg_class form;
1359 
1360  tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
1361  if (!HeapTupleIsValid(tuple))
1362  return; /* concurrently dropped */
1363  form = (Form_pg_class) GETSTRUCT(tuple);
1364 
1365  /* only tables and views can have triggers */
1366  if (form->relkind != RELKIND_RELATION && form->relkind != RELKIND_VIEW &&
1367  form->relkind != RELKIND_FOREIGN_TABLE &&
1368  form->relkind != RELKIND_PARTITIONED_TABLE)
1369  ereport(ERROR,
1370  (errcode(ERRCODE_WRONG_OBJECT_TYPE),
1371  errmsg("\"%s\" is not a table, view, or foreign table",
1372  rv->relname)));
1373 
1374  /* you must own the table to rename one of its triggers */
1375  if (!pg_class_ownercheck(relid, GetUserId()))
1377  if (!allowSystemTableMods && IsSystemClass(relid, form))
1378  ereport(ERROR,
1379  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
1380  errmsg("permission denied: \"%s\" is a system catalog",
1381  rv->relname)));
1382 
1383  ReleaseSysCache(tuple);
1384 }
1385 
1386 /*
1387  * renametrig - changes the name of a trigger on a relation
1388  *
1389  * trigger name is changed in trigger catalog.
1390  * No record of the previous name is kept.
1391  *
1392  * get proper relrelation from relation catalog (if not arg)
1393  * scan trigger catalog
1394  * for name conflict (within rel)
1395  * for original trigger (if not arg)
1396  * modify tgname in trigger tuple
1397  * update row in catalog
1398  */
1401 {
1402  Oid tgoid;
1403  Relation targetrel;
1404  Relation tgrel;
1405  HeapTuple tuple;
1406  SysScanDesc tgscan;
1407  ScanKeyData key[2];
1408  Oid relid;
1409  ObjectAddress address;
1410 
1411  /*
1412  * Look up name, check permissions, and acquire lock (which we will NOT
1413  * release until end of transaction).
1414  */
1416  0,
1418  NULL);
1419 
1420  /* Have lock already, so just need to build relcache entry. */
1421  targetrel = relation_open(relid, NoLock);
1422 
1423  /*
1424  * Scan pg_trigger twice for existing triggers on relation. We do this in
1425  * order to ensure a trigger does not exist with newname (The unique index
1426  * on tgrelid/tgname would complain anyway) and to ensure a trigger does
1427  * exist with oldname.
1428  *
1429  * NOTE that this is cool only because we have AccessExclusiveLock on the
1430  * relation, so the trigger set won't be changing underneath us.
1431  */
1432  tgrel = table_open(TriggerRelationId, RowExclusiveLock);
1433 
1434  /*
1435  * First pass -- look for name conflict
1436  */
1437  ScanKeyInit(&key[0],
1438  Anum_pg_trigger_tgrelid,
1439  BTEqualStrategyNumber, F_OIDEQ,
1440  ObjectIdGetDatum(relid));
1441  ScanKeyInit(&key[1],
1442  Anum_pg_trigger_tgname,
1443  BTEqualStrategyNumber, F_NAMEEQ,
1444  PointerGetDatum(stmt->newname));
1445  tgscan = systable_beginscan(tgrel, TriggerRelidNameIndexId, true,
1446  NULL, 2, key);
1447  if (HeapTupleIsValid(tuple = systable_getnext(tgscan)))
1448  ereport(ERROR,
1450  errmsg("trigger \"%s\" for relation \"%s\" already exists",
1451  stmt->newname, RelationGetRelationName(targetrel))));
1452  systable_endscan(tgscan);
1453 
1454  /*
1455  * Second pass -- look for trigger existing with oldname and update
1456  */
1457  ScanKeyInit(&key[0],
1458  Anum_pg_trigger_tgrelid,
1459  BTEqualStrategyNumber, F_OIDEQ,
1460  ObjectIdGetDatum(relid));
1461  ScanKeyInit(&key[1],
1462  Anum_pg_trigger_tgname,
1463  BTEqualStrategyNumber, F_NAMEEQ,
1464  PointerGetDatum(stmt->subname));
1465  tgscan = systable_beginscan(tgrel, TriggerRelidNameIndexId, true,
1466  NULL, 2, key);
1467  if (HeapTupleIsValid(tuple = systable_getnext(tgscan)))
1468  {
1469  Form_pg_trigger trigform;
1470 
1471  /*
1472  * Update pg_trigger tuple with new tgname.
1473  */
1474  tuple = heap_copytuple(tuple); /* need a modifiable copy */
1475  trigform = (Form_pg_trigger) GETSTRUCT(tuple);
1476  tgoid = trigform->oid;
1477 
1478  namestrcpy(&trigform->tgname,
1479  stmt->newname);
1480 
1481  CatalogTupleUpdate(tgrel, &tuple->t_self, tuple);
1482 
1483  InvokeObjectPostAlterHook(TriggerRelationId,
1484  tgoid, 0);
1485 
1486  /*
1487  * Invalidate relation's relcache entry so that other backends (and
1488  * this one too!) are sent SI message to make them rebuild relcache
1489  * entries. (Ideally this should happen automatically...)
1490  */
1491  CacheInvalidateRelcache(targetrel);
1492  }
1493  else
1494  {
1495  ereport(ERROR,
1496  (errcode(ERRCODE_UNDEFINED_OBJECT),
1497  errmsg("trigger \"%s\" for table \"%s\" does not exist",
1498  stmt->subname, RelationGetRelationName(targetrel))));
1499  }
1500 
1501  ObjectAddressSet(address, TriggerRelationId, tgoid);
1502 
1503  systable_endscan(tgscan);
1504 
1505  table_close(tgrel, RowExclusiveLock);
1506 
1507  /*
1508  * Close rel, but keep exclusive lock!
1509  */
1510  relation_close(targetrel, NoLock);
1511 
1512  return address;
1513 }
1514 
1515 
1516 /*
1517  * EnableDisableTrigger()
1518  *
1519  * Called by ALTER TABLE ENABLE/DISABLE [ REPLICA | ALWAYS ] TRIGGER
1520  * to change 'tgenabled' field for the specified trigger(s)
1521  *
1522  * rel: relation to process (caller must hold suitable lock on it)
1523  * tgname: trigger to process, or NULL to scan all triggers
1524  * fires_when: new value for tgenabled field. In addition to generic
1525  * enablement/disablement, this also defines when the trigger
1526  * should be fired in session replication roles.
1527  * skip_system: if true, skip "system" triggers (constraint triggers)
1528  *
1529  * Caller should have checked permissions for the table; here we also
1530  * enforce that superuser privilege is required to alter the state of
1531  * system triggers
1532  */
1533 void
1534 EnableDisableTrigger(Relation rel, const char *tgname,
1535  char fires_when, bool skip_system, LOCKMODE lockmode)
1536 {
1537  Relation tgrel;
1538  int nkeys;
1539  ScanKeyData keys[2];
1540  SysScanDesc tgscan;
1541  HeapTuple tuple;
1542  bool found;
1543  bool changed;
1544 
1545  /* Scan the relevant entries in pg_triggers */
1546  tgrel = table_open(TriggerRelationId, RowExclusiveLock);
1547 
1548  ScanKeyInit(&keys[0],
1549  Anum_pg_trigger_tgrelid,
1550  BTEqualStrategyNumber, F_OIDEQ,
1552  if (tgname)
1553  {
1554  ScanKeyInit(&keys[1],
1555  Anum_pg_trigger_tgname,
1556  BTEqualStrategyNumber, F_NAMEEQ,
1557  CStringGetDatum(tgname));
1558  nkeys = 2;
1559  }
1560  else
1561  nkeys = 1;
1562 
1563  tgscan = systable_beginscan(tgrel, TriggerRelidNameIndexId, true,
1564  NULL, nkeys, keys);
1565 
1566  found = changed = false;
1567 
1568  while (HeapTupleIsValid(tuple = systable_getnext(tgscan)))
1569  {
1570  Form_pg_trigger oldtrig = (Form_pg_trigger) GETSTRUCT(tuple);
1571 
1572  if (oldtrig->tgisinternal)
1573  {
1574  /* system trigger ... ok to process? */
1575  if (skip_system)
1576  continue;
1577  if (!superuser())
1578  ereport(ERROR,
1579  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
1580  errmsg("permission denied: \"%s\" is a system trigger",
1581  NameStr(oldtrig->tgname))));
1582  }
1583 
1584  found = true;
1585 
1586  if (oldtrig->tgenabled != fires_when)
1587  {
1588  /* need to change this one ... make a copy to scribble on */
1589  HeapTuple newtup = heap_copytuple(tuple);
1590  Form_pg_trigger newtrig = (Form_pg_trigger) GETSTRUCT(newtup);
1591 
1592  newtrig->tgenabled = fires_when;
1593 
1594  CatalogTupleUpdate(tgrel, &newtup->t_self, newtup);
1595 
1596  heap_freetuple(newtup);
1597 
1598  changed = true;
1599  }
1600 
1601  InvokeObjectPostAlterHook(TriggerRelationId,
1602  oldtrig->oid, 0);
1603  }
1604 
1605  systable_endscan(tgscan);
1606 
1607  table_close(tgrel, RowExclusiveLock);
1608 
1609  if (tgname && !found)
1610  ereport(ERROR,
1611  (errcode(ERRCODE_UNDEFINED_OBJECT),
1612  errmsg("trigger \"%s\" for table \"%s\" does not exist",
1613  tgname, RelationGetRelationName(rel))));
1614 
1615  /*
1616  * If we changed anything, broadcast a SI inval message to force each
1617  * backend (including our own!) to rebuild relation's relcache entry.
1618  * Otherwise they will fail to apply the change promptly.
1619  */
1620  if (changed)
1622 }
1623 
1624 
1625 /*
1626  * Build trigger data to attach to the given relcache entry.
1627  *
1628  * Note that trigger data attached to a relcache entry must be stored in
1629  * CacheMemoryContext to ensure it survives as long as the relcache entry.
1630  * But we should be running in a less long-lived working context. To avoid
1631  * leaking cache memory if this routine fails partway through, we build a
1632  * temporary TriggerDesc in working memory and then copy the completed
1633  * structure into cache memory.
1634  */
1635 void
1637 {
1638  TriggerDesc *trigdesc;
1639  int numtrigs;
1640  int maxtrigs;
1641  Trigger *triggers;
1642  Relation tgrel;
1643  ScanKeyData skey;
1644  SysScanDesc tgscan;
1645  HeapTuple htup;
1646  MemoryContext oldContext;
1647  int i;
1648 
1649  /*
1650  * Allocate a working array to hold the triggers (the array is extended if
1651  * necessary)
1652  */
1653  maxtrigs = 16;
1654  triggers = (Trigger *) palloc(maxtrigs * sizeof(Trigger));
1655  numtrigs = 0;
1656 
1657  /*
1658  * Note: since we scan the triggers using TriggerRelidNameIndexId, we will
1659  * be reading the triggers in name order, except possibly during
1660  * emergency-recovery operations (ie, IgnoreSystemIndexes). This in turn
1661  * ensures that triggers will be fired in name order.
1662  */
1663  ScanKeyInit(&skey,
1664  Anum_pg_trigger_tgrelid,
1665  BTEqualStrategyNumber, F_OIDEQ,
1666  ObjectIdGetDatum(RelationGetRelid(relation)));
1667 
1668  tgrel = table_open(TriggerRelationId, AccessShareLock);
1669  tgscan = systable_beginscan(tgrel, TriggerRelidNameIndexId, true,
1670  NULL, 1, &skey);
1671 
1672  while (HeapTupleIsValid(htup = systable_getnext(tgscan)))
1673  {
1674  Form_pg_trigger pg_trigger = (Form_pg_trigger) GETSTRUCT(htup);
1675  Trigger *build;
1676  Datum datum;
1677  bool isnull;
1678 
1679  if (numtrigs >= maxtrigs)
1680  {
1681  maxtrigs *= 2;
1682  triggers = (Trigger *) repalloc(triggers, maxtrigs * sizeof(Trigger));
1683  }
1684  build = &(triggers[numtrigs]);
1685 
1686  build->tgoid = pg_trigger->oid;
1688  NameGetDatum(&pg_trigger->tgname)));
1689  build->tgfoid = pg_trigger->tgfoid;
1690  build->tgtype = pg_trigger->tgtype;
1691  build->tgenabled = pg_trigger->tgenabled;
1692  build->tgisinternal = pg_trigger->tgisinternal;
1693  build->tgisclone = OidIsValid(pg_trigger->tgparentid);
1694  build->tgconstrrelid = pg_trigger->tgconstrrelid;
1695  build->tgconstrindid = pg_trigger->tgconstrindid;
1696  build->tgconstraint = pg_trigger->tgconstraint;
1697  build->tgdeferrable = pg_trigger->tgdeferrable;
1698  build->tginitdeferred = pg_trigger->tginitdeferred;
1699  build->tgnargs = pg_trigger->tgnargs;
1700  /* tgattr is first var-width field, so OK to access directly */
1701  build->tgnattr = pg_trigger->tgattr.dim1;
1702  if (build->tgnattr > 0)
1703  {
1704  build->tgattr = (int16 *) palloc(build->tgnattr * sizeof(int16));
1705  memcpy(build->tgattr, &(pg_trigger->tgattr.values),
1706  build->tgnattr * sizeof(int16));
1707  }
1708  else
1709  build->tgattr = NULL;
1710  if (build->tgnargs > 0)
1711  {
1712  bytea *val;
1713  char *p;
1714 
1715  val = DatumGetByteaPP(fastgetattr(htup,
1716  Anum_pg_trigger_tgargs,
1717  tgrel->rd_att, &isnull));
1718  if (isnull)
1719  elog(ERROR, "tgargs is null in trigger for relation \"%s\"",
1720  RelationGetRelationName(relation));
1721  p = (char *) VARDATA_ANY(val);
1722  build->tgargs = (char **) palloc(build->tgnargs * sizeof(char *));
1723  for (i = 0; i < build->tgnargs; i++)
1724  {
1725  build->tgargs[i] = pstrdup(p);
1726  p += strlen(p) + 1;
1727  }
1728  }
1729  else
1730  build->tgargs = NULL;
1731 
1732  datum = fastgetattr(htup, Anum_pg_trigger_tgoldtable,
1733  tgrel->rd_att, &isnull);
1734  if (!isnull)
1735  build->tgoldtable =
1737  else
1738  build->tgoldtable = NULL;
1739 
1740  datum = fastgetattr(htup, Anum_pg_trigger_tgnewtable,
1741  tgrel->rd_att, &isnull);
1742  if (!isnull)
1743  build->tgnewtable =
1745  else
1746  build->tgnewtable = NULL;
1747 
1748  datum = fastgetattr(htup, Anum_pg_trigger_tgqual,
1749  tgrel->rd_att, &isnull);
1750  if (!isnull)
1751  build->tgqual = TextDatumGetCString(datum);
1752  else
1753  build->tgqual = NULL;
1754 
1755  numtrigs++;
1756  }
1757 
1758  systable_endscan(tgscan);
1759  table_close(tgrel, AccessShareLock);
1760 
1761  /* There might not be any triggers */
1762  if (numtrigs == 0)
1763  {
1764  pfree(triggers);
1765  return;
1766  }
1767 
1768  /* Build trigdesc */
1769  trigdesc = (TriggerDesc *) palloc0(sizeof(TriggerDesc));
1770  trigdesc->triggers = triggers;
1771  trigdesc->numtriggers = numtrigs;
1772  for (i = 0; i < numtrigs; i++)
1773  SetTriggerFlags(trigdesc, &(triggers[i]));
1774 
1775  /* Copy completed trigdesc into cache storage */
1777  relation->trigdesc = CopyTriggerDesc(trigdesc);
1778  MemoryContextSwitchTo(oldContext);
1779 
1780  /* Release working memory */
1781  FreeTriggerDesc(trigdesc);
1782 }
1783 
1784 /*
1785  * Update the TriggerDesc's hint flags to include the specified trigger
1786  */
1787 static void
1789 {
1790  int16 tgtype = trigger->tgtype;
1791 
1792  trigdesc->trig_insert_before_row |=
1793  TRIGGER_TYPE_MATCHES(tgtype, TRIGGER_TYPE_ROW,
1794  TRIGGER_TYPE_BEFORE, TRIGGER_TYPE_INSERT);
1795  trigdesc->trig_insert_after_row |=
1796  TRIGGER_TYPE_MATCHES(tgtype, TRIGGER_TYPE_ROW,
1797  TRIGGER_TYPE_AFTER, TRIGGER_TYPE_INSERT);
1798  trigdesc->trig_insert_instead_row |=
1799  TRIGGER_TYPE_MATCHES(tgtype, TRIGGER_TYPE_ROW,
1800  TRIGGER_TYPE_INSTEAD, TRIGGER_TYPE_INSERT);
1801  trigdesc->trig_insert_before_statement |=
1802  TRIGGER_TYPE_MATCHES(tgtype, TRIGGER_TYPE_STATEMENT,
1803  TRIGGER_TYPE_BEFORE, TRIGGER_TYPE_INSERT);
1804  trigdesc->trig_insert_after_statement |=
1805  TRIGGER_TYPE_MATCHES(tgtype, TRIGGER_TYPE_STATEMENT,
1806  TRIGGER_TYPE_AFTER, TRIGGER_TYPE_INSERT);
1807  trigdesc->trig_update_before_row |=
1808  TRIGGER_TYPE_MATCHES(tgtype, TRIGGER_TYPE_ROW,
1809  TRIGGER_TYPE_BEFORE, TRIGGER_TYPE_UPDATE);
1810  trigdesc->trig_update_after_row |=
1811  TRIGGER_TYPE_MATCHES(tgtype, TRIGGER_TYPE_ROW,
1812  TRIGGER_TYPE_AFTER, TRIGGER_TYPE_UPDATE);
1813  trigdesc->trig_update_instead_row |=
1814  TRIGGER_TYPE_MATCHES(tgtype, TRIGGER_TYPE_ROW,
1815  TRIGGER_TYPE_INSTEAD, TRIGGER_TYPE_UPDATE);
1816  trigdesc->trig_update_before_statement |=
1817  TRIGGER_TYPE_MATCHES(tgtype, TRIGGER_TYPE_STATEMENT,
1818  TRIGGER_TYPE_BEFORE, TRIGGER_TYPE_UPDATE);
1819  trigdesc->trig_update_after_statement |=
1820  TRIGGER_TYPE_MATCHES(tgtype, TRIGGER_TYPE_STATEMENT,
1821  TRIGGER_TYPE_AFTER, TRIGGER_TYPE_UPDATE);
1822  trigdesc->trig_delete_before_row |=
1823  TRIGGER_TYPE_MATCHES(tgtype, TRIGGER_TYPE_ROW,
1824  TRIGGER_TYPE_BEFORE, TRIGGER_TYPE_DELETE);
1825  trigdesc->trig_delete_after_row |=
1826  TRIGGER_TYPE_MATCHES(tgtype, TRIGGER_TYPE_ROW,
1827  TRIGGER_TYPE_AFTER, TRIGGER_TYPE_DELETE);
1828  trigdesc->trig_delete_instead_row |=
1829  TRIGGER_TYPE_MATCHES(tgtype, TRIGGER_TYPE_ROW,
1830  TRIGGER_TYPE_INSTEAD, TRIGGER_TYPE_DELETE);
1831  trigdesc->trig_delete_before_statement |=
1832  TRIGGER_TYPE_MATCHES(tgtype, TRIGGER_TYPE_STATEMENT,
1833  TRIGGER_TYPE_BEFORE, TRIGGER_TYPE_DELETE);
1834  trigdesc->trig_delete_after_statement |=
1835  TRIGGER_TYPE_MATCHES(tgtype, TRIGGER_TYPE_STATEMENT,
1836  TRIGGER_TYPE_AFTER, TRIGGER_TYPE_DELETE);
1837  /* there are no row-level truncate triggers */
1838  trigdesc->trig_truncate_before_statement |=
1839  TRIGGER_TYPE_MATCHES(tgtype, TRIGGER_TYPE_STATEMENT,
1840  TRIGGER_TYPE_BEFORE, TRIGGER_TYPE_TRUNCATE);
1841  trigdesc->trig_truncate_after_statement |=
1842  TRIGGER_TYPE_MATCHES(tgtype, TRIGGER_TYPE_STATEMENT,
1843  TRIGGER_TYPE_AFTER, TRIGGER_TYPE_TRUNCATE);
1844 
1845  trigdesc->trig_insert_new_table |=
1846  (TRIGGER_FOR_INSERT(tgtype) &&
1847  TRIGGER_USES_TRANSITION_TABLE(trigger->tgnewtable));
1848  trigdesc->trig_update_old_table |=
1849  (TRIGGER_FOR_UPDATE(tgtype) &&
1850  TRIGGER_USES_TRANSITION_TABLE(trigger->tgoldtable));
1851  trigdesc->trig_update_new_table |=
1852  (TRIGGER_FOR_UPDATE(tgtype) &&
1853  TRIGGER_USES_TRANSITION_TABLE(trigger->tgnewtable));
1854  trigdesc->trig_delete_old_table |=
1855  (TRIGGER_FOR_DELETE(tgtype) &&
1856  TRIGGER_USES_TRANSITION_TABLE(trigger->tgoldtable));
1857 }
1858 
1859 /*
1860  * Copy a TriggerDesc data structure.
1861  *
1862  * The copy is allocated in the current memory context.
1863  */
1864 TriggerDesc *
1866 {
1867  TriggerDesc *newdesc;
1868  Trigger *trigger;
1869  int i;
1870 
1871  if (trigdesc == NULL || trigdesc->numtriggers <= 0)
1872  return NULL;
1873 
1874  newdesc = (TriggerDesc *) palloc(sizeof(TriggerDesc));
1875  memcpy(newdesc, trigdesc, sizeof(TriggerDesc));
1876 
1877  trigger = (Trigger *) palloc(trigdesc->numtriggers * sizeof(Trigger));
1878  memcpy(trigger, trigdesc->triggers,
1879  trigdesc->numtriggers * sizeof(Trigger));
1880  newdesc->triggers = trigger;
1881 
1882  for (i = 0; i < trigdesc->numtriggers; i++)
1883  {
1884  trigger->tgname = pstrdup(trigger->tgname);
1885  if (trigger->tgnattr > 0)
1886  {
1887  int16 *newattr;
1888 
1889  newattr = (int16 *) palloc(trigger->tgnattr * sizeof(int16));
1890  memcpy(newattr, trigger->tgattr,
1891  trigger->tgnattr * sizeof(int16));
1892  trigger->tgattr = newattr;
1893  }
1894  if (trigger->tgnargs > 0)
1895  {
1896  char **newargs;
1897  int16 j;
1898 
1899  newargs = (char **) palloc(trigger->tgnargs * sizeof(char *));
1900  for (j = 0; j < trigger->tgnargs; j++)
1901  newargs[j] = pstrdup(trigger->tgargs[j]);
1902  trigger->tgargs = newargs;
1903  }
1904  if (trigger->tgqual)
1905  trigger->tgqual = pstrdup(trigger->tgqual);
1906  if (trigger->tgoldtable)
1907  trigger->tgoldtable = pstrdup(trigger->tgoldtable);
1908  if (trigger->tgnewtable)
1909  trigger->tgnewtable = pstrdup(trigger->tgnewtable);
1910  trigger++;
1911  }
1912 
1913  return newdesc;
1914 }
1915 
1916 /*
1917  * Free a TriggerDesc data structure.
1918  */
1919 void
1921 {
1922  Trigger *trigger;
1923  int i;
1924 
1925  if (trigdesc == NULL)
1926  return;
1927 
1928  trigger = trigdesc->triggers;
1929  for (i = 0; i < trigdesc->numtriggers; i++)
1930  {
1931  pfree(trigger->tgname);
1932  if (trigger->tgnattr > 0)
1933  pfree(trigger->tgattr);
1934  if (trigger->tgnargs > 0)
1935  {
1936  while (--(trigger->tgnargs) >= 0)
1937  pfree(trigger->tgargs[trigger->tgnargs]);
1938  pfree(trigger->tgargs);
1939  }
1940  if (trigger->tgqual)
1941  pfree(trigger->tgqual);
1942  if (trigger->tgoldtable)
1943  pfree(trigger->tgoldtable);
1944  if (trigger->tgnewtable)
1945  pfree(trigger->tgnewtable);
1946  trigger++;
1947  }
1948  pfree(trigdesc->triggers);
1949  pfree(trigdesc);
1950 }
1951 
1952 /*
1953  * Compare two TriggerDesc structures for logical equality.
1954  */
1955 #ifdef NOT_USED
1956 bool
1957 equalTriggerDescs(TriggerDesc *trigdesc1, TriggerDesc *trigdesc2)
1958 {
1959  int i,
1960  j;
1961 
1962  /*
1963  * We need not examine the hint flags, just the trigger array itself; if
1964  * we have the same triggers with the same types, the flags should match.
1965  *
1966  * As of 7.3 we assume trigger set ordering is significant in the
1967  * comparison; so we just compare corresponding slots of the two sets.
1968  *
1969  * Note: comparing the stringToNode forms of the WHEN clauses means that
1970  * parse column locations will affect the result. This is okay as long as
1971  * this function is only used for detecting exact equality, as for example
1972  * in checking for staleness of a cache entry.
1973  */
1974  if (trigdesc1 != NULL)
1975  {
1976  if (trigdesc2 == NULL)
1977  return false;
1978  if (trigdesc1->numtriggers != trigdesc2->numtriggers)
1979  return false;
1980  for (i = 0; i < trigdesc1->numtriggers; i++)
1981  {
1982  Trigger *trig1 = trigdesc1->triggers + i;
1983  Trigger *trig2 = trigdesc2->triggers + i;
1984 
1985  if (trig1->tgoid != trig2->tgoid)
1986  return false;
1987  if (strcmp(trig1->tgname, trig2->tgname) != 0)
1988  return false;
1989  if (trig1->tgfoid != trig2->tgfoid)
1990  return false;
1991  if (trig1->tgtype != trig2->tgtype)
1992  return false;
1993  if (trig1->tgenabled != trig2->tgenabled)
1994  return false;
1995  if (trig1->tgisinternal != trig2->tgisinternal)
1996  return false;
1997  if (trig1->tgisclone != trig2->tgisclone)
1998  return false;
1999  if (trig1->tgconstrrelid != trig2->tgconstrrelid)
2000  return false;
2001  if (trig1->tgconstrindid != trig2->tgconstrindid)
2002  return false;
2003  if (trig1->tgconstraint != trig2->tgconstraint)
2004  return false;
2005  if (trig1->tgdeferrable != trig2->tgdeferrable)
2006  return false;
2007  if (trig1->tginitdeferred != trig2->tginitdeferred)
2008  return false;
2009  if (trig1->tgnargs != trig2->tgnargs)
2010  return false;
2011  if (trig1->tgnattr != trig2->tgnattr)
2012  return false;
2013  if (trig1->tgnattr > 0 &&
2014  memcmp(trig1->tgattr, trig2->tgattr,
2015  trig1->tgnattr * sizeof(int16)) != 0)
2016  return false;
2017  for (j = 0; j < trig1->tgnargs; j++)
2018  if (strcmp(trig1->tgargs[j], trig2->tgargs[j]) != 0)
2019  return false;
2020  if (trig1->tgqual == NULL && trig2->tgqual == NULL)
2021  /* ok */ ;
2022  else if (trig1->tgqual == NULL || trig2->tgqual == NULL)
2023  return false;
2024  else if (strcmp(trig1->tgqual, trig2->tgqual) != 0)
2025  return false;
2026  if (trig1->tgoldtable == NULL && trig2->tgoldtable == NULL)
2027  /* ok */ ;
2028  else if (trig1->tgoldtable == NULL || trig2->tgoldtable == NULL)
2029  return false;
2030  else if (strcmp(trig1->tgoldtable, trig2->tgoldtable) != 0)
2031  return false;
2032  if (trig1->tgnewtable == NULL && trig2->tgnewtable == NULL)
2033  /* ok */ ;
2034  else if (trig1->tgnewtable == NULL || trig2->tgnewtable == NULL)
2035  return false;
2036  else if (strcmp(trig1->tgnewtable, trig2->tgnewtable) != 0)
2037  return false;
2038  }
2039  }
2040  else if (trigdesc2 != NULL)
2041  return false;
2042  return true;
2043 }
2044 #endif /* NOT_USED */
2045 
2046 /*
2047  * Check if there is a row-level trigger with transition tables that prevents
2048  * a table from becoming an inheritance child or partition. Return the name
2049  * of the first such incompatible trigger, or NULL if there is none.
2050  */
2051 const char *
2053 {
2054  if (trigdesc != NULL)
2055  {
2056  int i;
2057 
2058  for (i = 0; i < trigdesc->numtriggers; ++i)
2059  {
2060  Trigger *trigger = &trigdesc->triggers[i];
2061 
2062  if (trigger->tgoldtable != NULL || trigger->tgnewtable != NULL)
2063  return trigger->tgname;
2064  }
2065  }
2066 
2067  return NULL;
2068 }
2069 
2070 /*
2071  * Call a trigger function.
2072  *
2073  * trigdata: trigger descriptor.
2074  * tgindx: trigger's index in finfo and instr arrays.
2075  * finfo: array of cached trigger function call information.
2076  * instr: optional array of EXPLAIN ANALYZE instrumentation state.
2077  * per_tuple_context: memory context to execute the function in.
2078  *
2079  * Returns the tuple (or NULL) as returned by the function.
2080  */
2081 static HeapTuple
2083  int tgindx,
2084  FmgrInfo *finfo,
2085  Instrumentation *instr,
2086  MemoryContext per_tuple_context)
2087 {
2088  LOCAL_FCINFO(fcinfo, 0);
2089  PgStat_FunctionCallUsage fcusage;
2090  Datum result;
2091  MemoryContext oldContext;
2092 
2093  /*
2094  * Protect against code paths that may fail to initialize transition table
2095  * info.
2096  */
2097  Assert(((TRIGGER_FIRED_BY_INSERT(trigdata->tg_event) ||
2098  TRIGGER_FIRED_BY_UPDATE(trigdata->tg_event) ||
2099  TRIGGER_FIRED_BY_DELETE(trigdata->tg_event)) &&
2100  TRIGGER_FIRED_AFTER(trigdata->tg_event) &&
2101  !(trigdata->tg_event & AFTER_TRIGGER_DEFERRABLE) &&
2102  !(trigdata->tg_event & AFTER_TRIGGER_INITDEFERRED)) ||
2103  (trigdata->tg_oldtable == NULL && trigdata->tg_newtable == NULL));
2104 
2105  finfo += tgindx;
2106 
2107  /*
2108  * We cache fmgr lookup info, to avoid making the lookup again on each
2109  * call.
2110  */
2111  if (finfo->fn_oid == InvalidOid)
2112  fmgr_info(trigdata->tg_trigger->tgfoid, finfo);
2113 
2114  Assert(finfo->fn_oid == trigdata->tg_trigger->tgfoid);
2115 
2116  /*
2117  * If doing EXPLAIN ANALYZE, start charging time to this trigger.
2118  */
2119  if (instr)
2120  InstrStartNode(instr + tgindx);
2121 
2122  /*
2123  * Do the function evaluation in the per-tuple memory context, so that
2124  * leaked memory will be reclaimed once per tuple. Note in particular that
2125  * any new tuple created by the trigger function will live till the end of
2126  * the tuple cycle.
2127  */
2128  oldContext = MemoryContextSwitchTo(per_tuple_context);
2129 
2130  /*
2131  * Call the function, passing no arguments but setting a context.
2132  */
2133  InitFunctionCallInfoData(*fcinfo, finfo, 0,
2134  InvalidOid, (Node *) trigdata, NULL);
2135 
2136  pgstat_init_function_usage(fcinfo, &fcusage);
2137 
2138  MyTriggerDepth++;
2139  PG_TRY();
2140  {
2141  result = FunctionCallInvoke(fcinfo);
2142  }
2143  PG_FINALLY();
2144  {
2145  MyTriggerDepth--;
2146  }
2147  PG_END_TRY();
2148 
2149  pgstat_end_function_usage(&fcusage, true);
2150 
2151  MemoryContextSwitchTo(oldContext);
2152 
2153  /*
2154  * Trigger protocol allows function to return a null pointer, but NOT to
2155  * set the isnull result flag.
2156  */
2157  if (fcinfo->isnull)
2158  ereport(ERROR,
2159  (errcode(ERRCODE_E_R_I_E_TRIGGER_PROTOCOL_VIOLATED),
2160  errmsg("trigger function %u returned null value",
2161  fcinfo->flinfo->fn_oid)));
2162 
2163  /*
2164  * If doing EXPLAIN ANALYZE, stop charging time to this trigger, and count
2165  * one "tuple returned" (really the number of firings).
2166  */
2167  if (instr)
2168  InstrStopNode(instr + tgindx, 1);
2169 
2170  return (HeapTuple) DatumGetPointer(result);
2171 }
2172 
2173 void
2175 {
2176  TriggerDesc *trigdesc;
2177  int i;
2178  TriggerData LocTriggerData = {0};
2179 
2180  trigdesc = relinfo->ri_TrigDesc;
2181 
2182  if (trigdesc == NULL)
2183  return;
2184  if (!trigdesc->trig_insert_before_statement)
2185  return;
2186 
2187  /* no-op if we already fired BS triggers in this context */
2189  CMD_INSERT))
2190  return;
2191 
2192  LocTriggerData.type = T_TriggerData;
2193  LocTriggerData.tg_event = TRIGGER_EVENT_INSERT |
2195  LocTriggerData.tg_relation = relinfo->ri_RelationDesc;
2196  for (i = 0; i < trigdesc->numtriggers; i++)
2197  {
2198  Trigger *trigger = &trigdesc->triggers[i];
2199  HeapTuple newtuple;
2200 
2201  if (!TRIGGER_TYPE_MATCHES(trigger->tgtype,
2202  TRIGGER_TYPE_STATEMENT,
2203  TRIGGER_TYPE_BEFORE,
2204  TRIGGER_TYPE_INSERT))
2205  continue;
2206  if (!TriggerEnabled(estate, relinfo, trigger, LocTriggerData.tg_event,
2207  NULL, NULL, NULL))
2208  continue;
2209 
2210  LocTriggerData.tg_trigger = trigger;
2211  newtuple = ExecCallTriggerFunc(&LocTriggerData,
2212  i,
2213  relinfo->ri_TrigFunctions,
2214  relinfo->ri_TrigInstrument,
2215  GetPerTupleMemoryContext(estate));
2216 
2217  if (newtuple)
2218  ereport(ERROR,
2219  (errcode(ERRCODE_E_R_I_E_TRIGGER_PROTOCOL_VIOLATED),
2220  errmsg("BEFORE STATEMENT trigger cannot return a value")));
2221  }
2222 }
2223 
2224 void
2226  TransitionCaptureState *transition_capture)
2227 {
2228  TriggerDesc *trigdesc = relinfo->ri_TrigDesc;
2229 
2230  if (trigdesc && trigdesc->trig_insert_after_statement)
2232  false, NULL, NULL, NIL, NULL, transition_capture);
2233 }
2234 
2235 bool
2237  TupleTableSlot *slot)
2238 {
2239  TriggerDesc *trigdesc = relinfo->ri_TrigDesc;
2240  HeapTuple newtuple = NULL;
2241  bool should_free;
2242  TriggerData LocTriggerData = {0};
2243  int i;
2244 
2245  LocTriggerData.type = T_TriggerData;
2246  LocTriggerData.tg_event = TRIGGER_EVENT_INSERT |
2249  LocTriggerData.tg_relation = relinfo->ri_RelationDesc;
2250  for (i = 0; i < trigdesc->numtriggers; i++)
2251  {
2252  Trigger *trigger = &trigdesc->triggers[i];
2253  HeapTuple oldtuple;
2254 
2255  if (!TRIGGER_TYPE_MATCHES(trigger->tgtype,
2256  TRIGGER_TYPE_ROW,
2257  TRIGGER_TYPE_BEFORE,
2258  TRIGGER_TYPE_INSERT))
2259  continue;
2260  if (!TriggerEnabled(estate, relinfo, trigger, LocTriggerData.tg_event,
2261  NULL, NULL, slot))
2262  continue;
2263 
2264  if (!newtuple)
2265  newtuple = ExecFetchSlotHeapTuple(slot, true, &should_free);
2266 
2267  LocTriggerData.tg_trigslot = slot;
2268  LocTriggerData.tg_trigtuple = oldtuple = newtuple;
2269  LocTriggerData.tg_trigger = trigger;
2270  newtuple = ExecCallTriggerFunc(&LocTriggerData,
2271  i,
2272  relinfo->ri_TrigFunctions,
2273  relinfo->ri_TrigInstrument,
2274  GetPerTupleMemoryContext(estate));
2275  if (newtuple == NULL)
2276  {
2277  if (should_free)
2278  heap_freetuple(oldtuple);
2279  return false; /* "do nothing" */
2280  }
2281  else if (newtuple != oldtuple)
2282  {
2283  ExecForceStoreHeapTuple(newtuple, slot, false);
2284 
2285  /*
2286  * After a tuple in a partition goes through a trigger, the user
2287  * could have changed the partition key enough that the tuple no
2288  * longer fits the partition. Verify that.
2289  */
2290  if (trigger->tgisclone &&
2291  !ExecPartitionCheck(relinfo, slot, estate, false))
2292  ereport(ERROR,
2293  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2294  errmsg("moving row to another partition during a BEFORE FOR EACH ROW trigger is not supported"),
2295  errdetail("Before executing trigger \"%s\", the row was to be in partition \"%s.%s\".",
2296  trigger->tgname,
2299 
2300  if (should_free)
2301  heap_freetuple(oldtuple);
2302 
2303  /* signal tuple should be re-fetched if used */
2304  newtuple = NULL;
2305  }
2306  }
2307 
2308  return true;
2309 }
2310 
2311 void
2313  TupleTableSlot *slot, List *recheckIndexes,
2314  TransitionCaptureState *transition_capture)
2315 {
2316  TriggerDesc *trigdesc = relinfo->ri_TrigDesc;
2317 
2318  if ((trigdesc && trigdesc->trig_insert_after_row) ||
2319  (transition_capture && transition_capture->tcs_insert_new_table))
2321  true, NULL, slot,
2322  recheckIndexes, NULL,
2323  transition_capture);
2324 }
2325 
2326 bool
2328  TupleTableSlot *slot)
2329 {
2330  TriggerDesc *trigdesc = relinfo->ri_TrigDesc;
2331  HeapTuple newtuple = NULL;
2332  bool should_free;
2333  TriggerData LocTriggerData = {0};
2334  int i;
2335 
2336  LocTriggerData.type = T_TriggerData;
2337  LocTriggerData.tg_event = TRIGGER_EVENT_INSERT |
2340  LocTriggerData.tg_relation = relinfo->ri_RelationDesc;
2341  for (i = 0; i < trigdesc->numtriggers; i++)
2342  {
2343  Trigger *trigger = &trigdesc->triggers[i];
2344  HeapTuple oldtuple;
2345 
2346  if (!TRIGGER_TYPE_MATCHES(trigger->tgtype,
2347  TRIGGER_TYPE_ROW,
2348  TRIGGER_TYPE_INSTEAD,
2349  TRIGGER_TYPE_INSERT))
2350  continue;
2351  if (!TriggerEnabled(estate, relinfo, trigger, LocTriggerData.tg_event,
2352  NULL, NULL, slot))
2353  continue;
2354 
2355  if (!newtuple)
2356  newtuple = ExecFetchSlotHeapTuple(slot, true, &should_free);
2357 
2358  LocTriggerData.tg_trigslot = slot;
2359  LocTriggerData.tg_trigtuple = oldtuple = newtuple;
2360  LocTriggerData.tg_trigger = trigger;
2361  newtuple = ExecCallTriggerFunc(&LocTriggerData,
2362  i,
2363  relinfo->ri_TrigFunctions,
2364  relinfo->ri_TrigInstrument,
2365  GetPerTupleMemoryContext(estate));
2366  if (newtuple == NULL)
2367  {
2368  if (should_free)
2369  heap_freetuple(oldtuple);
2370  return false; /* "do nothing" */
2371  }
2372  else if (newtuple != oldtuple)
2373  {
2374  ExecForceStoreHeapTuple(newtuple, slot, false);
2375 
2376  if (should_free)
2377  heap_freetuple(oldtuple);
2378 
2379  /* signal tuple should be re-fetched if used */
2380  newtuple = NULL;
2381  }
2382  }
2383 
2384  return true;
2385 }
2386 
2387 void
2389 {
2390  TriggerDesc *trigdesc;
2391  int i;
2392  TriggerData LocTriggerData = {0};
2393 
2394  trigdesc = relinfo->ri_TrigDesc;
2395 
2396  if (trigdesc == NULL)
2397  return;
2398  if (!trigdesc->trig_delete_before_statement)
2399  return;
2400 
2401  /* no-op if we already fired BS triggers in this context */
2403  CMD_DELETE))
2404  return;
2405 
2406  LocTriggerData.type = T_TriggerData;
2407  LocTriggerData.tg_event = TRIGGER_EVENT_DELETE |
2409  LocTriggerData.tg_relation = relinfo->ri_RelationDesc;
2410  for (i = 0; i < trigdesc->numtriggers; i++)
2411  {
2412  Trigger *trigger = &trigdesc->triggers[i];
2413  HeapTuple newtuple;
2414 
2415  if (!TRIGGER_TYPE_MATCHES(trigger->tgtype,
2416  TRIGGER_TYPE_STATEMENT,
2417  TRIGGER_TYPE_BEFORE,
2418  TRIGGER_TYPE_DELETE))
2419  continue;
2420  if (!TriggerEnabled(estate, relinfo, trigger, LocTriggerData.tg_event,
2421  NULL, NULL, NULL))
2422  continue;
2423 
2424  LocTriggerData.tg_trigger = trigger;
2425  newtuple = ExecCallTriggerFunc(&LocTriggerData,
2426  i,
2427  relinfo->ri_TrigFunctions,
2428  relinfo->ri_TrigInstrument,
2429  GetPerTupleMemoryContext(estate));
2430 
2431  if (newtuple)
2432  ereport(ERROR,
2433  (errcode(ERRCODE_E_R_I_E_TRIGGER_PROTOCOL_VIOLATED),
2434  errmsg("BEFORE STATEMENT trigger cannot return a value")));
2435  }
2436 }
2437 
2438 void
2440  TransitionCaptureState *transition_capture)
2441 {
2442  TriggerDesc *trigdesc = relinfo->ri_TrigDesc;
2443 
2444  if (trigdesc && trigdesc->trig_delete_after_statement)
2446  false, NULL, NULL, NIL, NULL, transition_capture);
2447 }
2448 
2449 /*
2450  * Execute BEFORE ROW DELETE triggers.
2451  *
2452  * True indicates caller can proceed with the delete. False indicates caller
2453  * need to suppress the delete and additionally if requested, we need to pass
2454  * back the concurrently updated tuple if any.
2455  */
2456 bool
2458  ResultRelInfo *relinfo,
2459  ItemPointer tupleid,
2460  HeapTuple fdw_trigtuple,
2461  TupleTableSlot **epqslot)
2462 {
2463  TupleTableSlot *slot = ExecGetTriggerOldSlot(estate, relinfo);
2464  TriggerDesc *trigdesc = relinfo->ri_TrigDesc;
2465  bool result = true;
2466  TriggerData LocTriggerData = {0};
2467  HeapTuple trigtuple;
2468  bool should_free = false;
2469  int i;
2470 
2471  Assert(HeapTupleIsValid(fdw_trigtuple) ^ ItemPointerIsValid(tupleid));
2472  if (fdw_trigtuple == NULL)
2473  {
2474  TupleTableSlot *epqslot_candidate = NULL;
2475 
2476  if (!GetTupleForTrigger(estate, epqstate, relinfo, tupleid,
2477  LockTupleExclusive, slot, &epqslot_candidate))
2478  return false;
2479 
2480  /*
2481  * If the tuple was concurrently updated and the caller of this
2482  * function requested for the updated tuple, skip the trigger
2483  * execution.
2484  */
2485  if (epqslot_candidate != NULL && epqslot != NULL)
2486  {
2487  *epqslot = epqslot_candidate;
2488  return false;
2489  }
2490 
2491  trigtuple = ExecFetchSlotHeapTuple(slot, true, &should_free);
2492 
2493  }
2494  else
2495  {
2496  trigtuple = fdw_trigtuple;
2497  ExecForceStoreHeapTuple(trigtuple, slot, false);
2498  }
2499 
2500  LocTriggerData.type = T_TriggerData;
2501  LocTriggerData.tg_event = TRIGGER_EVENT_DELETE |
2504  LocTriggerData.tg_relation = relinfo->ri_RelationDesc;
2505  for (i = 0; i < trigdesc->numtriggers; i++)
2506  {
2507  HeapTuple newtuple;
2508  Trigger *trigger = &trigdesc->triggers[i];
2509 
2510  if (!TRIGGER_TYPE_MATCHES(trigger->tgtype,
2511  TRIGGER_TYPE_ROW,
2512  TRIGGER_TYPE_BEFORE,
2513  TRIGGER_TYPE_DELETE))
2514  continue;
2515  if (!TriggerEnabled(estate, relinfo, trigger, LocTriggerData.tg_event,
2516  NULL, slot, NULL))
2517  continue;
2518 
2519  LocTriggerData.tg_trigslot = slot;
2520  LocTriggerData.tg_trigtuple = trigtuple;
2521  LocTriggerData.tg_trigger = trigger;
2522  newtuple = ExecCallTriggerFunc(&LocTriggerData,
2523  i,
2524  relinfo->ri_TrigFunctions,
2525  relinfo->ri_TrigInstrument,
2526  GetPerTupleMemoryContext(estate));
2527  if (newtuple == NULL)
2528  {
2529  result = false; /* tell caller to suppress delete */
2530  break;
2531  }
2532  if (newtuple != trigtuple)
2533  heap_freetuple(newtuple);
2534  }
2535  if (should_free)
2536  heap_freetuple(trigtuple);
2537 
2538  return result;
2539 }
2540 
2541 void
2543  ItemPointer tupleid,
2544  HeapTuple fdw_trigtuple,
2545  TransitionCaptureState *transition_capture)
2546 {
2547  TriggerDesc *trigdesc = relinfo->ri_TrigDesc;
2548 
2549  if ((trigdesc && trigdesc->trig_delete_after_row) ||
2550  (transition_capture && transition_capture->tcs_delete_old_table))
2551  {
2552  TupleTableSlot *slot = ExecGetTriggerOldSlot(estate, relinfo);
2553 
2554  Assert(HeapTupleIsValid(fdw_trigtuple) ^ ItemPointerIsValid(tupleid));
2555  if (fdw_trigtuple == NULL)
2556  GetTupleForTrigger(estate,
2557  NULL,
2558  relinfo,
2559  tupleid,
2561  slot,
2562  NULL);
2563  else
2564  ExecForceStoreHeapTuple(fdw_trigtuple, slot, false);
2565 
2567  true, slot, NULL, NIL, NULL,
2568  transition_capture);
2569  }
2570 }
2571 
2572 bool
2574  HeapTuple trigtuple)
2575 {
2576  TriggerDesc *trigdesc = relinfo->ri_TrigDesc;
2577  TupleTableSlot *slot = ExecGetTriggerOldSlot(estate, relinfo);
2578  TriggerData LocTriggerData = {0};
2579  int i;
2580 
2581  LocTriggerData.type = T_TriggerData;
2582  LocTriggerData.tg_event = TRIGGER_EVENT_DELETE |
2585  LocTriggerData.tg_relation = relinfo->ri_RelationDesc;
2586 
2587  ExecForceStoreHeapTuple(trigtuple, slot, false);
2588 
2589  for (i = 0; i < trigdesc->numtriggers; i++)
2590  {
2591  HeapTuple rettuple;
2592  Trigger *trigger = &trigdesc->triggers[i];
2593 
2594  if (!TRIGGER_TYPE_MATCHES(trigger->tgtype,
2595  TRIGGER_TYPE_ROW,
2596  TRIGGER_TYPE_INSTEAD,
2597  TRIGGER_TYPE_DELETE))
2598  continue;
2599  if (!TriggerEnabled(estate, relinfo, trigger, LocTriggerData.tg_event,
2600  NULL, slot, NULL))
2601  continue;
2602 
2603  LocTriggerData.tg_trigslot = slot;
2604  LocTriggerData.tg_trigtuple = trigtuple;
2605  LocTriggerData.tg_trigger = trigger;
2606  rettuple = ExecCallTriggerFunc(&LocTriggerData,
2607  i,
2608  relinfo->ri_TrigFunctions,
2609  relinfo->ri_TrigInstrument,
2610  GetPerTupleMemoryContext(estate));
2611  if (rettuple == NULL)
2612  return false; /* Delete was suppressed */
2613  if (rettuple != trigtuple)
2614  heap_freetuple(rettuple);
2615  }
2616  return true;
2617 }
2618 
2619 void
2621 {
2622  TriggerDesc *trigdesc;
2623  int i;
2624  TriggerData LocTriggerData = {0};
2625  Bitmapset *updatedCols;
2626 
2627  trigdesc = relinfo->ri_TrigDesc;
2628 
2629  if (trigdesc == NULL)
2630  return;
2631  if (!trigdesc->trig_update_before_statement)
2632  return;
2633 
2634  /* no-op if we already fired BS triggers in this context */
2636  CMD_UPDATE))
2637  return;
2638 
2639  /* statement-level triggers operate on the parent table */
2640  Assert(relinfo->ri_RootResultRelInfo == NULL);
2641 
2642  updatedCols = ExecGetAllUpdatedCols(relinfo, estate);
2643 
2644  LocTriggerData.type = T_TriggerData;
2645  LocTriggerData.tg_event = TRIGGER_EVENT_UPDATE |
2647  LocTriggerData.tg_relation = relinfo->ri_RelationDesc;
2648  LocTriggerData.tg_updatedcols = updatedCols;
2649  for (i = 0; i < trigdesc->numtriggers; i++)
2650  {
2651  Trigger *trigger = &trigdesc->triggers[i];
2652  HeapTuple newtuple;
2653 
2654  if (!TRIGGER_TYPE_MATCHES(trigger->tgtype,
2655  TRIGGER_TYPE_STATEMENT,
2656  TRIGGER_TYPE_BEFORE,
2657  TRIGGER_TYPE_UPDATE))
2658  continue;
2659  if (!TriggerEnabled(estate, relinfo, trigger, LocTriggerData.tg_event,
2660  updatedCols, NULL, NULL))
2661  continue;
2662 
2663  LocTriggerData.tg_trigger = trigger;
2664  newtuple = ExecCallTriggerFunc(&LocTriggerData,
2665  i,
2666  relinfo->ri_TrigFunctions,
2667  relinfo->ri_TrigInstrument,
2668  GetPerTupleMemoryContext(estate));
2669 
2670  if (newtuple)
2671  ereport(ERROR,
2672  (errcode(ERRCODE_E_R_I_E_TRIGGER_PROTOCOL_VIOLATED),
2673  errmsg("BEFORE STATEMENT trigger cannot return a value")));
2674  }
2675 }
2676 
2677 void
2679  TransitionCaptureState *transition_capture)
2680 {
2681  TriggerDesc *trigdesc = relinfo->ri_TrigDesc;
2682 
2683  /* statement-level triggers operate on the parent table */
2684  Assert(relinfo->ri_RootResultRelInfo == NULL);
2685 
2686  if (trigdesc && trigdesc->trig_update_after_statement)
2688  false, NULL, NULL, NIL,
2689  ExecGetAllUpdatedCols(relinfo, estate),
2690  transition_capture);
2691 }
2692 
2693 bool
2695  ResultRelInfo *relinfo,
2696  ItemPointer tupleid,
2697  HeapTuple fdw_trigtuple,
2698  TupleTableSlot *newslot)
2699 {
2700  TriggerDesc *trigdesc = relinfo->ri_TrigDesc;
2701  TupleTableSlot *oldslot = ExecGetTriggerOldSlot(estate, relinfo);
2702  HeapTuple newtuple = NULL;
2703  HeapTuple trigtuple;
2704  bool should_free_trig = false;
2705  bool should_free_new = false;
2706  TriggerData LocTriggerData = {0};
2707  int i;
2708  Bitmapset *updatedCols;
2709  LockTupleMode lockmode;
2710 
2711  /* Determine lock mode to use */
2712  lockmode = ExecUpdateLockMode(estate, relinfo);
2713 
2714  Assert(HeapTupleIsValid(fdw_trigtuple) ^ ItemPointerIsValid(tupleid));
2715  if (fdw_trigtuple == NULL)
2716  {
2717  TupleTableSlot *epqslot_candidate = NULL;
2718 
2719  /* get a copy of the on-disk tuple we are planning to update */
2720  if (!GetTupleForTrigger(estate, epqstate, relinfo, tupleid,
2721  lockmode, oldslot, &epqslot_candidate))
2722  return false; /* cancel the update action */
2723 
2724  /*
2725  * In READ COMMITTED isolation level it's possible that target tuple
2726  * was changed due to concurrent update. In that case we have a raw
2727  * subplan output tuple in epqslot_candidate, and need to form a new
2728  * insertable tuple using ExecGetUpdateNewTuple to replace the one we
2729  * received in newslot. Neither we nor our callers have any further
2730  * interest in the passed-in tuple, so it's okay to overwrite newslot
2731  * with the newer data.
2732  *
2733  * (Typically, newslot was also generated by ExecGetUpdateNewTuple, so
2734  * that epqslot_clean will be that same slot and the copy step below
2735  * is not needed.)
2736  */
2737  if (epqslot_candidate != NULL)
2738  {
2739  TupleTableSlot *epqslot_clean;
2740 
2741  epqslot_clean = ExecGetUpdateNewTuple(relinfo, epqslot_candidate,
2742  oldslot);
2743 
2744  if (newslot != epqslot_clean)
2745  ExecCopySlot(newslot, epqslot_clean);
2746  }
2747 
2748  trigtuple = ExecFetchSlotHeapTuple(oldslot, true, &should_free_trig);
2749  }
2750  else
2751  {
2752  ExecForceStoreHeapTuple(fdw_trigtuple, oldslot, false);
2753  trigtuple = fdw_trigtuple;
2754  }
2755 
2756  LocTriggerData.type = T_TriggerData;
2757  LocTriggerData.tg_event = TRIGGER_EVENT_UPDATE |
2760  LocTriggerData.tg_relation = relinfo->ri_RelationDesc;
2761  updatedCols = ExecGetAllUpdatedCols(relinfo, estate);
2762  LocTriggerData.tg_updatedcols = updatedCols;
2763  for (i = 0; i < trigdesc->numtriggers; i++)
2764  {
2765  Trigger *trigger = &trigdesc->triggers[i];
2766  HeapTuple oldtuple;
2767 
2768  if (!TRIGGER_TYPE_MATCHES(trigger->tgtype,
2769  TRIGGER_TYPE_ROW,
2770  TRIGGER_TYPE_BEFORE,
2771  TRIGGER_TYPE_UPDATE))
2772  continue;
2773  if (!TriggerEnabled(estate, relinfo, trigger, LocTriggerData.tg_event,
2774  updatedCols, oldslot, newslot))
2775  continue;
2776 
2777  if (!newtuple)
2778  newtuple = ExecFetchSlotHeapTuple(newslot, true, &should_free_new);
2779 
2780  LocTriggerData.tg_trigslot = oldslot;
2781  LocTriggerData.tg_trigtuple = trigtuple;
2782  LocTriggerData.tg_newtuple = oldtuple = newtuple;
2783  LocTriggerData.tg_newslot = newslot;
2784  LocTriggerData.tg_trigger = trigger;
2785  newtuple = ExecCallTriggerFunc(&LocTriggerData,
2786  i,
2787  relinfo->ri_TrigFunctions,
2788  relinfo->ri_TrigInstrument,
2789  GetPerTupleMemoryContext(estate));
2790 
2791  if (newtuple == NULL)
2792  {
2793  if (should_free_trig)
2794  heap_freetuple(trigtuple);
2795  if (should_free_new)
2796  heap_freetuple(oldtuple);
2797  return false; /* "do nothing" */
2798  }
2799  else if (newtuple != oldtuple)
2800  {
2801  ExecForceStoreHeapTuple(newtuple, newslot, false);
2802 
2803  /*
2804  * If the tuple returned by the trigger / being stored, is the old
2805  * row version, and the heap tuple passed to the trigger was
2806  * allocated locally, materialize the slot. Otherwise we might
2807  * free it while still referenced by the slot.
2808  */
2809  if (should_free_trig && newtuple == trigtuple)
2810  ExecMaterializeSlot(newslot);
2811 
2812  if (should_free_new)
2813  heap_freetuple(oldtuple);
2814 
2815  /* signal tuple should be re-fetched if used */
2816  newtuple = NULL;
2817  }
2818  }
2819  if (should_free_trig)
2820  heap_freetuple(trigtuple);
2821 
2822  return true;
2823 }
2824 
2825 void
2827  ItemPointer tupleid,
2828  HeapTuple fdw_trigtuple,
2829  TupleTableSlot *newslot,
2830  List *recheckIndexes,
2831  TransitionCaptureState *transition_capture)
2832 {
2833  TriggerDesc *trigdesc = relinfo->ri_TrigDesc;
2834 
2835  if ((trigdesc && trigdesc->trig_update_after_row) ||
2836  (transition_capture &&
2837  (transition_capture->tcs_update_old_table ||
2838  transition_capture->tcs_update_new_table)))
2839  {
2840  /*
2841  * Note: if the UPDATE is converted into a DELETE+INSERT as part of
2842  * update-partition-key operation, then this function is also called
2843  * separately for DELETE and INSERT to capture transition table rows.
2844  * In such case, either old tuple or new tuple can be NULL.
2845  */
2846  TupleTableSlot *oldslot = ExecGetTriggerOldSlot(estate, relinfo);
2847 
2848  if (fdw_trigtuple == NULL && ItemPointerIsValid(tupleid))
2849  GetTupleForTrigger(estate,
2850  NULL,
2851  relinfo,
2852  tupleid,
2854  oldslot,
2855  NULL);
2856  else if (fdw_trigtuple != NULL)
2857  ExecForceStoreHeapTuple(fdw_trigtuple, oldslot, false);
2858  else
2859  ExecClearTuple(oldslot);
2860 
2862  true, oldslot, newslot, recheckIndexes,
2863  ExecGetAllUpdatedCols(relinfo, estate),
2864  transition_capture);
2865  }
2866 }
2867 
2868 bool
2870  HeapTuple trigtuple, TupleTableSlot *newslot)
2871 {
2872  TriggerDesc *trigdesc = relinfo->ri_TrigDesc;
2873  TupleTableSlot *oldslot = ExecGetTriggerOldSlot(estate, relinfo);
2874  HeapTuple newtuple = NULL;
2875  bool should_free;
2876  TriggerData LocTriggerData = {0};
2877  int i;
2878 
2879  LocTriggerData.type = T_TriggerData;
2880  LocTriggerData.tg_event = TRIGGER_EVENT_UPDATE |
2883  LocTriggerData.tg_relation = relinfo->ri_RelationDesc;
2884 
2885  ExecForceStoreHeapTuple(trigtuple, oldslot, false);
2886 
2887  for (i = 0; i < trigdesc->numtriggers; i++)
2888  {
2889  Trigger *trigger = &trigdesc->triggers[i];
2890  HeapTuple oldtuple;
2891 
2892  if (!TRIGGER_TYPE_MATCHES(trigger->tgtype,
2893  TRIGGER_TYPE_ROW,
2894  TRIGGER_TYPE_INSTEAD,
2895  TRIGGER_TYPE_UPDATE))
2896  continue;
2897  if (!TriggerEnabled(estate, relinfo, trigger, LocTriggerData.tg_event,
2898  NULL, oldslot, newslot))
2899  continue;
2900 
2901  if (!newtuple)
2902  newtuple = ExecFetchSlotHeapTuple(newslot, true, &should_free);
2903 
2904  LocTriggerData.tg_trigslot = oldslot;
2905  LocTriggerData.tg_trigtuple = trigtuple;
2906  LocTriggerData.tg_newslot = newslot;
2907  LocTriggerData.tg_newtuple = oldtuple = newtuple;
2908 
2909  LocTriggerData.tg_trigger = trigger;
2910  newtuple = ExecCallTriggerFunc(&LocTriggerData,
2911  i,
2912  relinfo->ri_TrigFunctions,
2913  relinfo->ri_TrigInstrument,
2914  GetPerTupleMemoryContext(estate));
2915  if (newtuple == NULL)
2916  {
2917  return false; /* "do nothing" */
2918  }
2919  else if (newtuple != oldtuple)
2920  {
2921  ExecForceStoreHeapTuple(newtuple, newslot, false);
2922 
2923  if (should_free)
2924  heap_freetuple(oldtuple);
2925 
2926  /* signal tuple should be re-fetched if used */
2927  newtuple = NULL;
2928  }
2929  }
2930 
2931  return true;
2932 }
2933 
2934 void
2936 {
2937  TriggerDesc *trigdesc;
2938  int i;
2939  TriggerData LocTriggerData = {0};
2940 
2941  trigdesc = relinfo->ri_TrigDesc;
2942 
2943  if (trigdesc == NULL)
2944  return;
2945  if (!trigdesc->trig_truncate_before_statement)
2946  return;
2947 
2948  LocTriggerData.type = T_TriggerData;
2949  LocTriggerData.tg_event = TRIGGER_EVENT_TRUNCATE |
2951  LocTriggerData.tg_relation = relinfo->ri_RelationDesc;
2952 
2953  for (i = 0; i < trigdesc->numtriggers; i++)
2954  {
2955  Trigger *trigger = &trigdesc->triggers[i];
2956  HeapTuple newtuple;
2957 
2958  if (!TRIGGER_TYPE_MATCHES(trigger->tgtype,
2959  TRIGGER_TYPE_STATEMENT,
2960  TRIGGER_TYPE_BEFORE,
2961  TRIGGER_TYPE_TRUNCATE))
2962  continue;
2963  if (!TriggerEnabled(estate, relinfo, trigger, LocTriggerData.tg_event,
2964  NULL, NULL, NULL))
2965  continue;
2966 
2967  LocTriggerData.tg_trigger = trigger;
2968  newtuple = ExecCallTriggerFunc(&LocTriggerData,
2969  i,
2970  relinfo->ri_TrigFunctions,
2971  relinfo->ri_TrigInstrument,
2972  GetPerTupleMemoryContext(estate));
2973 
2974  if (newtuple)
2975  ereport(ERROR,
2976  (errcode(ERRCODE_E_R_I_E_TRIGGER_PROTOCOL_VIOLATED),
2977  errmsg("BEFORE STATEMENT trigger cannot return a value")));
2978  }
2979 }
2980 
2981 void
2983 {
2984  TriggerDesc *trigdesc = relinfo->ri_TrigDesc;
2985 
2986  if (trigdesc && trigdesc->trig_truncate_after_statement)
2988  false, NULL, NULL, NIL, NULL, NULL);
2989 }
2990 
2991 
2992 /*
2993  * Fetch tuple into "oldslot", dealing with locking and EPQ if necessary
2994  */
2995 static bool
2997  EPQState *epqstate,
2998  ResultRelInfo *relinfo,
2999  ItemPointer tid,
3000  LockTupleMode lockmode,
3001  TupleTableSlot *oldslot,
3002  TupleTableSlot **epqslot)
3003 {
3004  Relation relation = relinfo->ri_RelationDesc;
3005 
3006  if (epqslot != NULL)
3007  {
3008  TM_Result test;
3009  TM_FailureData tmfd;
3010  int lockflags = 0;
3011 
3012  *epqslot = NULL;
3013 
3014  /* caller must pass an epqstate if EvalPlanQual is possible */
3015  Assert(epqstate != NULL);
3016 
3017  /*
3018  * lock tuple for update
3019  */
3021  lockflags |= TUPLE_LOCK_FLAG_FIND_LAST_VERSION;
3022  test = table_tuple_lock(relation, tid, estate->es_snapshot, oldslot,
3023  estate->es_output_cid,
3024  lockmode, LockWaitBlock,
3025  lockflags,
3026  &tmfd);
3027 
3028  switch (test)
3029  {
3030  case TM_SelfModified:
3031 
3032  /*
3033  * The target tuple was already updated or deleted by the
3034  * current command, or by a later command in the current
3035  * transaction. We ignore the tuple in the former case, and
3036  * throw error in the latter case, for the same reasons
3037  * enumerated in ExecUpdate and ExecDelete in
3038  * nodeModifyTable.c.
3039  */
3040  if (tmfd.cmax != estate->es_output_cid)
3041  ereport(ERROR,
3042  (errcode(ERRCODE_TRIGGERED_DATA_CHANGE_VIOLATION),
3043  errmsg("tuple to be updated was already modified by an operation triggered by the current command"),
3044  errhint("Consider using an AFTER trigger instead of a BEFORE trigger to propagate changes to other rows.")));
3045 
3046  /* treat it as deleted; do not process */
3047  return false;
3048 
3049  case TM_Ok:
3050  if (tmfd.traversed)
3051  {
3052  *epqslot = EvalPlanQual(epqstate,
3053  relation,
3054  relinfo->ri_RangeTableIndex,
3055  oldslot);
3056 
3057  /*
3058  * If PlanQual failed for updated tuple - we must not
3059  * process this tuple!
3060  */
3061  if (TupIsNull(*epqslot))
3062  {
3063  *epqslot = NULL;
3064  return false;
3065  }
3066  }
3067  break;
3068 
3069  case TM_Updated:
3071  ereport(ERROR,
3072  (errcode(ERRCODE_T_R_SERIALIZATION_FAILURE),
3073  errmsg("could not serialize access due to concurrent update")));
3074  elog(ERROR, "unexpected table_tuple_lock status: %u", test);
3075  break;
3076 
3077  case TM_Deleted:
3079  ereport(ERROR,
3080  (errcode(ERRCODE_T_R_SERIALIZATION_FAILURE),
3081  errmsg("could not serialize access due to concurrent delete")));
3082  /* tuple was deleted */
3083  return false;
3084 
3085  case TM_Invisible:
3086  elog(ERROR, "attempted to lock invisible tuple");
3087  break;
3088 
3089  default:
3090  elog(ERROR, "unrecognized table_tuple_lock status: %u", test);
3091  return false; /* keep compiler quiet */
3092  }
3093  }
3094  else
3095  {
3096  /*
3097  * We expect the tuple to be present, thus very simple error handling
3098  * suffices.
3099  */
3100  if (!table_tuple_fetch_row_version(relation, tid, SnapshotAny,
3101  oldslot))
3102  elog(ERROR, "failed to fetch tuple for trigger");
3103  }
3104 
3105  return true;
3106 }
3107 
3108 /*
3109  * Is trigger enabled to fire?
3110  */
3111 static bool
3113  Trigger *trigger, TriggerEvent event,
3114  Bitmapset *modifiedCols,
3115  TupleTableSlot *oldslot, TupleTableSlot *newslot)
3116 {
3117  /* Check replication-role-dependent enable state */
3119  {
3120  if (trigger->tgenabled == TRIGGER_FIRES_ON_ORIGIN ||
3121  trigger->tgenabled == TRIGGER_DISABLED)
3122  return false;
3123  }
3124  else /* ORIGIN or LOCAL role */
3125  {
3126  if (trigger->tgenabled == TRIGGER_FIRES_ON_REPLICA ||
3127  trigger->tgenabled == TRIGGER_DISABLED)
3128  return false;
3129  }
3130 
3131  /*
3132  * Check for column-specific trigger (only possible for UPDATE, and in
3133  * fact we *must* ignore tgattr for other event types)
3134  */
3135  if (trigger->tgnattr > 0 && TRIGGER_FIRED_BY_UPDATE(event))
3136  {
3137  int i;
3138  bool modified;
3139 
3140  modified = false;
3141  for (i = 0; i < trigger->tgnattr; i++)
3142  {
3144  modifiedCols))
3145  {
3146  modified = true;
3147  break;
3148  }
3149  }
3150  if (!modified)
3151  return false;
3152  }
3153 
3154  /* Check for WHEN clause */
3155  if (trigger->tgqual)
3156  {
3157  ExprState **predicate;
3158  ExprContext *econtext;
3159  MemoryContext oldContext;
3160  int i;
3161 
3162  Assert(estate != NULL);
3163 
3164  /*
3165  * trigger is an element of relinfo->ri_TrigDesc->triggers[]; find the
3166  * matching element of relinfo->ri_TrigWhenExprs[]
3167  */
3168  i = trigger - relinfo->ri_TrigDesc->triggers;
3169  predicate = &relinfo->ri_TrigWhenExprs[i];
3170 
3171  /*
3172  * If first time through for this WHEN expression, build expression
3173  * nodetrees for it. Keep them in the per-query memory context so
3174  * they'll survive throughout the query.
3175  */
3176  if (*predicate == NULL)
3177  {
3178  Node *tgqual;
3179 
3180  oldContext = MemoryContextSwitchTo(estate->es_query_cxt);
3181  tgqual = stringToNode(trigger->tgqual);
3182  /* Change references to OLD and NEW to INNER_VAR and OUTER_VAR */
3185  /* ExecPrepareQual wants implicit-AND form */
3186  tgqual = (Node *) make_ands_implicit((Expr *) tgqual);
3187  *predicate = ExecPrepareQual((List *) tgqual, estate);
3188  MemoryContextSwitchTo(oldContext);
3189  }
3190 
3191  /*
3192  * We will use the EState's per-tuple context for evaluating WHEN
3193  * expressions (creating it if it's not already there).
3194  */
3195  econtext = GetPerTupleExprContext(estate);
3196 
3197  /*
3198  * Finally evaluate the expression, making the old and/or new tuples
3199  * available as INNER_VAR/OUTER_VAR respectively.
3200  */
3201  econtext->ecxt_innertuple = oldslot;
3202  econtext->ecxt_outertuple = newslot;
3203  if (!ExecQual(*predicate, econtext))
3204  return false;
3205  }
3206 
3207  return true;
3208 }
3209 
3210 
3211 /* ----------
3212  * After-trigger stuff
3213  *
3214  * The AfterTriggersData struct holds data about pending AFTER trigger events
3215  * during the current transaction tree. (BEFORE triggers are fired
3216  * immediately so we don't need any persistent state about them.) The struct
3217  * and most of its subsidiary data are kept in TopTransactionContext; however
3218  * some data that can be discarded sooner appears in the CurTransactionContext
3219  * of the relevant subtransaction. Also, the individual event records are
3220  * kept in a separate sub-context of TopTransactionContext. This is done
3221  * mainly so that it's easy to tell from a memory context dump how much space
3222  * is being eaten by trigger events.
3223  *
3224  * Because the list of pending events can grow large, we go to some
3225  * considerable effort to minimize per-event memory consumption. The event
3226  * records are grouped into chunks and common data for similar events in the
3227  * same chunk is only stored once.
3228  *
3229  * XXX We need to be able to save the per-event data in a file if it grows too
3230  * large.
3231  * ----------
3232  */
3233 
3234 /* Per-trigger SET CONSTRAINT status */
3236 {
3240 
3242 
3243 /*
3244  * SET CONSTRAINT intra-transaction status.
3245  *
3246  * We make this a single palloc'd object so it can be copied and freed easily.
3247  *
3248  * all_isset and all_isdeferred are used to keep track
3249  * of SET CONSTRAINTS ALL {DEFERRED, IMMEDIATE}.
3250  *
3251  * trigstates[] stores per-trigger tgisdeferred settings.
3252  */
3254 {
3257  int numstates; /* number of trigstates[] entries in use */
3258  int numalloc; /* allocated size of trigstates[] */
3261 
3263 
3264 
3265 /*
3266  * Per-trigger-event data
3267  *
3268  * The actual per-event data, AfterTriggerEventData, includes DONE/IN_PROGRESS
3269  * status bits and up to two tuple CTIDs. Each event record also has an
3270  * associated AfterTriggerSharedData that is shared across all instances of
3271  * similar events within a "chunk".
3272  *
3273  * For row-level triggers, we arrange not to waste storage on unneeded ctid
3274  * fields. Updates of regular tables use two; inserts and deletes of regular
3275  * tables use one; foreign tables always use zero and save the tuple(s) to a
3276  * tuplestore. AFTER_TRIGGER_FDW_FETCH directs AfterTriggerExecute() to
3277  * retrieve a fresh tuple or pair of tuples from that tuplestore, while
3278  * AFTER_TRIGGER_FDW_REUSE directs it to use the most-recently-retrieved
3279  * tuple(s). This permits storing tuples once regardless of the number of
3280  * row-level triggers on a foreign table.
3281  *
3282  * Note that we need triggers on foreign tables to be fired in exactly the
3283  * order they were queued, so that the tuples come out of the tuplestore in
3284  * the right order. To ensure that, we forbid deferrable (constraint)
3285  * triggers on foreign tables. This also ensures that such triggers do not
3286  * get deferred into outer trigger query levels, meaning that it's okay to
3287  * destroy the tuplestore at the end of the query level.
3288  *
3289  * Statement-level triggers always bear AFTER_TRIGGER_1CTID, though they
3290  * require no ctid field. We lack the flag bit space to neatly represent that
3291  * distinct case, and it seems unlikely to be worth much trouble.
3292  *
3293  * Note: ats_firing_id is initially zero and is set to something else when
3294  * AFTER_TRIGGER_IN_PROGRESS is set. It indicates which trigger firing
3295  * cycle the trigger will be fired in (or was fired in, if DONE is set).
3296  * Although this is mutable state, we can keep it in AfterTriggerSharedData
3297  * because all instances of the same type of event in a given event list will
3298  * be fired at the same time, if they were queued between the same firing
3299  * cycles. So we need only ensure that ats_firing_id is zero when attaching
3300  * a new event to an existing AfterTriggerSharedData record.
3301  */
3303 
3304 #define AFTER_TRIGGER_OFFSET 0x0FFFFFFF /* must be low-order bits */
3305 #define AFTER_TRIGGER_DONE 0x10000000
3306 #define AFTER_TRIGGER_IN_PROGRESS 0x20000000
3307 /* bits describing the size and tuple sources of this event */
3308 #define AFTER_TRIGGER_FDW_REUSE 0x00000000
3309 #define AFTER_TRIGGER_FDW_FETCH 0x80000000
3310 #define AFTER_TRIGGER_1CTID 0x40000000
3311 #define AFTER_TRIGGER_2CTID 0xC0000000
3312 #define AFTER_TRIGGER_TUP_BITS 0xC0000000
3313 
3315 
3317 {
3318  TriggerEvent ats_event; /* event type indicator, see trigger.h */
3319  Oid ats_tgoid; /* the trigger's ID */
3320  Oid ats_relid; /* the relation it's on */
3321  CommandId ats_firing_id; /* ID for firing cycle */
3322  struct AfterTriggersTableData *ats_table; /* transition table access */
3323  Bitmapset *ats_modifiedcols; /* modified columns */
3325 
3327 
3329 {
3330  TriggerFlags ate_flags; /* status bits and offset to shared data */
3331  ItemPointerData ate_ctid1; /* inserted, deleted, or old updated tuple */
3332  ItemPointerData ate_ctid2; /* new updated tuple */
3334 
3335 /* AfterTriggerEventData, minus ate_ctid2 */
3337 {
3338  TriggerFlags ate_flags; /* status bits and offset to shared data */
3339  ItemPointerData ate_ctid1; /* inserted, deleted, or old updated tuple */
3341 
3342 /* AfterTriggerEventData, minus ate_ctid1 and ate_ctid2 */
3344 {
3345  TriggerFlags ate_flags; /* status bits and offset to shared data */
3347 
3348 #define SizeofTriggerEvent(evt) \
3349  (((evt)->ate_flags & AFTER_TRIGGER_TUP_BITS) == AFTER_TRIGGER_2CTID ? \
3350  sizeof(AfterTriggerEventData) : \
3351  ((evt)->ate_flags & AFTER_TRIGGER_TUP_BITS) == AFTER_TRIGGER_1CTID ? \
3352  sizeof(AfterTriggerEventDataOneCtid) : \
3353  sizeof(AfterTriggerEventDataZeroCtids))
3354 
3355 #define GetTriggerSharedData(evt) \
3356  ((AfterTriggerShared) ((char *) (evt) + ((evt)->ate_flags & AFTER_TRIGGER_OFFSET)))
3357 
3358 /*
3359  * To avoid palloc overhead, we keep trigger events in arrays in successively-
3360  * larger chunks (a slightly more sophisticated version of an expansible
3361  * array). The space between CHUNK_DATA_START and freeptr is occupied by
3362  * AfterTriggerEventData records; the space between endfree and endptr is
3363  * occupied by AfterTriggerSharedData records.
3364  */
3366 {
3367  struct AfterTriggerEventChunk *next; /* list link */
3368  char *freeptr; /* start of free space in chunk */
3369  char *endfree; /* end of free space in chunk */
3370  char *endptr; /* end of chunk */
3371  /* event data follows here */
3373 
3374 #define CHUNK_DATA_START(cptr) ((char *) (cptr) + MAXALIGN(sizeof(AfterTriggerEventChunk)))
3375 
3376 /* A list of events */
3378 {
3381  char *tailfree; /* freeptr of tail chunk */
3383 
3384 /* Macros to help in iterating over a list of events */
3385 #define for_each_chunk(cptr, evtlist) \
3386  for (cptr = (evtlist).head; cptr != NULL; cptr = cptr->next)
3387 #define for_each_event(eptr, cptr) \
3388  for (eptr = (AfterTriggerEvent) CHUNK_DATA_START(cptr); \
3389  (char *) eptr < (cptr)->freeptr; \
3390  eptr = (AfterTriggerEvent) (((char *) eptr) + SizeofTriggerEvent(eptr)))
3391 /* Use this if no special per-chunk processing is needed */
3392 #define for_each_event_chunk(eptr, cptr, evtlist) \
3393  for_each_chunk(cptr, evtlist) for_each_event(eptr, cptr)
3394 
3395 /* Macros for iterating from a start point that might not be list start */
3396 #define for_each_chunk_from(cptr) \
3397  for (; cptr != NULL; cptr = cptr->next)
3398 #define for_each_event_from(eptr, cptr) \
3399  for (; \
3400  (char *) eptr < (cptr)->freeptr; \
3401  eptr = (AfterTriggerEvent) (((char *) eptr) + SizeofTriggerEvent(eptr)))
3402 
3403 
3404 /*
3405  * All per-transaction data for the AFTER TRIGGERS module.
3406  *
3407  * AfterTriggersData has the following fields:
3408  *
3409  * firing_counter is incremented for each call of afterTriggerInvokeEvents.
3410  * We mark firable events with the current firing cycle's ID so that we can
3411  * tell which ones to work on. This ensures sane behavior if a trigger
3412  * function chooses to do SET CONSTRAINTS: the inner SET CONSTRAINTS will
3413  * only fire those events that weren't already scheduled for firing.
3414  *
3415  * state keeps track of the transaction-local effects of SET CONSTRAINTS.
3416  * This is saved and restored across failed subtransactions.
3417  *
3418  * events is the current list of deferred events. This is global across
3419  * all subtransactions of the current transaction. In a subtransaction
3420  * abort, we know that the events added by the subtransaction are at the
3421  * end of the list, so it is relatively easy to discard them. The event
3422  * list chunks themselves are stored in event_cxt.
3423  *
3424  * query_depth is the current depth of nested AfterTriggerBeginQuery calls
3425  * (-1 when the stack is empty).
3426  *
3427  * query_stack[query_depth] is the per-query-level data, including these fields:
3428  *
3429  * events is a list of AFTER trigger events queued by the current query.
3430  * None of these are valid until the matching AfterTriggerEndQuery call
3431  * occurs. At that point we fire immediate-mode triggers, and append any
3432  * deferred events to the main events list.
3433  *
3434  * fdw_tuplestore is a tuplestore containing the foreign-table tuples
3435  * needed by events queued by the current query. (Note: we use just one
3436  * tuplestore even though more than one foreign table might be involved.
3437  * This is okay because tuplestores don't really care what's in the tuples
3438  * they store; but it's possible that someday it'd break.)
3439  *
3440  * tables is a List of AfterTriggersTableData structs for target tables
3441  * of the current query (see below).
3442  *
3443  * maxquerydepth is just the allocated length of query_stack.
3444  *
3445  * trans_stack holds per-subtransaction data, including these fields:
3446  *
3447  * state is NULL or a pointer to a saved copy of the SET CONSTRAINTS
3448  * state data. Each subtransaction level that modifies that state first
3449  * saves a copy, which we use to restore the state if we abort.
3450  *
3451  * events is a copy of the events head/tail pointers,
3452  * which we use to restore those values during subtransaction abort.
3453  *
3454  * query_depth is the subtransaction-start-time value of query_depth,
3455  * which we similarly use to clean up at subtransaction abort.
3456  *
3457  * firing_counter is the subtransaction-start-time value of firing_counter.
3458  * We use this to recognize which deferred triggers were fired (or marked
3459  * for firing) within an aborted subtransaction.
3460  *
3461  * We use GetCurrentTransactionNestLevel() to determine the correct array
3462  * index in trans_stack. maxtransdepth is the number of allocated entries in
3463  * trans_stack. (By not keeping our own stack pointer, we can avoid trouble
3464  * in cases where errors during subxact abort cause multiple invocations
3465  * of AfterTriggerEndSubXact() at the same nesting depth.)
3466  *
3467  * We create an AfterTriggersTableData struct for each target table of the
3468  * current query, and each operation mode (INSERT/UPDATE/DELETE), that has
3469  * either transition tables or statement-level triggers. This is used to
3470  * hold the relevant transition tables, as well as info tracking whether
3471  * we already queued the statement triggers. (We use that info to prevent
3472  * firing the same statement triggers more than once per statement, or really
3473  * once per transition table set.) These structs, along with the transition
3474  * table tuplestores, live in the (sub)transaction's CurTransactionContext.
3475  * That's sufficient lifespan because we don't allow transition tables to be
3476  * used by deferrable triggers, so they only need to survive until
3477  * AfterTriggerEndQuery.
3478  */
3482 
3483 typedef struct AfterTriggersData
3484 {
3485  CommandId firing_counter; /* next firing ID to assign */
3486  SetConstraintState state; /* the active S C state */
3487  AfterTriggerEventList events; /* deferred-event list */
3488  MemoryContext event_cxt; /* memory context for events, if any */
3489 
3490  /* per-query-level data: */
3491  AfterTriggersQueryData *query_stack; /* array of structs shown below */
3492  int query_depth; /* current index in above array */
3493  int maxquerydepth; /* allocated len of above array */
3494 
3495  /* per-subtransaction-level data: */
3496  AfterTriggersTransData *trans_stack; /* array of structs shown below */
3497  int maxtransdepth; /* allocated len of above array */
3499 
3501 {
3502  AfterTriggerEventList events; /* events pending from this query */
3503  Tuplestorestate *fdw_tuplestore; /* foreign tuples for said events */
3504  List *tables; /* list of AfterTriggersTableData, see below */
3505 };
3506 
3508 {
3509  /* these fields are just for resetting at subtrans abort: */
3510  SetConstraintState state; /* saved S C state, or NULL if not yet saved */
3511  AfterTriggerEventList events; /* saved list pointer */
3512  int query_depth; /* saved query_depth */
3513  CommandId firing_counter; /* saved firing_counter */
3514 };
3515 
3517 {
3518  /* relid + cmdType form the lookup key for these structs: */
3519  Oid relid; /* target table's OID */
3520  CmdType cmdType; /* event type, CMD_INSERT/UPDATE/DELETE */
3521  bool closed; /* true when no longer OK to add tuples */
3522  bool before_trig_done; /* did we already queue BS triggers? */
3523  bool after_trig_done; /* did we already queue AS triggers? */
3524  AfterTriggerEventList after_trig_events; /* if so, saved list pointer */
3525  Tuplestorestate *old_tuplestore; /* "old" transition table, if any */
3526  Tuplestorestate *new_tuplestore; /* "new" transition table, if any */
3527  TupleTableSlot *storeslot; /* for converting to tuplestore's format */
3528 };
3529 
3531 
3532 static void AfterTriggerExecute(EState *estate,
3533  AfterTriggerEvent event,
3534  ResultRelInfo *relInfo,
3535  TriggerDesc *trigdesc,
3536  FmgrInfo *finfo,
3537  Instrumentation *instr,
3538  MemoryContext per_tuple_context,
3539  TupleTableSlot *trig_tuple_slot1,
3540  TupleTableSlot *trig_tuple_slot2);
3542  CmdType cmdType);
3544  TupleDesc tupdesc);
3546 static SetConstraintState SetConstraintStateCreate(int numalloc);
3549  Oid tgoid, bool tgisdeferred);
3550 static void cancel_prior_stmt_triggers(Oid relid, CmdType cmdType, int tgevent);
3551 
3552 
3553 /*
3554  * Get the FDW tuplestore for the current trigger query level, creating it
3555  * if necessary.
3556  */
3557 static Tuplestorestate *
3559 {
3560  Tuplestorestate *ret;
3561 
3562  ret = afterTriggers.query_stack[afterTriggers.query_depth].fdw_tuplestore;
3563  if (ret == NULL)
3564  {
3565  MemoryContext oldcxt;
3566  ResourceOwner saveResourceOwner;
3567 
3568  /*
3569  * Make the tuplestore valid until end of subtransaction. We really
3570  * only need it until AfterTriggerEndQuery().
3571  */
3573  saveResourceOwner = CurrentResourceOwner;
3575 
3576  ret = tuplestore_begin_heap(false, false, work_mem);
3577 
3578  CurrentResourceOwner = saveResourceOwner;
3579  MemoryContextSwitchTo(oldcxt);
3580 
3581  afterTriggers.query_stack[afterTriggers.query_depth].fdw_tuplestore = ret;
3582  }
3583 
3584  return ret;
3585 }
3586 
3587 /* ----------
3588  * afterTriggerCheckState()
3589  *
3590  * Returns true if the trigger event is actually in state DEFERRED.
3591  * ----------
3592  */
3593 static bool
3594 afterTriggerCheckState(AfterTriggerShared evtshared)
3595 {
3596  Oid tgoid = evtshared->ats_tgoid;
3597  SetConstraintState state = afterTriggers.state;
3598  int i;
3599 
3600  /*
3601  * For not-deferrable triggers (i.e. normal AFTER ROW triggers and
3602  * constraints declared NOT DEFERRABLE), the state is always false.
3603  */
3604  if ((evtshared->ats_event & AFTER_TRIGGER_DEFERRABLE) == 0)
3605  return false;
3606 
3607  /*
3608  * If constraint state exists, SET CONSTRAINTS might have been executed
3609  * either for this trigger or for all triggers.
3610  */
3611  if (state != NULL)
3612  {
3613  /* Check for SET CONSTRAINTS for this specific trigger. */
3614  for (i = 0; i < state->numstates; i++)
3615  {
3616  if (state->trigstates[i].sct_tgoid == tgoid)
3617  return state->trigstates[i].sct_tgisdeferred;
3618  }
3619 
3620  /* Check for SET CONSTRAINTS ALL. */
3621  if (state->all_isset)
3622  return state->all_isdeferred;
3623  }
3624 
3625  /*
3626  * Otherwise return the default state for the trigger.
3627  */
3628  return ((evtshared->ats_event & AFTER_TRIGGER_INITDEFERRED) != 0);
3629 }
3630 
3631 
3632 /* ----------
3633  * afterTriggerAddEvent()
3634  *
3635  * Add a new trigger event to the specified queue.
3636  * The passed-in event data is copied.
3637  * ----------
3638  */
3639 static void
3641  AfterTriggerEvent event, AfterTriggerShared evtshared)
3642 {
3643  Size eventsize = SizeofTriggerEvent(event);
3644  Size needed = eventsize + sizeof(AfterTriggerSharedData);
3645  AfterTriggerEventChunk *chunk;
3646  AfterTriggerShared newshared;
3647  AfterTriggerEvent newevent;
3648 
3649  /*
3650  * If empty list or not enough room in the tail chunk, make a new chunk.
3651  * We assume here that a new shared record will always be needed.
3652  */
3653  chunk = events->tail;
3654  if (chunk == NULL ||
3655  chunk->endfree - chunk->freeptr < needed)
3656  {
3657  Size chunksize;
3658 
3659  /* Create event context if we didn't already */
3660  if (afterTriggers.event_cxt == NULL)
3661  afterTriggers.event_cxt =
3663  "AfterTriggerEvents",
3665 
3666  /*
3667  * Chunk size starts at 1KB and is allowed to increase up to 1MB.
3668  * These numbers are fairly arbitrary, though there is a hard limit at
3669  * AFTER_TRIGGER_OFFSET; else we couldn't link event records to their
3670  * shared records using the available space in ate_flags. Another
3671  * constraint is that if the chunk size gets too huge, the search loop
3672  * below would get slow given a (not too common) usage pattern with
3673  * many distinct event types in a chunk. Therefore, we double the
3674  * preceding chunk size only if there weren't too many shared records
3675  * in the preceding chunk; otherwise we halve it. This gives us some
3676  * ability to adapt to the actual usage pattern of the current query
3677  * while still having large chunk sizes in typical usage. All chunk
3678  * sizes used should be MAXALIGN multiples, to ensure that the shared
3679  * records will be aligned safely.
3680  */
3681 #define MIN_CHUNK_SIZE 1024
3682 #define MAX_CHUNK_SIZE (1024*1024)
3683 
3684 #if MAX_CHUNK_SIZE > (AFTER_TRIGGER_OFFSET+1)
3685 #error MAX_CHUNK_SIZE must not exceed AFTER_TRIGGER_OFFSET
3686 #endif
3687 
3688  if (chunk == NULL)
3689  chunksize = MIN_CHUNK_SIZE;
3690  else
3691  {
3692  /* preceding chunk size... */
3693  chunksize = chunk->endptr - (char *) chunk;
3694  /* check number of shared records in preceding chunk */
3695  if ((chunk->endptr - chunk->endfree) <=
3696  (100 * sizeof(AfterTriggerSharedData)))
3697  chunksize *= 2; /* okay, double it */
3698  else
3699  chunksize /= 2; /* too many shared records */
3700  chunksize = Min(chunksize, MAX_CHUNK_SIZE);
3701  }
3702  chunk = MemoryContextAlloc(afterTriggers.event_cxt, chunksize);
3703  chunk->next = NULL;
3704  chunk->freeptr = CHUNK_DATA_START(chunk);
3705  chunk->endptr = chunk->endfree = (char *) chunk + chunksize;
3706  Assert(chunk->endfree - chunk->freeptr >= needed);
3707 
3708  if (events->head == NULL)
3709  events->head = chunk;
3710  else
3711  events->tail->next = chunk;
3712  events->tail = chunk;
3713  /* events->tailfree is now out of sync, but we'll fix it below */
3714  }
3715 
3716  /*
3717  * Try to locate a matching shared-data record already in the chunk. If
3718  * none, make a new one.
3719  */
3720  for (newshared = ((AfterTriggerShared) chunk->endptr) - 1;
3721  (char *) newshared >= chunk->endfree;
3722  newshared--)
3723  {
3724  if (newshared->ats_tgoid == evtshared->ats_tgoid &&
3725  newshared->ats_relid == evtshared->ats_relid &&
3726  newshared->ats_event == evtshared->ats_event &&
3727  newshared->ats_table == evtshared->ats_table &&
3728  newshared->ats_firing_id == 0)
3729  break;
3730  }
3731  if ((char *) newshared < chunk->endfree)
3732  {
3733  *newshared = *evtshared;
3734  newshared->ats_firing_id = 0; /* just to be sure */
3735  chunk->endfree = (char *) newshared;
3736  }
3737 
3738  /* Insert the data */
3739  newevent = (AfterTriggerEvent) chunk->freeptr;
3740  memcpy(newevent, event, eventsize);
3741  /* ... and link the new event to its shared record */
3742  newevent->ate_flags &= ~AFTER_TRIGGER_OFFSET;
3743  newevent->ate_flags |= (char *) newshared - (char *) newevent;
3744 
3745  chunk->freeptr += eventsize;
3746  events->tailfree = chunk->freeptr;
3747 }
3748 
3749 /* ----------
3750  * afterTriggerFreeEventList()
3751  *
3752  * Free all the event storage in the given list.
3753  * ----------
3754  */
3755 static void
3757 {
3758  AfterTriggerEventChunk *chunk;
3759 
3760  while ((chunk = events->head) != NULL)
3761  {
3762  events->head = chunk->next;
3763  pfree(chunk);
3764  }
3765  events->tail = NULL;
3766  events->tailfree = NULL;
3767 }
3768 
3769 /* ----------
3770  * afterTriggerRestoreEventList()
3771  *
3772  * Restore an event list to its prior length, removing all the events
3773  * added since it had the value old_events.
3774  * ----------
3775  */
3776 static void
3778  const AfterTriggerEventList *old_events)
3779 {
3780  AfterTriggerEventChunk *chunk;
3781  AfterTriggerEventChunk *next_chunk;
3782 
3783  if (old_events->tail == NULL)
3784  {
3785  /* restoring to a completely empty state, so free everything */
3786  afterTriggerFreeEventList(events);
3787  }
3788  else
3789  {
3790  *events = *old_events;
3791  /* free any chunks after the last one we want to keep */
3792  for (chunk = events->tail->next; chunk != NULL; chunk = next_chunk)
3793  {
3794  next_chunk = chunk->next;
3795  pfree(chunk);
3796  }
3797  /* and clean up the tail chunk to be the right length */
3798  events->tail->next = NULL;
3799  events->tail->freeptr = events->tailfree;
3800 
3801  /*
3802  * We don't make any effort to remove now-unused shared data records.
3803  * They might still be useful, anyway.
3804  */
3805  }
3806 }
3807 
3808 /* ----------
3809  * afterTriggerDeleteHeadEventChunk()
3810  *
3811  * Remove the first chunk of events from the query level's event list.
3812  * Keep any event list pointers elsewhere in the query level's data
3813  * structures in sync.
3814  * ----------
3815  */
3816 static void
3818 {
3819  AfterTriggerEventChunk *target = qs->events.head;
3820  ListCell *lc;
3821 
3822  Assert(target && target->next);
3823 
3824  /*
3825  * First, update any pointers in the per-table data, so that they won't be
3826  * dangling. Resetting obsoleted pointers to NULL will make
3827  * cancel_prior_stmt_triggers start from the list head, which is fine.
3828  */
3829  foreach(lc, qs->tables)
3830  {
3832 
3833  if (table->after_trig_done &&
3834  table->after_trig_events.tail == target)
3835  {
3836  table->after_trig_events.head = NULL;
3837  table->after_trig_events.tail = NULL;
3838  table->after_trig_events.tailfree = NULL;
3839  }
3840  }
3841 
3842  /* Now we can flush the head chunk */
3843  qs->events.head = target->next;
3844  pfree(target);
3845 }
3846 
3847 
3848 /* ----------
3849  * AfterTriggerExecute()
3850  *
3851  * Fetch the required tuples back from the heap and fire one
3852  * single trigger function.
3853  *
3854  * Frequently, this will be fired many times in a row for triggers of
3855  * a single relation. Therefore, we cache the open relation and provide
3856  * fmgr lookup cache space at the caller level. (For triggers fired at
3857  * the end of a query, we can even piggyback on the executor's state.)
3858  *
3859  * event: event currently being fired.
3860  * rel: open relation for event.
3861  * trigdesc: working copy of rel's trigger info.
3862  * finfo: array of fmgr lookup cache entries (one per trigger in trigdesc).
3863  * instr: array of EXPLAIN ANALYZE instrumentation nodes (one per trigger),
3864  * or NULL if no instrumentation is wanted.
3865  * per_tuple_context: memory context to call trigger function in.
3866  * trig_tuple_slot1: scratch slot for tg_trigtuple (foreign tables only)
3867  * trig_tuple_slot2: scratch slot for tg_newtuple (foreign tables only)
3868  * ----------
3869  */
3870 static void
3872  AfterTriggerEvent event,
3873  ResultRelInfo *relInfo,
3874  TriggerDesc *trigdesc,
3875  FmgrInfo *finfo, Instrumentation *instr,
3876  MemoryContext per_tuple_context,
3877  TupleTableSlot *trig_tuple_slot1,
3878  TupleTableSlot *trig_tuple_slot2)
3879 {
3880  Relation rel = relInfo->ri_RelationDesc;
3881  AfterTriggerShared evtshared = GetTriggerSharedData(event);
3882  Oid tgoid = evtshared->ats_tgoid;
3883  TriggerData LocTriggerData = {0};
3884  HeapTuple rettuple;
3885  int tgindx;
3886  bool should_free_trig = false;
3887  bool should_free_new = false;
3888 
3889  /*
3890  * Locate trigger in trigdesc.
3891  */
3892  for (tgindx = 0; tgindx < trigdesc->numtriggers; tgindx++)
3893  {
3894  if (trigdesc->triggers[tgindx].tgoid == tgoid)
3895  {
3896  LocTriggerData.tg_trigger = &(trigdesc->triggers[tgindx]);
3897  break;
3898  }
3899  }
3900  if (LocTriggerData.tg_trigger == NULL)
3901  elog(ERROR, "could not find trigger %u", tgoid);
3902 
3903  /*
3904  * If doing EXPLAIN ANALYZE, start charging time to this trigger. We want
3905  * to include time spent re-fetching tuples in the trigger cost.
3906  */
3907  if (instr)
3908  InstrStartNode(instr + tgindx);
3909 
3910  /*
3911  * Fetch the required tuple(s).
3912  */
3913  switch (event->ate_flags & AFTER_TRIGGER_TUP_BITS)
3914  {
3916  {
3917  Tuplestorestate *fdw_tuplestore = GetCurrentFDWTuplestore();
3918 
3919  if (!tuplestore_gettupleslot(fdw_tuplestore, true, false,
3920  trig_tuple_slot1))
3921  elog(ERROR, "failed to fetch tuple1 for AFTER trigger");
3922 
3923  if ((evtshared->ats_event & TRIGGER_EVENT_OPMASK) ==
3925  !tuplestore_gettupleslot(fdw_tuplestore, true, false,
3926  trig_tuple_slot2))
3927  elog(ERROR, "failed to fetch tuple2 for AFTER trigger");
3928  }
3929  /* fall through */
3931 
3932  /*
3933  * Store tuple in the slot so that tg_trigtuple does not reference
3934  * tuplestore memory. (It is formally possible for the trigger
3935  * function to queue trigger events that add to the same
3936  * tuplestore, which can push other tuples out of memory.) The
3937  * distinction is academic, because we start with a minimal tuple
3938  * that is stored as a heap tuple, constructed in different memory
3939  * context, in the slot anyway.
3940  */
3941  LocTriggerData.tg_trigslot = trig_tuple_slot1;
3942  LocTriggerData.tg_trigtuple =
3943  ExecFetchSlotHeapTuple(trig_tuple_slot1, true, &should_free_trig);
3944 
3945  if ((evtshared->ats_event & TRIGGER_EVENT_OPMASK) ==
3947  {
3948  LocTriggerData.tg_newslot = trig_tuple_slot2;
3949  LocTriggerData.tg_newtuple =
3950  ExecFetchSlotHeapTuple(trig_tuple_slot2, true, &should_free_new);
3951  }
3952  else
3953  {
3954  LocTriggerData.tg_newtuple = NULL;
3955  }
3956  break;
3957 
3958  default:
3959  if (ItemPointerIsValid(&(event->ate_ctid1)))
3960  {
3961  LocTriggerData.tg_trigslot = ExecGetTriggerOldSlot(estate, relInfo);
3962 
3963  if (!table_tuple_fetch_row_version(rel, &(event->ate_ctid1),
3964  SnapshotAny,
3965  LocTriggerData.tg_trigslot))
3966  elog(ERROR, "failed to fetch tuple1 for AFTER trigger");
3967  LocTriggerData.tg_trigtuple =
3968  ExecFetchSlotHeapTuple(LocTriggerData.tg_trigslot, false, &should_free_trig);
3969  }
3970  else
3971  {
3972  LocTriggerData.tg_trigtuple = NULL;
3973  }
3974 
3975  /* don't touch ctid2 if not there */
3976  if ((event->ate_flags & AFTER_TRIGGER_TUP_BITS) ==
3978  ItemPointerIsValid(&(event->ate_ctid2)))
3979  {
3980  LocTriggerData.tg_newslot = ExecGetTriggerNewSlot(estate, relInfo);
3981 
3982  if (!table_tuple_fetch_row_version(rel, &(event->ate_ctid2),
3983  SnapshotAny,
3984  LocTriggerData.tg_newslot))
3985  elog(ERROR, "failed to fetch tuple2 for AFTER trigger");
3986  LocTriggerData.tg_newtuple =
3987  ExecFetchSlotHeapTuple(LocTriggerData.tg_newslot, false, &should_free_new);
3988  }
3989  else
3990  {
3991  LocTriggerData.tg_newtuple = NULL;
3992  }
3993  }
3994 
3995  /*
3996  * Set up the tuplestore information to let the trigger have access to
3997  * transition tables. When we first make a transition table available to
3998  * a trigger, mark it "closed" so that it cannot change anymore. If any
3999  * additional events of the same type get queued in the current trigger
4000  * query level, they'll go into new transition tables.
4001  */
4002  LocTriggerData.tg_oldtable = LocTriggerData.tg_newtable = NULL;
4003  if (evtshared->ats_table)
4004  {
4005  if (LocTriggerData.tg_trigger->tgoldtable)
4006  {
4007  LocTriggerData.tg_oldtable = evtshared->ats_table->old_tuplestore;
4008  evtshared->ats_table->closed = true;
4009  }
4010 
4011  if (LocTriggerData.tg_trigger->tgnewtable)
4012  {
4013  LocTriggerData.tg_newtable = evtshared->ats_table->new_tuplestore;
4014  evtshared->ats_table->closed = true;
4015  }
4016  }
4017 
4018  /*
4019  * Setup the remaining trigger information
4020  */
4021  LocTriggerData.type = T_TriggerData;
4022  LocTriggerData.tg_event =
4024  LocTriggerData.tg_relation = rel;
4025  if (TRIGGER_FOR_UPDATE(LocTriggerData.tg_trigger->tgtype))
4026  LocTriggerData.tg_updatedcols = evtshared->ats_modifiedcols;
4027 
4028  MemoryContextReset(per_tuple_context);
4029 
4030  /*
4031  * Call the trigger and throw away any possibly returned updated tuple.
4032  * (Don't let ExecCallTriggerFunc measure EXPLAIN time.)
4033  */
4034  rettuple = ExecCallTriggerFunc(&LocTriggerData,
4035  tgindx,
4036  finfo,
4037  NULL,
4038  per_tuple_context);
4039  if (rettuple != NULL &&
4040  rettuple != LocTriggerData.tg_trigtuple &&
4041  rettuple != LocTriggerData.tg_newtuple)
4042  heap_freetuple(rettuple);
4043 
4044  /*
4045  * Release resources
4046  */
4047  if (should_free_trig)
4048  heap_freetuple(LocTriggerData.tg_trigtuple);
4049  if (should_free_new)
4050  heap_freetuple(LocTriggerData.tg_newtuple);
4051 
4052  /* don't clear slots' contents if foreign table */
4053  if (trig_tuple_slot1 == NULL)
4054  {
4055  if (LocTriggerData.tg_trigslot)
4056  ExecClearTuple(LocTriggerData.tg_trigslot);
4057  if (LocTriggerData.tg_newslot)
4058  ExecClearTuple(LocTriggerData.tg_newslot);
4059  }
4060 
4061  /*
4062  * If doing EXPLAIN ANALYZE, stop charging time to this trigger, and count
4063  * one "tuple returned" (really the number of firings).
4064  */
4065  if (instr)
4066  InstrStopNode(instr + tgindx, 1);
4067 }
4068 
4069 
4070 /*
4071  * afterTriggerMarkEvents()
4072  *
4073  * Scan the given event list for not yet invoked events. Mark the ones
4074  * that can be invoked now with the current firing ID.
4075  *
4076  * If move_list isn't NULL, events that are not to be invoked now are
4077  * transferred to move_list.
4078  *
4079  * When immediate_only is true, do not invoke currently-deferred triggers.
4080  * (This will be false only at main transaction exit.)
4081  *
4082  * Returns true if any invokable events were found.
4083  */
4084 static bool
4086  AfterTriggerEventList *move_list,
4087  bool immediate_only)
4088 {
4089  bool found = false;
4090  bool deferred_found = false;
4091  AfterTriggerEvent event;
4092  AfterTriggerEventChunk *chunk;
4093 
4094  for_each_event_chunk(event, chunk, *events)
4095  {
4096  AfterTriggerShared evtshared = GetTriggerSharedData(event);
4097  bool defer_it = false;
4098 
4099  if (!(event->ate_flags &
4101  {
4102  /*
4103  * This trigger hasn't been called or scheduled yet. Check if we
4104  * should call it now.
4105  */
4106  if (immediate_only && afterTriggerCheckState(evtshared))
4107  {
4108  defer_it = true;
4109  }
4110  else
4111  {
4112  /*
4113  * Mark it as to be fired in this firing cycle.
4114  */
4115  evtshared->ats_firing_id = afterTriggers.firing_counter;
4116  event->ate_flags |= AFTER_TRIGGER_IN_PROGRESS;
4117  found = true;
4118  }
4119  }
4120 
4121  /*
4122  * If it's deferred, move it to move_list, if requested.
4123  */
4124  if (defer_it && move_list != NULL)
4125  {
4126  deferred_found = true;
4127  /* add it to move_list */
4128  afterTriggerAddEvent(move_list, event, evtshared);
4129  /* mark original copy "done" so we don't do it again */
4130  event->ate_flags |= AFTER_TRIGGER_DONE;
4131  }
4132  }
4133 
4134  /*
4135  * We could allow deferred triggers if, before the end of the
4136  * security-restricted operation, we were to verify that a SET CONSTRAINTS
4137  * ... IMMEDIATE has fired all such triggers. For now, don't bother.
4138  */
4139  if (deferred_found && InSecurityRestrictedOperation())
4140  ereport(ERROR,
4141  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
4142  errmsg("cannot fire deferred trigger within security-restricted operation")));
4143 
4144  return found;
4145 }
4146 
4147 /*
4148  * afterTriggerInvokeEvents()
4149  *
4150  * Scan the given event list for events that are marked as to be fired
4151  * in the current firing cycle, and fire them.
4152  *
4153  * If estate isn't NULL, we use its result relation info to avoid repeated
4154  * openings and closing of trigger target relations. If it is NULL, we
4155  * make one locally to cache the info in case there are multiple trigger
4156  * events per rel.
4157  *
4158  * When delete_ok is true, it's safe to delete fully-processed events.
4159  * (We are not very tense about that: we simply reset a chunk to be empty
4160  * if all its events got fired. The objective here is just to avoid useless
4161  * rescanning of events when a trigger queues new events during transaction
4162  * end, so it's not necessary to worry much about the case where only
4163  * some events are fired.)
4164  *
4165  * Returns true if no unfired events remain in the list (this allows us
4166  * to avoid repeating afterTriggerMarkEvents).
4167  */
4168 static bool
4170  CommandId firing_id,
4171  EState *estate,
4172  bool delete_ok)
4173 {
4174  bool all_fired = true;
4175  AfterTriggerEventChunk *chunk;
4176  MemoryContext per_tuple_context;
4177  bool local_estate = false;
4178  ResultRelInfo *rInfo = NULL;
4179  Relation rel = NULL;
4180  TriggerDesc *trigdesc = NULL;
4181  FmgrInfo *finfo = NULL;
4182  Instrumentation *instr = NULL;
4183  TupleTableSlot *slot1 = NULL,
4184  *slot2 = NULL;
4185 
4186  /* Make a local EState if need be */
4187  if (estate == NULL)
4188  {
4189  estate = CreateExecutorState();
4190  local_estate = true;
4191  }
4192 
4193  /* Make a per-tuple memory context for trigger function calls */
4194  per_tuple_context =
4196  "AfterTriggerTupleContext",
4198 
4199  for_each_chunk(chunk, *events)
4200  {
4201  AfterTriggerEvent event;
4202  bool all_fired_in_chunk = true;
4203 
4204  for_each_event(event, chunk)
4205  {
4206  AfterTriggerShared evtshared = GetTriggerSharedData(event);
4207 
4208  /*
4209  * Is it one for me to fire?
4210  */
4211  if ((event->ate_flags & AFTER_TRIGGER_IN_PROGRESS) &&
4212  evtshared->ats_firing_id == firing_id)
4213  {
4214  /*
4215  * So let's fire it... but first, find the correct relation if
4216  * this is not the same relation as before.
4217  */
4218  if (rel == NULL || RelationGetRelid(rel) != evtshared->ats_relid)
4219  {
4220  rInfo = ExecGetTriggerResultRel(estate, evtshared->ats_relid);
4221  rel = rInfo->ri_RelationDesc;
4222  trigdesc = rInfo->ri_TrigDesc;
4223  finfo = rInfo->ri_TrigFunctions;
4224  instr = rInfo->ri_TrigInstrument;
4225  if (slot1 != NULL)
4226  {
4229  slot1 = slot2 = NULL;
4230  }
4231  if (rel->rd_rel->relkind == RELKIND_FOREIGN_TABLE)
4232  {
4233  slot1 = MakeSingleTupleTableSlot(rel->rd_att,
4235  slot2 = MakeSingleTupleTableSlot(rel->rd_att,
4237  }
4238  if (trigdesc == NULL) /* should not happen */
4239  elog(ERROR, "relation %u has no triggers",
4240  evtshared->ats_relid);
4241  }
4242 
4243  /*
4244  * Fire it. Note that the AFTER_TRIGGER_IN_PROGRESS flag is
4245  * still set, so recursive examinations of the event list
4246  * won't try to re-fire it.
4247  */
4248  AfterTriggerExecute(estate, event, rInfo, trigdesc, finfo, instr,
4249  per_tuple_context, slot1, slot2);
4250 
4251  /*
4252  * Mark the event as done.
4253  */
4254  event->ate_flags &= ~AFTER_TRIGGER_IN_PROGRESS;
4255  event->ate_flags |= AFTER_TRIGGER_DONE;
4256  }
4257  else if (!(event->ate_flags & AFTER_TRIGGER_DONE))
4258  {
4259  /* something remains to be done */
4260  all_fired = all_fired_in_chunk = false;
4261  }
4262  }
4263 
4264  /* Clear the chunk if delete_ok and nothing left of interest */
4265  if (delete_ok && all_fired_in_chunk)
4266  {
4267  chunk->freeptr = CHUNK_DATA_START(chunk);
4268  chunk->endfree = chunk->endptr;
4269 
4270  /*
4271  * If it's last chunk, must sync event list's tailfree too. Note
4272  * that delete_ok must NOT be passed as true if there could be
4273  * additional AfterTriggerEventList values pointing at this event
4274  * list, since we'd fail to fix their copies of tailfree.
4275  */
4276  if (chunk == events->tail)
4277  events->tailfree = chunk->freeptr;
4278  }
4279  }
4280  if (slot1 != NULL)
4281  {
4284  }
4285 
4286  /* Release working resources */
4287  MemoryContextDelete(per_tuple_context);
4288 
4289  if (local_estate)
4290  {
4291  ExecCloseResultRelations(estate);
4292  ExecResetTupleTable(estate->es_tupleTable, false);
4293  FreeExecutorState(estate);
4294  }
4295 
4296  return all_fired;
4297 }
4298 
4299 
4300 /*
4301  * GetAfterTriggersTableData
4302  *
4303  * Find or create an AfterTriggersTableData struct for the specified
4304  * trigger event (relation + operation type). Ignore existing structs
4305  * marked "closed"; we don't want to put any additional tuples into them,
4306  * nor change their stmt-triggers-fired state.
4307  *
4308  * Note: the AfterTriggersTableData list is allocated in the current
4309  * (sub)transaction's CurTransactionContext. This is OK because
4310  * we don't need it to live past AfterTriggerEndQuery.
4311  */
4312 static AfterTriggersTableData *
4314 {
4315  AfterTriggersTableData *table;
4317  MemoryContext oldcxt;
4318  ListCell *lc;
4319 
4320  /* Caller should have ensured query_depth is OK. */
4321  Assert(afterTriggers.query_depth >= 0 &&
4322  afterTriggers.query_depth < afterTriggers.maxquerydepth);
4323  qs = &afterTriggers.query_stack[afterTriggers.query_depth];
4324 
4325  foreach(lc, qs->tables)
4326  {
4327  table = (AfterTriggersTableData *) lfirst(lc);
4328  if (table->relid == relid && table->cmdType == cmdType &&
4329  !table->closed)
4330  return table;
4331  }
4332 
4334 
4336  table->relid = relid;
4337  table->cmdType = cmdType;
4338  qs->tables = lappend(qs->tables, table);
4339 
4340  MemoryContextSwitchTo(oldcxt);
4341 
4342  return table;
4343 }
4344 
4345 /*
4346  * Returns a TupleTableSlot suitable for holding the tuples to be put
4347  * into AfterTriggersTableData's transition table tuplestores.
4348  */
4349 static TupleTableSlot *
4351  TupleDesc tupdesc)
4352 {
4353  /* Create it if not already done. */
4354  if (!table->storeslot)
4355  {
4356  MemoryContext oldcxt;
4357 
4358  /*
4359  * We only need this slot only until AfterTriggerEndQuery, but making
4360  * it last till end-of-subxact is good enough. It'll be freed by
4361  * AfterTriggerFreeQuery().
4362  */
4364  table->storeslot = MakeSingleTupleTableSlot(tupdesc, &TTSOpsVirtual);
4365  MemoryContextSwitchTo(oldcxt);
4366  }
4367 
4368  return table->storeslot;
4369 }
4370 
4371 /*
4372  * MakeTransitionCaptureState
4373  *
4374  * Make a TransitionCaptureState object for the given TriggerDesc, target
4375  * relation, and operation type. The TCS object holds all the state needed
4376  * to decide whether to capture tuples in transition tables.
4377  *
4378  * If there are no triggers in 'trigdesc' that request relevant transition
4379  * tables, then return NULL.
4380  *
4381  * The resulting object can be passed to the ExecAR* functions. When
4382  * dealing with child tables, the caller can set tcs_original_insert_tuple
4383  * to avoid having to reconstruct the original tuple in the root table's
4384  * format.
4385  *
4386  * Note that we copy the flags from a parent table into this struct (rather
4387  * than subsequently using the relation's TriggerDesc directly) so that we can
4388  * use it to control collection of transition tuples from child tables.
4389  *
4390  * Per SQL spec, all operations of the same kind (INSERT/UPDATE/DELETE)
4391  * on the same table during one query should share one transition table.
4392  * Therefore, the Tuplestores are owned by an AfterTriggersTableData struct
4393  * looked up using the table OID + CmdType, and are merely referenced by
4394  * the TransitionCaptureState objects we hand out to callers.
4395  */
4398 {
4400  bool need_old,
4401  need_new;
4402  AfterTriggersTableData *table;
4403  MemoryContext oldcxt;
4404  ResourceOwner saveResourceOwner;
4405 
4406  if (trigdesc == NULL)
4407  return NULL;
4408 
4409  /* Detect which table(s) we need. */
4410  switch (cmdType)
4411  {
4412  case CMD_INSERT:
4413  need_old = false;
4414  need_new = trigdesc->trig_insert_new_table;
4415  break;
4416  case CMD_UPDATE:
4417  need_old = trigdesc->trig_update_old_table;
4418  need_new = trigdesc->trig_update_new_table;
4419  break;
4420  case CMD_DELETE:
4421  need_old = trigdesc->trig_delete_old_table;
4422  need_new = false;
4423  break;
4424  default:
4425  elog(ERROR, "unexpected CmdType: %d", (int) cmdType);
4426  need_old = need_new = false; /* keep compiler quiet */
4427  break;
4428  }
4429  if (!need_old && !need_new)
4430  return NULL;
4431 
4432  /* Check state, like AfterTriggerSaveEvent. */
4433  if (afterTriggers.query_depth < 0)
4434  elog(ERROR, "MakeTransitionCaptureState() called outside of query");
4435 
4436  /* Be sure we have enough space to record events at this query depth. */
4437  if (afterTriggers.query_depth >= afterTriggers.maxquerydepth)
4439 
4440  /*
4441  * Find or create an AfterTriggersTableData struct to hold the
4442  * tuplestore(s). If there's a matching struct but it's marked closed,
4443  * ignore it; we need a newer one.
4444  *
4445  * Note: the AfterTriggersTableData list, as well as the tuplestores, are
4446  * allocated in the current (sub)transaction's CurTransactionContext, and
4447  * the tuplestores are managed by the (sub)transaction's resource owner.
4448  * This is sufficient lifespan because we do not allow triggers using
4449  * transition tables to be deferrable; they will be fired during
4450  * AfterTriggerEndQuery, after which it's okay to delete the data.
4451  */
4452  table = GetAfterTriggersTableData(relid, cmdType);
4453 
4454  /* Now create required tuplestore(s), if we don't have them already. */
4456  saveResourceOwner = CurrentResourceOwner;
4458 
4459  if (need_old && table->old_tuplestore == NULL)
4460  table->old_tuplestore = tuplestore_begin_heap(false, false, work_mem);
4461  if (need_new && table->new_tuplestore == NULL)
4462  table->new_tuplestore = tuplestore_begin_heap(false, false, work_mem);
4463 
4464  CurrentResourceOwner = saveResourceOwner;
4465  MemoryContextSwitchTo(oldcxt);
4466 
4467  /* Now build the TransitionCaptureState struct, in caller's context */
4469  state->tcs_delete_old_table = trigdesc->trig_delete_old_table;
4470  state->tcs_update_old_table = trigdesc->trig_update_old_table;
4471  state->tcs_update_new_table = trigdesc->trig_update_new_table;
4472  state->tcs_insert_new_table = trigdesc->trig_insert_new_table;
4473  state->tcs_private = table;
4474 
4475  return state;
4476 }
4477 
4478 
4479 /* ----------
4480  * AfterTriggerBeginXact()
4481  *
4482  * Called at transaction start (either BEGIN or implicit for single
4483  * statement outside of transaction block).
4484  * ----------
4485  */
4486 void
4488 {
4489  /*
4490  * Initialize after-trigger state structure to empty
4491  */
4492  afterTriggers.firing_counter = (CommandId) 1; /* mustn't be 0 */
4493  afterTriggers.query_depth = -1;
4494 
4495  /*
4496  * Verify that there is no leftover state remaining. If these assertions
4497  * trip, it means that AfterTriggerEndXact wasn't called or didn't clean
4498  * up properly.
4499  */
4500  Assert(afterTriggers.state == NULL);
4501  Assert(afterTriggers.query_stack == NULL);
4502  Assert(afterTriggers.maxquerydepth == 0);
4503  Assert(afterTriggers.event_cxt == NULL);
4504  Assert(afterTriggers.events.head == NULL);
4505  Assert(afterTriggers.trans_stack == NULL);
4506  Assert(afterTriggers.maxtransdepth == 0);
4507 }
4508 
4509 
4510 /* ----------
4511  * AfterTriggerBeginQuery()
4512  *
4513  * Called just before we start processing a single query within a
4514  * transaction (or subtransaction). Most of the real work gets deferred
4515  * until somebody actually tries to queue a trigger event.
4516  * ----------
4517  */
4518 void
4520 {
4521  /* Increase the query stack depth */
4522  afterTriggers.query_depth++;
4523 }
4524 
4525 
4526 /* ----------
4527  * AfterTriggerEndQuery()
4528  *
4529  * Called after one query has been completely processed. At this time
4530  * we invoke all AFTER IMMEDIATE trigger events queued by the query, and
4531  * transfer deferred trigger events to the global deferred-trigger list.
4532  *
4533  * Note that this must be called BEFORE closing down the executor
4534  * with ExecutorEnd, because we make use of the EState's info about
4535  * target relations. Normally it is called from ExecutorFinish.
4536  * ----------
4537  */
4538 void
4540 {
4542 
4543  /* Must be inside a query, too */
4544  Assert(afterTriggers.query_depth >= 0);
4545 
4546  /*
4547  * If we never even got as far as initializing the event stack, there
4548  * certainly won't be any events, so exit quickly.
4549  */
4550  if (afterTriggers.query_depth >= afterTriggers.maxquerydepth)
4551  {
4552  afterTriggers.query_depth--;
4553  return;
4554  }
4555 
4556  /*
4557  * Process all immediate-mode triggers queued by the query, and move the
4558  * deferred ones to the main list of deferred events.
4559  *
4560  * Notice that we decide which ones will be fired, and put the deferred
4561  * ones on the main list, before anything is actually fired. This ensures
4562  * reasonably sane behavior if a trigger function does SET CONSTRAINTS ...
4563  * IMMEDIATE: all events we have decided to defer will be available for it
4564  * to fire.
4565  *
4566  * We loop in case a trigger queues more events at the same query level.
4567  * Ordinary trigger functions, including all PL/pgSQL trigger functions,
4568  * will instead fire any triggers in a dedicated query level. Foreign key
4569  * enforcement triggers do add to the current query level, thanks to their
4570  * passing fire_triggers = false to SPI_execute_snapshot(). Other
4571  * C-language triggers might do likewise.
4572  *
4573  * If we find no firable events, we don't have to increment
4574  * firing_counter.
4575  */
4576  qs = &afterTriggers.query_stack[afterTriggers.query_depth];
4577 
4578  for (;;)
4579  {
4580  if (afterTriggerMarkEvents(&qs->events, &afterTriggers.events, true))
4581  {
4582  CommandId firing_id = afterTriggers.firing_counter++;
4583  AfterTriggerEventChunk *oldtail = qs->events.tail;
4584 
4585  if (afterTriggerInvokeEvents(&qs->events, firing_id, estate, false))
4586  break; /* all fired */
4587 
4588  /*
4589  * Firing a trigger could result in query_stack being repalloc'd,
4590  * so we must recalculate qs after each afterTriggerInvokeEvents
4591  * call. Furthermore, it's unsafe to pass delete_ok = true here,
4592  * because that could cause afterTriggerInvokeEvents to try to
4593  * access qs->events after the stack has been repalloc'd.
4594  */
4595  qs = &afterTriggers.query_stack[afterTriggers.query_depth];
4596 
4597  /*
4598  * We'll need to scan the events list again. To reduce the cost
4599  * of doing so, get rid of completely-fired chunks. We know that
4600  * all events were marked IN_PROGRESS or DONE at the conclusion of
4601  * afterTriggerMarkEvents, so any still-interesting events must
4602  * have been added after that, and so must be in the chunk that
4603  * was then the tail chunk, or in later chunks. So, zap all
4604  * chunks before oldtail. This is approximately the same set of
4605  * events we would have gotten rid of by passing delete_ok = true.
4606  */
4607  Assert(oldtail != NULL);
4608  while (qs->events.head != oldtail)
4610  }
4611  else
4612  break;
4613  }
4614 
4615  /* Release query-level-local storage, including tuplestores if any */
4616  AfterTriggerFreeQuery(&afterTriggers.query_stack[afterTriggers.query_depth]);
4617 
4618  afterTriggers.query_depth--;
4619 }
4620 
4621 
4622 /*
4623  * AfterTriggerFreeQuery
4624  * Release subsidiary storage for a trigger query level.
4625  * This includes closing down tuplestores.
4626  * Note: it's important for this to be safe if interrupted by an error
4627  * and then called again for the same query level.
4628  */
4629 static void
4631 {
4632  Tuplestorestate *ts;
4633  List *tables;
4634  ListCell *lc;
4635 
4636  /* Drop the trigger events */
4638 
4639  /* Drop FDW tuplestore if any */
4640  ts = qs->fdw_tuplestore;
4641  qs->fdw_tuplestore = NULL;
4642  if (ts)
4643  tuplestore_end(ts);
4644 
4645  /* Release per-table subsidiary storage */
4646  tables = qs->tables;
4647  foreach(lc, tables)
4648  {
4650 
4651  ts = table->old_tuplestore;
4652  table->old_tuplestore = NULL;
4653  if (ts)
4654  tuplestore_end(ts);
4655  ts = table->new_tuplestore;
4656  table->new_tuplestore = NULL;
4657  if (ts)
4658  tuplestore_end(ts);
4659  if (table->storeslot)
4661  }
4662 
4663  /*
4664  * Now free the AfterTriggersTableData structs and list cells. Reset list
4665  * pointer first; if list_free_deep somehow gets an error, better to leak
4666  * that storage than have an infinite loop.
4667  */
4668  qs->tables = NIL;
4669  list_free_deep(tables);
4670 }
4671 
4672 
4673 /* ----------
4674  * AfterTriggerFireDeferred()
4675  *
4676  * Called just before the current transaction is committed. At this
4677  * time we invoke all pending DEFERRED triggers.
4678  *
4679  * It is possible for other modules to queue additional deferred triggers
4680  * during pre-commit processing; therefore xact.c may have to call this
4681  * multiple times.
4682  * ----------
4683  */
4684 void
4686 {
4687  AfterTriggerEventList *events;
4688  bool snap_pushed = false;
4689 
4690  /* Must not be inside a query */
4691  Assert(afterTriggers.query_depth == -1);
4692 
4693  /*
4694  * If there are any triggers to fire, make sure we have set a snapshot for
4695  * them to use. (Since PortalRunUtility doesn't set a snap for COMMIT, we
4696  * can't assume ActiveSnapshot is valid on entry.)
4697  */
4698  events = &afterTriggers.events;
4699  if (events->head != NULL)
4700  {
4702  snap_pushed = true;
4703  }
4704 
4705  /*
4706  * Run all the remaining triggers. Loop until they are all gone, in case
4707  * some trigger queues more for us to do.
4708  */
4709  while (afterTriggerMarkEvents(events, NULL, false))
4710  {
4711  CommandId firing_id = afterTriggers.firing_counter++;
4712 
4713  if (afterTriggerInvokeEvents(events, firing_id, NULL, true))
4714  break; /* all fired */
4715  }
4716 
4717  /*
4718  * We don't bother freeing the event list, since it will go away anyway
4719  * (and more efficiently than via pfree) in AfterTriggerEndXact.
4720  */
4721 
4722  if (snap_pushed)
4724 }
4725 
4726 
4727 /* ----------
4728  * AfterTriggerEndXact()
4729  *
4730  * The current transaction is finishing.
4731  *
4732  * Any unfired triggers are canceled so we simply throw
4733  * away anything we know.
4734  *
4735  * Note: it is possible for this to be called repeatedly in case of
4736  * error during transaction abort; therefore, do not complain if
4737  * already closed down.
4738  * ----------
4739  */
4740 void
4741 AfterTriggerEndXact(bool isCommit)
4742 {
4743  /*
4744  * Forget the pending-events list.
4745  *
4746  * Since all the info is in TopTransactionContext or children thereof, we
4747  * don't really need to do anything to reclaim memory. However, the
4748  * pending-events list could be large, and so it's useful to discard it as
4749  * soon as possible --- especially if we are aborting because we ran out
4750  * of memory for the list!
4751  */
4752  if (afterTriggers.event_cxt)
4753  {
4754  MemoryContextDelete(afterTriggers.event_cxt);
4755  afterTriggers.event_cxt = NULL;
4756  afterTriggers.events.head = NULL;
4757  afterTriggers.events.tail = NULL;
4758  afterTriggers.events.tailfree = NULL;
4759  }
4760 
4761  /*
4762  * Forget any subtransaction state as well. Since this can't be very
4763  * large, we let the eventual reset of TopTransactionContext free the
4764  * memory instead of doing it here.
4765  */
4766  afterTriggers.trans_stack = NULL;
4767  afterTriggers.maxtransdepth = 0;
4768 
4769 
4770  /*
4771  * Forget the query stack and constraint-related state information. As
4772  * with the subtransaction state information, we don't bother freeing the
4773  * memory here.
4774  */
4775  afterTriggers.query_stack = NULL;
4776  afterTriggers.maxquerydepth = 0;
4777  afterTriggers.state = NULL;
4778 
4779  /* No more afterTriggers manipulation until next transaction starts. */
4780  afterTriggers.query_depth = -1;
4781 }
4782 
4783 /*
4784  * AfterTriggerBeginSubXact()
4785  *
4786  * Start a subtransaction.
4787  */
4788 void
4790 {
4791  int my_level = GetCurrentTransactionNestLevel();
4792 
4793  /*
4794  * Allocate more space in the trans_stack if needed. (Note: because the
4795  * minimum nest level of a subtransaction is 2, we waste the first couple
4796  * entries of the array; not worth the notational effort to avoid it.)
4797  */
4798  while (my_level >= afterTriggers.maxtransdepth)
4799  {
4800  if (afterTriggers.maxtransdepth == 0)
4801  {
4802  /* Arbitrarily initialize for max of 8 subtransaction levels */
4803  afterTriggers.trans_stack = (AfterTriggersTransData *)
4805  8 * sizeof(AfterTriggersTransData));
4806  afterTriggers.maxtransdepth = 8;
4807  }
4808  else
4809  {
4810  /* repalloc will keep the stack in the same context */
4811  int new_alloc = afterTriggers.maxtransdepth * 2;
4812 
4813  afterTriggers.trans_stack = (AfterTriggersTransData *)
4814  repalloc(afterTriggers.trans_stack,
4815  new_alloc * sizeof(AfterTriggersTransData));
4816  afterTriggers.maxtransdepth = new_alloc;
4817  }
4818  }
4819 
4820  /*
4821  * Push the current information into the stack. The SET CONSTRAINTS state
4822  * is not saved until/unless changed. Likewise, we don't make a
4823  * per-subtransaction event context until needed.
4824  */
4825  afterTriggers.trans_stack[my_level].state = NULL;
4826  afterTriggers.trans_stack[my_level].events = afterTriggers.events;
4827  afterTriggers.trans_stack[my_level].query_depth = afterTriggers.query_depth;
4828  afterTriggers.trans_stack[my_level].firing_counter = afterTriggers.firing_counter;
4829 }
4830 
4831 /*
4832  * AfterTriggerEndSubXact()
4833  *
4834  * The current subtransaction is ending.
4835  */
4836 void
4838 {
4839  int my_level = GetCurrentTransactionNestLevel();
4841  AfterTriggerEvent event;
4842  AfterTriggerEventChunk *chunk;
4843  CommandId subxact_firing_id;
4844 
4845  /*
4846  * Pop the prior state if needed.
4847  */
4848  if (isCommit)
4849  {
4850  Assert(my_level < afterTriggers.maxtransdepth);
4851  /* If we saved a prior state, we don't need it anymore */
4852  state = afterTriggers.trans_stack[my_level].state;
4853  if (state != NULL)
4854  pfree(state);
4855  /* this avoids double pfree if error later: */
4856  afterTriggers.trans_stack[my_level].state = NULL;
4857  Assert(afterTriggers.query_depth ==
4858  afterTriggers.trans_stack[my_level].query_depth);
4859  }
4860  else
4861  {
4862  /*
4863  * Aborting. It is possible subxact start failed before calling
4864  * AfterTriggerBeginSubXact, in which case we mustn't risk touching
4865  * trans_stack levels that aren't there.
4866  */
4867  if (my_level >= afterTriggers.maxtransdepth)
4868  return;
4869 
4870  /*
4871  * Release query-level storage for queries being aborted, and restore
4872  * query_depth to its pre-subxact value. This assumes that a
4873  * subtransaction will not add events to query levels started in a
4874  * earlier transaction state.
4875  */
4876  while (afterTriggers.query_depth > afterTriggers.trans_stack[my_level].query_depth)
4877  {
4878  if (afterTriggers.query_depth < afterTriggers.maxquerydepth)
4879  AfterTriggerFreeQuery(&afterTriggers.query_stack[afterTriggers.query_depth]);
4880  afterTriggers.query_depth--;
4881  }
4882  Assert(afterTriggers.query_depth ==
4883  afterTriggers.trans_stack[my_level].query_depth);
4884 
4885  /*
4886  * Restore the global deferred-event list to its former length,
4887  * discarding any events queued by the subxact.
4888  */
4889  afterTriggerRestoreEventList(&afterTriggers.events,
4890  &afterTriggers.trans_stack[my_level].events);
4891 
4892  /*
4893  * Restore the trigger state. If the saved state is NULL, then this
4894  * subxact didn't save it, so it doesn't need restoring.
4895  */
4896  state = afterTriggers.trans_stack[my_level].state;
4897  if (state != NULL)
4898  {
4899  pfree(afterTriggers.state);
4900  afterTriggers.state = state;
4901  }
4902  /* this avoids double pfree if error later: */
4903  afterTriggers.trans_stack[my_level].state = NULL;
4904 
4905  /*
4906  * Scan for any remaining deferred events that were marked DONE or IN
4907  * PROGRESS by this subxact or a child, and un-mark them. We can
4908  * recognize such events because they have a firing ID greater than or
4909  * equal to the firing_counter value we saved at subtransaction start.
4910  * (This essentially assumes that the current subxact includes all
4911  * subxacts started after it.)
4912  */
4913  subxact_firing_id = afterTriggers.trans_stack[my_level].firing_counter;
4914  for_each_event_chunk(event, chunk, afterTriggers.events)
4915  {
4916  AfterTriggerShared evtshared = GetTriggerSharedData(event);
4917 
4918  if (event->ate_flags &
4920  {
4921  if (evtshared->ats_firing_id >= subxact_firing_id)
4922  event->ate_flags &=
4924  }
4925  }
4926  }
4927 }
4928 
4929 /* ----------
4930  * AfterTriggerEnlargeQueryState()
4931  *
4932  * Prepare the necessary state so that we can record AFTER trigger events
4933  * queued by a query. It is allowed to have nested queries within a
4934  * (sub)transaction, so we need to have separate state for each query
4935  * nesting level.
4936  * ----------
4937  */
4938 static void
4940 {
4941  int init_depth = afterTriggers.maxquerydepth;
4942 
4943  Assert(afterTriggers.query_depth >= afterTriggers.maxquerydepth);
4944 
4945  if (afterTriggers.maxquerydepth == 0)
4946  {
4947  int new_alloc = Max(afterTriggers.query_depth + 1, 8);
4948 
4949  afterTriggers.query_stack = (AfterTriggersQueryData *)
4951  new_alloc * sizeof(AfterTriggersQueryData));
4952  afterTriggers.maxquerydepth = new_alloc;
4953  }
4954  else
4955  {
4956  /* repalloc will keep the stack in the same context */
4957  int old_alloc = afterTriggers.maxquerydepth;
4958  int new_alloc = Max(afterTriggers.query_depth + 1,
4959  old_alloc * 2);
4960 
4961  afterTriggers.query_stack = (AfterTriggersQueryData *)
4962  repalloc(afterTriggers.query_stack,
4963  new_alloc * sizeof(AfterTriggersQueryData));
4964  afterTriggers.maxquerydepth = new_alloc;
4965  }
4966 
4967  /* Initialize new array entries to empty */
4968  while (init_depth < afterTriggers.maxquerydepth)
4969  {
4970  AfterTriggersQueryData *qs = &afterTriggers.query_stack[init_depth];
4971 
4972  qs->events.head = NULL;
4973  qs->events.tail = NULL;
4974  qs->events.tailfree = NULL;
4975  qs->fdw_tuplestore = NULL;
4976  qs->tables = NIL;
4977 
4978  ++init_depth;
4979  }
4980 }
4981 
4982 /*
4983  * Create an empty SetConstraintState with room for numalloc trigstates
4984  */
4985 static SetConstraintState
4987 {
4989 
4990  /* Behave sanely with numalloc == 0 */
4991  if (numalloc <= 0)
4992  numalloc = 1;
4993 
4994  /*
4995  * We assume that zeroing will correctly initialize the state values.
4996  */
4997  state = (SetConstraintState)
4999  offsetof(SetConstraintStateData, trigstates) +
5000  numalloc * sizeof(SetConstraintTriggerData));
5001 
5002  state->numalloc = numalloc;
5003 
5004  return state;
5005 }
5006 
5007 /*
5008  * Copy a SetConstraintState
5009  */
5010 static SetConstraintState
5012 {
5014 
5015  state = SetConstraintStateCreate(origstate->numstates);
5016 
5017  state->all_isset = origstate->all_isset;
5018  state->all_isdeferred = origstate->all_isdeferred;
5019  state->numstates = origstate->numstates;
5020  memcpy(state->trigstates, origstate->trigstates,
5021  origstate->numstates * sizeof(SetConstraintTriggerData));
5022 
5023  return state;
5024 }
5025 
5026 /*
5027  * Add a per-trigger item to a SetConstraintState. Returns possibly-changed
5028  * pointer to the state object (it will change if we have to repalloc).
5029  */
5030 static SetConstraintState
5032  Oid tgoid, bool tgisdeferred)
5033 {
5034  if (state->numstates >= state->numalloc)
5035  {
5036  int newalloc = state->numalloc * 2;
5037 
5038  newalloc = Max(newalloc, 8); /* in case original has size 0 */
5039  state = (SetConstraintState)
5040  repalloc(state,
5041  offsetof(SetConstraintStateData, trigstates) +
5042  newalloc * sizeof(SetConstraintTriggerData));
5043  state->numalloc = newalloc;
5044  Assert(state->numstates < state->numalloc);
5045  }
5046 
5047  state->trigstates[state->numstates].sct_tgoid = tgoid;
5048  state->trigstates[state->numstates].sct_tgisdeferred = tgisdeferred;
5049  state->numstates++;
5050 
5051  return state;
5052 }
5053 
5054 /* ----------
5055  * AfterTriggerSetState()
5056  *
5057  * Execute the SET CONSTRAINTS ... utility command.
5058  * ----------
5059  */
5060 void
5062 {
5063  int my_level = GetCurrentTransactionNestLevel();
5064 
5065  /* If we haven't already done so, initialize our state. */
5066  if (afterTriggers.state == NULL)
5067  afterTriggers.state = SetConstraintStateCreate(8);
5068 
5069  /*
5070  * If in a subtransaction, and we didn't save the current state already,
5071  * save it so it can be restored if the subtransaction aborts.
5072  */
5073  if (my_level > 1 &&
5074  afterTriggers.trans_stack[my_level].state == NULL)
5075  {
5076  afterTriggers.trans_stack[my_level].state =
5077  SetConstraintStateCopy(afterTriggers.state);
5078  }
5079 
5080  /*
5081  * Handle SET CONSTRAINTS ALL ...
5082  */
5083  if (stmt->constraints == NIL)
5084  {
5085  /*
5086  * Forget any previous SET CONSTRAINTS commands in this transaction.
5087  */
5088  afterTriggers.state->numstates = 0;
5089 
5090  /*
5091  * Set the per-transaction ALL state to known.
5092  */
5093  afterTriggers.state->all_isset = true;
5094  afterTriggers.state->all_isdeferred = stmt->deferred;
5095  }
5096  else
5097  {
5098  Relation conrel;
5099  Relation tgrel;
5100  List *conoidlist = NIL;
5101  List *tgoidlist = NIL;
5102  ListCell *lc;
5103 
5104  /*
5105  * Handle SET CONSTRAINTS constraint-name [, ...]
5106  *
5107  * First, identify all the named constraints and make a list of their
5108  * OIDs. Since, unlike the SQL spec, we allow multiple constraints of
5109  * the same name within a schema, the specifications are not
5110  * necessarily unique. Our strategy is to target all matching
5111  * constraints within the first search-path schema that has any
5112  * matches, but disregard matches in schemas beyond the first match.
5113  * (This is a bit odd but it's the historical behavior.)
5114  *
5115  * A constraint in a partitioned table may have corresponding
5116  * constraints in the partitions. Grab those too.
5117  */
5118  conrel = table_open(ConstraintRelationId, AccessShareLock);
5119 
5120  foreach(lc, stmt->constraints)
5121  {
5122  RangeVar *constraint = lfirst(lc);
5123  bool found;
5124  List *namespacelist;
5125  ListCell *nslc;
5126 
5127  if (constraint->catalogname)
5128  {
5129  if (strcmp(constraint->catalogname, get_database_name(MyDatabaseId)) != 0)
5130  ereport(ERROR,
5131  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
5132  errmsg("cross-database references are not implemented: \"%s.%s.%s\"",
5133  constraint->catalogname, constraint->schemaname,
5134  constraint->relname)));
5135  }
5136 
5137  /*
5138  * If we're given the schema name with the constraint, look only
5139  * in that schema. If given a bare constraint name, use the
5140  * search path to find the first matching constraint.
5141  */
5142  if (constraint->schemaname)
5143  {
5144  Oid namespaceId = LookupExplicitNamespace(constraint->schemaname,
5145  false);
5146 
5147  namespacelist = list_make1_oid(namespaceId);
5148  }
5149  else
5150  {
5151  namespacelist = fetch_search_path(true);
5152  }
5153 
5154  found = false;
5155  foreach(nslc, namespacelist)
5156  {
5157  Oid namespaceId = lfirst_oid(nslc);
5158  SysScanDesc conscan;
5159  ScanKeyData skey[2];
5160  HeapTuple tup;
5161 
5162  ScanKeyInit(&skey[0],
5163  Anum_pg_constraint_conname,
5164  BTEqualStrategyNumber, F_NAMEEQ,
5165  CStringGetDatum(constraint->relname));
5166  ScanKeyInit(&skey[1],
5167  Anum_pg_constraint_connamespace,
5168  BTEqualStrategyNumber, F_OIDEQ,
5169  ObjectIdGetDatum(namespaceId));
5170 
5171  conscan = systable_beginscan(conrel, ConstraintNameNspIndexId,
5172  true, NULL, 2, skey);
5173 
5174  while (HeapTupleIsValid(tup = systable_getnext(conscan)))
5175  {
5177 
5178  if (con->condeferrable)
5179  conoidlist = lappend_oid(conoidlist, con->oid);
5180  else if (stmt->deferred)
5181  ereport(ERROR,
5182  (errcode(ERRCODE_WRONG_OBJECT_TYPE),
5183  errmsg("constraint \"%s\" is not deferrable",
5184  constraint->relname)));
5185  found = true;
5186  }
5187 
5188  systable_endscan(conscan);
5189 
5190  /*
5191  * Once we've found a matching constraint we do not search
5192  * later parts of the search path.
5193  */
5194  if (found)
5195  break;
5196  }
5197 
5198  list_free(namespacelist);
5199 
5200  /*
5201  * Not found ?
5202  */
5203  if (!found)
5204  ereport(ERROR,
5205  (errcode(ERRCODE_UNDEFINED_OBJECT),
5206  errmsg("constraint \"%s\" does not exist",
5207  constraint->relname)));
5208  }
5209 
5210  /*
5211  * Scan for any possible descendants of the constraints. We append
5212  * whatever we find to the same list that we're scanning; this has the
5213  * effect that we create new scans for those, too, so if there are
5214  * further descendents, we'll also catch them.
5215  */
5216  foreach(lc, conoidlist)
5217  {
5218  Oid parent = lfirst_oid(lc);
5219  ScanKeyData key;
5220  SysScanDesc scan;
5221  HeapTuple tuple;
5222 
5223  ScanKeyInit(&key,
5224  Anum_pg_constraint_conparentid,
5225  BTEqualStrategyNumber, F_OIDEQ,
5226  ObjectIdGetDatum(parent));
5227 
5228  scan = systable_beginscan(conrel, ConstraintParentIndexId, true, NULL, 1, &key);
5229 
5230  while (HeapTupleIsValid(tuple = systable_getnext(scan)))
5231  {
5233 
5234  conoidlist = lappend_oid(conoidlist, con->oid);
5235  }
5236 
5237  systable_endscan(scan);
5238  }
5239 
5240  table_close(conrel, AccessShareLock);
5241 
5242  /*
5243  * Now, locate the trigger(s) implementing each of these constraints,
5244  * and make a list of their OIDs.
5245  */
5246  tgrel = table_open(TriggerRelationId, AccessShareLock);
5247 
5248  foreach(lc, conoidlist)
5249  {
5250  Oid conoid = lfirst_oid(lc);
5251  ScanKeyData skey;
5252  SysScanDesc tgscan;
5253  HeapTuple htup;
5254 
5255  ScanKeyInit(&skey,
5256  Anum_pg_trigger_tgconstraint,
5257  BTEqualStrategyNumber, F_OIDEQ,
5258  ObjectIdGetDatum(conoid));
5259 
5260  tgscan = systable_beginscan(tgrel, TriggerConstraintIndexId, true,
5261  NULL, 1, &skey);
5262 
5263  while (HeapTupleIsValid(htup = systable_getnext(tgscan)))
5264  {
5265  Form_pg_trigger pg_trigger = (Form_pg_trigger) GETSTRUCT(htup);
5266 
5267  /*
5268  * Silently skip triggers that are marked as non-deferrable in
5269  * pg_trigger. This is not an error condition, since a
5270  * deferrable RI constraint may have some non-deferrable
5271  * actions.
5272  */
5273  if (pg_trigger->tgdeferrable)
5274  tgoidlist = lappend_oid(tgoidlist, pg_trigger->oid);
5275  }
5276 
5277  systable_endscan(tgscan);
5278  }
5279 
5280  table_close(tgrel, AccessShareLock);
5281 
5282  /*
5283  * Now we can set the trigger states of individual triggers for this
5284  * xact.
5285  */
5286  foreach(lc, tgoidlist)
5287  {
5288  Oid tgoid = lfirst_oid(lc);
5289  SetConstraintState state = afterTriggers.state;
5290  bool found = false;
5291  int i;
5292 
5293  for (i = 0; i < state->numstates; i++)
5294  {
5295  if (state->trigstates[i].sct_tgoid == tgoid)
5296  {
5297  state->trigstates[i].sct_tgisdeferred = stmt->deferred;
5298  found = true;
5299  break;
5300  }
5301  }
5302  if (!found)
5303  {
5304  afterTriggers.state =
5305  SetConstraintStateAddItem(state, tgoid, stmt->deferred);
5306  }
5307  }
5308  }
5309 
5310  /*
5311  * SQL99 requires that when a constraint is set to IMMEDIATE, any deferred
5312  * checks against that constraint must be made when the SET CONSTRAINTS
5313  * command is executed -- i.e. the effects of the SET CONSTRAINTS command
5314  * apply retroactively. We've updated the constraints state, so scan the
5315  * list of previously deferred events to fire any that have now become
5316  * immediate.
5317  *
5318  * Obviously, if this was SET ... DEFERRED then it can't have converted
5319  * any unfired events to immediate, so we need do nothing in that case.
5320  */
5321  if (!stmt->deferred)
5322  {
5323  AfterTriggerEventList *events = &afterTriggers.events;
5324  bool snapshot_set = false;
5325 
5326  while (afterTriggerMarkEvents(events, NULL, true))
5327  {
5328  CommandId firing_id = afterTriggers.firing_counter++;
5329 
5330  /*
5331  * Make sure a snapshot has been established in case trigger
5332  * functions need one. Note that we avoid setting a snapshot if
5333  * we don't find at least one trigger that has to be fired now.
5334  * This is so that BEGIN; SET CONSTRAINTS ...; SET TRANSACTION
5335  * ISOLATION LEVEL SERIALIZABLE; ... works properly. (If we are
5336  * at the start of a transaction it's not possible for any trigger
5337  * events to be queued yet.)
5338  */
5339  if (!snapshot_set)
5340  {
5342  snapshot_set = true;
5343  }
5344 
5345  /*
5346  * We can delete fired events if we are at top transaction level,
5347  * but we'd better not if inside a subtransaction, since the
5348  * subtransaction could later get rolled back.
5349  */
5350  if (afterTriggerInvokeEvents(events, firing_id, NULL,
5351  !IsSubTransaction()))
5352  break; /* all fired */
5353  }
5354 
5355  if (snapshot_set)
5357  }
5358 }
5359 
5360 /* ----------
5361  * AfterTriggerPendingOnRel()
5362  * Test to see if there are any pending after-trigger events for rel.
5363  *
5364  * This is used by TRUNCATE, CLUSTER, ALTER TABLE, etc to detect whether
5365  * it is unsafe to perform major surgery on a relation. Note that only
5366  * local pending events are examined. We assume that having exclusive lock
5367  * on a rel guarantees there are no unserviced events in other backends ---
5368  * but having a lock does not prevent there being such events in our own.
5369  *
5370  * In some scenarios it'd be reasonable to remove pending events (more
5371  * specifically, mark them DONE by the current subxact) but without a lot
5372  * of knowledge of the trigger semantics we can't do this in general.
5373  * ----------
5374  */
5375 bool
5377 {
5378  AfterTriggerEvent event;
5379  AfterTriggerEventChunk *chunk;
5380  int depth;
5381 
5382  /* Scan queued events */
5383  for_each_event_chunk(event, chunk, afterTriggers.events)
5384  {
5385  AfterTriggerShared evtshared = GetTriggerSharedData(event);
5386 
5387  /*
5388  * We can ignore completed events. (Even if a DONE flag is rolled
5389  * back by subxact abort, it's OK because the effects of the TRUNCATE
5390  * or whatever must get rolled back too.)
5391  */
5392  if (event->ate_flags & AFTER_TRIGGER_DONE)
5393  continue;
5394 
5395  if (evtshared->ats_relid == relid)
5396  return true;
5397  }
5398 
5399  /*
5400  * Also scan events queued by incomplete queries. This could only matter
5401  * if TRUNCATE/etc is executed by a function or trigger within an updating
5402  * query on the same relation, which is pretty perverse, but let's check.
5403  */
5404  for (depth = 0; depth <= afterTriggers.query_depth && depth < afterTriggers.maxquerydepth; depth++)
5405  {
5406  for_each_event_chunk(event, chunk, afterTriggers.query_stack[depth].events)
5407  {
5408  AfterTriggerShared evtshared = GetTriggerSharedData(event);
5409 
5410  if (event->ate_flags & AFTER_TRIGGER_DONE)
5411  continue;
5412 
5413  if (evtshared->ats_relid == relid)
5414  return true;
5415  }
5416  }
5417 
5418  return false;
5419 }
5420 
5421 
5422 /* ----------
5423  * AfterTriggerSaveEvent()
5424  *
5425  * Called by ExecA[RS]...Triggers() to queue up the triggers that should
5426  * be fired for an event.
5427  *
5428  * NOTE: this is called whenever there are any triggers associated with
5429  * the event (even if they are disabled). This function decides which
5430  * triggers actually need to be queued. It is also called after each row,
5431  * even if there are no triggers for that event, if there are any AFTER
5432  * STATEMENT triggers for the statement which use transition tables, so that
5433  * the transition tuplestores can be built. Furthermore, if the transition
5434  * capture is happening for UPDATEd rows being moved to another partition due
5435  * to the partition-key being changed, then this function is called once when
5436  * the row is deleted (to capture OLD row), and once when the row is inserted
5437  * into another partition (to capture NEW row). This is done separately because
5438  * DELETE and INSERT happen on different tables.
5439  *
5440  * Transition tuplestores are built now, rather than when events are pulled
5441  * off of the queue because AFTER ROW triggers are allowed to select from the
5442  * transition tables for the statement.
5443  * ----------
5444  */
5445 static void
5447  int event, bool row_trigger,
5448  TupleTableSlot *oldslot, TupleTableSlot *newslot,
5449  List *recheckIndexes, Bitmapset *modifiedCols,
5450  TransitionCaptureState *transition_capture)
5451 {
5452  Relation rel = relinfo->ri_RelationDesc;
5453  TriggerDesc *trigdesc = relinfo->ri_TrigDesc;
5454  AfterTriggerEventData new_event;
5455  AfterTriggerSharedData new_shared;
5456  char relkind = rel->rd_rel->relkind;
5457  int tgtype_event;
5458  int tgtype_level;
5459  int i;
5460  Tuplestorestate *fdw_tuplestore = NULL;
5461 
5462  /*
5463  * Check state. We use a normal test not Assert because it is possible to
5464  * reach here in the wrong state given misconfigured RI triggers, in
5465  * particular deferring a cascade action trigger.
5466  */
5467  if (afterTriggers.query_depth < 0)
5468  elog(ERROR, "AfterTriggerSaveEvent() called outside of query");
5469 
5470  /* Be sure we have enough space to record events at this query depth. */
5471  if (afterTriggers.query_depth >= afterTriggers.maxquerydepth)
5473 
5474  /*
5475  * If the directly named relation has any triggers with transition tables,
5476  * then we need to capture transition tuples.
5477  */
5478  if (row_trigger && transition_capture != NULL)
5479  {
5480  TupleTableSlot *original_insert_tuple = transition_capture->tcs_original_insert_tuple;
5481  TupleConversionMap *map = ExecGetChildToRootMap(relinfo);
5482  bool delete_old_table = transition_capture->tcs_delete_old_table;
5483  bool update_old_table = transition_capture->tcs_update_old_table;
5484  bool update_new_table = transition_capture->tcs_update_new_table;
5485  bool insert_new_table = transition_capture->tcs_insert_new_table;
5486 
5487  /*
5488  * For INSERT events NEW should be non-NULL, for DELETE events OLD
5489  * should be non-NULL, whereas for UPDATE events normally both OLD and
5490  * NEW are non-NULL. But for UPDATE events fired for capturing
5491  * transition tuples during UPDATE partition-key row movement, OLD is
5492  * NULL when the event is for a row being inserted, whereas NEW is
5493  * NULL when the event is for a row being deleted.
5494  */
5495  Assert(!(event == TRIGGER_EVENT_DELETE && delete_old_table &&
5496  TupIsNull(oldslot)));
5497  Assert(!(event == TRIGGER_EVENT_INSERT && insert_new_table &&
5498  TupIsNull(newslot)));
5499 
5500  if (!TupIsNull(oldslot) &&
5501  ((event == TRIGGER_EVENT_DELETE && delete_old_table) ||
5502  (event == TRIGGER_EVENT_UPDATE && update_old_table)))
5503  {
5504  Tuplestorestate *old_tuplestore;
5505 
5506  old_tuplestore = transition_capture->tcs_private->old_tuplestore;
5507 
5508  if (map != NULL)
5509  {
5510  AfterTriggersTableData *table = transition_capture->tcs_private;
5511  TupleTableSlot *storeslot;
5512 
5513  storeslot = GetAfterTriggersStoreSlot(table, map->outdesc);
5514  execute_attr_map_slot(map->attrMap, oldslot, storeslot);
5515  tuplestore_puttupleslot(old_tuplestore, storeslot);
5516  }
5517  else
5518  tuplestore_puttupleslot(old_tuplestore, oldslot);
5519  }
5520  if (!TupIsNull(newslot) &&
5521  ((event == TRIGGER_EVENT_INSERT && insert_new_table) ||
5522  (event == TRIGGER_EVENT_UPDATE && update_new_table)))
5523  {
5524  Tuplestorestate *new_tuplestore;
5525 
5526  new_tuplestore = transition_capture->tcs_private->new_tuplestore;
5527 
5528  if (original_insert_tuple != NULL)
5529  tuplestore_puttupleslot(new_tuplestore,
5530  original_insert_tuple);
5531  else if (map != NULL)
5532  {
5533  AfterTriggersTableData *table = transition_capture->tcs_private;
5534  TupleTableSlot *storeslot;
5535 
5536  storeslot = GetAfterTriggersStoreSlot(table, map->outdesc);
5537  execute_attr_map_slot(map->attrMap, newslot, storeslot);
5538  tuplestore_puttupleslot(new_tuplestore, storeslot);
5539  }
5540  else
5541  tuplestore_puttupleslot(new_tuplestore, newslot);
5542  }
5543 
5544  /*
5545  * If transition tables are the only reason we're here, return. As
5546  * mentioned above, we can also be here during update tuple routing in
5547  * presence of transition tables, in which case this function is
5548  * called separately for oldtup and newtup, so we expect exactly one
5549  * of them to be NULL.
5550  */
5551  if (trigdesc == NULL ||
5552  (event == TRIGGER_EVENT_DELETE && !trigdesc->trig_delete_after_row) ||
5553  (event == TRIGGER_EVENT_INSERT && !trigdesc->trig_insert_after_row) ||
5554  (event == TRIGGER_EVENT_UPDATE && !trigdesc->trig_update_after_row) ||
5555  (event == TRIGGER_EVENT_UPDATE && (TupIsNull(oldslot) ^ TupIsNull(newslot))))
5556  return;
5557  }
5558 
5559  /*
5560  * Validate the event code and collect the associated tuple CTIDs.
5561  *
5562  * The event code will be used both as a bitmask and an array offset, so
5563  * validation is important to make sure we don't walk off the edge of our
5564  * arrays.
5565  *
5566  * Also, if we're considering statement-level triggers, check whether we
5567  * already queued a set of them for this event, and cancel the prior set
5568  * if so. This preserves the behavior that statement-level triggers fire
5569  * just once per statement and fire after row-level triggers.
5570  */
5571  switch (event)
5572  {
5573  case TRIGGER_EVENT_INSERT:
5574  tgtype_event = TRIGGER_TYPE_INSERT;
5575  if (row_trigger)
5576  {
5577  Assert(oldslot == NULL);
5578  Assert(newslot != NULL);
5579  ItemPointerCopy(&(newslot->tts_tid), &(new_event.ate_ctid1));
5580  ItemPointerSetInvalid(&(new_event.ate_ctid2));
5581  }
5582  else
5583  {
5584  Assert(oldslot == NULL);
5585  Assert(newslot == NULL);
5586  ItemPointerSetInvalid(&(new_event.ate_ctid1));
5587  ItemPointerSetInvalid(&(new_event.ate_ctid2));
5589  CMD_INSERT, event);
5590  }
5591  break;
5592  case TRIGGER_EVENT_DELETE:
5593  tgtype_event = TRIGGER_TYPE_DELETE;
5594  if (row_trigger)
5595  {
5596  Assert(oldslot != NULL);
5597  Assert(newslot == NULL);
5598  ItemPointerCopy(&(oldslot->tts_tid), &(new_event.ate_ctid1));
5599  ItemPointerSetInvalid(&(new_event.ate_ctid2));
5600  }
5601  else
5602  {
5603  Assert(oldslot == NULL);
5604  Assert(newslot == NULL);
5605  ItemPointerSetInvalid(&(new_event.ate_ctid1));
5606  ItemPointerSetInvalid(&(new_event.ate_ctid2));
5608  CMD_DELETE, event);
5609  }
5610  break;
5611  case TRIGGER_EVENT_UPDATE:
5612  tgtype_event = TRIGGER_TYPE_UPDATE;
5613  if (row_trigger)
5614  {
5615  Assert(oldslot != NULL);
5616  Assert(newslot != NULL);
5617  ItemPointerCopy(&(oldslot->tts_tid), &(new_event.ate_ctid1));
5618  ItemPointerCopy(&(newslot->tts_tid), &(new_event.ate_ctid2));
5619  }
5620  else
5621  {
5622  Assert(oldslot == NULL);
5623  Assert(newslot == NULL);
5624  ItemPointerSetInvalid(&(new_event.ate_ctid1));
5625  ItemPointerSetInvalid(&(new_event.ate_ctid2));
5627  CMD_UPDATE, event);
5628  }
5629  break;
5631  tgtype_event = TRIGGER_TYPE_TRUNCATE;
5632  Assert(oldslot == NULL);
5633  Assert(newslot == NULL);
5634  ItemPointerSetInvalid(&(new_event.ate_ctid1));
5635  ItemPointerSetInvalid(&(new_event.ate_ctid2));
5636  break;
5637  default:
5638  elog(ERROR, "invalid after-trigger event code: %d", event);
5639  tgtype_event = 0; /* keep compiler quiet */
5640  break;
5641  }
5642 
5643  if (!(relkind == RELKIND_FOREIGN_TABLE && row_trigger))
5644  new_event.ate_flags = (row_trigger && event == TRIGGER_EVENT_UPDATE) ?
5646  /* else, we'll initialize ate_flags for each trigger */
5647 
5648  tgtype_level = (row_trigger ? TRIGGER_TYPE_ROW : TRIGGER_TYPE_STATEMENT);
5649 
5650  for (i = 0; i < trigdesc->numtriggers; i++)
5651  {
5652  Trigger *trigger = &trigdesc->triggers[i];
5653 
5654  if (!TRIGGER_TYPE_MATCHES(trigger->tgtype,
5655  tgtype_level,
5656  TRIGGER_TYPE_AFTER,
5657  tgtype_event))
5658  continue;
5659  if (!TriggerEnabled(estate, relinfo, trigger, event,
5660  modifiedCols, oldslot, newslot))
5661  continue;
5662 
5663  if (relkind == RELKIND_FOREIGN_TABLE && row_trigger)
5664  {
5665  if (fdw_tuplestore == NULL)
5666  {
5667  fdw_tuplestore = GetCurrentFDWTuplestore();
5668  new_event.ate_flags = AFTER_TRIGGER_FDW_FETCH;
5669  }
5670  else
5671  /* subsequent event for the same tuple */
5672  new_event.ate_flags = AFTER_TRIGGER_FDW_REUSE;
5673  }
5674 
5675  /*
5676  * If the trigger is a foreign key enforcement trigger, there are
5677  * certain cases where we can skip queueing the event because we can
5678  * tell by inspection that the FK constraint will still pass.
5679  */
5680  if (TRIGGER_FIRED_BY_UPDATE(event) || TRIGGER_FIRED_BY_DELETE(event))
5681  {
5682  switch (RI_FKey_trigger_type(trigger->tgfoid))
5683  {
5684  case RI_TRIGGER_PK:
5685  /* Update or delete on trigger's PK table */
5686  if (!RI_FKey_pk_upd_check_required(trigger, rel,
5687  oldslot, newslot))
5688  {
5689  /* skip queuing this event */
5690  continue;
5691  }
5692  break;
5693 
5694  case RI_TRIGGER_FK:
5695  /* Update on trigger's FK table */
5696  if (!RI_FKey_fk_upd_check_required(trigger, rel,
5697  oldslot, newslot))
5698  {
5699  /* skip queuing this event */
5700  continue;
5701  }
5702  break;
5703 
5704  case RI_TRIGGER_NONE:
5705  /* Not an FK trigger */
5706  break;
5707  }
5708  }
5709 
5710  /*
5711  * If the trigger is a deferred unique constraint check trigger, only
5712  * queue it if the unique constraint was potentially violated, which
5713  * we know from index insertion time.
5714  */
5715  if (trigger->tgfoid == F_UNIQUE_KEY_RECHECK)
5716  {
5717  if (!list_member_oid(recheckIndexes, trigger->tgconstrindid))
5718  continue; /* Uniqueness definitely not violated */
5719  }
5720 
5721  /*
5722  * Fill in event structure and add it to the current query's queue.
5723  * Note we set ats_table to NULL whenever this trigger doesn't use
5724  * transition tables, to improve sharability of the shared event data.
5725  */
5726  new_shared.ats_event =
5727  (event & TRIGGER_EVENT_OPMASK) |
5728  (row_trigger ? TRIGGER_EVENT_ROW : 0) |
5729  (trigger->tgdeferrable ? AFTER_TRIGGER_DEFERRABLE : 0) |
5730  (trigger->tginitdeferred ? AFTER_TRIGGER_INITDEFERRED : 0);
5731  new_shared.ats_tgoid = trigger->tgoid;
5732  new_shared.ats_relid = RelationGetRelid(rel);
5733  new_shared.ats_firing_id = 0;
5734  if ((trigger->tgoldtable || trigger->tgnewtable) &&
5735  transition_capture != NULL)
5736  new_shared.ats_table = transition_capture->tcs_private;
5737  else
5738  new_shared.ats_table = NULL;
5739  new_shared.ats_modifiedcols = modifiedCols;
5740 
5741  afterTriggerAddEvent(&afterTriggers.