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