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-2020, 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  ParseNamespaceItem *nsitem;
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 nsitems for OLD and NEW references.
578  *
579  * 'OLD' must always have varno equal to 1 and 'NEW' equal to 2.
580  */
581  nsitem = addRangeTableEntryForRelation(pstate, rel,
583  makeAlias("old", NIL),
584  false, false);
585  addNSItemToQuery(pstate, nsitem, false, true, true);
586  nsitem = addRangeTableEntryForRelation(pstate, rel,
588  makeAlias("new", NIL),
589  false, false);
590  addNSItemToQuery(pstate, nsitem, 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 
1148  childTbl = table_open(partdesc->oids[i], ShareRowExclusiveLock);
1149 
1150  /* Find which of the child indexes is the one on this partition */
1151  if (OidIsValid(indexOid))
1152  {
1153  forboth(l, idxs, l2, childTbls)
1154  {
1155  if (lfirst_oid(l2) == partdesc->oids[i])
1156  {
1157  indexOnChild = lfirst_oid(l);
1158  break;
1159  }
1160  }
1161  if (!OidIsValid(indexOnChild))
1162  elog(ERROR, "failed to find index matching index \"%s\" in partition \"%s\"",
1163  get_rel_name(indexOid),
1164  get_rel_name(partdesc->oids[i]));
1165  }
1166 
1167  /*
1168  * Initialize our fabricated parse node by copying the original
1169  * one, then resetting fields that we pass separately.
1170  */
1171  childStmt = (CreateTrigStmt *) copyObject(stmt);
1172  childStmt->funcname = NIL;
1173  childStmt->whenClause = NULL;
1174 
1175  /* If there is a WHEN clause, create a modified copy of it */
1176  qual = copyObject(whenClause);
1177  qual = (Node *)
1179  childTbl, rel);
1180  qual = (Node *)
1182  childTbl, rel);
1183 
1184  CreateTrigger(childStmt, queryString,
1185  partdesc->oids[i], refRelOid,
1186  InvalidOid, indexOnChild,
1187  funcoid, trigoid, qual,
1188  isInternal, true);
1189 
1190  table_close(childTbl, NoLock);
1191 
1192  MemoryContextReset(perChildCxt);
1193  }
1194 
1195  MemoryContextSwitchTo(oldcxt);
1196  MemoryContextDelete(perChildCxt);
1197  list_free(idxs);
1198  list_free(childTbls);
1199  }
1200 
1201  /* Keep lock on target rel until end of xact */
1202  table_close(rel, NoLock);
1203 
1204  return myself;
1205 }
1206 
1207 
1208 /*
1209  * Convert legacy (pre-7.3) CREATE CONSTRAINT TRIGGER commands into
1210  * full-fledged foreign key constraints.
1211  *
1212  * The conversion is complex because a pre-7.3 foreign key involved three
1213  * separate triggers, which were reported separately in dumps. While the
1214  * single trigger on the referencing table adds no new information, we need
1215  * to know the trigger functions of both of the triggers on the referenced
1216  * table to build the constraint declaration. Also, due to lack of proper
1217  * dependency checking pre-7.3, it is possible that the source database had
1218  * an incomplete set of triggers resulting in an only partially enforced
1219  * FK constraint. (This would happen if one of the tables had been dropped
1220  * and re-created, but only if the DB had been affected by a 7.0 pg_dump bug
1221  * that caused loss of tgconstrrelid information.) We choose to translate to
1222  * an FK constraint only when we've seen all three triggers of a set. This is
1223  * implemented by storing unmatched items in a list in TopMemoryContext.
1224  * We match triggers together by comparing the trigger arguments (which
1225  * include constraint name, table and column names, so should be good enough).
1226  */
1227 typedef struct
1228 {
1229  List *args; /* list of (T_String) Values or NIL */
1230  Oid funcoids[3]; /* OIDs of trigger functions */
1231  /* The three function OIDs are stored in the order update, delete, child */
1232 } OldTriggerInfo;
1233 
1234 static void
1236 {
1237  static List *info_list = NIL;
1238 
1239  static const char *const funcdescr[3] = {
1240  gettext_noop("Found referenced table's UPDATE trigger."),
1241  gettext_noop("Found referenced table's DELETE trigger."),
1242  gettext_noop("Found referencing table's trigger.")
1243  };
1244 
1245  char *constr_name;
1246  char *fk_table_name;
1247  char *pk_table_name;
1248  char fk_matchtype = FKCONSTR_MATCH_SIMPLE;
1249  List *fk_attrs = NIL;
1250  List *pk_attrs = NIL;
1252  int funcnum;
1253  OldTriggerInfo *info = NULL;
1254  ListCell *l;
1255  int i;
1256 
1257  /* Parse out the trigger arguments */
1258  constr_name = strVal(linitial(stmt->args));
1259  fk_table_name = strVal(lsecond(stmt->args));
1260  pk_table_name = strVal(lthird(stmt->args));
1261  i = 0;
1262  foreach(l, stmt->args)
1263  {
1264  Value *arg = (Value *) lfirst(l);
1265 
1266  i++;
1267  if (i < 4) /* skip constraint and table names */
1268  continue;
1269  if (i == 4) /* handle match type */
1270  {
1271  if (strcmp(strVal(arg), "FULL") == 0)
1272  fk_matchtype = FKCONSTR_MATCH_FULL;
1273  else
1274  fk_matchtype = FKCONSTR_MATCH_SIMPLE;
1275  continue;
1276  }
1277  if (i % 2)
1278  fk_attrs = lappend(fk_attrs, arg);
1279  else
1280  pk_attrs = lappend(pk_attrs, arg);
1281  }
1282 
1283  /* Prepare description of constraint for use in messages */
1284  initStringInfo(&buf);
1285  appendStringInfo(&buf, "FOREIGN KEY %s(",
1286  quote_identifier(fk_table_name));
1287  i = 0;
1288  foreach(l, fk_attrs)
1289  {
1290  Value *arg = (Value *) lfirst(l);
1291 
1292  if (i++ > 0)
1293  appendStringInfoChar(&buf, ',');
1295  }
1296  appendStringInfo(&buf, ") REFERENCES %s(",
1297  quote_identifier(pk_table_name));
1298  i = 0;
1299  foreach(l, pk_attrs)
1300  {
1301  Value *arg = (Value *) lfirst(l);
1302 
1303  if (i++ > 0)
1304  appendStringInfoChar(&buf, ',');
1306  }
1307  appendStringInfoChar(&buf, ')');
1308 
1309  /* Identify class of trigger --- update, delete, or referencing-table */
1310  switch (funcoid)
1311  {
1312  case F_RI_FKEY_CASCADE_UPD:
1313  case F_RI_FKEY_RESTRICT_UPD:
1314  case F_RI_FKEY_SETNULL_UPD:
1315  case F_RI_FKEY_SETDEFAULT_UPD:
1316  case F_RI_FKEY_NOACTION_UPD:
1317  funcnum = 0;
1318  break;
1319 
1320  case F_RI_FKEY_CASCADE_DEL:
1321  case F_RI_FKEY_RESTRICT_DEL:
1322  case F_RI_FKEY_SETNULL_DEL:
1323  case F_RI_FKEY_SETDEFAULT_DEL:
1324  case F_RI_FKEY_NOACTION_DEL:
1325  funcnum = 1;
1326  break;
1327 
1328  default:
1329  funcnum = 2;
1330  break;
1331  }
1332 
1333  /* See if we have a match to this trigger */
1334  foreach(l, info_list)
1335  {
1336  info = (OldTriggerInfo *) lfirst(l);
1337  if (info->funcoids[funcnum] == InvalidOid &&
1338  equal(info->args, stmt->args))
1339  {
1340  info->funcoids[funcnum] = funcoid;
1341  break;
1342  }
1343  }
1344 
1345  if (l == NULL)
1346  {
1347  /* First trigger of set, so create a new list entry */
1348  MemoryContext oldContext;
1349 
1350  ereport(NOTICE,
1351  (errmsg("ignoring incomplete trigger group for constraint \"%s\" %s",
1352  constr_name, buf.data),
1353  errdetail_internal("%s", _(funcdescr[funcnum]))));
1355  info = (OldTriggerInfo *) palloc0(sizeof(OldTriggerInfo));
1356  info->args = copyObject(stmt->args);
1357  info->funcoids[funcnum] = funcoid;
1358  info_list = lappend(info_list, info);
1359  MemoryContextSwitchTo(oldContext);
1360  }
1361  else if (info->funcoids[0] == InvalidOid ||
1362  info->funcoids[1] == InvalidOid ||
1363  info->funcoids[2] == InvalidOid)
1364  {
1365  /* Second trigger of set */
1366  ereport(NOTICE,
1367  (errmsg("ignoring incomplete trigger group for constraint \"%s\" %s",
1368  constr_name, buf.data),
1369  errdetail_internal("%s", _(funcdescr[funcnum]))));
1370  }
1371  else
1372  {
1373  /* OK, we have a set, so make the FK constraint ALTER TABLE cmd */
1376  Constraint *fkcon = makeNode(Constraint);
1377  PlannedStmt *wrapper = makeNode(PlannedStmt);
1378 
1379  ereport(NOTICE,
1380  (errmsg("converting trigger group into constraint \"%s\" %s",
1381  constr_name, buf.data),
1382  errdetail_internal("%s", _(funcdescr[funcnum]))));
1383  fkcon->contype = CONSTR_FOREIGN;
1384  fkcon->location = -1;
1385  if (funcnum == 2)
1386  {
1387  /* This trigger is on the FK table */
1388  atstmt->relation = stmt->relation;
1389  if (stmt->constrrel)
1390  fkcon->pktable = stmt->constrrel;
1391  else
1392  {
1393  /* Work around ancient pg_dump bug that omitted constrrel */
1394  fkcon->pktable = makeRangeVar(NULL, pk_table_name, -1);
1395  }
1396  }
1397  else
1398  {
1399  /* This trigger is on the PK table */
1400  fkcon->pktable = stmt->relation;
1401  if (stmt->constrrel)
1402  atstmt->relation = stmt->constrrel;
1403  else
1404  {
1405  /* Work around ancient pg_dump bug that omitted constrrel */
1406  atstmt->relation = makeRangeVar(NULL, fk_table_name, -1);
1407  }
1408  }
1409  atstmt->cmds = list_make1(atcmd);
1410  atstmt->relkind = OBJECT_TABLE;
1411  atcmd->subtype = AT_AddConstraint;
1412  atcmd->def = (Node *) fkcon;
1413  if (strcmp(constr_name, "<unnamed>") == 0)
1414  fkcon->conname = NULL;
1415  else
1416  fkcon->conname = constr_name;
1417  fkcon->fk_attrs = fk_attrs;
1418  fkcon->pk_attrs = pk_attrs;
1419  fkcon->fk_matchtype = fk_matchtype;
1420  switch (info->funcoids[0])
1421  {
1422  case F_RI_FKEY_NOACTION_UPD:
1424  break;
1425  case F_RI_FKEY_CASCADE_UPD:
1427  break;
1428  case F_RI_FKEY_RESTRICT_UPD:
1430  break;
1431  case F_RI_FKEY_SETNULL_UPD:
1433  break;
1434  case F_RI_FKEY_SETDEFAULT_UPD:
1436  break;
1437  default:
1438  /* can't get here because of earlier checks */
1439  elog(ERROR, "confused about RI update function");
1440  }
1441  switch (info->funcoids[1])
1442  {
1443  case F_RI_FKEY_NOACTION_DEL:
1445  break;
1446  case F_RI_FKEY_CASCADE_DEL:
1448  break;
1449  case F_RI_FKEY_RESTRICT_DEL:
1451  break;
1452  case F_RI_FKEY_SETNULL_DEL:
1454  break;
1455  case F_RI_FKEY_SETDEFAULT_DEL:
1457  break;
1458  default:
1459  /* can't get here because of earlier checks */
1460  elog(ERROR, "confused about RI delete function");
1461  }
1462  fkcon->deferrable = stmt->deferrable;
1463  fkcon->initdeferred = stmt->initdeferred;
1464  fkcon->skip_validation = false;
1465  fkcon->initially_valid = true;
1466 
1467  /* finally, wrap it in a dummy PlannedStmt */
1468  wrapper->commandType = CMD_UTILITY;
1469  wrapper->canSetTag = false;
1470  wrapper->utilityStmt = (Node *) atstmt;
1471  wrapper->stmt_location = -1;
1472  wrapper->stmt_len = -1;
1473 
1474  /* ... and execute it */
1475  ProcessUtility(wrapper,
1476  "(generated ALTER TABLE ADD FOREIGN KEY command)",
1477  PROCESS_UTILITY_SUBCOMMAND, NULL, NULL,
1478  None_Receiver, NULL);
1479 
1480  /* Remove the matched item from the list */
1481  info_list = list_delete_ptr(info_list, info);
1482  pfree(info);
1483  /* We leak the copied args ... not worth worrying about */
1484  }
1485 }
1486 
1487 /*
1488  * Guts of trigger deletion.
1489  */
1490 void
1492 {
1493  Relation tgrel;
1494  SysScanDesc tgscan;
1495  ScanKeyData skey[1];
1496  HeapTuple tup;
1497  Oid relid;
1498  Relation rel;
1499 
1500  tgrel = table_open(TriggerRelationId, RowExclusiveLock);
1501 
1502  /*
1503  * Find the trigger to delete.
1504  */
1505  ScanKeyInit(&skey[0],
1506  Anum_pg_trigger_oid,
1507  BTEqualStrategyNumber, F_OIDEQ,
1508  ObjectIdGetDatum(trigOid));
1509 
1510  tgscan = systable_beginscan(tgrel, TriggerOidIndexId, true,
1511  NULL, 1, skey);
1512 
1513  tup = systable_getnext(tgscan);
1514  if (!HeapTupleIsValid(tup))
1515  elog(ERROR, "could not find tuple for trigger %u", trigOid);
1516 
1517  /*
1518  * Open and exclusive-lock the relation the trigger belongs to.
1519  */
1520  relid = ((Form_pg_trigger) GETSTRUCT(tup))->tgrelid;
1521 
1522  rel = table_open(relid, AccessExclusiveLock);
1523 
1524  if (rel->rd_rel->relkind != RELKIND_RELATION &&
1525  rel->rd_rel->relkind != RELKIND_VIEW &&
1526  rel->rd_rel->relkind != RELKIND_FOREIGN_TABLE &&
1527  rel->rd_rel->relkind != RELKIND_PARTITIONED_TABLE)
1528  ereport(ERROR,
1529  (errcode(ERRCODE_WRONG_OBJECT_TYPE),
1530  errmsg("\"%s\" is not a table, view, or foreign table",
1531  RelationGetRelationName(rel))));
1532 
1534  ereport(ERROR,
1535  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
1536  errmsg("permission denied: \"%s\" is a system catalog",
1537  RelationGetRelationName(rel))));
1538 
1539  /*
1540  * Delete the pg_trigger tuple.
1541  */
1542  CatalogTupleDelete(tgrel, &tup->t_self);
1543 
1544  systable_endscan(tgscan);
1545  table_close(tgrel, RowExclusiveLock);
1546 
1547  /*
1548  * We do not bother to try to determine whether any other triggers remain,
1549  * which would be needed in order to decide whether it's safe to clear the
1550  * relation's relhastriggers. (In any case, there might be a concurrent
1551  * process adding new triggers.) Instead, just force a relcache inval to
1552  * make other backends (and this one too!) rebuild their relcache entries.
1553  * There's no great harm in leaving relhastriggers true even if there are
1554  * no triggers left.
1555  */
1557 
1558  /* Keep lock on trigger's rel until end of xact */
1559  table_close(rel, NoLock);
1560 }
1561 
1562 /*
1563  * get_trigger_oid - Look up a trigger by name to find its OID.
1564  *
1565  * If missing_ok is false, throw an error if trigger not found. If
1566  * true, just return InvalidOid.
1567  */
1568 Oid
1569 get_trigger_oid(Oid relid, const char *trigname, bool missing_ok)
1570 {
1571  Relation tgrel;
1572  ScanKeyData skey[2];
1573  SysScanDesc tgscan;
1574  HeapTuple tup;
1575  Oid oid;
1576 
1577  /*
1578  * Find the trigger, verify permissions, set up object address
1579  */
1580  tgrel = table_open(TriggerRelationId, AccessShareLock);
1581 
1582  ScanKeyInit(&skey[0],
1583  Anum_pg_trigger_tgrelid,
1584  BTEqualStrategyNumber, F_OIDEQ,
1585  ObjectIdGetDatum(relid));
1586  ScanKeyInit(&skey[1],
1587  Anum_pg_trigger_tgname,
1588  BTEqualStrategyNumber, F_NAMEEQ,
1589  CStringGetDatum(trigname));
1590 
1591  tgscan = systable_beginscan(tgrel, TriggerRelidNameIndexId, true,
1592  NULL, 2, skey);
1593 
1594  tup = systable_getnext(tgscan);
1595 
1596  if (!HeapTupleIsValid(tup))
1597  {
1598  if (!missing_ok)
1599  ereport(ERROR,
1600  (errcode(ERRCODE_UNDEFINED_OBJECT),
1601  errmsg("trigger \"%s\" for table \"%s\" does not exist",
1602  trigname, get_rel_name(relid))));
1603  oid = InvalidOid;
1604  }
1605  else
1606  {
1607  oid = ((Form_pg_trigger) GETSTRUCT(tup))->oid;
1608  }
1609 
1610  systable_endscan(tgscan);
1611  table_close(tgrel, AccessShareLock);
1612  return oid;
1613 }
1614 
1615 /*
1616  * Perform permissions and integrity checks before acquiring a relation lock.
1617  */
1618 static void
1620  void *arg)
1621 {
1622  HeapTuple tuple;
1623  Form_pg_class form;
1624 
1625  tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
1626  if (!HeapTupleIsValid(tuple))
1627  return; /* concurrently dropped */
1628  form = (Form_pg_class) GETSTRUCT(tuple);
1629 
1630  /* only tables and views can have triggers */
1631  if (form->relkind != RELKIND_RELATION && form->relkind != RELKIND_VIEW &&
1632  form->relkind != RELKIND_FOREIGN_TABLE &&
1633  form->relkind != RELKIND_PARTITIONED_TABLE)
1634  ereport(ERROR,
1635  (errcode(ERRCODE_WRONG_OBJECT_TYPE),
1636  errmsg("\"%s\" is not a table, view, or foreign table",
1637  rv->relname)));
1638 
1639  /* you must own the table to rename one of its triggers */
1640  if (!pg_class_ownercheck(relid, GetUserId()))
1642  if (!allowSystemTableMods && IsSystemClass(relid, form))
1643  ereport(ERROR,
1644  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
1645  errmsg("permission denied: \"%s\" is a system catalog",
1646  rv->relname)));
1647 
1648  ReleaseSysCache(tuple);
1649 }
1650 
1651 /*
1652  * renametrig - changes the name of a trigger on a relation
1653  *
1654  * trigger name is changed in trigger catalog.
1655  * No record of the previous name is kept.
1656  *
1657  * get proper relrelation from relation catalog (if not arg)
1658  * scan trigger catalog
1659  * for name conflict (within rel)
1660  * for original trigger (if not arg)
1661  * modify tgname in trigger tuple
1662  * update row in catalog
1663  */
1666 {
1667  Oid tgoid;
1668  Relation targetrel;
1669  Relation tgrel;
1670  HeapTuple tuple;
1671  SysScanDesc tgscan;
1672  ScanKeyData key[2];
1673  Oid relid;
1674  ObjectAddress address;
1675 
1676  /*
1677  * Look up name, check permissions, and acquire lock (which we will NOT
1678  * release until end of transaction).
1679  */
1681  0,
1683  NULL);
1684 
1685  /* Have lock already, so just need to build relcache entry. */
1686  targetrel = relation_open(relid, NoLock);
1687 
1688  /*
1689  * Scan pg_trigger twice for existing triggers on relation. We do this in
1690  * order to ensure a trigger does not exist with newname (The unique index
1691  * on tgrelid/tgname would complain anyway) and to ensure a trigger does
1692  * exist with oldname.
1693  *
1694  * NOTE that this is cool only because we have AccessExclusiveLock on the
1695  * relation, so the trigger set won't be changing underneath us.
1696  */
1697  tgrel = table_open(TriggerRelationId, RowExclusiveLock);
1698 
1699  /*
1700  * First pass -- look for name conflict
1701  */
1702  ScanKeyInit(&key[0],
1703  Anum_pg_trigger_tgrelid,
1704  BTEqualStrategyNumber, F_OIDEQ,
1705  ObjectIdGetDatum(relid));
1706  ScanKeyInit(&key[1],
1707  Anum_pg_trigger_tgname,
1708  BTEqualStrategyNumber, F_NAMEEQ,
1709  PointerGetDatum(stmt->newname));
1710  tgscan = systable_beginscan(tgrel, TriggerRelidNameIndexId, true,
1711  NULL, 2, key);
1712  if (HeapTupleIsValid(tuple = systable_getnext(tgscan)))
1713  ereport(ERROR,
1715  errmsg("trigger \"%s\" for relation \"%s\" already exists",
1716  stmt->newname, RelationGetRelationName(targetrel))));
1717  systable_endscan(tgscan);
1718 
1719  /*
1720  * Second pass -- look for trigger existing with oldname and update
1721  */
1722  ScanKeyInit(&key[0],
1723  Anum_pg_trigger_tgrelid,
1724  BTEqualStrategyNumber, F_OIDEQ,
1725  ObjectIdGetDatum(relid));
1726  ScanKeyInit(&key[1],
1727  Anum_pg_trigger_tgname,
1728  BTEqualStrategyNumber, F_NAMEEQ,
1729  PointerGetDatum(stmt->subname));
1730  tgscan = systable_beginscan(tgrel, TriggerRelidNameIndexId, true,
1731  NULL, 2, key);
1732  if (HeapTupleIsValid(tuple = systable_getnext(tgscan)))
1733  {
1734  Form_pg_trigger trigform;
1735 
1736  /*
1737  * Update pg_trigger tuple with new tgname.
1738  */
1739  tuple = heap_copytuple(tuple); /* need a modifiable copy */
1740  trigform = (Form_pg_trigger) GETSTRUCT(tuple);
1741  tgoid = trigform->oid;
1742 
1743  namestrcpy(&trigform->tgname,
1744  stmt->newname);
1745 
1746  CatalogTupleUpdate(tgrel, &tuple->t_self, tuple);
1747 
1748  InvokeObjectPostAlterHook(TriggerRelationId,
1749  tgoid, 0);
1750 
1751  /*
1752  * Invalidate relation's relcache entry so that other backends (and
1753  * this one too!) are sent SI message to make them rebuild relcache
1754  * entries. (Ideally this should happen automatically...)
1755  */
1756  CacheInvalidateRelcache(targetrel);
1757  }
1758  else
1759  {
1760  ereport(ERROR,
1761  (errcode(ERRCODE_UNDEFINED_OBJECT),
1762  errmsg("trigger \"%s\" for table \"%s\" does not exist",
1763  stmt->subname, RelationGetRelationName(targetrel))));
1764  }
1765 
1766  ObjectAddressSet(address, TriggerRelationId, tgoid);
1767 
1768  systable_endscan(tgscan);
1769 
1770  table_close(tgrel, RowExclusiveLock);
1771 
1772  /*
1773  * Close rel, but keep exclusive lock!
1774  */
1775  relation_close(targetrel, NoLock);
1776 
1777  return address;
1778 }
1779 
1780 
1781 /*
1782  * EnableDisableTrigger()
1783  *
1784  * Called by ALTER TABLE ENABLE/DISABLE [ REPLICA | ALWAYS ] TRIGGER
1785  * to change 'tgenabled' field for the specified trigger(s)
1786  *
1787  * rel: relation to process (caller must hold suitable lock on it)
1788  * tgname: trigger to process, or NULL to scan all triggers
1789  * fires_when: new value for tgenabled field. In addition to generic
1790  * enablement/disablement, this also defines when the trigger
1791  * should be fired in session replication roles.
1792  * skip_system: if true, skip "system" triggers (constraint triggers)
1793  *
1794  * Caller should have checked permissions for the table; here we also
1795  * enforce that superuser privilege is required to alter the state of
1796  * system triggers
1797  */
1798 void
1799 EnableDisableTrigger(Relation rel, const char *tgname,
1800  char fires_when, bool skip_system, LOCKMODE lockmode)
1801 {
1802  Relation tgrel;
1803  int nkeys;
1804  ScanKeyData keys[2];
1805  SysScanDesc tgscan;
1806  HeapTuple tuple;
1807  bool found;
1808  bool changed;
1809 
1810  /* Scan the relevant entries in pg_triggers */
1811  tgrel = table_open(TriggerRelationId, RowExclusiveLock);
1812 
1813  ScanKeyInit(&keys[0],
1814  Anum_pg_trigger_tgrelid,
1815  BTEqualStrategyNumber, F_OIDEQ,
1817  if (tgname)
1818  {
1819  ScanKeyInit(&keys[1],
1820  Anum_pg_trigger_tgname,
1821  BTEqualStrategyNumber, F_NAMEEQ,
1822  CStringGetDatum(tgname));
1823  nkeys = 2;
1824  }
1825  else
1826  nkeys = 1;
1827 
1828  tgscan = systable_beginscan(tgrel, TriggerRelidNameIndexId, true,
1829  NULL, nkeys, keys);
1830 
1831  found = changed = false;
1832 
1833  while (HeapTupleIsValid(tuple = systable_getnext(tgscan)))
1834  {
1835  Form_pg_trigger oldtrig = (Form_pg_trigger) GETSTRUCT(tuple);
1836 
1837  if (oldtrig->tgisinternal)
1838  {
1839  /* system trigger ... ok to process? */
1840  if (skip_system)
1841  continue;
1842  if (!superuser())
1843  ereport(ERROR,
1844  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
1845  errmsg("permission denied: \"%s\" is a system trigger",
1846  NameStr(oldtrig->tgname))));
1847  }
1848 
1849  found = true;
1850 
1851  if (oldtrig->tgenabled != fires_when)
1852  {
1853  /* need to change this one ... make a copy to scribble on */
1854  HeapTuple newtup = heap_copytuple(tuple);
1855  Form_pg_trigger newtrig = (Form_pg_trigger) GETSTRUCT(newtup);
1856 
1857  newtrig->tgenabled = fires_when;
1858 
1859  CatalogTupleUpdate(tgrel, &newtup->t_self, newtup);
1860 
1861  heap_freetuple(newtup);
1862 
1863  /*
1864  * When altering FOR EACH ROW triggers on a partitioned table, do
1865  * the same on the partitions as well.
1866  */
1867  if (rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE &&
1868  (TRIGGER_FOR_ROW(oldtrig->tgtype)))
1869  {
1870  PartitionDesc partdesc = RelationGetPartitionDesc(rel);
1871  int i;
1872 
1873  for (i = 0; i < partdesc->nparts; i++)
1874  {
1875  Relation part;
1876 
1877  part = relation_open(partdesc->oids[i], lockmode);
1878  EnableDisableTrigger(part, NameStr(oldtrig->tgname),
1879  fires_when, skip_system, lockmode);
1880  table_close(part, NoLock); /* keep lock till commit */
1881  }
1882  }
1883 
1884  changed = true;
1885  }
1886 
1887  InvokeObjectPostAlterHook(TriggerRelationId,
1888  oldtrig->oid, 0);
1889  }
1890 
1891  systable_endscan(tgscan);
1892 
1893  table_close(tgrel, RowExclusiveLock);
1894 
1895  if (tgname && !found)
1896  ereport(ERROR,
1897  (errcode(ERRCODE_UNDEFINED_OBJECT),
1898  errmsg("trigger \"%s\" for table \"%s\" does not exist",
1899  tgname, RelationGetRelationName(rel))));
1900 
1901  /*
1902  * If we changed anything, broadcast a SI inval message to force each
1903  * backend (including our own!) to rebuild relation's relcache entry.
1904  * Otherwise they will fail to apply the change promptly.
1905  */
1906  if (changed)
1908 }
1909 
1910 
1911 /*
1912  * Build trigger data to attach to the given relcache entry.
1913  *
1914  * Note that trigger data attached to a relcache entry must be stored in
1915  * CacheMemoryContext to ensure it survives as long as the relcache entry.
1916  * But we should be running in a less long-lived working context. To avoid
1917  * leaking cache memory if this routine fails partway through, we build a
1918  * temporary TriggerDesc in working memory and then copy the completed
1919  * structure into cache memory.
1920  */
1921 void
1923 {
1924  TriggerDesc *trigdesc;
1925  int numtrigs;
1926  int maxtrigs;
1927  Trigger *triggers;
1928  Relation tgrel;
1929  ScanKeyData skey;
1930  SysScanDesc tgscan;
1931  HeapTuple htup;
1932  MemoryContext oldContext;
1933  int i;
1934 
1935  /*
1936  * Allocate a working array to hold the triggers (the array is extended if
1937  * necessary)
1938  */
1939  maxtrigs = 16;
1940  triggers = (Trigger *) palloc(maxtrigs * sizeof(Trigger));
1941  numtrigs = 0;
1942 
1943  /*
1944  * Note: since we scan the triggers using TriggerRelidNameIndexId, we will
1945  * be reading the triggers in name order, except possibly during
1946  * emergency-recovery operations (ie, IgnoreSystemIndexes). This in turn
1947  * ensures that triggers will be fired in name order.
1948  */
1949  ScanKeyInit(&skey,
1950  Anum_pg_trigger_tgrelid,
1951  BTEqualStrategyNumber, F_OIDEQ,
1952  ObjectIdGetDatum(RelationGetRelid(relation)));
1953 
1954  tgrel = table_open(TriggerRelationId, AccessShareLock);
1955  tgscan = systable_beginscan(tgrel, TriggerRelidNameIndexId, true,
1956  NULL, 1, &skey);
1957 
1958  while (HeapTupleIsValid(htup = systable_getnext(tgscan)))
1959  {
1960  Form_pg_trigger pg_trigger = (Form_pg_trigger) GETSTRUCT(htup);
1961  Trigger *build;
1962  Datum datum;
1963  bool isnull;
1964 
1965  if (numtrigs >= maxtrigs)
1966  {
1967  maxtrigs *= 2;
1968  triggers = (Trigger *) repalloc(triggers, maxtrigs * sizeof(Trigger));
1969  }
1970  build = &(triggers[numtrigs]);
1971 
1972  build->tgoid = pg_trigger->oid;
1974  NameGetDatum(&pg_trigger->tgname)));
1975  build->tgfoid = pg_trigger->tgfoid;
1976  build->tgtype = pg_trigger->tgtype;
1977  build->tgenabled = pg_trigger->tgenabled;
1978  build->tgisinternal = pg_trigger->tgisinternal;
1979  build->tgconstrrelid = pg_trigger->tgconstrrelid;
1980  build->tgconstrindid = pg_trigger->tgconstrindid;
1981  build->tgconstraint = pg_trigger->tgconstraint;
1982  build->tgdeferrable = pg_trigger->tgdeferrable;
1983  build->tginitdeferred = pg_trigger->tginitdeferred;
1984  build->tgnargs = pg_trigger->tgnargs;
1985  /* tgattr is first var-width field, so OK to access directly */
1986  build->tgnattr = pg_trigger->tgattr.dim1;
1987  if (build->tgnattr > 0)
1988  {
1989  build->tgattr = (int16 *) palloc(build->tgnattr * sizeof(int16));
1990  memcpy(build->tgattr, &(pg_trigger->tgattr.values),
1991  build->tgnattr * sizeof(int16));
1992  }
1993  else
1994  build->tgattr = NULL;
1995  if (build->tgnargs > 0)
1996  {
1997  bytea *val;
1998  char *p;
1999 
2000  val = DatumGetByteaPP(fastgetattr(htup,
2001  Anum_pg_trigger_tgargs,
2002  tgrel->rd_att, &isnull));
2003  if (isnull)
2004  elog(ERROR, "tgargs is null in trigger for relation \"%s\"",
2005  RelationGetRelationName(relation));
2006  p = (char *) VARDATA_ANY(val);
2007  build->tgargs = (char **) palloc(build->tgnargs * sizeof(char *));
2008  for (i = 0; i < build->tgnargs; i++)
2009  {
2010  build->tgargs[i] = pstrdup(p);
2011  p += strlen(p) + 1;
2012  }
2013  }
2014  else
2015  build->tgargs = NULL;
2016 
2017  datum = fastgetattr(htup, Anum_pg_trigger_tgoldtable,
2018  tgrel->rd_att, &isnull);
2019  if (!isnull)
2020  build->tgoldtable =
2022  else
2023  build->tgoldtable = NULL;
2024 
2025  datum = fastgetattr(htup, Anum_pg_trigger_tgnewtable,
2026  tgrel->rd_att, &isnull);
2027  if (!isnull)
2028  build->tgnewtable =
2030  else
2031  build->tgnewtable = NULL;
2032 
2033  datum = fastgetattr(htup, Anum_pg_trigger_tgqual,
2034  tgrel->rd_att, &isnull);
2035  if (!isnull)
2036  build->tgqual = TextDatumGetCString(datum);
2037  else
2038  build->tgqual = NULL;
2039 
2040  numtrigs++;
2041  }
2042 
2043  systable_endscan(tgscan);
2044  table_close(tgrel, AccessShareLock);
2045 
2046  /* There might not be any triggers */
2047  if (numtrigs == 0)
2048  {
2049  pfree(triggers);
2050  return;
2051  }
2052 
2053  /* Build trigdesc */
2054  trigdesc = (TriggerDesc *) palloc0(sizeof(TriggerDesc));
2055  trigdesc->triggers = triggers;
2056  trigdesc->numtriggers = numtrigs;
2057  for (i = 0; i < numtrigs; i++)
2058  SetTriggerFlags(trigdesc, &(triggers[i]));
2059 
2060  /* Copy completed trigdesc into cache storage */
2062  relation->trigdesc = CopyTriggerDesc(trigdesc);
2063  MemoryContextSwitchTo(oldContext);
2064 
2065  /* Release working memory */
2066  FreeTriggerDesc(trigdesc);
2067 }
2068 
2069 /*
2070  * Update the TriggerDesc's hint flags to include the specified trigger
2071  */
2072 static void
2074 {
2075  int16 tgtype = trigger->tgtype;
2076 
2077  trigdesc->trig_insert_before_row |=
2078  TRIGGER_TYPE_MATCHES(tgtype, TRIGGER_TYPE_ROW,
2079  TRIGGER_TYPE_BEFORE, TRIGGER_TYPE_INSERT);
2080  trigdesc->trig_insert_after_row |=
2081  TRIGGER_TYPE_MATCHES(tgtype, TRIGGER_TYPE_ROW,
2082  TRIGGER_TYPE_AFTER, TRIGGER_TYPE_INSERT);
2083  trigdesc->trig_insert_instead_row |=
2084  TRIGGER_TYPE_MATCHES(tgtype, TRIGGER_TYPE_ROW,
2085  TRIGGER_TYPE_INSTEAD, TRIGGER_TYPE_INSERT);
2086  trigdesc->trig_insert_before_statement |=
2087  TRIGGER_TYPE_MATCHES(tgtype, TRIGGER_TYPE_STATEMENT,
2088  TRIGGER_TYPE_BEFORE, TRIGGER_TYPE_INSERT);
2089  trigdesc->trig_insert_after_statement |=
2090  TRIGGER_TYPE_MATCHES(tgtype, TRIGGER_TYPE_STATEMENT,
2091  TRIGGER_TYPE_AFTER, TRIGGER_TYPE_INSERT);
2092  trigdesc->trig_update_before_row |=
2093  TRIGGER_TYPE_MATCHES(tgtype, TRIGGER_TYPE_ROW,
2094  TRIGGER_TYPE_BEFORE, TRIGGER_TYPE_UPDATE);
2095  trigdesc->trig_update_after_row |=
2096  TRIGGER_TYPE_MATCHES(tgtype, TRIGGER_TYPE_ROW,
2097  TRIGGER_TYPE_AFTER, TRIGGER_TYPE_UPDATE);
2098  trigdesc->trig_update_instead_row |=
2099  TRIGGER_TYPE_MATCHES(tgtype, TRIGGER_TYPE_ROW,
2100  TRIGGER_TYPE_INSTEAD, TRIGGER_TYPE_UPDATE);
2101  trigdesc->trig_update_before_statement |=
2102  TRIGGER_TYPE_MATCHES(tgtype, TRIGGER_TYPE_STATEMENT,
2103  TRIGGER_TYPE_BEFORE, TRIGGER_TYPE_UPDATE);
2104  trigdesc->trig_update_after_statement |=
2105  TRIGGER_TYPE_MATCHES(tgtype, TRIGGER_TYPE_STATEMENT,
2106  TRIGGER_TYPE_AFTER, TRIGGER_TYPE_UPDATE);
2107  trigdesc->trig_delete_before_row |=
2108  TRIGGER_TYPE_MATCHES(tgtype, TRIGGER_TYPE_ROW,
2109  TRIGGER_TYPE_BEFORE, TRIGGER_TYPE_DELETE);
2110  trigdesc->trig_delete_after_row |=
2111  TRIGGER_TYPE_MATCHES(tgtype, TRIGGER_TYPE_ROW,
2112  TRIGGER_TYPE_AFTER, TRIGGER_TYPE_DELETE);
2113  trigdesc->trig_delete_instead_row |=
2114  TRIGGER_TYPE_MATCHES(tgtype, TRIGGER_TYPE_ROW,
2115  TRIGGER_TYPE_INSTEAD, TRIGGER_TYPE_DELETE);
2116  trigdesc->trig_delete_before_statement |=
2117  TRIGGER_TYPE_MATCHES(tgtype, TRIGGER_TYPE_STATEMENT,
2118  TRIGGER_TYPE_BEFORE, TRIGGER_TYPE_DELETE);
2119  trigdesc->trig_delete_after_statement |=
2120  TRIGGER_TYPE_MATCHES(tgtype, TRIGGER_TYPE_STATEMENT,
2121  TRIGGER_TYPE_AFTER, TRIGGER_TYPE_DELETE);
2122  /* there are no row-level truncate triggers */
2123  trigdesc->trig_truncate_before_statement |=
2124  TRIGGER_TYPE_MATCHES(tgtype, TRIGGER_TYPE_STATEMENT,
2125  TRIGGER_TYPE_BEFORE, TRIGGER_TYPE_TRUNCATE);
2126  trigdesc->trig_truncate_after_statement |=
2127  TRIGGER_TYPE_MATCHES(tgtype, TRIGGER_TYPE_STATEMENT,
2128  TRIGGER_TYPE_AFTER, TRIGGER_TYPE_TRUNCATE);
2129 
2130  trigdesc->trig_insert_new_table |=
2131  (TRIGGER_FOR_INSERT(tgtype) &&
2132  TRIGGER_USES_TRANSITION_TABLE(trigger->tgnewtable));
2133  trigdesc->trig_update_old_table |=
2134  (TRIGGER_FOR_UPDATE(tgtype) &&
2135  TRIGGER_USES_TRANSITION_TABLE(trigger->tgoldtable));
2136  trigdesc->trig_update_new_table |=
2137  (TRIGGER_FOR_UPDATE(tgtype) &&
2138  TRIGGER_USES_TRANSITION_TABLE(trigger->tgnewtable));
2139  trigdesc->trig_delete_old_table |=
2140  (TRIGGER_FOR_DELETE(tgtype) &&
2141  TRIGGER_USES_TRANSITION_TABLE(trigger->tgoldtable));
2142 }
2143 
2144 /*
2145  * Copy a TriggerDesc data structure.
2146  *
2147  * The copy is allocated in the current memory context.
2148  */
2149 TriggerDesc *
2151 {
2152  TriggerDesc *newdesc;
2153  Trigger *trigger;
2154  int i;
2155 
2156  if (trigdesc == NULL || trigdesc->numtriggers <= 0)
2157  return NULL;
2158 
2159  newdesc = (TriggerDesc *) palloc(sizeof(TriggerDesc));
2160  memcpy(newdesc, trigdesc, sizeof(TriggerDesc));
2161 
2162  trigger = (Trigger *) palloc(trigdesc->numtriggers * sizeof(Trigger));
2163  memcpy(trigger, trigdesc->triggers,
2164  trigdesc->numtriggers * sizeof(Trigger));
2165  newdesc->triggers = trigger;
2166 
2167  for (i = 0; i < trigdesc->numtriggers; i++)
2168  {
2169  trigger->tgname = pstrdup(trigger->tgname);
2170  if (trigger->tgnattr > 0)
2171  {
2172  int16 *newattr;
2173 
2174  newattr = (int16 *) palloc(trigger->tgnattr * sizeof(int16));
2175  memcpy(newattr, trigger->tgattr,
2176  trigger->tgnattr * sizeof(int16));
2177  trigger->tgattr = newattr;
2178  }
2179  if (trigger->tgnargs > 0)
2180  {
2181  char **newargs;
2182  int16 j;
2183 
2184  newargs = (char **) palloc(trigger->tgnargs * sizeof(char *));
2185  for (j = 0; j < trigger->tgnargs; j++)
2186  newargs[j] = pstrdup(trigger->tgargs[j]);
2187  trigger->tgargs = newargs;
2188  }
2189  if (trigger->tgqual)
2190  trigger->tgqual = pstrdup(trigger->tgqual);
2191  if (trigger->tgoldtable)
2192  trigger->tgoldtable = pstrdup(trigger->tgoldtable);
2193  if (trigger->tgnewtable)
2194  trigger->tgnewtable = pstrdup(trigger->tgnewtable);
2195  trigger++;
2196  }
2197 
2198  return newdesc;
2199 }
2200 
2201 /*
2202  * Free a TriggerDesc data structure.
2203  */
2204 void
2206 {
2207  Trigger *trigger;
2208  int i;
2209 
2210  if (trigdesc == NULL)
2211  return;
2212 
2213  trigger = trigdesc->triggers;
2214  for (i = 0; i < trigdesc->numtriggers; i++)
2215  {
2216  pfree(trigger->tgname);
2217  if (trigger->tgnattr > 0)
2218  pfree(trigger->tgattr);
2219  if (trigger->tgnargs > 0)
2220  {
2221  while (--(trigger->tgnargs) >= 0)
2222  pfree(trigger->tgargs[trigger->tgnargs]);
2223  pfree(trigger->tgargs);
2224  }
2225  if (trigger->tgqual)
2226  pfree(trigger->tgqual);
2227  if (trigger->tgoldtable)
2228  pfree(trigger->tgoldtable);
2229  if (trigger->tgnewtable)
2230  pfree(trigger->tgnewtable);
2231  trigger++;
2232  }
2233  pfree(trigdesc->triggers);
2234  pfree(trigdesc);
2235 }
2236 
2237 /*
2238  * Compare two TriggerDesc structures for logical equality.
2239  */
2240 #ifdef NOT_USED
2241 bool
2242 equalTriggerDescs(TriggerDesc *trigdesc1, TriggerDesc *trigdesc2)
2243 {
2244  int i,
2245  j;
2246 
2247  /*
2248  * We need not examine the hint flags, just the trigger array itself; if
2249  * we have the same triggers with the same types, the flags should match.
2250  *
2251  * As of 7.3 we assume trigger set ordering is significant in the
2252  * comparison; so we just compare corresponding slots of the two sets.
2253  *
2254  * Note: comparing the stringToNode forms of the WHEN clauses means that
2255  * parse column locations will affect the result. This is okay as long as
2256  * this function is only used for detecting exact equality, as for example
2257  * in checking for staleness of a cache entry.
2258  */
2259  if (trigdesc1 != NULL)
2260  {
2261  if (trigdesc2 == NULL)
2262  return false;
2263  if (trigdesc1->numtriggers != trigdesc2->numtriggers)
2264  return false;
2265  for (i = 0; i < trigdesc1->numtriggers; i++)
2266  {
2267  Trigger *trig1 = trigdesc1->triggers + i;
2268  Trigger *trig2 = trigdesc2->triggers + i;
2269 
2270  if (trig1->tgoid != trig2->tgoid)
2271  return false;
2272  if (strcmp(trig1->tgname, trig2->tgname) != 0)
2273  return false;
2274  if (trig1->tgfoid != trig2->tgfoid)
2275  return false;
2276  if (trig1->tgtype != trig2->tgtype)
2277  return false;
2278  if (trig1->tgenabled != trig2->tgenabled)
2279  return false;
2280  if (trig1->tgisinternal != trig2->tgisinternal)
2281  return false;
2282  if (trig1->tgconstrrelid != trig2->tgconstrrelid)
2283  return false;
2284  if (trig1->tgconstrindid != trig2->tgconstrindid)
2285  return false;
2286  if (trig1->tgconstraint != trig2->tgconstraint)
2287  return false;
2288  if (trig1->tgdeferrable != trig2->tgdeferrable)
2289  return false;
2290  if (trig1->tginitdeferred != trig2->tginitdeferred)
2291  return false;
2292  if (trig1->tgnargs != trig2->tgnargs)
2293  return false;
2294  if (trig1->tgnattr != trig2->tgnattr)
2295  return false;
2296  if (trig1->tgnattr > 0 &&
2297  memcmp(trig1->tgattr, trig2->tgattr,
2298  trig1->tgnattr * sizeof(int16)) != 0)
2299  return false;
2300  for (j = 0; j < trig1->tgnargs; j++)
2301  if (strcmp(trig1->tgargs[j], trig2->tgargs[j]) != 0)
2302  return false;
2303  if (trig1->tgqual == NULL && trig2->tgqual == NULL)
2304  /* ok */ ;
2305  else if (trig1->tgqual == NULL || trig2->tgqual == NULL)
2306  return false;
2307  else if (strcmp(trig1->tgqual, trig2->tgqual) != 0)
2308  return false;
2309  if (trig1->tgoldtable == NULL && trig2->tgoldtable == NULL)
2310  /* ok */ ;
2311  else if (trig1->tgoldtable == NULL || trig2->tgoldtable == NULL)
2312  return false;
2313  else if (strcmp(trig1->tgoldtable, trig2->tgoldtable) != 0)
2314  return false;
2315  if (trig1->tgnewtable == NULL && trig2->tgnewtable == NULL)
2316  /* ok */ ;
2317  else if (trig1->tgnewtable == NULL || trig2->tgnewtable == NULL)
2318  return false;
2319  else if (strcmp(trig1->tgnewtable, trig2->tgnewtable) != 0)
2320  return false;
2321  }
2322  }
2323  else if (trigdesc2 != NULL)
2324  return false;
2325  return true;
2326 }
2327 #endif /* NOT_USED */
2328 
2329 /*
2330  * Check if there is a row-level trigger with transition tables that prevents
2331  * a table from becoming an inheritance child or partition. Return the name
2332  * of the first such incompatible trigger, or NULL if there is none.
2333  */
2334 const char *
2336 {
2337  if (trigdesc != NULL)
2338  {
2339  int i;
2340 
2341  for (i = 0; i < trigdesc->numtriggers; ++i)
2342  {
2343  Trigger *trigger = &trigdesc->triggers[i];
2344 
2345  if (trigger->tgoldtable != NULL || trigger->tgnewtable != NULL)
2346  return trigger->tgname;
2347  }
2348  }
2349 
2350  return NULL;
2351 }
2352 
2353 /*
2354  * Call a trigger function.
2355  *
2356  * trigdata: trigger descriptor.
2357  * tgindx: trigger's index in finfo and instr arrays.
2358  * finfo: array of cached trigger function call information.
2359  * instr: optional array of EXPLAIN ANALYZE instrumentation state.
2360  * per_tuple_context: memory context to execute the function in.
2361  *
2362  * Returns the tuple (or NULL) as returned by the function.
2363  */
2364 static HeapTuple
2366  int tgindx,
2367  FmgrInfo *finfo,
2368  Instrumentation *instr,
2369  MemoryContext per_tuple_context)
2370 {
2371  LOCAL_FCINFO(fcinfo, 0);
2372  PgStat_FunctionCallUsage fcusage;
2373  Datum result;
2374  MemoryContext oldContext;
2375 
2376  /*
2377  * Protect against code paths that may fail to initialize transition table
2378  * info.
2379  */
2380  Assert(((TRIGGER_FIRED_BY_INSERT(trigdata->tg_event) ||
2381  TRIGGER_FIRED_BY_UPDATE(trigdata->tg_event) ||
2382  TRIGGER_FIRED_BY_DELETE(trigdata->tg_event)) &&
2383  TRIGGER_FIRED_AFTER(trigdata->tg_event) &&
2384  !(trigdata->tg_event & AFTER_TRIGGER_DEFERRABLE) &&
2385  !(trigdata->tg_event & AFTER_TRIGGER_INITDEFERRED)) ||
2386  (trigdata->tg_oldtable == NULL && trigdata->tg_newtable == NULL));
2387 
2388  finfo += tgindx;
2389 
2390  /*
2391  * We cache fmgr lookup info, to avoid making the lookup again on each
2392  * call.
2393  */
2394  if (finfo->fn_oid == InvalidOid)
2395  fmgr_info(trigdata->tg_trigger->tgfoid, finfo);
2396 
2397  Assert(finfo->fn_oid == trigdata->tg_trigger->tgfoid);
2398 
2399  /*
2400  * If doing EXPLAIN ANALYZE, start charging time to this trigger.
2401  */
2402  if (instr)
2403  InstrStartNode(instr + tgindx);
2404 
2405  /*
2406  * Do the function evaluation in the per-tuple memory context, so that
2407  * leaked memory will be reclaimed once per tuple. Note in particular that
2408  * any new tuple created by the trigger function will live till the end of
2409  * the tuple cycle.
2410  */
2411  oldContext = MemoryContextSwitchTo(per_tuple_context);
2412 
2413  /*
2414  * Call the function, passing no arguments but setting a context.
2415  */
2416  InitFunctionCallInfoData(*fcinfo, finfo, 0,
2417  InvalidOid, (Node *) trigdata, NULL);
2418 
2419  pgstat_init_function_usage(fcinfo, &fcusage);
2420 
2421  MyTriggerDepth++;
2422  PG_TRY();
2423  {
2424  result = FunctionCallInvoke(fcinfo);
2425  }
2426  PG_FINALLY();
2427  {
2428  MyTriggerDepth--;
2429  }
2430  PG_END_TRY();
2431 
2432  pgstat_end_function_usage(&fcusage, true);
2433 
2434  MemoryContextSwitchTo(oldContext);
2435 
2436  /*
2437  * Trigger protocol allows function to return a null pointer, but NOT to
2438  * set the isnull result flag.
2439  */
2440  if (fcinfo->isnull)
2441  ereport(ERROR,
2442  (errcode(ERRCODE_E_R_I_E_TRIGGER_PROTOCOL_VIOLATED),
2443  errmsg("trigger function %u returned null value",
2444  fcinfo->flinfo->fn_oid)));
2445 
2446  /*
2447  * If doing EXPLAIN ANALYZE, stop charging time to this trigger, and count
2448  * one "tuple returned" (really the number of firings).
2449  */
2450  if (instr)
2451  InstrStopNode(instr + tgindx, 1);
2452 
2453  return (HeapTuple) DatumGetPointer(result);
2454 }
2455 
2456 void
2458 {
2459  TriggerDesc *trigdesc;
2460  int i;
2461  TriggerData LocTriggerData;
2462 
2463  trigdesc = relinfo->ri_TrigDesc;
2464 
2465  if (trigdesc == NULL)
2466  return;
2467  if (!trigdesc->trig_insert_before_statement)
2468  return;
2469 
2470  /* no-op if we already fired BS triggers in this context */
2472  CMD_INSERT))
2473  return;
2474 
2475  LocTriggerData.type = T_TriggerData;
2476  LocTriggerData.tg_event = TRIGGER_EVENT_INSERT |
2478  LocTriggerData.tg_relation = relinfo->ri_RelationDesc;
2479  LocTriggerData.tg_trigtuple = NULL;
2480  LocTriggerData.tg_newtuple = NULL;
2481  LocTriggerData.tg_trigslot = NULL;
2482  LocTriggerData.tg_newslot = NULL;
2483  LocTriggerData.tg_oldtable = NULL;
2484  LocTriggerData.tg_newtable = NULL;
2485  for (i = 0; i < trigdesc->numtriggers; i++)
2486  {
2487  Trigger *trigger = &trigdesc->triggers[i];
2488  HeapTuple newtuple;
2489 
2490  if (!TRIGGER_TYPE_MATCHES(trigger->tgtype,
2491  TRIGGER_TYPE_STATEMENT,
2492  TRIGGER_TYPE_BEFORE,
2493  TRIGGER_TYPE_INSERT))
2494  continue;
2495  if (!TriggerEnabled(estate, relinfo, trigger, LocTriggerData.tg_event,
2496  NULL, NULL, NULL))
2497  continue;
2498 
2499  LocTriggerData.tg_trigger = trigger;
2500  newtuple = ExecCallTriggerFunc(&LocTriggerData,
2501  i,
2502  relinfo->ri_TrigFunctions,
2503  relinfo->ri_TrigInstrument,
2504  GetPerTupleMemoryContext(estate));
2505 
2506  if (newtuple)
2507  ereport(ERROR,
2508  (errcode(ERRCODE_E_R_I_E_TRIGGER_PROTOCOL_VIOLATED),
2509  errmsg("BEFORE STATEMENT trigger cannot return a value")));
2510  }
2511 }
2512 
2513 void
2515  TransitionCaptureState *transition_capture)
2516 {
2517  TriggerDesc *trigdesc = relinfo->ri_TrigDesc;
2518 
2519  if (trigdesc && trigdesc->trig_insert_after_statement)
2521  false, NULL, NULL, NIL, NULL, transition_capture);
2522 }
2523 
2524 bool
2526  TupleTableSlot *slot)
2527 {
2528  TriggerDesc *trigdesc = relinfo->ri_TrigDesc;
2529  HeapTuple newtuple = NULL;
2530  bool should_free;
2531  TriggerData LocTriggerData;
2532  int i;
2533 
2534  LocTriggerData.type = T_TriggerData;
2535  LocTriggerData.tg_event = TRIGGER_EVENT_INSERT |
2538  LocTriggerData.tg_relation = relinfo->ri_RelationDesc;
2539  LocTriggerData.tg_trigtuple = NULL;
2540  LocTriggerData.tg_newtuple = NULL;
2541  LocTriggerData.tg_trigslot = NULL;
2542  LocTriggerData.tg_newslot = NULL;
2543  LocTriggerData.tg_oldtable = NULL;
2544  LocTriggerData.tg_newtable = NULL;
2545  for (i = 0; i < trigdesc->numtriggers; i++)
2546  {
2547  Trigger *trigger = &trigdesc->triggers[i];
2548  HeapTuple oldtuple;
2549 
2550  if (!TRIGGER_TYPE_MATCHES(trigger->tgtype,
2551  TRIGGER_TYPE_ROW,
2552  TRIGGER_TYPE_BEFORE,
2553  TRIGGER_TYPE_INSERT))
2554  continue;
2555  if (!TriggerEnabled(estate, relinfo, trigger, LocTriggerData.tg_event,
2556  NULL, NULL, slot))
2557  continue;
2558 
2559  if (!newtuple)
2560  newtuple = ExecFetchSlotHeapTuple(slot, true, &should_free);
2561 
2562  LocTriggerData.tg_trigslot = slot;
2563  LocTriggerData.tg_trigtuple = oldtuple = newtuple;
2564  LocTriggerData.tg_trigger = trigger;
2565  newtuple = ExecCallTriggerFunc(&LocTriggerData,
2566  i,
2567  relinfo->ri_TrigFunctions,
2568  relinfo->ri_TrigInstrument,
2569  GetPerTupleMemoryContext(estate));
2570  if (newtuple == NULL)
2571  {
2572  if (should_free)
2573  heap_freetuple(oldtuple);
2574  return false; /* "do nothing" */
2575  }
2576  else if (newtuple != oldtuple)
2577  {
2578  ExecForceStoreHeapTuple(newtuple, slot, false);
2579 
2580  if (should_free)
2581  heap_freetuple(oldtuple);
2582 
2583  /* signal tuple should be re-fetched if used */
2584  newtuple = NULL;
2585  }
2586  }
2587 
2588  return true;
2589 }
2590 
2591 void
2593  TupleTableSlot *slot, List *recheckIndexes,
2594  TransitionCaptureState *transition_capture)
2595 {
2596  TriggerDesc *trigdesc = relinfo->ri_TrigDesc;
2597 
2598  if ((trigdesc && trigdesc->trig_insert_after_row) ||
2599  (transition_capture && transition_capture->tcs_insert_new_table))
2601  true, NULL, slot,
2602  recheckIndexes, NULL,
2603  transition_capture);
2604 }
2605 
2606 bool
2608  TupleTableSlot *slot)
2609 {
2610  TriggerDesc *trigdesc = relinfo->ri_TrigDesc;
2611  HeapTuple newtuple = NULL;
2612  bool should_free;
2613  TriggerData LocTriggerData;
2614  int i;
2615 
2616  LocTriggerData.type = T_TriggerData;
2617  LocTriggerData.tg_event = TRIGGER_EVENT_INSERT |
2620  LocTriggerData.tg_relation = relinfo->ri_RelationDesc;
2621  LocTriggerData.tg_trigtuple = NULL;
2622  LocTriggerData.tg_newtuple = NULL;
2623  LocTriggerData.tg_trigslot = NULL;
2624  LocTriggerData.tg_newslot = NULL;
2625  LocTriggerData.tg_oldtable = NULL;
2626  LocTriggerData.tg_newtable = NULL;
2627  for (i = 0; i < trigdesc->numtriggers; i++)
2628  {
2629  Trigger *trigger = &trigdesc->triggers[i];
2630  HeapTuple oldtuple;
2631 
2632  if (!TRIGGER_TYPE_MATCHES(trigger->tgtype,
2633  TRIGGER_TYPE_ROW,
2634  TRIGGER_TYPE_INSTEAD,
2635  TRIGGER_TYPE_INSERT))
2636  continue;
2637  if (!TriggerEnabled(estate, relinfo, trigger, LocTriggerData.tg_event,
2638  NULL, NULL, slot))
2639  continue;
2640 
2641  if (!newtuple)
2642  newtuple = ExecFetchSlotHeapTuple(slot, true, &should_free);
2643 
2644  LocTriggerData.tg_trigslot = slot;
2645  LocTriggerData.tg_trigtuple = oldtuple = newtuple;
2646  LocTriggerData.tg_trigger = trigger;
2647  newtuple = ExecCallTriggerFunc(&LocTriggerData,
2648  i,
2649  relinfo->ri_TrigFunctions,
2650  relinfo->ri_TrigInstrument,
2651  GetPerTupleMemoryContext(estate));
2652  if (newtuple == NULL)
2653  {
2654  if (should_free)
2655  heap_freetuple(oldtuple);
2656  return false; /* "do nothing" */
2657  }
2658  else if (newtuple != oldtuple)
2659  {
2660  ExecForceStoreHeapTuple(newtuple, slot, false);
2661 
2662  if (should_free)
2663  heap_freetuple(oldtuple);
2664 
2665  /* signal tuple should be re-fetched if used */
2666  newtuple = NULL;
2667  }
2668  }
2669 
2670  return true;
2671 }
2672 
2673 void
2675 {
2676  TriggerDesc *trigdesc;
2677  int i;
2678  TriggerData LocTriggerData;
2679 
2680  trigdesc = relinfo->ri_TrigDesc;
2681 
2682  if (trigdesc == NULL)
2683  return;
2684  if (!trigdesc->trig_delete_before_statement)
2685  return;
2686 
2687  /* no-op if we already fired BS triggers in this context */
2689  CMD_DELETE))
2690  return;
2691 
2692  LocTriggerData.type = T_TriggerData;
2693  LocTriggerData.tg_event = TRIGGER_EVENT_DELETE |
2695  LocTriggerData.tg_relation = relinfo->ri_RelationDesc;
2696  LocTriggerData.tg_trigtuple = NULL;
2697  LocTriggerData.tg_newtuple = NULL;
2698  LocTriggerData.tg_trigslot = NULL;
2699  LocTriggerData.tg_newslot = NULL;
2700  LocTriggerData.tg_oldtable = NULL;
2701  LocTriggerData.tg_newtable = NULL;
2702  for (i = 0; i < trigdesc->numtriggers; i++)
2703  {
2704  Trigger *trigger = &trigdesc->triggers[i];
2705  HeapTuple newtuple;
2706 
2707  if (!TRIGGER_TYPE_MATCHES(trigger->tgtype,
2708  TRIGGER_TYPE_STATEMENT,
2709  TRIGGER_TYPE_BEFORE,
2710  TRIGGER_TYPE_DELETE))
2711  continue;
2712  if (!TriggerEnabled(estate, relinfo, trigger, LocTriggerData.tg_event,
2713  NULL, NULL, NULL))
2714  continue;
2715 
2716  LocTriggerData.tg_trigger = trigger;
2717  newtuple = ExecCallTriggerFunc(&LocTriggerData,
2718  i,
2719  relinfo->ri_TrigFunctions,
2720  relinfo->ri_TrigInstrument,
2721  GetPerTupleMemoryContext(estate));
2722 
2723  if (newtuple)
2724  ereport(ERROR,
2725  (errcode(ERRCODE_E_R_I_E_TRIGGER_PROTOCOL_VIOLATED),
2726  errmsg("BEFORE STATEMENT trigger cannot return a value")));
2727  }
2728 }
2729 
2730 void
2732  TransitionCaptureState *transition_capture)
2733 {
2734  TriggerDesc *trigdesc = relinfo->ri_TrigDesc;
2735 
2736  if (trigdesc && trigdesc->trig_delete_after_statement)
2738  false, NULL, NULL, NIL, NULL, transition_capture);
2739 }
2740 
2741 /*
2742  * Execute BEFORE ROW DELETE triggers.
2743  *
2744  * True indicates caller can proceed with the delete. False indicates caller
2745  * need to suppress the delete and additionally if requested, we need to pass
2746  * back the concurrently updated tuple if any.
2747  */
2748 bool
2750  ResultRelInfo *relinfo,
2751  ItemPointer tupleid,
2752  HeapTuple fdw_trigtuple,
2753  TupleTableSlot **epqslot)
2754 {
2755  TupleTableSlot *slot = ExecGetTriggerOldSlot(estate, relinfo);
2756  TriggerDesc *trigdesc = relinfo->ri_TrigDesc;
2757  bool result = true;
2758  TriggerData LocTriggerData;
2759  HeapTuple trigtuple;
2760  bool should_free = false;
2761  int i;
2762 
2763  Assert(HeapTupleIsValid(fdw_trigtuple) ^ ItemPointerIsValid(tupleid));
2764  if (fdw_trigtuple == NULL)
2765  {
2766  TupleTableSlot *epqslot_candidate = NULL;
2767 
2768  if (!GetTupleForTrigger(estate, epqstate, relinfo, tupleid,
2769  LockTupleExclusive, slot, &epqslot_candidate))
2770  return false;
2771 
2772  /*
2773  * If the tuple was concurrently updated and the caller of this
2774  * function requested for the updated tuple, skip the trigger
2775  * execution.
2776  */
2777  if (epqslot_candidate != NULL && epqslot != NULL)
2778  {
2779  *epqslot = epqslot_candidate;
2780  return false;
2781  }
2782 
2783  trigtuple = ExecFetchSlotHeapTuple(slot, true, &should_free);
2784 
2785  }
2786  else
2787  {
2788  trigtuple = fdw_trigtuple;
2789  ExecForceStoreHeapTuple(trigtuple, slot, false);
2790  }
2791 
2792  LocTriggerData.type = T_TriggerData;
2793  LocTriggerData.tg_event = TRIGGER_EVENT_DELETE |
2796  LocTriggerData.tg_relation = relinfo->ri_RelationDesc;
2797  LocTriggerData.tg_trigtuple = NULL;
2798  LocTriggerData.tg_newtuple = NULL;
2799  LocTriggerData.tg_trigslot = NULL;
2800  LocTriggerData.tg_newslot = NULL;
2801  LocTriggerData.tg_oldtable = NULL;
2802  LocTriggerData.tg_newtable = NULL;
2803  for (i = 0; i < trigdesc->numtriggers; i++)
2804  {
2805  HeapTuple newtuple;
2806  Trigger *trigger = &trigdesc->triggers[i];
2807 
2808  if (!TRIGGER_TYPE_MATCHES(trigger->tgtype,
2809  TRIGGER_TYPE_ROW,
2810  TRIGGER_TYPE_BEFORE,
2811  TRIGGER_TYPE_DELETE))
2812  continue;
2813  if (!TriggerEnabled(estate, relinfo, trigger, LocTriggerData.tg_event,
2814  NULL, slot, NULL))
2815  continue;
2816 
2817  LocTriggerData.tg_trigslot = slot;
2818  LocTriggerData.tg_trigtuple = trigtuple;
2819  LocTriggerData.tg_trigger = trigger;
2820  newtuple = ExecCallTriggerFunc(&LocTriggerData,
2821  i,
2822  relinfo->ri_TrigFunctions,
2823  relinfo->ri_TrigInstrument,
2824  GetPerTupleMemoryContext(estate));
2825  if (newtuple == NULL)
2826  {
2827  result = false; /* tell caller to suppress delete */
2828  break;
2829  }
2830  if (newtuple != trigtuple)
2831  heap_freetuple(newtuple);
2832  }
2833  if (should_free)
2834  heap_freetuple(trigtuple);
2835 
2836  return result;
2837 }
2838 
2839 void
2841  ItemPointer tupleid,
2842  HeapTuple fdw_trigtuple,
2843  TransitionCaptureState *transition_capture)
2844 {
2845  TriggerDesc *trigdesc = relinfo->ri_TrigDesc;
2846  TupleTableSlot *slot = ExecGetTriggerOldSlot(estate, relinfo);
2847 
2848  if ((trigdesc && trigdesc->trig_delete_after_row) ||
2849  (transition_capture && transition_capture->tcs_delete_old_table))
2850  {
2851  Assert(HeapTupleIsValid(fdw_trigtuple) ^ ItemPointerIsValid(tupleid));
2852  if (fdw_trigtuple == NULL)
2853  GetTupleForTrigger(estate,
2854  NULL,
2855  relinfo,
2856  tupleid,
2858  slot,
2859  NULL);
2860  else
2861  ExecForceStoreHeapTuple(fdw_trigtuple, slot, false);
2862 
2864  true, slot, NULL, NIL, NULL,
2865  transition_capture);
2866  }
2867 }
2868 
2869 bool
2871  HeapTuple trigtuple)
2872 {
2873  TriggerDesc *trigdesc = relinfo->ri_TrigDesc;
2874  TupleTableSlot *slot = ExecGetTriggerOldSlot(estate, relinfo);
2875  TriggerData LocTriggerData;
2876  int i;
2877 
2878  LocTriggerData.type = T_TriggerData;
2879  LocTriggerData.tg_event = TRIGGER_EVENT_DELETE |
2882  LocTriggerData.tg_relation = relinfo->ri_RelationDesc;
2883  LocTriggerData.tg_trigtuple = NULL;
2884  LocTriggerData.tg_newtuple = NULL;
2885  LocTriggerData.tg_trigslot = NULL;
2886  LocTriggerData.tg_newslot = NULL;
2887  LocTriggerData.tg_oldtable = NULL;
2888  LocTriggerData.tg_newtable = NULL;
2889 
2890  ExecForceStoreHeapTuple(trigtuple, slot, false);
2891 
2892  for (i = 0; i < trigdesc->numtriggers; i++)
2893  {
2894  HeapTuple rettuple;
2895  Trigger *trigger = &trigdesc->triggers[i];
2896 
2897  if (!TRIGGER_TYPE_MATCHES(trigger->tgtype,
2898  TRIGGER_TYPE_ROW,
2899  TRIGGER_TYPE_INSTEAD,
2900  TRIGGER_TYPE_DELETE))
2901  continue;
2902  if (!TriggerEnabled(estate, relinfo, trigger, LocTriggerData.tg_event,
2903  NULL, slot, NULL))
2904  continue;
2905 
2906  LocTriggerData.tg_trigslot = slot;
2907  LocTriggerData.tg_trigtuple = trigtuple;
2908  LocTriggerData.tg_trigger = trigger;
2909  rettuple = ExecCallTriggerFunc(&LocTriggerData,
2910  i,
2911  relinfo->ri_TrigFunctions,
2912  relinfo->ri_TrigInstrument,
2913  GetPerTupleMemoryContext(estate));
2914  if (rettuple == NULL)
2915  return false; /* Delete was suppressed */
2916  if (rettuple != trigtuple)
2917  heap_freetuple(rettuple);
2918  }
2919  return true;
2920 }
2921 
2922 void
2924 {
2925  TriggerDesc *trigdesc;
2926  int i;
2927  TriggerData LocTriggerData;
2928  Bitmapset *updatedCols;
2929 
2930  trigdesc = relinfo->ri_TrigDesc;
2931 
2932  if (trigdesc == NULL)
2933  return;
2934  if (!trigdesc->trig_update_before_statement)
2935  return;
2936 
2937  /* no-op if we already fired BS triggers in this context */
2939  CMD_UPDATE))
2940  return;
2941 
2942  updatedCols = GetAllUpdatedColumns(relinfo, estate);
2943 
2944  LocTriggerData.type = T_TriggerData;
2945  LocTriggerData.tg_event = TRIGGER_EVENT_UPDATE |
2947  LocTriggerData.tg_relation = relinfo->ri_RelationDesc;
2948  LocTriggerData.tg_trigtuple = NULL;
2949  LocTriggerData.tg_newtuple = NULL;
2950  LocTriggerData.tg_trigslot = NULL;
2951  LocTriggerData.tg_newslot = NULL;
2952  LocTriggerData.tg_oldtable = NULL;
2953  LocTriggerData.tg_newtable = NULL;
2954  for (i = 0; i < trigdesc->numtriggers; i++)
2955  {
2956  Trigger *trigger = &trigdesc->triggers[i];
2957  HeapTuple newtuple;
2958 
2959  if (!TRIGGER_TYPE_MATCHES(trigger->tgtype,
2960  TRIGGER_TYPE_STATEMENT,
2961  TRIGGER_TYPE_BEFORE,
2962  TRIGGER_TYPE_UPDATE))
2963  continue;
2964  if (!TriggerEnabled(estate, relinfo, trigger, LocTriggerData.tg_event,
2965  updatedCols, NULL, NULL))
2966  continue;
2967 
2968  LocTriggerData.tg_trigger = trigger;
2969  newtuple = ExecCallTriggerFunc(&LocTriggerData,
2970  i,
2971  relinfo->ri_TrigFunctions,
2972  relinfo->ri_TrigInstrument,
2973  GetPerTupleMemoryContext(estate));
2974 
2975  if (newtuple)
2976  ereport(ERROR,
2977  (errcode(ERRCODE_E_R_I_E_TRIGGER_PROTOCOL_VIOLATED),
2978  errmsg("BEFORE STATEMENT trigger cannot return a value")));
2979  }
2980 }
2981 
2982 void
2984  TransitionCaptureState *transition_capture)
2985 {
2986  TriggerDesc *trigdesc = relinfo->ri_TrigDesc;
2987 
2988  if (trigdesc && trigdesc->trig_update_after_statement)
2990  false, NULL, NULL, NIL,
2991  GetAllUpdatedColumns(relinfo, estate),
2992  transition_capture);
2993 }
2994 
2995 bool
2997  ResultRelInfo *relinfo,
2998  ItemPointer tupleid,
2999  HeapTuple fdw_trigtuple,
3000  TupleTableSlot *newslot)
3001 {
3002  TriggerDesc *trigdesc = relinfo->ri_TrigDesc;
3003  TupleTableSlot *oldslot = ExecGetTriggerOldSlot(estate, relinfo);
3004  HeapTuple newtuple = NULL;
3005  HeapTuple trigtuple;
3006  bool should_free_trig = false;
3007  bool should_free_new = false;
3008  TriggerData LocTriggerData;
3009  int i;
3010  Bitmapset *updatedCols;
3011  LockTupleMode lockmode;
3012 
3013  /* Determine lock mode to use */
3014  lockmode = ExecUpdateLockMode(estate, relinfo);
3015 
3016  Assert(HeapTupleIsValid(fdw_trigtuple) ^ ItemPointerIsValid(tupleid));
3017  if (fdw_trigtuple == NULL)
3018  {
3019  TupleTableSlot *epqslot_candidate = NULL;
3020 
3021  /* get a copy of the on-disk tuple we are planning to update */
3022  if (!GetTupleForTrigger(estate, epqstate, relinfo, tupleid,
3023  lockmode, oldslot, &epqslot_candidate))
3024  return false; /* cancel the update action */
3025 
3026  /*
3027  * In READ COMMITTED isolation level it's possible that target tuple
3028  * was changed due to concurrent update. In that case we have a raw
3029  * subplan output tuple in epqslot_candidate, and need to run it
3030  * through the junk filter to produce an insertable tuple.
3031  *
3032  * Caution: more than likely, the passed-in slot is the same as the
3033  * junkfilter's output slot, so we are clobbering the original value
3034  * of slottuple by doing the filtering. This is OK since neither we
3035  * nor our caller have any more interest in the prior contents of that
3036  * slot.
3037  */
3038  if (epqslot_candidate != NULL)
3039  {
3040  TupleTableSlot *epqslot_clean;
3041 
3042  epqslot_clean = ExecFilterJunk(relinfo->ri_junkFilter, epqslot_candidate);
3043 
3044  if (newslot != epqslot_clean)
3045  ExecCopySlot(newslot, epqslot_clean);
3046  }
3047 
3048  trigtuple = ExecFetchSlotHeapTuple(oldslot, true, &should_free_trig);
3049  }
3050  else
3051  {
3052  ExecForceStoreHeapTuple(fdw_trigtuple, oldslot, false);
3053  trigtuple = fdw_trigtuple;
3054  }
3055 
3056  LocTriggerData.type = T_TriggerData;
3057  LocTriggerData.tg_event = TRIGGER_EVENT_UPDATE |
3060  LocTriggerData.tg_relation = relinfo->ri_RelationDesc;
3061  LocTriggerData.tg_oldtable = NULL;
3062  LocTriggerData.tg_newtable = NULL;
3063  updatedCols = GetAllUpdatedColumns(relinfo, estate);
3064  for (i = 0; i < trigdesc->numtriggers; i++)
3065  {
3066  Trigger *trigger = &trigdesc->triggers[i];
3067  HeapTuple oldtuple;
3068 
3069  if (!TRIGGER_TYPE_MATCHES(trigger->tgtype,
3070  TRIGGER_TYPE_ROW,
3071  TRIGGER_TYPE_BEFORE,
3072  TRIGGER_TYPE_UPDATE))
3073  continue;
3074  if (!TriggerEnabled(estate, relinfo, trigger, LocTriggerData.tg_event,
3075  updatedCols, oldslot, newslot))
3076  continue;
3077 
3078  if (!newtuple)
3079  newtuple = ExecFetchSlotHeapTuple(newslot, true, &should_free_new);
3080 
3081  LocTriggerData.tg_trigslot = oldslot;
3082  LocTriggerData.tg_trigtuple = trigtuple;
3083  LocTriggerData.tg_newtuple = oldtuple = newtuple;
3084  LocTriggerData.tg_newslot = newslot;
3085  LocTriggerData.tg_trigger = trigger;
3086  newtuple = ExecCallTriggerFunc(&LocTriggerData,
3087  i,
3088  relinfo->ri_TrigFunctions,
3089  relinfo->ri_TrigInstrument,
3090  GetPerTupleMemoryContext(estate));
3091 
3092  if (newtuple == NULL)
3093  {
3094  if (should_free_trig)
3095  heap_freetuple(trigtuple);
3096  if (should_free_new)
3097  heap_freetuple(oldtuple);
3098  return false; /* "do nothing" */
3099  }
3100  else if (newtuple != oldtuple)
3101  {
3102  ExecForceStoreHeapTuple(newtuple, newslot, false);
3103 
3104  /*
3105  * If the tuple returned by the trigger / being stored, is the old
3106  * row version, and the heap tuple passed to the trigger was
3107  * allocated locally, materialize the slot. Otherwise we might
3108  * free it while still referenced by the slot.
3109  */
3110  if (should_free_trig && newtuple == trigtuple)
3111  ExecMaterializeSlot(newslot);
3112 
3113  if (should_free_new)
3114  heap_freetuple(oldtuple);
3115 
3116  /* signal tuple should be re-fetched if used */
3117  newtuple = NULL;
3118  }
3119  }
3120  if (should_free_trig)
3121  heap_freetuple(trigtuple);
3122 
3123  return true;
3124 }
3125 
3126 void
3128  ItemPointer tupleid,
3129  HeapTuple fdw_trigtuple,
3130  TupleTableSlot *newslot,
3131  List *recheckIndexes,
3132  TransitionCaptureState *transition_capture)
3133 {
3134  TriggerDesc *trigdesc = relinfo->ri_TrigDesc;
3135  TupleTableSlot *oldslot = ExecGetTriggerOldSlot(estate, relinfo);
3136 
3137  ExecClearTuple(oldslot);
3138 
3139  if ((trigdesc && trigdesc->trig_update_after_row) ||
3140  (transition_capture &&
3141  (transition_capture->tcs_update_old_table ||
3142  transition_capture->tcs_update_new_table)))
3143  {
3144  /*
3145  * Note: if the UPDATE is converted into a DELETE+INSERT as part of
3146  * update-partition-key operation, then this function is also called
3147  * separately for DELETE and INSERT to capture transition table rows.
3148  * In such case, either old tuple or new tuple can be NULL.
3149  */
3150  if (fdw_trigtuple == NULL && ItemPointerIsValid(tupleid))
3151  GetTupleForTrigger(estate,
3152  NULL,
3153  relinfo,
3154  tupleid,
3156  oldslot,
3157  NULL);
3158  else if (fdw_trigtuple != NULL)
3159  ExecForceStoreHeapTuple(fdw_trigtuple, oldslot, false);
3160 
3162  true, oldslot, newslot, recheckIndexes,
3163  GetAllUpdatedColumns(relinfo, estate),
3164  transition_capture);
3165  }
3166 }
3167 
3168 bool
3170  HeapTuple trigtuple, TupleTableSlot *newslot)
3171 {
3172  TriggerDesc *trigdesc = relinfo->ri_TrigDesc;
3173  TupleTableSlot *oldslot = ExecGetTriggerOldSlot(estate, relinfo);
3174  HeapTuple newtuple = NULL;
3175  bool should_free;
3176  TriggerData LocTriggerData;
3177  int i;
3178 
3179  LocTriggerData.type = T_TriggerData;
3180  LocTriggerData.tg_event = TRIGGER_EVENT_UPDATE |
3183  LocTriggerData.tg_relation = relinfo->ri_RelationDesc;
3184  LocTriggerData.tg_oldtable = NULL;
3185  LocTriggerData.tg_newtable = NULL;
3186 
3187  ExecForceStoreHeapTuple(trigtuple, oldslot, false);
3188 
3189  for (i = 0; i < trigdesc->numtriggers; i++)
3190  {
3191  Trigger *trigger = &trigdesc->triggers[i];
3192  HeapTuple oldtuple;
3193 
3194  if (!TRIGGER_TYPE_MATCHES(trigger->tgtype,
3195  TRIGGER_TYPE_ROW,
3196  TRIGGER_TYPE_INSTEAD,
3197  TRIGGER_TYPE_UPDATE))
3198  continue;
3199  if (!TriggerEnabled(estate, relinfo, trigger, LocTriggerData.tg_event,
3200  NULL, oldslot, newslot))
3201  continue;
3202 
3203  if (!newtuple)
3204  newtuple = ExecFetchSlotHeapTuple(newslot, true, &should_free);
3205 
3206  LocTriggerData.tg_trigslot = oldslot;
3207  LocTriggerData.tg_trigtuple = trigtuple;
3208  LocTriggerData.tg_newslot = newslot;
3209  LocTriggerData.tg_newtuple = oldtuple = newtuple;
3210 
3211  LocTriggerData.tg_trigger = trigger;
3212  newtuple = ExecCallTriggerFunc(&LocTriggerData,
3213  i,
3214  relinfo->ri_TrigFunctions,
3215  relinfo->ri_TrigInstrument,
3216  GetPerTupleMemoryContext(estate));
3217  if (newtuple == NULL)
3218  {
3219  return false; /* "do nothing" */
3220  }
3221  else if (newtuple != oldtuple)
3222  {
3223  ExecForceStoreHeapTuple(newtuple, newslot, false);
3224 
3225  if (should_free)
3226  heap_freetuple(oldtuple);
3227 
3228  /* signal tuple should be re-fetched if used */
3229  newtuple = NULL;
3230  }
3231  }
3232 
3233  return true;
3234 }
3235 
3236 void
3238 {
3239  TriggerDesc *trigdesc;
3240  int i;
3241  TriggerData LocTriggerData;
3242 
3243  trigdesc = relinfo->ri_TrigDesc;
3244 
3245  if (trigdesc == NULL)
3246  return;
3247  if (!trigdesc->trig_truncate_before_statement)
3248  return;
3249 
3250  LocTriggerData.type = T_TriggerData;
3251  LocTriggerData.tg_event = TRIGGER_EVENT_TRUNCATE |
3253  LocTriggerData.tg_relation = relinfo->ri_RelationDesc;
3254  LocTriggerData.tg_trigtuple = NULL;
3255  LocTriggerData.tg_newtuple = NULL;
3256  LocTriggerData.tg_trigslot = NULL;
3257  LocTriggerData.tg_newslot = NULL;
3258  LocTriggerData.tg_oldtable = NULL;
3259  LocTriggerData.tg_newtable = NULL;
3260 
3261  for (i = 0; i < trigdesc->numtriggers; i++)
3262  {
3263  Trigger *trigger = &trigdesc->triggers[i];
3264  HeapTuple newtuple;
3265 
3266  if (!TRIGGER_TYPE_MATCHES(trigger->tgtype,
3267  TRIGGER_TYPE_STATEMENT,
3268  TRIGGER_TYPE_BEFORE,
3269  TRIGGER_TYPE_TRUNCATE))
3270  continue;
3271  if (!TriggerEnabled(estate, relinfo, trigger, LocTriggerData.tg_event,
3272  NULL, NULL, NULL))
3273  continue;
3274 
3275  LocTriggerData.tg_trigger = trigger;
3276  newtuple = ExecCallTriggerFunc(&LocTriggerData,
3277  i,
3278  relinfo->ri_TrigFunctions,
3279  relinfo->ri_TrigInstrument,
3280  GetPerTupleMemoryContext(estate));
3281 
3282  if (newtuple)
3283  ereport(ERROR,
3284  (errcode(ERRCODE_E_R_I_E_TRIGGER_PROTOCOL_VIOLATED),
3285  errmsg("BEFORE STATEMENT trigger cannot return a value")));
3286  }
3287 }
3288 
3289 void
3291 {
3292  TriggerDesc *trigdesc = relinfo->ri_TrigDesc;
3293 
3294  if (trigdesc && trigdesc->trig_truncate_after_statement)
3296  false, NULL, NULL, NIL, NULL, NULL);
3297 }
3298 
3299 
3300 static bool
3302  EPQState *epqstate,
3303  ResultRelInfo *relinfo,
3304  ItemPointer tid,
3305  LockTupleMode lockmode,
3306  TupleTableSlot *oldslot,
3307  TupleTableSlot **epqslot)
3308 {
3309  Relation relation = relinfo->ri_RelationDesc;
3310 
3311  if (epqslot != NULL)
3312  {
3313  TM_Result test;
3314  TM_FailureData tmfd;
3315  int lockflags = 0;
3316 
3317  *epqslot = NULL;
3318 
3319  /* caller must pass an epqstate if EvalPlanQual is possible */
3320  Assert(epqstate != NULL);
3321 
3322  /*
3323  * lock tuple for update
3324  */
3326  lockflags |= TUPLE_LOCK_FLAG_FIND_LAST_VERSION;
3327  test = table_tuple_lock(relation, tid, estate->es_snapshot, oldslot,
3328  estate->es_output_cid,
3329  lockmode, LockWaitBlock,
3330  lockflags,
3331  &tmfd);
3332 
3333  switch (test)
3334  {
3335  case TM_SelfModified:
3336 
3337  /*
3338  * The target tuple was already updated or deleted by the
3339  * current command, or by a later command in the current
3340  * transaction. We ignore the tuple in the former case, and
3341  * throw error in the latter case, for the same reasons
3342  * enumerated in ExecUpdate and ExecDelete in
3343  * nodeModifyTable.c.
3344  */
3345  if (tmfd.cmax != estate->es_output_cid)
3346  ereport(ERROR,
3347  (errcode(ERRCODE_TRIGGERED_DATA_CHANGE_VIOLATION),
3348  errmsg("tuple to be updated was already modified by an operation triggered by the current command"),
3349  errhint("Consider using an AFTER trigger instead of a BEFORE trigger to propagate changes to other rows.")));
3350 
3351  /* treat it as deleted; do not process */
3352  return false;
3353 
3354  case TM_Ok:
3355  if (tmfd.traversed)
3356  {
3357  *epqslot = EvalPlanQual(epqstate,
3358  relation,
3359  relinfo->ri_RangeTableIndex,
3360  oldslot);
3361 
3362  /*
3363  * If PlanQual failed for updated tuple - we must not
3364  * process this tuple!
3365  */
3366  if (TupIsNull(*epqslot))
3367  {
3368  *epqslot = NULL;
3369  return false;
3370  }
3371  }
3372  break;
3373 
3374  case TM_Updated:
3376  ereport(ERROR,
3377  (errcode(ERRCODE_T_R_SERIALIZATION_FAILURE),
3378  errmsg("could not serialize access due to concurrent update")));
3379  elog(ERROR, "unexpected table_tuple_lock status: %u", test);
3380  break;
3381 
3382  case TM_Deleted:
3384  ereport(ERROR,
3385  (errcode(ERRCODE_T_R_SERIALIZATION_FAILURE),
3386  errmsg("could not serialize access due to concurrent delete")));
3387  /* tuple was deleted */
3388  return false;
3389 
3390  case TM_Invisible:
3391  elog(ERROR, "attempted to lock invisible tuple");
3392  break;
3393 
3394  default:
3395  elog(ERROR, "unrecognized table_tuple_lock status: %u", test);
3396  return false; /* keep compiler quiet */
3397  }
3398  }
3399  else
3400  {
3401  /*
3402  * We expect the tuple to be present, thus very simple error handling
3403  * suffices.
3404  */
3405  if (!table_tuple_fetch_row_version(relation, tid, SnapshotAny,
3406  oldslot))
3407  elog(ERROR, "failed to fetch tuple for trigger");
3408  }
3409 
3410  return true;
3411 }
3412 
3413 /*
3414  * Is trigger enabled to fire?
3415  */
3416 static bool
3418  Trigger *trigger, TriggerEvent event,
3419  Bitmapset *modifiedCols,
3420  TupleTableSlot *oldslot, TupleTableSlot *newslot)
3421 {
3422  /* Check replication-role-dependent enable state */
3424  {
3425  if (trigger->tgenabled == TRIGGER_FIRES_ON_ORIGIN ||
3426  trigger->tgenabled == TRIGGER_DISABLED)
3427  return false;
3428  }
3429  else /* ORIGIN or LOCAL role */
3430  {
3431  if (trigger->tgenabled == TRIGGER_FIRES_ON_REPLICA ||
3432  trigger->tgenabled == TRIGGER_DISABLED)
3433  return false;
3434  }
3435 
3436  /*
3437  * Check for column-specific trigger (only possible for UPDATE, and in
3438  * fact we *must* ignore tgattr for other event types)
3439  */
3440  if (trigger->tgnattr > 0 && TRIGGER_FIRED_BY_UPDATE(event))
3441  {
3442  int i;
3443  bool modified;
3444 
3445  modified = false;
3446  for (i = 0; i < trigger->tgnattr; i++)
3447  {
3449  modifiedCols))
3450  {
3451  modified = true;
3452  break;
3453  }
3454  }
3455  if (!modified)
3456  return false;
3457  }
3458 
3459  /* Check for WHEN clause */
3460  if (trigger->tgqual)
3461  {
3462  ExprState **predicate;
3463  ExprContext *econtext;
3464  MemoryContext oldContext;
3465  int i;
3466 
3467  Assert(estate != NULL);
3468 
3469  /*
3470  * trigger is an element of relinfo->ri_TrigDesc->triggers[]; find the
3471  * matching element of relinfo->ri_TrigWhenExprs[]
3472  */
3473  i = trigger - relinfo->ri_TrigDesc->triggers;
3474  predicate = &relinfo->ri_TrigWhenExprs[i];
3475 
3476  /*
3477  * If first time through for this WHEN expression, build expression
3478  * nodetrees for it. Keep them in the per-query memory context so
3479  * they'll survive throughout the query.
3480  */
3481  if (*predicate == NULL)
3482  {
3483  Node *tgqual;
3484 
3485  oldContext = MemoryContextSwitchTo(estate->es_query_cxt);
3486  tgqual = stringToNode(trigger->tgqual);
3487  /* Change references to OLD and NEW to INNER_VAR and OUTER_VAR */
3490  /* ExecPrepareQual wants implicit-AND form */
3491  tgqual = (Node *) make_ands_implicit((Expr *) tgqual);
3492  *predicate = ExecPrepareQual((List *) tgqual, estate);
3493  MemoryContextSwitchTo(oldContext);
3494  }
3495 
3496  /*
3497  * We will use the EState's per-tuple context for evaluating WHEN
3498  * expressions (creating it if it's not already there).
3499  */
3500  econtext = GetPerTupleExprContext(estate);
3501 
3502  /*
3503  * Finally evaluate the expression, making the old and/or new tuples
3504  * available as INNER_VAR/OUTER_VAR respectively.
3505  */
3506  econtext->ecxt_innertuple = oldslot;
3507  econtext->ecxt_outertuple = newslot;
3508  if (!ExecQual(*predicate, econtext))
3509  return false;
3510  }
3511 
3512  return true;
3513 }
3514 
3515 
3516 /* ----------
3517  * After-trigger stuff
3518  *
3519  * The AfterTriggersData struct holds data about pending AFTER trigger events
3520  * during the current transaction tree. (BEFORE triggers are fired
3521  * immediately so we don't need any persistent state about them.) The struct
3522  * and most of its subsidiary data are kept in TopTransactionContext; however
3523  * some data that can be discarded sooner appears in the CurTransactionContext
3524  * of the relevant subtransaction. Also, the individual event records are
3525  * kept in a separate sub-context of TopTransactionContext. This is done
3526  * mainly so that it's easy to tell from a memory context dump how much space
3527  * is being eaten by trigger events.
3528  *
3529  * Because the list of pending events can grow large, we go to some
3530  * considerable effort to minimize per-event memory consumption. The event
3531  * records are grouped into chunks and common data for similar events in the
3532  * same chunk is only stored once.
3533  *
3534  * XXX We need to be able to save the per-event data in a file if it grows too
3535  * large.
3536  * ----------
3537  */
3538 
3539 /* Per-trigger SET CONSTRAINT status */
3541 {
3545 
3547 
3548 /*
3549  * SET CONSTRAINT intra-transaction status.
3550  *
3551  * We make this a single palloc'd object so it can be copied and freed easily.
3552  *
3553  * all_isset and all_isdeferred are used to keep track
3554  * of SET CONSTRAINTS ALL {DEFERRED, IMMEDIATE}.
3555  *
3556  * trigstates[] stores per-trigger tgisdeferred settings.
3557  */
3559 {
3562  int numstates; /* number of trigstates[] entries in use */
3563  int numalloc; /* allocated size of trigstates[] */
3564  SetConstraintTriggerData trigstates[FLEXIBLE_ARRAY_MEMBER];
3566 
3568 
3569 
3570 /*
3571  * Per-trigger-event data
3572  *
3573  * The actual per-event data, AfterTriggerEventData, includes DONE/IN_PROGRESS
3574  * status bits and up to two tuple CTIDs. Each event record also has an
3575  * associated AfterTriggerSharedData that is shared across all instances of
3576  * similar events within a "chunk".
3577  *
3578  * For row-level triggers, we arrange not to waste storage on unneeded ctid
3579  * fields. Updates of regular tables use two; inserts and deletes of regular
3580  * tables use one; foreign tables always use zero and save the tuple(s) to a
3581  * tuplestore. AFTER_TRIGGER_FDW_FETCH directs AfterTriggerExecute() to
3582  * retrieve a fresh tuple or pair of tuples from that tuplestore, while
3583  * AFTER_TRIGGER_FDW_REUSE directs it to use the most-recently-retrieved
3584  * tuple(s). This permits storing tuples once regardless of the number of
3585  * row-level triggers on a foreign table.
3586  *
3587  * Note that we need triggers on foreign tables to be fired in exactly the
3588  * order they were queued, so that the tuples come out of the tuplestore in
3589  * the right order. To ensure that, we forbid deferrable (constraint)
3590  * triggers on foreign tables. This also ensures that such triggers do not
3591  * get deferred into outer trigger query levels, meaning that it's okay to
3592  * destroy the tuplestore at the end of the query level.
3593  *
3594  * Statement-level triggers always bear AFTER_TRIGGER_1CTID, though they
3595  * require no ctid field. We lack the flag bit space to neatly represent that
3596  * distinct case, and it seems unlikely to be worth much trouble.
3597  *
3598  * Note: ats_firing_id is initially zero and is set to something else when
3599  * AFTER_TRIGGER_IN_PROGRESS is set. It indicates which trigger firing
3600  * cycle the trigger will be fired in (or was fired in, if DONE is set).
3601  * Although this is mutable state, we can keep it in AfterTriggerSharedData
3602  * because all instances of the same type of event in a given event list will
3603  * be fired at the same time, if they were queued between the same firing
3604  * cycles. So we need only ensure that ats_firing_id is zero when attaching
3605  * a new event to an existing AfterTriggerSharedData record.
3606  */
3608 
3609 #define AFTER_TRIGGER_OFFSET 0x0FFFFFFF /* must be low-order bits */
3610 #define AFTER_TRIGGER_DONE 0x10000000
3611 #define AFTER_TRIGGER_IN_PROGRESS 0x20000000
3612 /* bits describing the size and tuple sources of this event */
3613 #define AFTER_TRIGGER_FDW_REUSE 0x00000000
3614 #define AFTER_TRIGGER_FDW_FETCH 0x80000000
3615 #define AFTER_TRIGGER_1CTID 0x40000000
3616 #define AFTER_TRIGGER_2CTID 0xC0000000
3617 #define AFTER_TRIGGER_TUP_BITS 0xC0000000
3618 
3620 
3622 {
3623  TriggerEvent ats_event; /* event type indicator, see trigger.h */
3624  Oid ats_tgoid; /* the trigger's ID */
3625  Oid ats_relid; /* the relation it's on */
3626  CommandId ats_firing_id; /* ID for firing cycle */
3627  struct AfterTriggersTableData *ats_table; /* transition table access */
3629 
3631 
3633 {
3634  TriggerFlags ate_flags; /* status bits and offset to shared data */
3635  ItemPointerData ate_ctid1; /* inserted, deleted, or old updated tuple */
3636  ItemPointerData ate_ctid2; /* new updated tuple */
3638 
3639 /* AfterTriggerEventData, minus ate_ctid2 */
3641 {
3642  TriggerFlags ate_flags; /* status bits and offset to shared data */
3643  ItemPointerData ate_ctid1; /* inserted, deleted, or old updated tuple */
3645 
3646 /* AfterTriggerEventData, minus ate_ctid1 and ate_ctid2 */
3648 {
3649  TriggerFlags ate_flags; /* status bits and offset to shared data */
3651 
3652 #define SizeofTriggerEvent(evt) \
3653  (((evt)->ate_flags & AFTER_TRIGGER_TUP_BITS) == AFTER_TRIGGER_2CTID ? \
3654  sizeof(AfterTriggerEventData) : \
3655  ((evt)->ate_flags & AFTER_TRIGGER_TUP_BITS) == AFTER_TRIGGER_1CTID ? \
3656  sizeof(AfterTriggerEventDataOneCtid) : \
3657  sizeof(AfterTriggerEventDataZeroCtids))
3658 
3659 #define GetTriggerSharedData(evt) \
3660  ((AfterTriggerShared) ((char *) (evt) + ((evt)->ate_flags & AFTER_TRIGGER_OFFSET)))
3661 
3662 /*
3663  * To avoid palloc overhead, we keep trigger events in arrays in successively-
3664  * larger chunks (a slightly more sophisticated version of an expansible
3665  * array). The space between CHUNK_DATA_START and freeptr is occupied by
3666  * AfterTriggerEventData records; the space between endfree and endptr is
3667  * occupied by AfterTriggerSharedData records.
3668  */
3670 {
3671  struct AfterTriggerEventChunk *next; /* list link */
3672  char *freeptr; /* start of free space in chunk */
3673  char *endfree; /* end of free space in chunk */
3674  char *endptr; /* end of chunk */
3675  /* event data follows here */
3677 
3678 #define CHUNK_DATA_START(cptr) ((char *) (cptr) + MAXALIGN(sizeof(AfterTriggerEventChunk)))
3679 
3680 /* A list of events */
3682 {
3685  char *tailfree; /* freeptr of tail chunk */
3687 
3688 /* Macros to help in iterating over a list of events */
3689 #define for_each_chunk(cptr, evtlist) \
3690  for (cptr = (evtlist).head; cptr != NULL; cptr = cptr->next)
3691 #define for_each_event(eptr, cptr) \
3692  for (eptr = (AfterTriggerEvent) CHUNK_DATA_START(cptr); \
3693  (char *) eptr < (cptr)->freeptr; \
3694  eptr = (AfterTriggerEvent) (((char *) eptr) + SizeofTriggerEvent(eptr)))
3695 /* Use this if no special per-chunk processing is needed */
3696 #define for_each_event_chunk(eptr, cptr, evtlist) \
3697  for_each_chunk(cptr, evtlist) for_each_event(eptr, cptr)
3698 
3699 /* Macros for iterating from a start point that might not be list start */
3700 #define for_each_chunk_from(cptr) \
3701  for (; cptr != NULL; cptr = cptr->next)
3702 #define for_each_event_from(eptr, cptr) \
3703  for (; \
3704  (char *) eptr < (cptr)->freeptr; \
3705  eptr = (AfterTriggerEvent) (((char *) eptr) + SizeofTriggerEvent(eptr)))
3706 
3707 
3708 /*
3709  * All per-transaction data for the AFTER TRIGGERS module.
3710  *
3711  * AfterTriggersData has the following fields:
3712  *
3713  * firing_counter is incremented for each call of afterTriggerInvokeEvents.
3714  * We mark firable events with the current firing cycle's ID so that we can
3715  * tell which ones to work on. This ensures sane behavior if a trigger
3716  * function chooses to do SET CONSTRAINTS: the inner SET CONSTRAINTS will
3717  * only fire those events that weren't already scheduled for firing.
3718  *
3719  * state keeps track of the transaction-local effects of SET CONSTRAINTS.
3720  * This is saved and restored across failed subtransactions.
3721  *
3722  * events is the current list of deferred events. This is global across
3723  * all subtransactions of the current transaction. In a subtransaction
3724  * abort, we know that the events added by the subtransaction are at the
3725  * end of the list, so it is relatively easy to discard them. The event
3726  * list chunks themselves are stored in event_cxt.
3727  *
3728  * query_depth is the current depth of nested AfterTriggerBeginQuery calls
3729  * (-1 when the stack is empty).
3730  *
3731  * query_stack[query_depth] is the per-query-level data, including these fields:
3732  *
3733  * events is a list of AFTER trigger events queued by the current query.
3734  * None of these are valid until the matching AfterTriggerEndQuery call
3735  * occurs. At that point we fire immediate-mode triggers, and append any
3736  * deferred events to the main events list.
3737  *
3738  * fdw_tuplestore is a tuplestore containing the foreign-table tuples
3739  * needed by events queued by the current query. (Note: we use just one
3740  * tuplestore even though more than one foreign table might be involved.
3741  * This is okay because tuplestores don't really care what's in the tuples
3742  * they store; but it's possible that someday it'd break.)
3743  *
3744  * tables is a List of AfterTriggersTableData structs for target tables
3745  * of the current query (see below).
3746  *
3747  * maxquerydepth is just the allocated length of query_stack.
3748  *
3749  * trans_stack holds per-subtransaction data, including these fields:
3750  *
3751  * state is NULL or a pointer to a saved copy of the SET CONSTRAINTS
3752  * state data. Each subtransaction level that modifies that state first
3753  * saves a copy, which we use to restore the state if we abort.
3754  *
3755  * events is a copy of the events head/tail pointers,
3756  * which we use to restore those values during subtransaction abort.
3757  *
3758  * query_depth is the subtransaction-start-time value of query_depth,
3759  * which we similarly use to clean up at subtransaction abort.
3760  *
3761  * firing_counter is the subtransaction-start-time value of firing_counter.
3762  * We use this to recognize which deferred triggers were fired (or marked
3763  * for firing) within an aborted subtransaction.
3764  *
3765  * We use GetCurrentTransactionNestLevel() to determine the correct array
3766  * index in trans_stack. maxtransdepth is the number of allocated entries in
3767  * trans_stack. (By not keeping our own stack pointer, we can avoid trouble
3768  * in cases where errors during subxact abort cause multiple invocations
3769  * of AfterTriggerEndSubXact() at the same nesting depth.)
3770  *
3771  * We create an AfterTriggersTableData struct for each target table of the
3772  * current query, and each operation mode (INSERT/UPDATE/DELETE), that has
3773  * either transition tables or statement-level triggers. This is used to
3774  * hold the relevant transition tables, as well as info tracking whether
3775  * we already queued the statement triggers. (We use that info to prevent
3776  * firing the same statement triggers more than once per statement, or really
3777  * once per transition table set.) These structs, along with the transition
3778  * table tuplestores, live in the (sub)transaction's CurTransactionContext.
3779  * That's sufficient lifespan because we don't allow transition tables to be
3780  * used by deferrable triggers, so they only need to survive until
3781  * AfterTriggerEndQuery.
3782  */
3786 
3787 typedef struct AfterTriggersData
3788 {
3789  CommandId firing_counter; /* next firing ID to assign */
3790  SetConstraintState state; /* the active S C state */
3791  AfterTriggerEventList events; /* deferred-event list */
3792  MemoryContext event_cxt; /* memory context for events, if any */
3793 
3794  /* per-query-level data: */
3795  AfterTriggersQueryData *query_stack; /* array of structs shown below */
3796  int query_depth; /* current index in above array */
3797  int maxquerydepth; /* allocated len of above array */
3798 
3799  /* per-subtransaction-level data: */
3800  AfterTriggersTransData *trans_stack; /* array of structs shown below */
3801  int maxtransdepth; /* allocated len of above array */
3803 
3805 {
3806  AfterTriggerEventList events; /* events pending from this query */
3807  Tuplestorestate *fdw_tuplestore; /* foreign tuples for said events */
3808  List *tables; /* list of AfterTriggersTableData, see below */
3809 };
3810 
3812 {
3813  /* these fields are just for resetting at subtrans abort: */
3814  SetConstraintState state; /* saved S C state, or NULL if not yet saved */
3815  AfterTriggerEventList events; /* saved list pointer */
3816  int query_depth; /* saved query_depth */
3817  CommandId firing_counter; /* saved firing_counter */
3818 };
3819 
3821 {
3822  /* relid + cmdType form the lookup key for these structs: */
3823  Oid relid; /* target table's OID */
3824  CmdType cmdType; /* event type, CMD_INSERT/UPDATE/DELETE */
3825  bool closed; /* true when no longer OK to add tuples */
3826  bool before_trig_done; /* did we already queue BS triggers? */
3827  bool after_trig_done; /* did we already queue AS triggers? */
3828  AfterTriggerEventList after_trig_events; /* if so, saved list pointer */
3829  Tuplestorestate *old_tuplestore; /* "old" transition table, if any */
3830  Tuplestorestate *new_tuplestore; /* "new" transition table, if any */
3831  TupleTableSlot *storeslot; /* for converting to tuplestore's format */
3832 };
3833 
3835 
3836 static void AfterTriggerExecute(EState *estate,
3837  AfterTriggerEvent event,
3838  ResultRelInfo *relInfo,
3839  TriggerDesc *trigdesc,
3840  FmgrInfo *finfo,
3841  Instrumentation *instr,
3842  MemoryContext per_tuple_context,
3843  TupleTableSlot *trig_tuple_slot1,
3844  TupleTableSlot *trig_tuple_slot2);
3846  CmdType cmdType);
3848 static SetConstraintState SetConstraintStateCreate(int numalloc);
3851  Oid tgoid, bool tgisdeferred);
3852 static void cancel_prior_stmt_triggers(Oid relid, CmdType cmdType, int tgevent);
3853 
3854 
3855 /*
3856  * Get the FDW tuplestore for the current trigger query level, creating it
3857  * if necessary.
3858  */
3859 static Tuplestorestate *
3861 {
3862  Tuplestorestate *ret;
3863 
3864  ret = afterTriggers.query_stack[afterTriggers.query_depth].fdw_tuplestore;
3865  if (ret == NULL)
3866  {
3867  MemoryContext oldcxt;
3868  ResourceOwner saveResourceOwner;
3869 
3870  /*
3871  * Make the tuplestore valid until end of subtransaction. We really
3872  * only need it until AfterTriggerEndQuery().
3873  */
3875  saveResourceOwner = CurrentResourceOwner;
3877 
3878  ret = tuplestore_begin_heap(false, false, work_mem);
3879 
3880  CurrentResourceOwner = saveResourceOwner;
3881  MemoryContextSwitchTo(oldcxt);
3882 
3883  afterTriggers.query_stack[afterTriggers.query_depth].fdw_tuplestore = ret;
3884  }
3885 
3886  return ret;
3887 }
3888 
3889 /* ----------
3890  * afterTriggerCheckState()
3891  *
3892  * Returns true if the trigger event is actually in state DEFERRED.
3893  * ----------
3894  */
3895 static bool
3896 afterTriggerCheckState(AfterTriggerShared evtshared)
3897 {
3898  Oid tgoid = evtshared->ats_tgoid;
3899  SetConstraintState state = afterTriggers.state;
3900  int i;
3901 
3902  /*
3903  * For not-deferrable triggers (i.e. normal AFTER ROW triggers and
3904  * constraints declared NOT DEFERRABLE), the state is always false.
3905  */
3906  if ((evtshared->ats_event & AFTER_TRIGGER_DEFERRABLE) == 0)
3907  return false;
3908 
3909  /*
3910  * If constraint state exists, SET CONSTRAINTS might have been executed
3911  * either for this trigger or for all triggers.
3912  */
3913  if (state != NULL)
3914  {
3915  /* Check for SET CONSTRAINTS for this specific trigger. */
3916  for (i = 0; i < state->numstates; i++)
3917  {
3918  if (state->trigstates[i].sct_tgoid == tgoid)
3919  return state->trigstates[i].sct_tgisdeferred;
3920  }
3921 
3922  /* Check for SET CONSTRAINTS ALL. */
3923  if (state->all_isset)
3924  return state->all_isdeferred;
3925  }
3926 
3927  /*
3928  * Otherwise return the default state for the trigger.
3929  */
3930  return ((evtshared->ats_event & AFTER_TRIGGER_INITDEFERRED) != 0);
3931 }
3932 
3933 
3934 /* ----------
3935  * afterTriggerAddEvent()
3936  *
3937  * Add a new trigger event to the specified queue.
3938  * The passed-in event data is copied.
3939  * ----------
3940  */
3941 static void
3943  AfterTriggerEvent event, AfterTriggerShared evtshared)
3944 {
3945  Size eventsize = SizeofTriggerEvent(event);
3946  Size needed = eventsize + sizeof(AfterTriggerSharedData);
3947  AfterTriggerEventChunk *chunk;
3948  AfterTriggerShared newshared;
3949  AfterTriggerEvent newevent;
3950 
3951  /*
3952  * If empty list or not enough room in the tail chunk, make a new chunk.
3953  * We assume here that a new shared record will always be needed.
3954  */
3955  chunk = events->tail;
3956  if (chunk == NULL ||
3957  chunk->endfree - chunk->freeptr < needed)
3958  {
3959  Size chunksize;
3960 
3961  /* Create event context if we didn't already */
3962  if (afterTriggers.event_cxt == NULL)
3963  afterTriggers.event_cxt =
3965  "AfterTriggerEvents",
3967 
3968  /*
3969  * Chunk size starts at 1KB and is allowed to increase up to 1MB.
3970  * These numbers are fairly arbitrary, though there is a hard limit at
3971  * AFTER_TRIGGER_OFFSET; else we couldn't link event records to their
3972  * shared records using the available space in ate_flags. Another
3973  * constraint is that if the chunk size gets too huge, the search loop
3974  * below would get slow given a (not too common) usage pattern with
3975  * many distinct event types in a chunk. Therefore, we double the
3976  * preceding chunk size only if there weren't too many shared records
3977  * in the preceding chunk; otherwise we halve it. This gives us some
3978  * ability to adapt to the actual usage pattern of the current query
3979  * while still having large chunk sizes in typical usage. All chunk
3980  * sizes used should be MAXALIGN multiples, to ensure that the shared
3981  * records will be aligned safely.
3982  */
3983 #define MIN_CHUNK_SIZE 1024
3984 #define MAX_CHUNK_SIZE (1024*1024)
3985 
3986 #if MAX_CHUNK_SIZE > (AFTER_TRIGGER_OFFSET+1)
3987 #error MAX_CHUNK_SIZE must not exceed AFTER_TRIGGER_OFFSET
3988 #endif
3989 
3990  if (chunk == NULL)
3991  chunksize = MIN_CHUNK_SIZE;
3992  else
3993  {
3994  /* preceding chunk size... */
3995  chunksize = chunk->endptr - (char *) chunk;
3996  /* check number of shared records in preceding chunk */
3997  if ((chunk->endptr - chunk->endfree) <=
3998  (100 * sizeof(AfterTriggerSharedData)))
3999  chunksize *= 2; /* okay, double it */
4000  else
4001  chunksize /= 2; /* too many shared records */
4002  chunksize = Min(chunksize, MAX_CHUNK_SIZE);
4003  }
4004  chunk = MemoryContextAlloc(afterTriggers.event_cxt, chunksize);
4005  chunk->next = NULL;
4006  chunk->freeptr = CHUNK_DATA_START(chunk);
4007  chunk->endptr = chunk->endfree = (char *) chunk + chunksize;
4008  Assert(chunk->endfree - chunk->freeptr >= needed);
4009 
4010  if (events->head == NULL)
4011  events->head = chunk;
4012  else
4013  events->tail->next = chunk;
4014  events->tail = chunk;
4015  /* events->tailfree is now out of sync, but we'll fix it below */
4016  }
4017 
4018  /*
4019  * Try to locate a matching shared-data record already in the chunk. If
4020  * none, make a new one.
4021  */
4022  for (newshared = ((AfterTriggerShared) chunk->endptr) - 1;
4023  (char *) newshared >= chunk->endfree;
4024  newshared--)
4025  {
4026  if (newshared->ats_tgoid == evtshared->ats_tgoid &&
4027  newshared->ats_relid == evtshared->ats_relid &&
4028  newshared->ats_event == evtshared->ats_event &&
4029  newshared->ats_table == evtshared->ats_table &&
4030  newshared->ats_firing_id == 0)
4031  break;
4032  }
4033  if ((char *) newshared < chunk->endfree)
4034  {
4035  *newshared = *evtshared;
4036  newshared->ats_firing_id = 0; /* just to be sure */
4037  chunk->endfree = (char *) newshared;
4038  }
4039 
4040  /* Insert the data */
4041  newevent = (AfterTriggerEvent) chunk->freeptr;
4042  memcpy(newevent, event, eventsize);
4043  /* ... and link the new event to its shared record */
4044  newevent->ate_flags &= ~AFTER_TRIGGER_OFFSET;
4045  newevent->ate_flags |= (char *) newshared - (char *) newevent;
4046 
4047  chunk->freeptr += eventsize;
4048  events->tailfree = chunk->freeptr;
4049 }
4050 
4051 /* ----------
4052  * afterTriggerFreeEventList()
4053  *
4054  * Free all the event storage in the given list.
4055  * ----------
4056  */
4057 static void
4059 {
4060  AfterTriggerEventChunk *chunk;
4061 
4062  while ((chunk = events->head) != NULL)
4063  {
4064  events->head = chunk->next;
4065  pfree(chunk);
4066  }
4067  events->tail = NULL;
4068  events->tailfree = NULL;
4069 }
4070 
4071 /* ----------
4072  * afterTriggerRestoreEventList()
4073  *
4074  * Restore an event list to its prior length, removing all the events
4075  * added since it had the value old_events.
4076  * ----------
4077  */
4078 static void
4080  const AfterTriggerEventList *old_events)
4081 {
4082  AfterTriggerEventChunk *chunk;
4083  AfterTriggerEventChunk *next_chunk;
4084 
4085  if (old_events->tail == NULL)
4086  {
4087  /* restoring to a completely empty state, so free everything */
4088  afterTriggerFreeEventList(events);
4089  }
4090  else
4091  {
4092  *events = *old_events;
4093  /* free any chunks after the last one we want to keep */
4094  for (chunk = events->tail->next; chunk != NULL; chunk = next_chunk)
4095  {
4096  next_chunk = chunk->next;
4097  pfree(chunk);
4098  }
4099  /* and clean up the tail chunk to be the right length */
4100  events->tail->next = NULL;
4101  events->tail->freeptr = events->tailfree;
4102 
4103  /*
4104  * We don't make any effort to remove now-unused shared data records.
4105  * They might still be useful, anyway.
4106  */
4107  }
4108 }
4109 
4110 /* ----------
4111  * afterTriggerDeleteHeadEventChunk()
4112  *
4113  * Remove the first chunk of events from the query level's event list.
4114  * Keep any event list pointers elsewhere in the query level's data
4115  * structures in sync.
4116  * ----------
4117  */
4118 static void
4120 {
4121  AfterTriggerEventChunk *target = qs->events.head;
4122  ListCell *lc;
4123 
4124  Assert(target && target->next);
4125 
4126  /*
4127  * First, update any pointers in the per-table data, so that they won't be
4128  * dangling. Resetting obsoleted pointers to NULL will make
4129  * cancel_prior_stmt_triggers start from the list head, which is fine.
4130  */
4131  foreach(lc, qs->tables)
4132  {
4134 
4135  if (table->after_trig_done &&
4136  table->after_trig_events.tail == target)
4137  {
4138  table->after_trig_events.head = NULL;
4139  table->after_trig_events.tail = NULL;
4140  table->after_trig_events.tailfree = NULL;
4141  }
4142  }
4143 
4144  /* Now we can flush the head chunk */
4145  qs->events.head = target->next;
4146  pfree(target);
4147 }
4148 
4149 
4150 /* ----------
4151  * AfterTriggerExecute()
4152  *
4153  * Fetch the required tuples back from the heap and fire one
4154  * single trigger function.
4155  *
4156  * Frequently, this will be fired many times in a row for triggers of
4157  * a single relation. Therefore, we cache the open relation and provide
4158  * fmgr lookup cache space at the caller level. (For triggers fired at
4159  * the end of a query, we can even piggyback on the executor's state.)
4160  *
4161  * event: event currently being fired.
4162  * rel: open relation for event.
4163  * trigdesc: working copy of rel's trigger info.
4164  * finfo: array of fmgr lookup cache entries (one per trigger in trigdesc).
4165  * instr: array of EXPLAIN ANALYZE instrumentation nodes (one per trigger),
4166  * or NULL if no instrumentation is wanted.
4167  * per_tuple_context: memory context to call trigger function in.
4168  * trig_tuple_slot1: scratch slot for tg_trigtuple (foreign tables only)
4169  * trig_tuple_slot2: scratch slot for tg_newtuple (foreign tables only)
4170  * ----------
4171  */
4172 static void
4174  AfterTriggerEvent event,
4175  ResultRelInfo *relInfo,
4176  TriggerDesc *trigdesc,
4177  FmgrInfo *finfo, Instrumentation *instr,
4178  MemoryContext per_tuple_context,
4179  TupleTableSlot *trig_tuple_slot1,
4180  TupleTableSlot *trig_tuple_slot2)
4181 {
4182  Relation rel = relInfo->ri_RelationDesc;
4183  AfterTriggerShared evtshared = GetTriggerSharedData(event);
4184  Oid tgoid = evtshared->ats_tgoid;
4185  TriggerData LocTriggerData;
4186  HeapTuple rettuple;
4187  int tgindx;
4188  bool should_free_trig = false;
4189  bool should_free_new = false;
4190 
4191  /*
4192  * Locate trigger in trigdesc.
4193  */
4194  LocTriggerData.tg_trigger = NULL;
4195  LocTriggerData.tg_trigslot = NULL;
4196  LocTriggerData.tg_newslot = NULL;
4197 
4198  for (tgindx = 0; tgindx < trigdesc->numtriggers; tgindx++)
4199  {
4200  if (trigdesc->triggers[tgindx].tgoid == tgoid)
4201  {
4202  LocTriggerData.tg_trigger = &(trigdesc->triggers[tgindx]);
4203  break;
4204  }
4205  }
4206  if (LocTriggerData.tg_trigger == NULL)
4207  elog(ERROR, "could not find trigger %u", tgoid);
4208 
4209  /*
4210  * If doing EXPLAIN ANALYZE, start charging time to this trigger. We want
4211  * to include time spent re-fetching tuples in the trigger cost.
4212  */
4213  if (instr)
4214  InstrStartNode(instr + tgindx);
4215 
4216  /*
4217  * Fetch the required tuple(s).
4218  */
4219  switch (event->ate_flags & AFTER_TRIGGER_TUP_BITS)
4220  {
4222  {
4223  Tuplestorestate *fdw_tuplestore = GetCurrentFDWTuplestore();
4224 
4225  if (!tuplestore_gettupleslot(fdw_tuplestore, true, false,
4226  trig_tuple_slot1))
4227  elog(ERROR, "failed to fetch tuple1 for AFTER trigger");
4228 
4229  if ((evtshared->ats_event & TRIGGER_EVENT_OPMASK) ==
4231  !tuplestore_gettupleslot(fdw_tuplestore, true, false,
4232  trig_tuple_slot2))
4233  elog(ERROR, "failed to fetch tuple2 for AFTER trigger");
4234  }
4235  /* fall through */
4237 
4238  /*
4239  * Store tuple in the slot so that tg_trigtuple does not reference
4240  * tuplestore memory. (It is formally possible for the trigger
4241  * function to queue trigger events that add to the same
4242  * tuplestore, which can push other tuples out of memory.) The
4243  * distinction is academic, because we start with a minimal tuple
4244  * that is stored as a heap tuple, constructed in different memory
4245  * context, in the slot anyway.
4246  */
4247  LocTriggerData.tg_trigslot = trig_tuple_slot1;
4248  LocTriggerData.tg_trigtuple =
4249  ExecFetchSlotHeapTuple(trig_tuple_slot1, true, &should_free_trig);
4250 
4251  if ((evtshared->ats_event & TRIGGER_EVENT_OPMASK) ==
4253  {
4254  LocTriggerData.tg_newslot = trig_tuple_slot2;
4255  LocTriggerData.tg_newtuple =
4256  ExecFetchSlotHeapTuple(trig_tuple_slot2, true, &should_free_new);
4257  }
4258  else
4259  {
4260  LocTriggerData.tg_newtuple = NULL;
4261  }
4262  break;
4263 
4264  default:
4265  if (ItemPointerIsValid(&(event->ate_ctid1)))
4266  {
4267  LocTriggerData.tg_trigslot = ExecGetTriggerOldSlot(estate, relInfo);
4268 
4269  if (!table_tuple_fetch_row_version(rel, &(event->ate_ctid1),
4270  SnapshotAny,
4271  LocTriggerData.tg_trigslot))
4272  elog(ERROR, "failed to fetch tuple1 for AFTER trigger");
4273  LocTriggerData.tg_trigtuple =
4274  ExecFetchSlotHeapTuple(LocTriggerData.tg_trigslot, false, &should_free_trig);
4275  }
4276  else
4277  {
4278  LocTriggerData.tg_trigtuple = NULL;
4279  }
4280 
4281  /* don't touch ctid2 if not there */
4282  if ((event->ate_flags & AFTER_TRIGGER_TUP_BITS) ==
4284  ItemPointerIsValid(&(event->ate_ctid2)))
4285  {
4286  LocTriggerData.tg_newslot = ExecGetTriggerNewSlot(estate, relInfo);
4287 
4288  if (!table_tuple_fetch_row_version(rel, &(event->ate_ctid2),
4289  SnapshotAny,
4290  LocTriggerData.tg_newslot))
4291  elog(ERROR, "failed to fetch tuple2 for AFTER trigger");
4292  LocTriggerData.tg_newtuple =
4293  ExecFetchSlotHeapTuple(LocTriggerData.tg_newslot, false, &should_free_new);
4294  }
4295  else
4296  {
4297  LocTriggerData.tg_newtuple = NULL;
4298  }
4299  }
4300 
4301  /*
4302  * Set up the tuplestore information to let the trigger have access to
4303  * transition tables. When we first make a transition table available to
4304  * a trigger, mark it "closed" so that it cannot change anymore. If any
4305  * additional events of the same type get queued in the current trigger
4306  * query level, they'll go into new transition tables.
4307  */
4308  LocTriggerData.tg_oldtable = LocTriggerData.tg_newtable = NULL;
4309  if (evtshared->ats_table)
4310  {
4311  if (LocTriggerData.tg_trigger->tgoldtable)
4312  {
4313  LocTriggerData.tg_oldtable = evtshared->ats_table->old_tuplestore;
4314  evtshared->ats_table->closed = true;
4315  }
4316 
4317  if (LocTriggerData.tg_trigger->tgnewtable)
4318  {
4319  LocTriggerData.tg_newtable = evtshared->ats_table->new_tuplestore;
4320  evtshared->ats_table->closed = true;
4321  }
4322  }
4323 
4324  /*
4325  * Setup the remaining trigger information
4326  */
4327  LocTriggerData.type = T_TriggerData;
4328  LocTriggerData.tg_event =
4330  LocTriggerData.tg_relation = rel;
4331 
4332  MemoryContextReset(per_tuple_context);
4333 
4334  /*
4335  * Call the trigger and throw away any possibly returned updated tuple.
4336  * (Don't let ExecCallTriggerFunc measure EXPLAIN time.)
4337  */
4338  rettuple = ExecCallTriggerFunc(&LocTriggerData,
4339  tgindx,
4340  finfo,
4341  NULL,
4342  per_tuple_context);
4343  if (rettuple != NULL &&
4344  rettuple != LocTriggerData.tg_trigtuple &&
4345  rettuple != LocTriggerData.tg_newtuple)
4346  heap_freetuple(rettuple);
4347 
4348  /*
4349  * Release resources
4350  */
4351  if (should_free_trig)
4352  heap_freetuple(LocTriggerData.tg_trigtuple);
4353  if (should_free_new)
4354  heap_freetuple(LocTriggerData.tg_newtuple);
4355 
4356  /* don't clear slots' contents if foreign table */
4357  if (trig_tuple_slot1 == NULL)
4358  {
4359  if (LocTriggerData.tg_trigslot)
4360  ExecClearTuple(LocTriggerData.tg_trigslot);
4361  if (LocTriggerData.tg_newslot)
4362  ExecClearTuple(LocTriggerData.tg_newslot);
4363  }
4364 
4365  /*
4366  * If doing EXPLAIN ANALYZE, stop charging time to this trigger, and count
4367  * one "tuple returned" (really the number of firings).
4368  */
4369  if (instr)
4370  InstrStopNode(instr + tgindx, 1);
4371 }
4372 
4373 
4374 /*
4375  * afterTriggerMarkEvents()
4376  *
4377  * Scan the given event list for not yet invoked events. Mark the ones
4378  * that can be invoked now with the current firing ID.
4379  *
4380  * If move_list isn't NULL, events that are not to be invoked now are
4381  * transferred to move_list.
4382  *
4383  * When immediate_only is true, do not invoke currently-deferred triggers.
4384  * (This will be false only at main transaction exit.)
4385  *
4386  * Returns true if any invokable events were found.
4387  */
4388 static bool
4390  AfterTriggerEventList *move_list,
4391  bool immediate_only)
4392 {
4393  bool found = false;
4394  AfterTriggerEvent event;
4395  AfterTriggerEventChunk *chunk;
4396 
4397  for_each_event_chunk(event, chunk, *events)
4398  {
4399  AfterTriggerShared evtshared = GetTriggerSharedData(event);
4400  bool defer_it = false;
4401 
4402  if (!(event->ate_flags &
4404  {
4405  /*
4406  * This trigger hasn't been called or scheduled yet. Check if we
4407  * should call it now.
4408  */
4409  if (immediate_only && afterTriggerCheckState(evtshared))
4410  {
4411  defer_it = true;
4412  }
4413  else
4414  {
4415  /*
4416  * Mark it as to be fired in this firing cycle.
4417  */
4418  evtshared->ats_firing_id = afterTriggers.firing_counter;
4419  event->ate_flags |= AFTER_TRIGGER_IN_PROGRESS;
4420  found = true;
4421  }
4422  }
4423 
4424  /*
4425  * If it's deferred, move it to move_list, if requested.
4426  */
4427  if (defer_it && move_list != NULL)
4428  {
4429  /* add it to move_list */
4430  afterTriggerAddEvent(move_list, event, evtshared);
4431  /* mark original copy "done" so we don't do it again */
4432  event->ate_flags |= AFTER_TRIGGER_DONE;
4433  }
4434  }
4435 
4436  return found;
4437 }
4438 
4439 /*
4440  * afterTriggerInvokeEvents()
4441  *
4442  * Scan the given event list for events that are marked as to be fired
4443  * in the current firing cycle, and fire them.
4444  *
4445  * If estate isn't NULL, we use its result relation info to avoid repeated
4446  * openings and closing of trigger target relations. If it is NULL, we
4447  * make one locally to cache the info in case there are multiple trigger
4448  * events per rel.
4449  *
4450  * When delete_ok is true, it's safe to delete fully-processed events.
4451  * (We are not very tense about that: we simply reset a chunk to be empty
4452  * if all its events got fired. The objective here is just to avoid useless
4453  * rescanning of events when a trigger queues new events during transaction
4454  * end, so it's not necessary to worry much about the case where only
4455  * some events are fired.)
4456  *
4457  * Returns true if no unfired events remain in the list (this allows us
4458  * to avoid repeating afterTriggerMarkEvents).
4459  */
4460 static bool
4462  CommandId firing_id,
4463  EState *estate,
4464  bool delete_ok)
4465 {
4466  bool all_fired = true;
4467  AfterTriggerEventChunk *chunk;
4468  MemoryContext per_tuple_context;
4469  bool local_estate = false;
4470  ResultRelInfo *rInfo = NULL;
4471  Relation rel = NULL;
4472  TriggerDesc *trigdesc = NULL;
4473  FmgrInfo *finfo = NULL;
4474  Instrumentation *instr = NULL;
4475  TupleTableSlot *slot1 = NULL,
4476  *slot2 = NULL;
4477 
4478  /* Make a local EState if need be */
4479  if (estate == NULL)
4480  {
4481  estate = CreateExecutorState();
4482  local_estate = true;
4483  }
4484 
4485  /* Make a per-tuple memory context for trigger function calls */
4486  per_tuple_context =
4488  "AfterTriggerTupleContext",
4490 
4491  for_each_chunk(chunk, *events)
4492  {
4493  AfterTriggerEvent event;
4494  bool all_fired_in_chunk = true;
4495 
4496  for_each_event(event, chunk)
4497  {
4498  AfterTriggerShared evtshared = GetTriggerSharedData(event);
4499 
4500  /*
4501  * Is it one for me to fire?
4502  */
4503  if ((event->ate_flags & AFTER_TRIGGER_IN_PROGRESS) &&
4504  evtshared->ats_firing_id == firing_id)
4505  {
4506  /*
4507  * So let's fire it... but first, find the correct relation if
4508  * this is not the same relation as before.
4509  */
4510  if (rel == NULL || RelationGetRelid(rel) != evtshared->ats_relid)
4511  {
4512  rInfo = ExecGetTriggerResultRel(estate, evtshared->ats_relid);
4513  rel = rInfo->ri_RelationDesc;
4514  trigdesc = rInfo->ri_TrigDesc;
4515  finfo = rInfo->ri_TrigFunctions;
4516  instr = rInfo->ri_TrigInstrument;
4517  if (slot1 != NULL)
4518  {
4521  slot1 = slot2 = NULL;
4522  }
4523  if (rel->rd_rel->relkind == RELKIND_FOREIGN_TABLE)
4524  {
4525  slot1 = MakeSingleTupleTableSlot(rel->rd_att,
4527  slot2 = MakeSingleTupleTableSlot(rel->rd_att,
4529  }
4530  if (trigdesc == NULL) /* should not happen */
4531  elog(ERROR, "relation %u has no triggers",
4532  evtshared->ats_relid);
4533  }
4534 
4535  /*
4536  * Fire it. Note that the AFTER_TRIGGER_IN_PROGRESS flag is
4537  * still set, so recursive examinations of the event list
4538  * won't try to re-fire it.
4539  */
4540  AfterTriggerExecute(estate, event, rInfo, trigdesc, finfo, instr,
4541  per_tuple_context, slot1, slot2);
4542 
4543  /*
4544  * Mark the event as done.
4545  */
4546  event->ate_flags &= ~AFTER_TRIGGER_IN_PROGRESS;
4547  event->ate_flags |= AFTER_TRIGGER_DONE;
4548  }
4549  else if (!(event->ate_flags & AFTER_TRIGGER_DONE))
4550  {
4551  /* something remains to be done */
4552  all_fired = all_fired_in_chunk = false;
4553  }
4554  }
4555 
4556  /* Clear the chunk if delete_ok and nothing left of interest */
4557  if (delete_ok && all_fired_in_chunk)
4558  {
4559  chunk->freeptr = CHUNK_DATA_START(chunk);
4560  chunk->endfree = chunk->endptr;
4561 
4562  /*
4563  * If it's last chunk, must sync event list's tailfree too. Note
4564  * that delete_ok must NOT be passed as true if there could be
4565  * additional AfterTriggerEventList values pointing at this event
4566  * list, since we'd fail to fix their copies of tailfree.
4567  */
4568  if (chunk == events->tail)
4569  events->tailfree = chunk->freeptr;
4570  }
4571  }
4572  if (slot1 != NULL)
4573  {
4576  }
4577 
4578  /* Release working resources */
4579  MemoryContextDelete(per_tuple_context);
4580 
4581  if (local_estate)
4582  {
4583  ExecCleanUpTriggerState(estate);
4584  ExecResetTupleTable(estate->es_tupleTable, false);
4585  FreeExecutorState(estate);
4586  }
4587 
4588  return all_fired;
4589 }
4590 
4591 
4592 /*
4593  * GetAfterTriggersTableData
4594  *
4595  * Find or create an AfterTriggersTableData struct for the specified
4596  * trigger event (relation + operation type). Ignore existing structs
4597  * marked "closed"; we don't want to put any additional tuples into them,
4598  * nor change their stmt-triggers-fired state.
4599  *
4600  * Note: the AfterTriggersTableData list is allocated in the current
4601  * (sub)transaction's CurTransactionContext. This is OK because
4602  * we don't need it to live past AfterTriggerEndQuery.
4603  */
4604 static AfterTriggersTableData *
4606 {
4607  AfterTriggersTableData *table;
4609  MemoryContext oldcxt;
4610  ListCell *lc;
4611 
4612  /* Caller should have ensured query_depth is OK. */
4613  Assert(afterTriggers.query_depth >= 0 &&
4614  afterTriggers.query_depth < afterTriggers.maxquerydepth);
4615  qs = &afterTriggers.query_stack[afterTriggers.query_depth];
4616 
4617  foreach(lc, qs->tables)
4618  {
4619  table = (AfterTriggersTableData *) lfirst(lc);
4620  if (table->relid == relid && table->cmdType == cmdType &&
4621  !table->closed)
4622  return table;
4623  }
4624 
4626 
4628  table->relid = relid;
4629  table->cmdType = cmdType;
4630  qs->tables = lappend(qs->tables, table);
4631 
4632  MemoryContextSwitchTo(oldcxt);
4633 
4634  return table;
4635 }
4636 
4637 
4638 /*
4639  * MakeTransitionCaptureState
4640  *
4641  * Make a TransitionCaptureState object for the given TriggerDesc, target
4642  * relation, and operation type. The TCS object holds all the state needed
4643  * to decide whether to capture tuples in transition tables.
4644  *
4645  * If there are no triggers in 'trigdesc' that request relevant transition
4646  * tables, then return NULL.
4647  *
4648  * The resulting object can be passed to the ExecAR* functions. The caller
4649  * should set tcs_map or tcs_original_insert_tuple as appropriate when dealing
4650  * with child tables.
4651  *
4652  * Note that we copy the flags from a parent table into this struct (rather
4653  * than subsequently using the relation's TriggerDesc directly) so that we can
4654  * use it to control collection of transition tuples from child tables.
4655  *
4656  * Per SQL spec, all operations of the same kind (INSERT/UPDATE/DELETE)
4657  * on the same table during one query should share one transition table.
4658  * Therefore, the Tuplestores are owned by an AfterTriggersTableData struct
4659  * looked up using the table OID + CmdType, and are merely referenced by
4660  * the TransitionCaptureState objects we hand out to callers.
4661  */
4664 {
4666  bool need_old,
4667  need_new;
4668  AfterTriggersTableData *table;
4669  MemoryContext oldcxt;
4670  ResourceOwner saveResourceOwner;
4671 
4672  if (trigdesc == NULL)
4673  return NULL;
4674 
4675  /* Detect which table(s) we need. */
4676  switch (cmdType)
4677  {
4678  case CMD_INSERT:
4679  need_old = false;
4680  need_new = trigdesc->trig_insert_new_table;
4681  break;
4682  case CMD_UPDATE:
4683  need_old = trigdesc->trig_update_old_table;
4684  need_new = trigdesc->trig_update_new_table;
4685  break;
4686  case CMD_DELETE:
4687  need_old = trigdesc->trig_delete_old_table;
4688  need_new = false;
4689  break;
4690  default:
4691  elog(ERROR, "unexpected CmdType: %d", (int) cmdType);
4692  need_old = need_new = false; /* keep compiler quiet */
4693  break;
4694  }
4695  if (!need_old && !need_new)
4696  return NULL;
4697 
4698  /* Check state, like AfterTriggerSaveEvent. */
4699  if (afterTriggers.query_depth < 0)
4700  elog(ERROR, "MakeTransitionCaptureState() called outside of query");
4701 
4702  /* Be sure we have enough space to record events at this query depth. */
4703  if (afterTriggers.query_depth >= afterTriggers.maxquerydepth)
4705 
4706  /*
4707  * Find or create an AfterTriggersTableData struct to hold the
4708  * tuplestore(s). If there's a matching struct but it's marked closed,
4709  * ignore it; we need a newer one.
4710  *
4711  * Note: the AfterTriggersTableData list, as well as the tuplestores, are
4712  * allocated in the current (sub)transaction's CurTransactionContext, and
4713  * the tuplestores are managed by the (sub)transaction's resource owner.
4714  * This is sufficient lifespan because we do not allow triggers using
4715  * transition tables to be deferrable; they will be fired during
4716  * AfterTriggerEndQuery, after which it's okay to delete the data.
4717  */
4718  table = GetAfterTriggersTableData(relid, cmdType);
4719 
4720  /* Now create required tuplestore(s), if we don't have them already. */
4722  saveResourceOwner = CurrentResourceOwner;
4724 
4725  if (need_old && table->old_tuplestore == NULL)
4726  table->old_tuplestore = tuplestore_begin_heap(false, false, work_mem);
4727  if (need_new && table->new_tuplestore == NULL)
4728  table->new_tuplestore = tuplestore_begin_heap(false, false, work_mem);
4729 
4730  CurrentResourceOwner = saveResourceOwner;
4731  MemoryContextSwitchTo(oldcxt);
4732 
4733  /* Now build the TransitionCaptureState struct, in caller's context */
4735  state->tcs_delete_old_table = trigdesc->trig_delete_old_table;
4736  state->tcs_update_old_table = trigdesc->trig_update_old_table;
4737  state->tcs_update_new_table = trigdesc->trig_update_new_table;
4738  state->tcs_insert_new_table = trigdesc->trig_insert_new_table;
4739  state->tcs_private = table;
4740 
4741  return state;
4742 }
4743 
4744 
4745 /* ----------
4746  * AfterTriggerBeginXact()
4747  *
4748  * Called at transaction start (either BEGIN or implicit for single
4749  * statement outside of transaction block).
4750  * ----------
4751  */
4752 void
4754 {
4755  /*
4756  * Initialize after-trigger state structure to empty
4757  */
4758  afterTriggers.firing_counter = (CommandId) 1; /* mustn't be 0 */
4759  afterTriggers.query_depth = -1;
4760 
4761  /*
4762  * Verify that there is no leftover state remaining. If these assertions
4763  * trip, it means that AfterTriggerEndXact wasn't called or didn't clean
4764  * up properly.
4765  */
4766  Assert(afterTriggers.state == NULL);
4767  Assert(afterTriggers.query_stack == NULL);
4768  Assert(afterTriggers.maxquerydepth == 0);
4769  Assert(afterTriggers.event_cxt == NULL);
4770  Assert(afterTriggers.events.head == NULL);
4771  Assert(afterTriggers.trans_stack == NULL);
4772  Assert(afterTriggers.maxtransdepth == 0);
4773 }
4774 
4775 
4776 /* ----------
4777  * AfterTriggerBeginQuery()
4778  *
4779  * Called just before we start processing a single query within a
4780  * transaction (or subtransaction). Most of the real work gets deferred
4781  * until somebody actually tries to queue a trigger event.
4782  * ----------
4783  */
4784 void
4786 {
4787  /* Increase the query stack depth */
4788  afterTriggers.query_depth++;
4789 }
4790 
4791 
4792 /* ----------
4793  * AfterTriggerEndQuery()
4794  *
4795  * Called after one query has been completely processed. At this time
4796  * we invoke all AFTER IMMEDIATE trigger events queued by the query, and
4797  * transfer deferred trigger events to the global deferred-trigger list.
4798  *
4799  * Note that this must be called BEFORE closing down the executor
4800  * with ExecutorEnd, because we make use of the EState's info about
4801  * target relations. Normally it is called from ExecutorFinish.
4802  * ----------
4803  */
4804 void
4806 {
4808 
4809  /* Must be inside a query, too */
4810  Assert(afterTriggers.query_depth >= 0);
4811 
4812  /*
4813  * If we never even got as far as initializing the event stack, there
4814  * certainly won't be any events, so exit quickly.
4815  */
4816  if (afterTriggers.query_depth >= afterTriggers.maxquerydepth)
4817  {
4818  afterTriggers.query_depth--;
4819  return;
4820  }
4821 
4822  /*
4823  * Process all immediate-mode triggers queued by the query, and move the
4824  * deferred ones to the main list of deferred events.
4825  *
4826  * Notice that we decide which ones will be fired, and put the deferred
4827  * ones on the main list, before anything is actually fired. This ensures
4828  * reasonably sane behavior if a trigger function does SET CONSTRAINTS ...
4829  * IMMEDIATE: all events we have decided to defer will be available for it
4830  * to fire.
4831  *
4832  * We loop in case a trigger queues more events at the same query level.
4833  * Ordinary trigger functions, including all PL/pgSQL trigger functions,
4834  * will instead fire any triggers in a dedicated query level. Foreign key
4835  * enforcement triggers do add to the current query level, thanks to their
4836  * passing fire_triggers = false to SPI_execute_snapshot(). Other
4837  * C-language triggers might do likewise.
4838  *
4839  * If we find no firable events, we don't have to increment
4840  * firing_counter.
4841  */
4842  qs = &afterTriggers.query_stack[afterTriggers.query_depth];
4843 
4844  for (;;)
4845  {
4846  if (afterTriggerMarkEvents(&qs->events, &afterTriggers.events, true))
4847  {
4848  CommandId firing_id = afterTriggers.firing_counter++;
4849  AfterTriggerEventChunk *oldtail = qs->events.tail;
4850 
4851  if (afterTriggerInvokeEvents(&qs->events, firing_id, estate, false))
4852  break; /* all fired */
4853 
4854  /*
4855  * Firing a trigger could result in query_stack being repalloc'd,
4856  * so we must recalculate qs after each afterTriggerInvokeEvents
4857  * call. Furthermore, it's unsafe to pass delete_ok = true here,
4858  * because that could cause afterTriggerInvokeEvents to try to
4859  * access qs->events after the stack has been repalloc'd.
4860  */
4861  qs = &afterTriggers.query_stack[afterTriggers.query_depth];
4862 
4863  /*
4864  * We'll need to scan the events list again. To reduce the cost
4865  * of doing so, get rid of completely-fired chunks. We know that
4866  * all events were marked IN_PROGRESS or DONE at the conclusion of
4867  * afterTriggerMarkEvents, so any still-interesting events must
4868  * have been added after that, and so must be in the chunk that
4869  * was then the tail chunk, or in later chunks. So, zap all
4870  * chunks before oldtail. This is approximately the same set of
4871  * events we would have gotten rid of by passing delete_ok = true.
4872  */
4873  Assert(oldtail != NULL);
4874  while (qs->events.head != oldtail)
4876  }
4877  else
4878  break;
4879  }
4880 
4881  /* Release query-level-local storage, including tuplestores if any */
4882  AfterTriggerFreeQuery(&afterTriggers.query_stack[afterTriggers.query_depth]);
4883 
4884  afterTriggers.query_depth--;
4885 }
4886 
4887 
4888 /*
4889  * AfterTriggerFreeQuery
4890  * Release subsidiary storage for a trigger query level.
4891  * This includes closing down tuplestores.
4892  * Note: it's important for this to be safe if interrupted by an error
4893  * and then called again for the same query level.
4894  */
4895 static void
4897 {
4898  Tuplestorestate *ts;
4899  List *tables;
4900  ListCell *lc;
4901 
4902  /* Drop the trigger events */
4904 
4905  /* Drop FDW tuplestore if any */
4906  ts = qs->fdw_tuplestore;
4907  qs->fdw_tuplestore = NULL;
4908  if (ts)
4909  tuplestore_end(ts);
4910 
4911  /* Release per-table subsidiary storage */
4912  tables = qs->tables;
4913  foreach(lc, tables)
4914  {
4916 
4917  ts = table->old_tuplestore;
4918  table->old_tuplestore = NULL;
4919  if (ts)
4920  tuplestore_end(ts);
4921  ts = table->new_tuplestore;
4922  table->new_tuplestore = NULL;
4923  if (ts)
4924  tuplestore_end(ts);
4925  }
4926 
4927  /*
4928  * Now free the AfterTriggersTableData structs and list cells. Reset list
4929  * pointer first; if list_free_deep somehow gets an error, better to leak
4930  * that storage than have an infinite loop.
4931  */
4932  qs->tables = NIL;
4933  list_free_deep(tables);
4934 }
4935 
4936 
4937 /* ----------
4938  * AfterTriggerFireDeferred()
4939  *
4940  * Called just before the current transaction is committed. At this
4941  * time we invoke all pending DEFERRED triggers.
4942  *
4943  * It is possible for other modules to queue additional deferred triggers
4944  * during pre-commit processing; therefore xact.c may have to call this
4945  * multiple times.
4946  * ----------
4947  */
4948 void
4950 {
4951  AfterTriggerEventList *events;
4952  bool snap_pushed = false;
4953 
4954  /* Must not be inside a query */
4955  Assert(afterTriggers.query_depth == -1);
4956 
4957  /*
4958  * If there are any triggers to fire, make sure we have set a snapshot for
4959  * them to use. (Since PortalRunUtility doesn't set a snap for COMMIT, we
4960  * can't assume ActiveSnapshot is valid on entry.)
4961  */
4962  events = &afterTriggers.events;
4963  if (events->head != NULL)
4964  {
4966  snap_pushed = true;
4967  }
4968 
4969  /*
4970  * Run all the remaining triggers. Loop until they are all gone, in case
4971  * some trigger queues more for us to do.
4972  */
4973  while (afterTriggerMarkEvents(events, NULL, false))
4974  {
4975  CommandId firing_id = afterTriggers.firing_counter++;
4976 
4977  if (afterTriggerInvokeEvents(events, firing_id, NULL, true))
4978  break; /* all fired */
4979  }
4980 
4981  /*
4982  * We don't bother freeing the event list, since it will go away anyway
4983  * (and more efficiently than via pfree) in AfterTriggerEndXact.
4984  */
4985 
4986  if (snap_pushed)
4988 }
4989 
4990 
4991 /* ----------
4992  * AfterTriggerEndXact()
4993  *
4994  * The current transaction is finishing.
4995  *
4996  * Any unfired triggers are canceled so we simply throw
4997  * away anything we know.
4998  *
4999  * Note: it is possible for this to be called repeatedly in case of
5000  * error during transaction abort; therefore, do not complain if
5001  * already closed down.
5002  * ----------
5003  */
5004 void
5005 AfterTriggerEndXact(bool isCommit)
5006 {
5007  /*
5008  * Forget the pending-events list.
5009  *
5010  * Since all the info is in TopTransactionContext or children thereof, we
5011  * don't really need to do anything to reclaim memory. However, the
5012  * pending-events list could be large, and so it's useful to discard it as
5013  * soon as possible --- especially if we are aborting because we ran out
5014  * of memory for the list!
5015  */
5016  if (afterTriggers.event_cxt)
5017  {
5018  MemoryContextDelete(afterTriggers.event_cxt);
5019  afterTriggers.event_cxt = NULL;
5020  afterTriggers.events.head = NULL;
5021  afterTriggers.events.tail = NULL;
5022  afterTriggers.events.tailfree = NULL;
5023  }
5024 
5025  /*
5026  * Forget any subtransaction state as well. Since this can't be very
5027  * large, we let the eventual reset of TopTransactionContext free the
5028  * memory instead of doing it here.
5029  */
5030  afterTriggers.trans_stack = NULL;
5031  afterTriggers.maxtransdepth = 0;
5032 
5033 
5034  /*
5035  * Forget the query stack and constraint-related state information. As
5036  * with the subtransaction state information, we don't bother freeing the
5037  * memory here.
5038  */
5039  afterTriggers.query_stack = NULL;
5040  afterTriggers.maxquerydepth = 0;
5041  afterTriggers.state = NULL;
5042 
5043  /* No more afterTriggers manipulation until next transaction starts. */
5044  afterTriggers.query_depth = -1;
5045 }
5046 
5047 /*
5048  * AfterTriggerBeginSubXact()
5049  *
5050  * Start a subtransaction.
5051  */
5052 void
5054 {
5055  int my_level = GetCurrentTransactionNestLevel();
5056 
5057  /*
5058  * Allocate more space in the trans_stack if needed. (Note: because the
5059  * minimum nest level of a subtransaction is 2, we waste the first couple
5060  * entries of the array; not worth the notational effort to avoid it.)
5061  */
5062  while (my_level >= afterTriggers.maxtransdepth)
5063  {
5064  if (afterTriggers.maxtransdepth == 0)
5065  {
5066  /* Arbitrarily initialize for max of 8 subtransaction levels */
5067  afterTriggers.trans_stack = (AfterTriggersTransData *)
5069  8 * sizeof(AfterTriggersTransData));
5070  afterTriggers.maxtransdepth = 8;
5071  }
5072  else
5073  {
5074  /* repalloc will keep the stack in the same context */
5075  int new_alloc = afterTriggers.maxtransdepth * 2;
5076 
5077  afterTriggers.trans_stack = (AfterTriggersTransData *)
5078  repalloc(afterTriggers.trans_stack,
5079  new_alloc * sizeof(AfterTriggersTransData));
5080  afterTriggers.maxtransdepth = new_alloc;
5081  }
5082  }
5083 
5084  /*
5085  * Push the current information into the stack. The SET CONSTRAINTS state
5086  * is not saved until/unless changed. Likewise, we don't make a
5087  * per-subtransaction event context until needed.
5088  */
5089  afterTriggers.trans_stack[my_level].state = NULL;
5090  afterTriggers.trans_stack[my_level].events = afterTriggers.events;
5091  afterTriggers.trans_stack[my_level].query_depth = afterTriggers.query_depth;
5092  afterTriggers.trans_stack[my_level].firing_counter = afterTriggers.firing_counter;
5093 }
5094 
5095 /*
5096  * AfterTriggerEndSubXact()
5097  *
5098  * The current subtransaction is ending.
5099  */
5100 void
5102 {
5103  int my_level = GetCurrentTransactionNestLevel();
5105  AfterTriggerEvent event;
5106  AfterTriggerEventChunk *chunk;
5107  CommandId subxact_firing_id;
5108 
5109  /*
5110  * Pop the prior state if needed.
5111  */
5112  if (isCommit)
5113  {
5114  Assert(my_level < afterTriggers.maxtransdepth);
5115  /* If we saved a prior state, we don't need it anymore */
5116  state = afterTriggers.trans_stack[my_level].state;
5117  if (state != NULL)
5118  pfree(state);
5119  /* this avoids double pfree if error later: */
5120  afterTriggers.trans_stack[my_level].state = NULL;
5121  Assert(afterTriggers.query_depth ==
5122  afterTriggers.trans_stack[my_level].query_depth);
5123  }
5124  else
5125  {
5126  /*
5127  * Aborting. It is possible subxact start failed before calling
5128  * AfterTriggerBeginSubXact, in which case we mustn't risk touching
5129  * trans_stack levels that aren't there.
5130  */
5131  if (my_level >= afterTriggers.maxtransdepth)
5132  return;
5133 
5134  /*
5135  * Release query-level storage for queries being aborted, and restore
5136  * query_depth to its pre-subxact value. This assumes that a
5137  * subtransaction will not add events to query levels started in a
5138  * earlier transaction state.
5139  */
5140  while (afterTriggers.query_depth > afterTriggers.trans_stack[my_level].query_depth)
5141  {
5142  if (afterTriggers.query_depth < afterTriggers.maxquerydepth)
5143  AfterTriggerFreeQuery(&afterTriggers.query_stack[afterTriggers.query_depth]);
5144  afterTriggers.query_depth--;
5145  }
5146  Assert(afterTriggers.query_depth ==
5147  afterTriggers.trans_stack[my_level].query_depth);
5148 
5149  /*
5150  * Restore the global deferred-event list to its former length,
5151  * discarding any events queued by the subxact.
5152  */
5153  afterTriggerRestoreEventList(&afterTriggers.events,
5154  &afterTriggers.trans_stack[my_level].events);
5155 
5156  /*
5157  * Restore the trigger state. If the saved state is NULL, then this
5158  * subxact didn't save it, so it doesn't need restoring.
5159  */
5160  state = afterTriggers.trans_stack[my_level].state;
5161  if (state != NULL)
5162  {
5163  pfree(afterTriggers.state);
5164  afterTriggers.state = state;
5165  }
5166  /* this avoids double pfree if error later: */
5167  afterTriggers.trans_stack[my_level].state = NULL;
5168 
5169  /*
5170  * Scan for any remaining deferred events that were marked DONE or IN
5171  * PROGRESS by this subxact or a child, and un-mark them. We can
5172  * recognize such events because they have a firing ID greater than or
5173  * equal to the firing_counter value we saved at subtransaction start.
5174  * (This essentially assumes that the current subxact includes all
5175  * subxacts started after it.)
5176  */
5177  subxact_firing_id = afterTriggers.trans_stack[my_level].firing_counter;
5178  for_each_event_chunk(event, chunk, afterTriggers.events)
5179  {
5180  AfterTriggerShared evtshared = GetTriggerSharedData(event);
5181 
5182  if (event->ate_flags &
5184  {
5185  if (evtshared->ats_firing_id >= subxact_firing_id)
5186  event->ate_flags &=
5188  }
5189  }
5190  }
5191 }
5192 
5193 /* ----------
5194  * AfterTriggerEnlargeQueryState()
5195  *
5196  * Prepare the necessary state so that we can record AFTER trigger events
5197  * queued by a query. It is allowed to have nested queries within a
5198  * (sub)transaction, so we need to have separate state for each query
5199  * nesting level.
5200  * ----------
5201  */
5202 static void
5204 {
5205  int init_depth = afterTriggers.maxquerydepth;
5206 
5207  Assert(afterTriggers.query_depth >= afterTriggers.maxquerydepth);
5208 
5209  if (afterTriggers.maxquerydepth == 0)
5210  {
5211  int new_alloc = Max(afterTriggers.query_depth + 1, 8);
5212 
5213  afterTriggers.query_stack = (AfterTriggersQueryData *)
5215  new_alloc * sizeof(AfterTriggersQueryData));
5216  afterTriggers.maxquerydepth = new_alloc;
5217  }
5218  else
5219  {
5220  /* repalloc will keep the stack in the same context */
5221  int old_alloc = afterTriggers.maxquerydepth;
5222  int new_alloc = Max(afterTriggers.query_depth + 1,
5223  old_alloc * 2);
5224 
5225  afterTriggers.query_stack = (AfterTriggersQueryData *)
5226  repalloc(afterTriggers.query_stack,
5227  new_alloc * sizeof(AfterTriggersQueryData));
5228  afterTriggers.maxquerydepth = new_alloc;
5229  }
5230 
5231  /* Initialize new array entries to empty */
5232  while (init_depth < afterTriggers.maxquerydepth)
5233  {
5234  AfterTriggersQueryData *qs = &afterTriggers.query_stack[init_depth];
5235 
5236  qs->events.head = NULL;
5237  qs->events.tail = NULL;
5238  qs->events.tailfree = NULL;
5239  qs->fdw_tuplestore = NULL;
5240  qs->tables = NIL;
5241 
5242  ++init_depth;
5243  }
5244 }
5245 
5246 /*
5247  * Create an empty SetConstraintState with room for numalloc trigstates
5248  */
5249 static SetConstraintState
5251 {
5253 
5254  /* Behave sanely with numalloc == 0 */
5255  if (numalloc <= 0)
5256  numalloc = 1;
5257 
5258  /*
5259  * We assume that zeroing will correctly initialize the state values.
5260  */
5261  state = (SetConstraintState)
5263  offsetof(SetConstraintStateData, trigstates) +
5264  numalloc * sizeof(SetConstraintTriggerData));
5265 
5266  state->numalloc = numalloc;
5267 
5268  return state;
5269 }
5270 
5271 /*
5272  * Copy a SetConstraintState
5273  */
5274 static SetConstraintState
5276 {
5278 
5279  state = SetConstraintStateCreate(origstate->numstates);
5280 
5281  state->all_isset = origstate->all_isset;
5282  state->all_isdeferred = origstate->all_isdeferred;
5283  state->numstates = origstate->numstates;
5284  memcpy(state->trigstates, origstate->trigstates,
5285  origstate->numstates * sizeof(SetConstraintTriggerData));
5286 
5287  return state;
5288 }
5289 
5290 /*
5291  * Add a per-trigger item to a SetConstraintState. Returns possibly-changed
5292  * pointer to the state object (it will change if we have to repalloc).
5293  */
5294 static SetConstraintState
5296  Oid tgoid, bool tgisdeferred)
5297 {
5298  if (state->numstates >= state->numalloc)
5299  {
5300  int newalloc = state->numalloc * 2;
5301 
5302  newalloc = Max(newalloc, 8); /* in case original has size 0 */
5303  state = (SetConstraintState)
5304  repalloc(state,
5305  offsetof(SetConstraintStateData, trigstates) +
5306  newalloc * sizeof(SetConstraintTriggerData));
5307  state->numalloc = newalloc;
5308  Assert(state->numstates < state->numalloc);
5309  }
5310 
5311  state->trigstates[state->numstates].sct_tgoid = tgoid;
5312  state->trigstates[state->numstates].sct_tgisdeferred = tgisdeferred;
5313  state->numstates++;
5314 
5315  return state;
5316 }
5317 
5318 /* ----------
5319  * AfterTriggerSetState()
5320  *
5321  * Execute the SET CONSTRAINTS ... utility command.
5322  * ----------
5323  */
5324 void
5326 {
5327  int my_level = GetCurrentTransactionNestLevel();
5328 
5329  /* If we haven't already done so, initialize our state. */
5330  if (afterTriggers.state == NULL)
5331  afterTriggers.state = SetConstraintStateCreate(8);
5332 
5333  /*
5334  * If in a subtransaction, and we didn't save the current state already,
5335  * save it so it can be restored if the subtransaction aborts.
5336  */
5337  if (my_level > 1 &&
5338  afterTriggers.trans_stack[my_level].state == NULL)
5339  {
5340  afterTriggers.trans_stack[my_level].state =
5341  SetConstraintStateCopy(afterTriggers.state);
5342  }
5343 
5344  /*
5345  * Handle SET CONSTRAINTS ALL ...
5346  */
5347  if (stmt->constraints == NIL)
5348  {
5349  /*
5350  * Forget any previous SET CONSTRAINTS commands in this transaction.
5351  */
5352  afterTriggers.state->numstates = 0;
5353 
5354  /*
5355  * Set the per-transaction ALL state to known.
5356  */
5357  afterTriggers.state->all_isset = true;
5358  afterTriggers.state->all_isdeferred = stmt->deferred;
5359  }
5360  else
5361  {
5362  Relation conrel;
5363  Relation tgrel;
5364  List *conoidlist = NIL;
5365  List *tgoidlist = NIL;
5366  ListCell *lc;
5367 
5368  /*
5369  * Handle SET CONSTRAINTS constraint-name [, ...]
5370  *
5371  * First, identify all the named constraints and make a list of their
5372  * OIDs. Since, unlike the SQL spec, we allow multiple constraints of
5373  * the same name within a schema, the specifications are not
5374  * necessarily unique. Our strategy is to target all matching
5375  * constraints within the first search-path schema that has any
5376  * matches, but disregard matches in schemas beyond the first match.
5377  * (This is a bit odd but it's the historical behavior.)
5378  *
5379  * A constraint in a partitioned table may have corresponding
5380  * constraints in the partitions. Grab those too.
5381  */
5382  conrel = table_open(ConstraintRelationId, AccessShareLock);
5383 
5384  foreach(lc, stmt->constraints)
5385  {
5386  RangeVar *constraint = lfirst(lc);
5387  bool found;
5388  List *namespacelist;
5389  ListCell *nslc;
5390 
5391  if (constraint->catalogname)
5392  {
5393  if (strcmp(constraint->catalogname, get_database_name(MyDatabaseId)) != 0)
5394  ereport(ERROR,
5395  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
5396  errmsg("cross-database references are not implemented: \"%s.%s.%s\"",
5397  constraint->catalogname, constraint->schemaname,
5398  constraint->relname)));
5399  }
5400 
5401  /*
5402  * If we're given the schema name with the constraint, look only
5403  * in that schema. If given a bare constraint name, use the
5404  * search path to find the first matching constraint.
5405  */
5406  if (constraint->schemaname)
5407  {
5408  Oid namespaceId = LookupExplicitNamespace(constraint->schemaname,
5409  false);
5410 
5411  namespacelist = list_make1_oid(namespaceId);
5412  }
5413  else
5414  {
5415  namespacelist = fetch_search_path(true);
5416  }
5417 
5418  found = false;
5419  foreach(nslc, namespacelist)
5420  {
5421  Oid namespaceId = lfirst_oid(nslc);
5422  SysScanDesc conscan;
5423  ScanKeyData skey[2];
5424  HeapTuple tup;
5425 
5426  ScanKeyInit(&skey[0],
5427  Anum_pg_constraint_conname,
5428  BTEqualStrategyNumber, F_NAMEEQ,
5429  CStringGetDatum(constraint->relname));
5430  ScanKeyInit(&skey[1],
5431  Anum_pg_constraint_connamespace,
5432  BTEqualStrategyNumber, F_OIDEQ,
5433  ObjectIdGetDatum(namespaceId));
5434 
5435  conscan = systable_beginscan(conrel, ConstraintNameNspIndexId,
5436  true, NULL, 2, skey);
5437 
5438  while (HeapTupleIsValid(tup = systable_getnext(conscan)))
5439  {
5441 
5442  if (con->condeferrable)
5443  conoidlist = lappend_oid(conoidlist, con->oid);
5444  else if (stmt->deferred)
5445  ereport(ERROR,
5446  (errcode(ERRCODE_WRONG_OBJECT_TYPE),
5447  errmsg("constraint \"%s\" is not deferrable",
5448  constraint->relname)));
5449  found = true;
5450  }
5451 
5452  systable_endscan(conscan);
5453 
5454  /*
5455  * Once we've found a matching constraint we do not search
5456  * later parts of the search path.
5457  */
5458  if (found)
5459  break;
5460  }
5461 
5462  list_free(namespacelist);
5463 
5464  /*
5465  * Not found ?
5466  */
5467  if (!found)
5468  ereport(ERROR,
5469  (errcode(ERRCODE_UNDEFINED_OBJECT),
5470  errmsg("constraint \"%s\" does not exist",
5471  constraint->relname)));
5472  }
5473 
5474  /*
5475  * Scan for any possible descendants of the constraints. We append
5476  * whatever we find to the same list that we're scanning; this has the
5477  * effect that we create new scans for those, too, so if there are
5478  * further descendents, we'll also catch them.
5479  */
5480  foreach(lc, conoidlist)
5481  {
5482  Oid parent = lfirst_oid(lc);
5483  ScanKeyData key;
5484  SysScanDesc scan;
5485  HeapTuple tuple;
5486 
5487  ScanKeyInit(&key,
5488  Anum_pg_constraint_conparentid,
5489  BTEqualStrategyNumber, F_OIDEQ,
5490  ObjectIdGetDatum(parent));
5491 
5492  scan = systable_beginscan(conrel, ConstraintParentIndexId, true, NULL, 1, &key);
5493 
5494  while (HeapTupleIsValid(tuple = systable_getnext(scan)))
5495  {
5497 
5498  conoidlist = lappend_oid(conoidlist, con->oid);
5499  }
5500 
5501  systable_endscan(scan);
5502  }
5503 
5504  table_close(conrel, AccessShareLock);
5505 
5506  /*
5507  * Now, locate the trigger(s) implementing each of these constraints,
5508  * and make a list of their OIDs.
5509  */
5510  tgrel = table_open(TriggerRelationId, AccessShareLock);
5511 
5512  foreach(lc, conoidlist)
5513  {
5514  Oid conoid = lfirst_oid(lc);
5515  ScanKeyData skey;
5516  SysScanDesc tgscan;
5517  HeapTuple htup;
5518 
5519  ScanKeyInit(&skey,
5520  Anum_pg_trigger_tgconstraint,
5521  BTEqualStrategyNumber, F_OIDEQ,
5522  ObjectIdGetDatum(conoid));
5523 
5524  tgscan = systable_beginscan(tgrel, TriggerConstraintIndexId, true,
5525  NULL, 1, &skey);
5526 
5527  while (HeapTupleIsValid(htup = systable_getnext(tgscan)))
5528  {
5529  Form_pg_trigger pg_trigger = (Form_pg_trigger) GETSTRUCT(htup);
5530 
5531  /*
5532  * Silently skip triggers that are marked as non-deferrable in
5533  * pg_trigger. This is not an error condition, since a
5534  * deferrable RI constraint may have some non-deferrable
5535  * actions.
5536  */
5537  if (pg_trigger->tgdeferrable)
5538  tgoidlist = lappend_oid(tgoidlist, pg_trigger->oid);
5539  }
5540 
5541  systable_endscan(tgscan);
5542  }
5543 
5544  table_close(tgrel, AccessShareLock);
5545 
5546  /*
5547  * Now we can set the trigger states of individual triggers for this
5548  * xact.
5549  */
5550  foreach(lc, tgoidlist)
5551  {
5552  Oid tgoid = lfirst_oid(lc);
5553  SetConstraintState state = afterTriggers.state;
5554  bool found = false;
5555  int i;
5556 
5557  for (i = 0; i < state->numstates; i++)
5558  {
5559  if (state->trigstates[i].sct_tgoid == tgoid)
5560  {
5561  state->trigstates[i].sct_tgisdeferred = stmt->deferred;
5562  found = true;
5563  break;
5564  }
5565  }
5566  if (!found)
5567  {
5568  afterTriggers.state =
5569  SetConstraintStateAddItem(state, tgoid, stmt->deferred);
5570  }
5571  }
5572  }
5573 
5574  /*
5575  * SQL99 requires that when a constraint is set to IMMEDIATE, any deferred
5576  * checks against that constraint must be made when the SET CONSTRAINTS
5577  * command is executed -- i.e. the effects of the SET CONSTRAINTS command
5578  * apply retroactively. We've updated the constraints state, so scan the
5579  * list of previously deferred events to fire any that have now become
5580  * immediate.
5581  *
5582  * Obviously, if this was SET ... DEFERRED then it can't have converted
5583  * any unfired events to immediate, so we need do nothing in that case.
5584  */
5585  if (!stmt->deferred)
5586  {
5587  AfterTriggerEventList *events = &afterTriggers.events;
5588  bool snapshot_set = false;
5589 
5590  while (afterTriggerMarkEvents(events, NULL, true))
5591  {
5592  CommandId firing_id = afterTriggers.firing_counter++;
5593 
5594  /*
5595  * Make sure a snapshot has been established in case trigger
5596  * functions need one. Note that we avoid setting a snapshot if
5597  * we don't find at least one trigger that has to be fired now.
5598  * This is so that BEGIN; SET CONSTRAINTS ...; SET TRANSACTION
5599  * ISOLATION LEVEL SERIALIZABLE; ... works properly. (If we are
5600  * at the start of a transaction it's not possible for any trigger
5601  * events to be queued yet.)
5602  */
5603  if (!snapshot_set)
5604  {
5606  snapshot_set = true;
5607  }
5608 
5609  /*
5610  * We can delete fired events if we are at top transaction level,
5611  * but we'd better not if inside a subtransaction, since the
5612  * subtransaction could later get rolled back.
5613  */
5614  if (afterTriggerInvokeEvents(events, firing_id, NULL,
5615  !IsSubTransaction()))
5616  break; /* all fired */
5617  }
5618 
5619  if (snapshot_set)
5621  }
5622 }
5623 
5624 /* ----------
5625  * AfterTriggerPendingOnRel()
5626  * Test to see if there are any pending after-trigger events for rel.
5627  *
5628  * This is used by TRUNCATE, CLUSTER, ALTER TABLE, etc to detect whether
5629  * it is unsafe to perform major surgery on a relation. Note that only
5630  * local pending events are examined. We assume that having exclusive lock
5631  * on a rel guarantees there are no unserviced events in other backends ---
5632  * but having a lock does not prevent there being such events in our own.
5633  *
5634  * In some scenarios it'd be reasonable to remove pending events (more
5635  * specifically, mark them DONE by the current subxact) but without a lot
5636  * of knowledge of the trigger semantics we can't do this in general.
5637  * ----------
5638  */
5639 bool
5641 {
5642  AfterTriggerEvent event;
5643  AfterTriggerEventChunk *chunk;
5644  int depth;
5645 
5646  /* Scan queued events */
5647  for_each_event_chunk(event, chunk, afterTriggers.events)
5648  {
5649  AfterTriggerShared evtshared = GetTriggerSharedData(event);
5650 
5651  /*
5652  * We can ignore completed events. (Even if a DONE flag is rolled
5653  * back by subxact abort, it's OK because the effects of the TRUNCATE
5654  * or whatever must get rolled back too.)
5655  */
5656  if (event->ate_flags & AFTER_TRIGGER_DONE)
5657  continue;
5658 
5659  if (evtshared->ats_relid == relid)
5660  return true;
5661  }
5662 
5663  /*
5664  * Also scan events queued by incomplete queries. This could only matter
5665  * if TRUNCATE/etc is executed by a function or trigger within an updating
5666  * query on the same relation, which is pretty perverse, but let's check.
5667  */
5668  for (depth = 0; depth <= afterTriggers.query_depth && depth < afterTriggers.maxquerydepth; depth++)
5669  {
5670  for_each_event_chunk(event, chunk, afterTriggers.query_stack[depth].events)
5671  {
5672  AfterTriggerShared evtshared = GetTriggerSharedData(event);
5673 
5674  if (event->ate_flags & AFTER_TRIGGER_DONE)
5675  continue;
5676 
5677  if (evtshared->ats_relid == relid)
5678  return true;
5679  }
5680  }
5681 
5682  return false;
5683 }
5684 
5685 
5686 /* ----------
5687  * AfterTriggerSaveEvent()
5688  *
5689  * Called by ExecA[RS]...Triggers() to queue up the triggers that should
5690  * be fired for an event.
5691  *
5692  * NOTE: this is called whenever there are any triggers associated with
5693  * the event (even if they are disabled). This function decides which
5694  * triggers actually need to be queued. It is also called after each row,
5695  * even if there are no triggers for that event, if there are any AFTER
5696  * STATEMENT triggers for the statement which use transition tables, so that
5697  * the transition tuplestores can be built. Furthermore, if the transition
5698  * capture is happening for UPDATEd rows being moved to another partition due
5699  * to the partition-key being changed, then this function is called once when
5700  * the row is deleted (to capture OLD row), and once when the row is inserted
5701  * into another partition (to capture NEW row). This is done separately because
5702  * DELETE and INSERT happen on different tables.
5703  *
5704  * Transition tuplestores are built now, rather than when events are pulled
5705  * off of the queue because AFTER ROW triggers are allowed to select from the
5706  * transition tables for the statement.
5707  * ----------
5708  */
5709 static void
5711  int event, bool row_trigger,
5712  TupleTableSlot *oldslot, TupleTableSlot *newslot,
5713  List *recheckIndexes, Bitmapset *modifiedCols,
5714  TransitionCaptureState *transition_capture)
5715 {
5716  Relation rel = relinfo->ri_RelationDesc;
5717  TriggerDesc *trigdesc = relinfo->ri_TrigDesc;
5718  AfterTriggerEventData new_event;
5719  AfterTriggerSharedData new_shared;
5720  char relkind = rel->rd_rel->relkind;
5721  int tgtype_event;
5722  int tgtype_level;
5723  int i;
5724  Tuplestorestate *fdw_tuplestore = NULL;
5725 
5726  /*
5727  * Check state. We use a normal test not Assert because it is possible to
5728  * reach here in the wrong state given misconfigured RI triggers, in
5729  * particular deferring a cascade action trigger.
5730  */
5731  if (afterTriggers.query_depth < 0)
5732  elog(ERROR, "AfterTriggerSaveEvent() called outside of query");
5733 
5734  /* Be sure we have enough space to record events at this query depth. */
5735  if (afterTriggers.query_depth >= afterTriggers.