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