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 *newSlot;
2777 
2778  if (!GetTupleForTrigger(estate, epqstate, relinfo, tupleid,
2779  LockTupleExclusive, slot, &newSlot))
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 (newSlot != NULL && epqslot != NULL)
2788  {
2789  *epqslot = newSlot;
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 *newSlot = 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, &newSlot))
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 (newSlot != NULL)
3049  {
3050  TupleTableSlot *slot = ExecFilterJunk(relinfo->ri_junkFilter, newSlot);
3051 
3052  ExecCopySlot(newslot, slot);
3053  }
3054 
3055  trigtuple = ExecFetchSlotHeapTuple(oldslot, true, &should_free_trig);
3056  }
3057  else
3058  {
3059  ExecForceStoreHeapTuple(fdw_trigtuple, oldslot, false);
3060  trigtuple = fdw_trigtuple;
3061  }
3062 
3063  LocTriggerData.type = T_TriggerData;
3064  LocTriggerData.tg_event = TRIGGER_EVENT_UPDATE |
3067  LocTriggerData.tg_relation = relinfo->ri_RelationDesc;
3068  LocTriggerData.tg_oldtable = NULL;
3069  LocTriggerData.tg_newtable = NULL;
3070  updatedCols = GetAllUpdatedColumns(relinfo, estate);
3071  for (i = 0; i < trigdesc->numtriggers; i++)
3072  {
3073  Trigger *trigger = &trigdesc->triggers[i];
3074  HeapTuple oldtuple;
3075 
3076  if (!TRIGGER_TYPE_MATCHES(trigger->tgtype,
3077  TRIGGER_TYPE_ROW,
3078  TRIGGER_TYPE_BEFORE,
3079  TRIGGER_TYPE_UPDATE))
3080  continue;
3081  if (!TriggerEnabled(estate, relinfo, trigger, LocTriggerData.tg_event,
3082  updatedCols, oldslot, newslot))
3083  continue;
3084 
3085  if (!newtuple)
3086  newtuple = ExecFetchSlotHeapTuple(newslot, true, &should_free_new);
3087 
3088  LocTriggerData.tg_trigslot = oldslot;
3089  LocTriggerData.tg_trigtuple = trigtuple;
3090  LocTriggerData.tg_newtuple = oldtuple = newtuple;
3091  LocTriggerData.tg_newslot = newslot;
3092  LocTriggerData.tg_trigger = trigger;
3093  newtuple = ExecCallTriggerFunc(&LocTriggerData,
3094  i,
3095  relinfo->ri_TrigFunctions,
3096  relinfo->ri_TrigInstrument,
3097  GetPerTupleMemoryContext(estate));
3098 
3099  if (newtuple == NULL)
3100  {
3101  if (should_free_trig)
3102  heap_freetuple(trigtuple);
3103  if (should_free_new)
3104  heap_freetuple(oldtuple);
3105  return false; /* "do nothing" */
3106  }
3107  else if (newtuple != oldtuple)
3108  {
3109  ExecForceStoreHeapTuple(newtuple, newslot, false);
3110 
3111  /*
3112  * If the tuple returned by the trigger / being stored, is the old
3113  * row version, and the heap tuple passed to the trigger was
3114  * allocated locally, materialize the slot. Otherwise we might
3115  * free it while still referenced by the slot.
3116  */
3117  if (should_free_trig && newtuple == trigtuple)
3118  ExecMaterializeSlot(newslot);
3119 
3120  if (should_free_new)
3121  heap_freetuple(oldtuple);
3122 
3123  /* signal tuple should be re-fetched if used */
3124  newtuple = NULL;
3125  }
3126  }
3127  if (should_free_trig)
3128  heap_freetuple(trigtuple);
3129 
3130  return true;
3131 }
3132 
3133 void
3135  ItemPointer tupleid,
3136  HeapTuple fdw_trigtuple,
3137  TupleTableSlot *newslot,
3138  List *recheckIndexes,
3139  TransitionCaptureState *transition_capture)
3140 {
3141  TriggerDesc *trigdesc = relinfo->ri_TrigDesc;
3142  TupleTableSlot *oldslot = ExecGetTriggerOldSlot(estate, relinfo);
3143 
3144  ExecClearTuple(oldslot);
3145 
3146  if ((trigdesc && trigdesc->trig_update_after_row) ||
3147  (transition_capture &&
3148  (transition_capture->tcs_update_old_table ||
3149  transition_capture->tcs_update_new_table)))
3150  {
3151  /*
3152  * Note: if the UPDATE is converted into a DELETE+INSERT as part of
3153  * update-partition-key operation, then this function is also called
3154  * separately for DELETE and INSERT to capture transition table rows.
3155  * In such case, either old tuple or new tuple can be NULL.
3156  */
3157  if (fdw_trigtuple == NULL && ItemPointerIsValid(tupleid))
3158  GetTupleForTrigger(estate,
3159  NULL,
3160  relinfo,
3161  tupleid,
3163  oldslot,
3164  NULL);
3165  else if (fdw_trigtuple != NULL)
3166  ExecForceStoreHeapTuple(fdw_trigtuple, oldslot, false);
3167 
3169  true, oldslot, newslot, recheckIndexes,
3170  GetAllUpdatedColumns(relinfo, estate),
3171  transition_capture);
3172  }
3173 }
3174 
3175 bool
3177  HeapTuple trigtuple, TupleTableSlot *newslot)
3178 {
3179  TriggerDesc *trigdesc = relinfo->ri_TrigDesc;
3180  TupleTableSlot *oldslot = ExecGetTriggerOldSlot(estate, relinfo);
3181  HeapTuple newtuple = false;
3182  bool should_free;
3183  TriggerData LocTriggerData;
3184  int i;
3185 
3186  LocTriggerData.type = T_TriggerData;
3187  LocTriggerData.tg_event = TRIGGER_EVENT_UPDATE |
3190  LocTriggerData.tg_relation = relinfo->ri_RelationDesc;
3191  LocTriggerData.tg_oldtable = NULL;
3192  LocTriggerData.tg_newtable = NULL;
3193 
3194  ExecForceStoreHeapTuple(trigtuple, oldslot, false);
3195 
3196  for (i = 0; i < trigdesc->numtriggers; i++)
3197  {
3198  Trigger *trigger = &trigdesc->triggers[i];
3199  HeapTuple oldtuple;
3200 
3201  if (!TRIGGER_TYPE_MATCHES(trigger->tgtype,
3202  TRIGGER_TYPE_ROW,
3203  TRIGGER_TYPE_INSTEAD,
3204  TRIGGER_TYPE_UPDATE))
3205  continue;
3206  if (!TriggerEnabled(estate, relinfo, trigger, LocTriggerData.tg_event,
3207  NULL, oldslot, newslot))
3208  continue;
3209 
3210  if (!newtuple)
3211  newtuple = ExecFetchSlotHeapTuple(newslot, true, &should_free);
3212 
3213  LocTriggerData.tg_trigslot = oldslot;
3214  LocTriggerData.tg_trigtuple = trigtuple;
3215  LocTriggerData.tg_newslot = newslot;
3216  LocTriggerData.tg_newtuple = oldtuple = newtuple;
3217 
3218  LocTriggerData.tg_trigger = trigger;
3219  newtuple = ExecCallTriggerFunc(&LocTriggerData,
3220  i,
3221  relinfo->ri_TrigFunctions,
3222  relinfo->ri_TrigInstrument,
3223  GetPerTupleMemoryContext(estate));
3224  if (newtuple == NULL)
3225  {
3226  return false; /* "do nothing" */
3227  }
3228  else if (newtuple != oldtuple)
3229  {
3230  ExecForceStoreHeapTuple(newtuple, newslot, false);
3231 
3232  if (should_free)
3233  heap_freetuple(oldtuple);
3234 
3235  /* signal tuple should be re-fetched if used */
3236  newtuple = NULL;
3237  }
3238  }
3239 
3240  return true;
3241 }
3242 
3243 void
3245 {
3246  TriggerDesc *trigdesc;
3247  int i;
3248  TriggerData LocTriggerData;
3249 
3250  trigdesc = relinfo->ri_TrigDesc;
3251 
3252  if (trigdesc == NULL)
3253  return;
3254  if (!trigdesc->trig_truncate_before_statement)
3255  return;
3256 
3257  LocTriggerData.type = T_TriggerData;
3258  LocTriggerData.tg_event = TRIGGER_EVENT_TRUNCATE |
3260  LocTriggerData.tg_relation = relinfo->ri_RelationDesc;
3261  LocTriggerData.tg_trigtuple = NULL;
3262  LocTriggerData.tg_newtuple = NULL;
3263  LocTriggerData.tg_trigslot = NULL;
3264  LocTriggerData.tg_newslot = NULL;
3265  LocTriggerData.tg_oldtable = NULL;
3266  LocTriggerData.tg_newtable = NULL;
3267 
3268  for (i = 0; i < trigdesc->numtriggers; i++)
3269  {
3270  Trigger *trigger = &trigdesc->triggers[i];
3271  HeapTuple newtuple;
3272 
3273  if (!TRIGGER_TYPE_MATCHES(trigger->tgtype,
3274  TRIGGER_TYPE_STATEMENT,
3275  TRIGGER_TYPE_BEFORE,
3276  TRIGGER_TYPE_TRUNCATE))
3277  continue;
3278  if (!TriggerEnabled(estate, relinfo, trigger, LocTriggerData.tg_event,
3279  NULL, NULL, NULL))
3280  continue;
3281 
3282  LocTriggerData.tg_trigger = trigger;
3283  newtuple = ExecCallTriggerFunc(&LocTriggerData,
3284  i,
3285  relinfo->ri_TrigFunctions,
3286  relinfo->ri_TrigInstrument,
3287  GetPerTupleMemoryContext(estate));
3288 
3289  if (newtuple)
3290  ereport(ERROR,
3291  (errcode(ERRCODE_E_R_I_E_TRIGGER_PROTOCOL_VIOLATED),
3292  errmsg("BEFORE STATEMENT trigger cannot return a value")));
3293  }
3294 }
3295 
3296 void
3298 {
3299  TriggerDesc *trigdesc = relinfo->ri_TrigDesc;
3300 
3301  if (trigdesc && trigdesc->trig_truncate_after_statement)
3303  false, NULL, NULL, NIL, NULL, NULL);
3304 }
3305 
3306 
3307 static bool
3309  EPQState *epqstate,
3310  ResultRelInfo *relinfo,
3311  ItemPointer tid,
3312  LockTupleMode lockmode,
3313  TupleTableSlot *oldslot,
3314  TupleTableSlot **newSlot)
3315 {
3316  Relation relation = relinfo->ri_RelationDesc;
3317 
3318  if (newSlot != NULL)
3319  {
3320  TM_Result test;
3321  TM_FailureData tmfd;
3322  int lockflags = 0;
3323 
3324  *newSlot = NULL;
3325 
3326  /* caller must pass an epqstate if EvalPlanQual is possible */
3327  Assert(epqstate != NULL);
3328 
3329  /*
3330  * lock tuple for update
3331  */
3333  lockflags |= TUPLE_LOCK_FLAG_FIND_LAST_VERSION;
3334  test = table_tuple_lock(relation, tid, estate->es_snapshot, oldslot,
3335  estate->es_output_cid,
3336  lockmode, LockWaitBlock,
3337  lockflags,
3338  &tmfd);
3339 
3340  switch (test)
3341  {
3342  case TM_SelfModified:
3343 
3344  /*
3345  * The target tuple was already updated or deleted by the
3346  * current command, or by a later command in the current
3347  * transaction. We ignore the tuple in the former case, and
3348  * throw error in the latter case, for the same reasons
3349  * enumerated in ExecUpdate and ExecDelete in
3350  * nodeModifyTable.c.
3351  */
3352  if (tmfd.cmax != estate->es_output_cid)
3353  ereport(ERROR,
3354  (errcode(ERRCODE_TRIGGERED_DATA_CHANGE_VIOLATION),
3355  errmsg("tuple to be updated was already modified by an operation triggered by the current command"),
3356  errhint("Consider using an AFTER trigger instead of a BEFORE trigger to propagate changes to other rows.")));
3357 
3358  /* treat it as deleted; do not process */
3359  return false;
3360 
3361  case TM_Ok:
3362  if (tmfd.traversed)
3363  {
3364  TupleTableSlot *epqslot;
3365 
3366  epqslot = EvalPlanQual(estate,
3367  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  return false;
3378 
3379  *newSlot = epqslot;
3380  }
3381  break;
3382 
3383  case TM_Updated:
3385  ereport(ERROR,
3386  (errcode(ERRCODE_T_R_SERIALIZATION_FAILURE),
3387  errmsg("could not serialize access due to concurrent update")));
3388  elog(ERROR, "unexpected table_tuple_lock status: %u", test);
3389  break;
3390 
3391  case TM_Deleted:
3393  ereport(ERROR,
3394  (errcode(ERRCODE_T_R_SERIALIZATION_FAILURE),
3395  errmsg("could not serialize access due to concurrent delete")));
3396  /* tuple was deleted */
3397  return false;
3398 
3399  case TM_Invisible:
3400  elog(ERROR, "attempted to lock invisible tuple");
3401  break;
3402 
3403  default:
3404  elog(ERROR, "unrecognized table_tuple_lock status: %u", test);
3405  return false; /* keep compiler quiet */
3406  }
3407  }
3408  else
3409  {
3410  /*
3411  * We expect the tuple to be present, thus very simple error handling
3412  * suffices.
3413  */
3414  if (!table_tuple_fetch_row_version(relation, tid, SnapshotAny,
3415  oldslot))
3416  elog(ERROR, "failed to fetch tuple for trigger");
3417  }
3418 
3419  return true;
3420 }
3421 
3422 /*
3423  * Is trigger enabled to fire?
3424  */
3425 static bool
3427  Trigger *trigger, TriggerEvent event,
3428  Bitmapset *modifiedCols,
3429  TupleTableSlot *oldslot, TupleTableSlot *newslot)
3430 {
3431  /* Check replication-role-dependent enable state */
3433  {
3434  if (trigger->tgenabled == TRIGGER_FIRES_ON_ORIGIN ||
3435  trigger->tgenabled == TRIGGER_DISABLED)
3436  return false;
3437  }
3438  else /* ORIGIN or LOCAL role */
3439  {
3440  if (trigger->tgenabled == TRIGGER_FIRES_ON_REPLICA ||
3441  trigger->tgenabled == TRIGGER_DISABLED)
3442  return false;
3443  }
3444 
3445  /*
3446  * Check for column-specific trigger (only possible for UPDATE, and in
3447  * fact we *must* ignore tgattr for other event types)
3448  */
3449  if (trigger->tgnattr > 0 && TRIGGER_FIRED_BY_UPDATE(event))
3450  {
3451  int i;
3452  bool modified;
3453 
3454  modified = false;
3455  for (i = 0; i < trigger->tgnattr; i++)
3456  {
3458  modifiedCols))
3459  {
3460  modified = true;
3461  break;
3462  }
3463  }
3464  if (!modified)
3465  return false;
3466  }
3467 
3468  /* Check for WHEN clause */
3469  if (trigger->tgqual)
3470  {
3471  ExprState **predicate;
3472  ExprContext *econtext;
3473  MemoryContext oldContext;
3474  int i;
3475 
3476  Assert(estate != NULL);
3477 
3478  /*
3479  * trigger is an element of relinfo->ri_TrigDesc->triggers[]; find the
3480  * matching element of relinfo->ri_TrigWhenExprs[]
3481  */
3482  i = trigger - relinfo->ri_TrigDesc->triggers;
3483  predicate = &relinfo->ri_TrigWhenExprs[i];
3484 
3485  /*
3486  * If first time through for this WHEN expression, build expression
3487  * nodetrees for it. Keep them in the per-query memory context so
3488  * they'll survive throughout the query.
3489  */
3490  if (*predicate == NULL)
3491  {
3492  Node *tgqual;
3493 
3494  oldContext = MemoryContextSwitchTo(estate->es_query_cxt);
3495  tgqual = stringToNode(trigger->tgqual);
3496  /* Change references to OLD and NEW to INNER_VAR and OUTER_VAR */
3499  /* ExecPrepareQual wants implicit-AND form */
3500  tgqual = (Node *) make_ands_implicit((Expr *) tgqual);
3501  *predicate = ExecPrepareQual((List *) tgqual, estate);
3502  MemoryContextSwitchTo(oldContext);
3503  }
3504 
3505  /*
3506  * We will use the EState's per-tuple context for evaluating WHEN
3507  * expressions (creating it if it's not already there).
3508  */
3509  econtext = GetPerTupleExprContext(estate);
3510 
3511  /*
3512  * Finally evaluate the expression, making the old and/or new tuples
3513  * available as INNER_VAR/OUTER_VAR respectively.
3514  */
3515  econtext->ecxt_innertuple = oldslot;
3516  econtext->ecxt_outertuple = newslot;
3517  if (!ExecQual(*predicate, econtext))
3518  return false;
3519  }
3520 
3521  return true;
3522 }
3523 
3524 
3525 /* ----------
3526  * After-trigger stuff
3527  *
3528  * The AfterTriggersData struct holds data about pending AFTER trigger events
3529  * during the current transaction tree. (BEFORE triggers are fired
3530  * immediately so we don't need any persistent state about them.) The struct
3531  * and most of its subsidiary data are kept in TopTransactionContext; however
3532  * some data that can be discarded sooner appears in the CurTransactionContext
3533  * of the relevant subtransaction. Also, the individual event records are
3534  * kept in a separate sub-context of TopTransactionContext. This is done
3535  * mainly so that it's easy to tell from a memory context dump how much space
3536  * is being eaten by trigger events.
3537  *
3538  * Because the list of pending events can grow large, we go to some
3539  * considerable effort to minimize per-event memory consumption. The event
3540  * records are grouped into chunks and common data for similar events in the
3541  * same chunk is only stored once.
3542  *
3543  * XXX We need to be able to save the per-event data in a file if it grows too
3544  * large.
3545  * ----------
3546  */
3547 
3548 /* Per-trigger SET CONSTRAINT status */
3550 {
3554 
3556 
3557 /*
3558  * SET CONSTRAINT intra-transaction status.
3559  *
3560  * We make this a single palloc'd object so it can be copied and freed easily.
3561  *
3562  * all_isset and all_isdeferred are used to keep track
3563  * of SET CONSTRAINTS ALL {DEFERRED, IMMEDIATE}.
3564  *
3565  * trigstates[] stores per-trigger tgisdeferred settings.
3566  */
3568 {
3571  int numstates; /* number of trigstates[] entries in use */
3572  int numalloc; /* allocated size of trigstates[] */
3573  SetConstraintTriggerData trigstates[FLEXIBLE_ARRAY_MEMBER];
3575 
3577 
3578 
3579 /*
3580  * Per-trigger-event data
3581  *
3582  * The actual per-event data, AfterTriggerEventData, includes DONE/IN_PROGRESS
3583  * status bits and up to two tuple CTIDs. Each event record also has an
3584  * associated AfterTriggerSharedData that is shared across all instances of
3585  * similar events within a "chunk".
3586  *
3587  * For row-level triggers, we arrange not to waste storage on unneeded ctid
3588  * fields. Updates of regular tables use two; inserts and deletes of regular
3589  * tables use one; foreign tables always use zero and save the tuple(s) to a
3590  * tuplestore. AFTER_TRIGGER_FDW_FETCH directs AfterTriggerExecute() to
3591  * retrieve a fresh tuple or pair of tuples from that tuplestore, while
3592  * AFTER_TRIGGER_FDW_REUSE directs it to use the most-recently-retrieved
3593  * tuple(s). This permits storing tuples once regardless of the number of
3594  * row-level triggers on a foreign table.
3595  *
3596  * Note that we need triggers on foreign tables to be fired in exactly the
3597  * order they were queued, so that the tuples come out of the tuplestore in
3598  * the right order. To ensure that, we forbid deferrable (constraint)
3599  * triggers on foreign tables. This also ensures that such triggers do not
3600  * get deferred into outer trigger query levels, meaning that it's okay to
3601  * destroy the tuplestore at the end of the query level.
3602  *
3603  * Statement-level triggers always bear AFTER_TRIGGER_1CTID, though they
3604  * require no ctid field. We lack the flag bit space to neatly represent that
3605  * distinct case, and it seems unlikely to be worth much trouble.
3606  *
3607  * Note: ats_firing_id is initially zero and is set to something else when
3608  * AFTER_TRIGGER_IN_PROGRESS is set. It indicates which trigger firing
3609  * cycle the trigger will be fired in (or was fired in, if DONE is set).
3610  * Although this is mutable state, we can keep it in AfterTriggerSharedData
3611  * because all instances of the same type of event in a given event list will
3612  * be fired at the same time, if they were queued between the same firing
3613  * cycles. So we need only ensure that ats_firing_id is zero when attaching
3614  * a new event to an existing AfterTriggerSharedData record.
3615  */
3617 
3618 #define AFTER_TRIGGER_OFFSET 0x0FFFFFFF /* must be low-order bits */
3619 #define AFTER_TRIGGER_DONE 0x10000000
3620 #define AFTER_TRIGGER_IN_PROGRESS 0x20000000
3621 /* bits describing the size and tuple sources of this event */
3622 #define AFTER_TRIGGER_FDW_REUSE 0x00000000
3623 #define AFTER_TRIGGER_FDW_FETCH 0x80000000
3624 #define AFTER_TRIGGER_1CTID 0x40000000
3625 #define AFTER_TRIGGER_2CTID 0xC0000000
3626 #define AFTER_TRIGGER_TUP_BITS 0xC0000000
3627 
3629 
3631 {
3632  TriggerEvent ats_event; /* event type indicator, see trigger.h */
3633  Oid ats_tgoid; /* the trigger's ID */
3634  Oid ats_relid; /* the relation it's on */
3635  CommandId ats_firing_id; /* ID for firing cycle */
3636  struct AfterTriggersTableData *ats_table; /* transition table access */
3638 
3640 
3642 {
3643  TriggerFlags ate_flags; /* status bits and offset to shared data */
3644  ItemPointerData ate_ctid1; /* inserted, deleted, or old updated tuple */
3645  ItemPointerData ate_ctid2; /* new updated tuple */
3647 
3648 /* AfterTriggerEventData, minus ate_ctid2 */
3650 {
3651  TriggerFlags ate_flags; /* status bits and offset to shared data */
3652  ItemPointerData ate_ctid1; /* inserted, deleted, or old updated tuple */
3654 
3655 /* AfterTriggerEventData, minus ate_ctid1 and ate_ctid2 */
3657 {
3658  TriggerFlags ate_flags; /* status bits and offset to shared data */
3660 
3661 #define SizeofTriggerEvent(evt) \
3662  (((evt)->ate_flags & AFTER_TRIGGER_TUP_BITS) == AFTER_TRIGGER_2CTID ? \
3663  sizeof(AfterTriggerEventData) : \
3664  ((evt)->ate_flags & AFTER_TRIGGER_TUP_BITS) == AFTER_TRIGGER_1CTID ? \
3665  sizeof(AfterTriggerEventDataOneCtid) : \
3666  sizeof(AfterTriggerEventDataZeroCtids))
3667 
3668 #define GetTriggerSharedData(evt) \
3669  ((AfterTriggerShared) ((char *) (evt) + ((evt)->ate_flags & AFTER_TRIGGER_OFFSET)))
3670 
3671 /*
3672  * To avoid palloc overhead, we keep trigger events in arrays in successively-
3673  * larger chunks (a slightly more sophisticated version of an expansible
3674  * array). The space between CHUNK_DATA_START and freeptr is occupied by
3675  * AfterTriggerEventData records; the space between endfree and endptr is
3676  * occupied by AfterTriggerSharedData records.
3677  */
3679 {
3680  struct AfterTriggerEventChunk *next; /* list link */
3681  char *freeptr; /* start of free space in chunk */
3682  char *endfree; /* end of free space in chunk */
3683  char *endptr; /* end of chunk */
3684  /* event data follows here */
3686 
3687 #define CHUNK_DATA_START(cptr) ((char *) (cptr) + MAXALIGN(sizeof(AfterTriggerEventChunk)))
3688 
3689 /* A list of events */
3691 {
3694  char *tailfree; /* freeptr of tail chunk */
3696 
3697 /* Macros to help in iterating over a list of events */
3698 #define for_each_chunk(cptr, evtlist) \
3699  for (cptr = (evtlist).head; cptr != NULL; cptr = cptr->next)
3700 #define for_each_event(eptr, cptr) \
3701  for (eptr = (AfterTriggerEvent) CHUNK_DATA_START(cptr); \
3702  (char *) eptr < (cptr)->freeptr; \
3703  eptr = (AfterTriggerEvent) (((char *) eptr) + SizeofTriggerEvent(eptr)))
3704 /* Use this if no special per-chunk processing is needed */
3705 #define for_each_event_chunk(eptr, cptr, evtlist) \
3706  for_each_chunk(cptr, evtlist) for_each_event(eptr, cptr)
3707 
3708 /* Macros for iterating from a start point that might not be list start */
3709 #define for_each_chunk_from(cptr) \
3710  for (; cptr != NULL; cptr = cptr->next)
3711 #define for_each_event_from(eptr, cptr) \
3712  for (; \
3713  (char *) eptr < (cptr)->freeptr; \
3714  eptr = (AfterTriggerEvent) (((char *) eptr) + SizeofTriggerEvent(eptr)))
3715 
3716 
3717 /*
3718  * All per-transaction data for the AFTER TRIGGERS module.
3719  *
3720  * AfterTriggersData has the following fields:
3721  *
3722  * firing_counter is incremented for each call of afterTriggerInvokeEvents.
3723  * We mark firable events with the current firing cycle's ID so that we can
3724  * tell which ones to work on. This ensures sane behavior if a trigger
3725  * function chooses to do SET CONSTRAINTS: the inner SET CONSTRAINTS will
3726  * only fire those events that weren't already scheduled for firing.
3727  *
3728  * state keeps track of the transaction-local effects of SET CONSTRAINTS.
3729  * This is saved and restored across failed subtransactions.
3730  *
3731  * events is the current list of deferred events. This is global across
3732  * all subtransactions of the current transaction. In a subtransaction
3733  * abort, we know that the events added by the subtransaction are at the
3734  * end of the list, so it is relatively easy to discard them. The event
3735  * list chunks themselves are stored in event_cxt.
3736  *
3737  * query_depth is the current depth of nested AfterTriggerBeginQuery calls
3738  * (-1 when the stack is empty).
3739  *
3740  * query_stack[query_depth] is the per-query-level data, including these fields:
3741  *
3742  * events is a list of AFTER trigger events queued by the current query.
3743  * None of these are valid until the matching AfterTriggerEndQuery call
3744  * occurs. At that point we fire immediate-mode triggers, and append any
3745  * deferred events to the main events list.
3746  *
3747  * fdw_tuplestore is a tuplestore containing the foreign-table tuples
3748  * needed by events queued by the current query. (Note: we use just one
3749  * tuplestore even though more than one foreign table might be involved.
3750  * This is okay because tuplestores don't really care what's in the tuples
3751  * they store; but it's possible that someday it'd break.)
3752  *
3753  * tables is a List of AfterTriggersTableData structs for target tables
3754  * of the current query (see below).
3755  *
3756  * maxquerydepth is just the allocated length of query_stack.
3757  *
3758  * trans_stack holds per-subtransaction data, including these fields:
3759  *
3760  * state is NULL or a pointer to a saved copy of the SET CONSTRAINTS
3761  * state data. Each subtransaction level that modifies that state first
3762  * saves a copy, which we use to restore the state if we abort.
3763  *
3764  * events is a copy of the events head/tail pointers,
3765  * which we use to restore those values during subtransaction abort.
3766  *
3767  * query_depth is the subtransaction-start-time value of query_depth,
3768  * which we similarly use to clean up at subtransaction abort.
3769  *
3770  * firing_counter is the subtransaction-start-time value of firing_counter.
3771  * We use this to recognize which deferred triggers were fired (or marked
3772  * for firing) within an aborted subtransaction.
3773  *
3774  * We use GetCurrentTransactionNestLevel() to determine the correct array
3775  * index in trans_stack. maxtransdepth is the number of allocated entries in
3776  * trans_stack. (By not keeping our own stack pointer, we can avoid trouble
3777  * in cases where errors during subxact abort cause multiple invocations
3778  * of AfterTriggerEndSubXact() at the same nesting depth.)
3779  *
3780  * We create an AfterTriggersTableData struct for each target table of the
3781  * current query, and each operation mode (INSERT/UPDATE/DELETE), that has
3782  * either transition tables or statement-level triggers. This is used to
3783  * hold the relevant transition tables, as well as info tracking whether
3784  * we already queued the statement triggers. (We use that info to prevent
3785  * firing the same statement triggers more than once per statement, or really
3786  * once per transition table set.) These structs, along with the transition
3787  * table tuplestores, live in the (sub)transaction's CurTransactionContext.
3788  * That's sufficient lifespan because we don't allow transition tables to be
3789  * used by deferrable triggers, so they only need to survive until
3790  * AfterTriggerEndQuery.
3791  */
3795 
3796 typedef struct AfterTriggersData
3797 {
3798  CommandId firing_counter; /* next firing ID to assign */
3799  SetConstraintState state; /* the active S C state */
3800  AfterTriggerEventList events; /* deferred-event list */
3801  MemoryContext event_cxt; /* memory context for events, if any */
3802 
3803  /* per-query-level data: */
3804  AfterTriggersQueryData *query_stack; /* array of structs shown below */
3805  int query_depth; /* current index in above array */
3806  int maxquerydepth; /* allocated len of above array */
3807 
3808  /* per-subtransaction-level data: */
3809  AfterTriggersTransData *trans_stack; /* array of structs shown below */
3810  int maxtransdepth; /* allocated len of above array */
3812 
3814 {
3815  AfterTriggerEventList events; /* events pending from this query */
3816  Tuplestorestate *fdw_tuplestore; /* foreign tuples for said events */
3817  List *tables; /* list of AfterTriggersTableData, see below */
3818 };
3819 
3821 {
3822  /* these fields are just for resetting at subtrans abort: */
3823  SetConstraintState state; /* saved S C state, or NULL if not yet saved */
3824  AfterTriggerEventList events; /* saved list pointer */
3825  int query_depth; /* saved query_depth */
3826  CommandId firing_counter; /* saved firing_counter */
3827 };
3828 
3830 {
3831  /* relid + cmdType form the lookup key for these structs: */
3832  Oid relid; /* target table's OID */
3833  CmdType cmdType; /* event type, CMD_INSERT/UPDATE/DELETE */
3834  bool closed; /* true when no longer OK to add tuples */
3835  bool before_trig_done; /* did we already queue BS triggers? */
3836  bool after_trig_done; /* did we already queue AS triggers? */
3837  AfterTriggerEventList after_trig_events; /* if so, saved list pointer */
3838  Tuplestorestate *old_tuplestore; /* "old" transition table, if any */
3839  Tuplestorestate *new_tuplestore; /* "new" transition table, if any */
3840  TupleTableSlot *storeslot; /* for converting to tuplestore's format */
3841 };
3842 
3844 
3845 static void AfterTriggerExecute(EState *estate,
3846  AfterTriggerEvent event,
3847  ResultRelInfo *relInfo,
3848  TriggerDesc *trigdesc,
3849  FmgrInfo *finfo,
3850  Instrumentation *instr,
3851  MemoryContext per_tuple_context,
3852  TupleTableSlot *trig_tuple_slot1,
3853  TupleTableSlot *trig_tuple_slot2);
3855  CmdType cmdType);
3857 static SetConstraintState SetConstraintStateCreate(int numalloc);
3860  Oid tgoid, bool tgisdeferred);
3861 static void cancel_prior_stmt_triggers(Oid relid, CmdType cmdType, int tgevent);
3862 
3863 
3864 /*
3865  * Get the FDW tuplestore for the current trigger query level, creating it
3866  * if necessary.
3867  */
3868 static Tuplestorestate *
3870 {
3871  Tuplestorestate *ret;
3872 
3873  ret = afterTriggers.query_stack[afterTriggers.query_depth].fdw_tuplestore;
3874  if (ret == NULL)
3875  {
3876  MemoryContext oldcxt;
3877  ResourceOwner saveResourceOwner;
3878 
3879  /*
3880  * Make the tuplestore valid until end of subtransaction. We really
3881  * only need it until AfterTriggerEndQuery().
3882  */
3884  saveResourceOwner = CurrentResourceOwner;
3886 
3887  ret = tuplestore_begin_heap(false, false, work_mem);
3888 
3889  CurrentResourceOwner = saveResourceOwner;
3890  MemoryContextSwitchTo(oldcxt);
3891 
3892  afterTriggers.query_stack[afterTriggers.query_depth].fdw_tuplestore = ret;
3893  }
3894 
3895  return ret;
3896 }
3897 
3898 /* ----------
3899  * afterTriggerCheckState()
3900  *
3901  * Returns true if the trigger event is actually in state DEFERRED.
3902  * ----------
3903  */
3904 static bool
3905 afterTriggerCheckState(AfterTriggerShared evtshared)
3906 {
3907  Oid tgoid = evtshared->ats_tgoid;
3908  SetConstraintState state = afterTriggers.state;
3909  int i;
3910 
3911  /*
3912  * For not-deferrable triggers (i.e. normal AFTER ROW triggers and
3913  * constraints declared NOT DEFERRABLE), the state is always false.
3914  */
3915  if ((evtshared->ats_event & AFTER_TRIGGER_DEFERRABLE) == 0)
3916  return false;
3917 
3918  /*
3919  * If constraint state exists, SET CONSTRAINTS might have been executed
3920  * either for this trigger or for all triggers.
3921  */
3922  if (state != NULL)
3923  {
3924  /* Check for SET CONSTRAINTS for this specific trigger. */
3925  for (i = 0; i < state->numstates; i++)
3926  {
3927  if (state->trigstates[i].sct_tgoid == tgoid)
3928  return state->trigstates[i].sct_tgisdeferred;
3929  }
3930 
3931  /* Check for SET CONSTRAINTS ALL. */
3932  if (state->all_isset)
3933  return state->all_isdeferred;
3934  }
3935 
3936  /*
3937  * Otherwise return the default state for the trigger.
3938  */
3939  return ((evtshared->ats_event & AFTER_TRIGGER_INITDEFERRED) != 0);
3940 }
3941 
3942 
3943 /* ----------
3944  * afterTriggerAddEvent()
3945  *
3946  * Add a new trigger event to the specified queue.
3947  * The passed-in event data is copied.
3948  * ----------
3949  */
3950 static void
3952  AfterTriggerEvent event, AfterTriggerShared evtshared)
3953 {
3954  Size eventsize = SizeofTriggerEvent(event);
3955  Size needed = eventsize + sizeof(AfterTriggerSharedData);
3956  AfterTriggerEventChunk *chunk;
3957  AfterTriggerShared newshared;
3958  AfterTriggerEvent newevent;
3959 
3960  /*
3961  * If empty list or not enough room in the tail chunk, make a new chunk.
3962  * We assume here that a new shared record will always be needed.
3963  */
3964  chunk = events->tail;
3965  if (chunk == NULL ||
3966  chunk->endfree - chunk->freeptr < needed)
3967  {
3968  Size chunksize;
3969 
3970  /* Create event context if we didn't already */
3971  if (afterTriggers.event_cxt == NULL)
3972  afterTriggers.event_cxt =
3974  "AfterTriggerEvents",
3976 
3977  /*
3978  * Chunk size starts at 1KB and is allowed to increase up to 1MB.
3979  * These numbers are fairly arbitrary, though there is a hard limit at
3980  * AFTER_TRIGGER_OFFSET; else we couldn't link event records to their
3981  * shared records using the available space in ate_flags. Another
3982  * constraint is that if the chunk size gets too huge, the search loop
3983  * below would get slow given a (not too common) usage pattern with
3984  * many distinct event types in a chunk. Therefore, we double the
3985  * preceding chunk size only if there weren't too many shared records
3986  * in the preceding chunk; otherwise we halve it. This gives us some
3987  * ability to adapt to the actual usage pattern of the current query
3988  * while still having large chunk sizes in typical usage. All chunk
3989  * sizes used should be MAXALIGN multiples, to ensure that the shared
3990  * records will be aligned safely.
3991  */
3992 #define MIN_CHUNK_SIZE 1024
3993 #define MAX_CHUNK_SIZE (1024*1024)
3994 
3995 #if MAX_CHUNK_SIZE > (AFTER_TRIGGER_OFFSET+1)
3996 #error MAX_CHUNK_SIZE must not exceed AFTER_TRIGGER_OFFSET
3997 #endif
3998 
3999  if (chunk == NULL)
4000  chunksize = MIN_CHUNK_SIZE;
4001  else
4002  {
4003  /* preceding chunk size... */
4004  chunksize = chunk->endptr - (char *) chunk;
4005  /* check number of shared records in preceding chunk */
4006  if ((chunk->endptr - chunk->endfree) <=
4007  (100 * sizeof(AfterTriggerSharedData)))
4008  chunksize *= 2; /* okay, double it */
4009  else
4010  chunksize /= 2; /* too many shared records */
4011  chunksize = Min(chunksize, MAX_CHUNK_SIZE);
4012  }
4013  chunk = MemoryContextAlloc(afterTriggers.event_cxt, chunksize);
4014  chunk->next = NULL;
4015  chunk->freeptr = CHUNK_DATA_START(chunk);
4016  chunk->endptr = chunk->endfree = (char *) chunk + chunksize;
4017  Assert(chunk->endfree - chunk->freeptr >= needed);
4018 
4019  if (events->head == NULL)
4020  events->head = chunk;
4021  else
4022  events->tail->next = chunk;
4023  events->tail = chunk;
4024  /* events->tailfree is now out of sync, but we'll fix it below */
4025  }
4026 
4027  /*
4028  * Try to locate a matching shared-data record already in the chunk. If
4029  * none, make a new one.
4030  */
4031  for (newshared = ((AfterTriggerShared) chunk->endptr) - 1;
4032  (char *) newshared >= chunk->endfree;
4033  newshared--)
4034  {
4035  if (newshared->ats_tgoid == evtshared->ats_tgoid &&
4036  newshared->ats_relid == evtshared->ats_relid &&
4037  newshared->ats_event == evtshared->ats_event &&
4038  newshared->ats_table == evtshared->ats_table &&
4039  newshared->ats_firing_id == 0)
4040  break;
4041  }
4042  if ((char *) newshared < chunk->endfree)
4043  {
4044  *newshared = *evtshared;
4045  newshared->ats_firing_id = 0; /* just to be sure */
4046  chunk->endfree = (char *) newshared;
4047  }
4048 
4049  /* Insert the data */
4050  newevent = (AfterTriggerEvent) chunk->freeptr;
4051  memcpy(newevent, event, eventsize);
4052  /* ... and link the new event to its shared record */
4053  newevent->ate_flags &= ~AFTER_TRIGGER_OFFSET;
4054  newevent->ate_flags |= (char *) newshared - (char *) newevent;
4055 
4056  chunk->freeptr += eventsize;
4057  events->tailfree = chunk->freeptr;
4058 }
4059 
4060 /* ----------
4061  * afterTriggerFreeEventList()
4062  *
4063  * Free all the event storage in the given list.
4064  * ----------
4065  */
4066 static void
4068 {
4069  AfterTriggerEventChunk *chunk;
4070 
4071  while ((chunk = events->head) != NULL)
4072  {
4073  events->head = chunk->next;
4074  pfree(chunk);
4075  }
4076  events->tail = NULL;
4077  events->tailfree = NULL;
4078 }
4079 
4080 /* ----------
4081  * afterTriggerRestoreEventList()
4082  *
4083  * Restore an event list to its prior length, removing all the events
4084  * added since it had the value old_events.
4085  * ----------
4086  */
4087 static void
4089  const AfterTriggerEventList *old_events)
4090 {
4091  AfterTriggerEventChunk *chunk;
4092  AfterTriggerEventChunk *next_chunk;
4093 
4094  if (old_events->tail == NULL)
4095  {
4096  /* restoring to a completely empty state, so free everything */
4097  afterTriggerFreeEventList(events);
4098  }
4099  else
4100  {
4101  *events = *old_events;
4102  /* free any chunks after the last one we want to keep */
4103  for (chunk = events->tail->next; chunk != NULL; chunk = next_chunk)
4104  {
4105  next_chunk = chunk->next;
4106  pfree(chunk);
4107  }
4108  /* and clean up the tail chunk to be the right length */
4109  events->tail->next = NULL;
4110  events->tail->freeptr = events->tailfree;
4111 
4112  /*
4113  * We don't make any effort to remove now-unused shared data records.
4114  * They might still be useful, anyway.
4115  */
4116  }
4117 }
4118 
4119 /* ----------
4120  * afterTriggerDeleteHeadEventChunk()
4121  *
4122  * Remove the first chunk of events from the query level's event list.
4123  * Keep any event list pointers elsewhere in the query level's data
4124  * structures in sync.
4125  * ----------
4126  */
4127 static void
4129 {
4130  AfterTriggerEventChunk *target = qs->events.head;
4131  ListCell *lc;
4132 
4133  Assert(target && target->next);
4134 
4135  /*
4136  * First, update any pointers in the per-table data, so that they won't be
4137  * dangling. Resetting obsoleted pointers to NULL will make
4138  * cancel_prior_stmt_triggers start from the list head, which is fine.
4139  */
4140  foreach(lc, qs->tables)
4141  {
4143 
4144  if (table->after_trig_done &&
4145  table->after_trig_events.tail == target)
4146  {
4147  table->after_trig_events.head = NULL;
4148  table->after_trig_events.tail = NULL;
4149  table->after_trig_events.tailfree = NULL;
4150  }
4151  }
4152 
4153  /* Now we can flush the head chunk */
4154  qs->events.head = target->next;
4155  pfree(target);
4156 }
4157 
4158 
4159 /* ----------
4160  * AfterTriggerExecute()
4161  *
4162  * Fetch the required tuples back from the heap and fire one
4163  * single trigger function.
4164  *
4165  * Frequently, this will be fired many times in a row for triggers of
4166  * a single relation. Therefore, we cache the open relation and provide
4167  * fmgr lookup cache space at the caller level. (For triggers fired at
4168  * the end of a query, we can even piggyback on the executor's state.)
4169  *
4170  * event: event currently being fired.
4171  * rel: open relation for event.
4172  * trigdesc: working copy of rel's trigger info.
4173  * finfo: array of fmgr lookup cache entries (one per trigger in trigdesc).
4174  * instr: array of EXPLAIN ANALYZE instrumentation nodes (one per trigger),
4175  * or NULL if no instrumentation is wanted.
4176  * per_tuple_context: memory context to call trigger function in.
4177  * trig_tuple_slot1: scratch slot for tg_trigtuple (foreign tables only)
4178  * trig_tuple_slot2: scratch slot for tg_newtuple (foreign tables only)
4179  * ----------
4180  */
4181 static void
4183  AfterTriggerEvent event,
4184  ResultRelInfo *relInfo,
4185  TriggerDesc *trigdesc,
4186  FmgrInfo *finfo, Instrumentation *instr,
4187  MemoryContext per_tuple_context,
4188  TupleTableSlot *trig_tuple_slot1,
4189  TupleTableSlot *trig_tuple_slot2)
4190 {
4191  Relation rel = relInfo->ri_RelationDesc;
4192  AfterTriggerShared evtshared = GetTriggerSharedData(event);
4193  Oid tgoid = evtshared->ats_tgoid;
4194  TriggerData LocTriggerData;
4195  HeapTuple rettuple;
4196  int tgindx;
4197  bool should_free_trig = false;
4198  bool should_free_new = false;
4199 
4200  /*
4201  * Locate trigger in trigdesc.
4202  */
4203  LocTriggerData.tg_trigger = NULL;
4204  LocTriggerData.tg_trigslot = NULL;
4205  LocTriggerData.tg_newslot = NULL;
4206 
4207  for (tgindx = 0; tgindx < trigdesc->numtriggers; tgindx++)
4208  {
4209  if (trigdesc->triggers[tgindx].tgoid == tgoid)
4210  {
4211  LocTriggerData.tg_trigger = &(trigdesc->triggers[tgindx]);
4212  break;
4213  }
4214  }
4215  if (LocTriggerData.tg_trigger == NULL)
4216  elog(ERROR, "could not find trigger %u", tgoid);
4217 
4218  /*
4219  * If doing EXPLAIN ANALYZE, start charging time to this trigger. We want
4220  * to include time spent re-fetching tuples in the trigger cost.
4221  */
4222  if (instr)
4223  InstrStartNode(instr + tgindx);
4224 
4225  /*
4226  * Fetch the required tuple(s).
4227  */
4228  switch (event->ate_flags & AFTER_TRIGGER_TUP_BITS)
4229  {
4231  {
4232  Tuplestorestate *fdw_tuplestore = GetCurrentFDWTuplestore();
4233 
4234  if (!tuplestore_gettupleslot(fdw_tuplestore, true, false,
4235  trig_tuple_slot1))
4236  elog(ERROR, "failed to fetch tuple1 for AFTER trigger");
4237 
4238  if ((evtshared->ats_event & TRIGGER_EVENT_OPMASK) ==
4240  !tuplestore_gettupleslot(fdw_tuplestore, true, false,
4241  trig_tuple_slot2))
4242  elog(ERROR, "failed to fetch tuple2 for AFTER trigger");
4243  }
4244  /* fall through */
4246 
4247  /*
4248  * Store tuple in the slot so that tg_trigtuple does not reference
4249  * tuplestore memory. (It is formally possible for the trigger
4250  * function to queue trigger events that add to the same
4251  * tuplestore, which can push other tuples out of memory.) The
4252  * distinction is academic, because we start with a minimal tuple
4253  * that is stored as a heap tuple, constructed in different memory
4254  * context, in the slot anyway.
4255  */
4256  LocTriggerData.tg_trigslot = trig_tuple_slot1;
4257  LocTriggerData.tg_trigtuple =
4258  ExecFetchSlotHeapTuple(trig_tuple_slot1, true, &should_free_trig);
4259 
4260  LocTriggerData.tg_newslot = trig_tuple_slot2;
4261  LocTriggerData.tg_newtuple =
4262  ((evtshared->ats_event & TRIGGER_EVENT_OPMASK) ==
4264  ExecFetchSlotHeapTuple(trig_tuple_slot2, true, &should_free_new) : NULL;
4265 
4266  break;
4267 
4268  default:
4269  if (ItemPointerIsValid(&(event->ate_ctid1)))
4270  {
4271  LocTriggerData.tg_trigslot = ExecGetTriggerOldSlot(estate, relInfo);
4272 
4273  if (!table_tuple_fetch_row_version(rel, &(event->ate_ctid1),
4274  SnapshotAny,
4275  LocTriggerData.tg_trigslot))
4276  elog(ERROR, "failed to fetch tuple1 for AFTER trigger");
4277  LocTriggerData.tg_trigtuple =
4278  ExecFetchSlotHeapTuple(LocTriggerData.tg_trigslot, false, &should_free_trig);
4279  }
4280  else
4281  {
4282  LocTriggerData.tg_trigtuple = NULL;
4283  }
4284 
4285  /* don't touch ctid2 if not there */
4286  if ((event->ate_flags & AFTER_TRIGGER_TUP_BITS) ==
4288  ItemPointerIsValid(&(event->ate_ctid2)))
4289  {
4290  LocTriggerData.tg_newslot = ExecGetTriggerNewSlot(estate, relInfo);
4291 
4292  if (!table_tuple_fetch_row_version(rel, &(event->ate_ctid2),
4293  SnapshotAny,
4294  LocTriggerData.tg_newslot))
4295  elog(ERROR, "failed to fetch tuple2 for AFTER trigger");
4296  LocTriggerData.tg_newtuple =
4297  ExecFetchSlotHeapTuple(LocTriggerData.tg_newslot, false, &should_free_new);
4298  }
4299  else
4300  {
4301  LocTriggerData.tg_newtuple = NULL;
4302  }
4303  }
4304 
4305  /*
4306  * Set up the tuplestore information to let the trigger have access to
4307  * transition tables. When we first make a transition table available to
4308  * a trigger, mark it "closed" so that it cannot change anymore. If any
4309  * additional events of the same type get queued in the current trigger
4310  * query level, they'll go into new transition tables.
4311  */
4312  LocTriggerData.tg_oldtable = LocTriggerData.tg_newtable = NULL;
4313  if (evtshared->ats_table)
4314  {
4315  if (LocTriggerData.tg_trigger->tgoldtable)
4316  {
4317  LocTriggerData.tg_oldtable = evtshared->ats_table->old_tuplestore;
4318  evtshared->ats_table->closed = true;
4319  }
4320 
4321  if (LocTriggerData.tg_trigger->tgnewtable)
4322  {
4323  LocTriggerData.tg_newtable = evtshared->ats_table->new_tuplestore;
4324  evtshared->ats_table->closed = true;
4325  }
4326  }
4327 
4328  /*
4329  * Setup the remaining trigger information
4330  */
4331  LocTriggerData.type = T_TriggerData;
4332  LocTriggerData.tg_event =
4334  LocTriggerData.tg_relation = rel;
4335 
4336  MemoryContextReset(per_tuple_context);
4337 
4338  /*
4339  * Call the trigger and throw away any possibly returned updated tuple.
4340  * (Don't let ExecCallTriggerFunc measure EXPLAIN time.)
4341  */
4342  rettuple = ExecCallTriggerFunc(&LocTriggerData,
4343  tgindx,
4344  finfo,
4345  NULL,
4346  per_tuple_context);
4347  if (rettuple != NULL &&
4348  rettuple != LocTriggerData.tg_trigtuple &&
4349  rettuple != LocTriggerData.tg_newtuple)
4350  heap_freetuple(rettuple);
4351 
4352  /*
4353  * Release resources
4354  */
4355  if (should_free_trig)
4356  heap_freetuple(LocTriggerData.tg_trigtuple);
4357  if (should_free_new)
4358  heap_freetuple(LocTriggerData.tg_newtuple);
4359 
4360  if (LocTriggerData.tg_trigslot)
4361  ExecClearTuple(LocTriggerData.tg_trigslot);
4362  if (LocTriggerData.tg_newslot)
4363  ExecClearTuple(LocTriggerData.tg_newslot);
4364 
4365  /*
4366  * If doing EXPLAIN ANALYZE, stop charging time to this trigger, and count
4367  * one "tuple returned" (really the number of firings).
4368  */
4369  if (instr)
4370  InstrStopNode(instr + tgindx, 1);
4371 }
4372 
4373 
4374 /*
4375  * afterTriggerMarkEvents()
4376  *
4377  * Scan the given event list for not yet invoked events. Mark the ones
4378  * that can be invoked now with the current firing ID.
4379  *
4380  * If move_list isn't NULL, events that are not to be invoked now are
4381  * transferred to move_list.
4382  *
4383  * When immediate_only is true, do not invoke currently-deferred triggers.
4384  * (This will be false only at main transaction exit.)
4385  *
4386  * Returns true if any invokable events were found.
4387  */
4388 static bool
4390  AfterTriggerEventList *move_list,
4391  bool immediate_only)
4392 {
4393  bool found = false;
4394  AfterTriggerEvent event;
4395  AfterTriggerEventChunk *chunk;
4396 
4397  for_each_event_chunk(event, chunk, *events)
4398  {
4399  AfterTriggerShared evtshared = GetTriggerSharedData(event);
4400  bool defer_it = false;
4401 
4402  if (!(event->ate_flags &
4404  {
4405  /*
4406  * This trigger hasn't been called or scheduled yet. Check if we
4407  * should call it now.
4408  */
4409  if (immediate_only && afterTriggerCheckState(evtshared))
4410  {
4411  defer_it = true;
4412  }
4413  else
4414  {
4415  /*
4416  * Mark it as to be fired in this firing cycle.
4417  */
4418  evtshared->ats_firing_id = afterTriggers.firing_counter;
4419  event->ate_flags |= AFTER_TRIGGER_IN_PROGRESS;
4420  found = true;
4421  }
4422  }
4423 
4424  /*
4425  * If it's deferred, move it to move_list, if requested.
4426  */
4427  if (defer_it && move_list != NULL)
4428  {
4429  /* add it to move_list */
4430  afterTriggerAddEvent(move_list, event, evtshared);
4431  /* mark original copy "done" so we don't do it again */
4432  event->ate_flags |= AFTER_TRIGGER_DONE;
4433  }
4434  }
4435 
4436  return found;
4437 }
4438 
4439 /*
4440  * afterTriggerInvokeEvents()
4441  *
4442  * Scan the given event list for events that are marked as to be fired
4443  * in the current firing cycle, and fire them.
4444  *
4445  * If estate isn't NULL, we use its result relation info to avoid repeated
4446  * openings and closing of trigger target relations. If it is NULL, we
4447  * make one locally to cache the info in case there are multiple trigger
4448  * events per rel.
4449  *
4450  * When delete_ok is true, it's safe to delete fully-processed events.
4451  * (We are not very tense about that: we simply reset a chunk to be empty
4452  * if all its events got fired. The objective here is just to avoid useless
4453  * rescanning of events when a trigger queues new events during transaction
4454  * end, so it's not necessary to worry much about the case where only
4455  * some events are fired.)
4456  *
4457  * Returns true if no unfired events remain in the list (this allows us
4458  * to avoid repeating afterTriggerMarkEvents).
4459  */
4460 static bool
4462  CommandId firing_id,
4463  EState *estate,
4464  bool delete_ok)
4465 {
4466  bool all_fired = true;
4467  AfterTriggerEventChunk *chunk;
4468  MemoryContext per_tuple_context;
4469  bool local_estate = false;
4470  ResultRelInfo *rInfo = NULL;
4471  Relation rel = NULL;
4472  TriggerDesc *trigdesc = NULL;
4473  FmgrInfo *finfo = NULL;
4474  Instrumentation *instr = NULL;
4475  TupleTableSlot *slot1 = NULL,
4476  *slot2 = NULL;
4477 
4478  /* Make a local EState if need be */
4479  if (estate == NULL)
4480  {
4481  estate = CreateExecutorState();
4482  local_estate = true;
4483  }
4484 
4485  /* Make a per-tuple memory context for trigger function calls */
4486  per_tuple_context =
4488  "AfterTriggerTupleContext",
4490 
4491  for_each_chunk(chunk, *events)
4492  {
4493  AfterTriggerEvent event;
4494  bool all_fired_in_chunk = true;
4495 
4496  for_each_event(event, chunk)
4497  {
4498  AfterTriggerShared evtshared = GetTriggerSharedData(event);
4499 
4500  /*
4501  * Is it one for me to fire?
4502  */
4503  if ((event->ate_flags & AFTER_TRIGGER_IN_PROGRESS) &&
4504  evtshared->ats_firing_id == firing_id)
4505  {
4506  /*
4507  * So let's fire it... but first, find the correct relation if
4508  * this is not the same relation as before.
4509  */
4510  if (rel == NULL || RelationGetRelid(rel) != evtshared->ats_relid)
4511  {
4512  rInfo = ExecGetTriggerResultRel(estate, evtshared->ats_relid);
4513  rel = rInfo->ri_RelationDesc;
4514  trigdesc = rInfo->ri_TrigDesc;
4515  finfo = rInfo->ri_TrigFunctions;
4516  instr = rInfo->ri_TrigInstrument;
4517  if (rel->rd_rel->relkind == RELKIND_FOREIGN_TABLE)
4518  {
4519  if (slot1 != NULL)
4520  {
4523  }
4524  slot1 = MakeSingleTupleTableSlot(rel->rd_att,
4526  slot2 = MakeSingleTupleTableSlot(rel->rd_att,
4528  }
4529  if (trigdesc == NULL) /* should not happen */
4530  elog(ERROR, "relation %u has no triggers",
4531  evtshared->ats_relid);
4532  }
4533 
4534  /*
4535  * Fire it. Note that the AFTER_TRIGGER_IN_PROGRESS flag is
4536  * still set, so recursive examinations of the event list
4537  * won't try to re-fire it.
4538  */
4539  AfterTriggerExecute(estate, event, rInfo, trigdesc, finfo, instr,
4540  per_tuple_context, slot1, slot2);
4541 
4542  /*
4543  * Mark the event as done.
4544  */
4545  event->ate_flags &= ~AFTER_TRIGGER_IN_PROGRESS;
4546  event->ate_flags |= AFTER_TRIGGER_DONE;
4547  }
4548  else if (!(event->ate_flags & AFTER_TRIGGER_DONE))
4549  {
4550  /* something remains to be done */
4551  all_fired = all_fired_in_chunk = false;
4552  }
4553  }
4554 
4555  /* Clear the chunk if delete_ok and nothing left of interest */
4556  if (delete_ok && all_fired_in_chunk)
4557  {
4558  chunk->freeptr = CHUNK_DATA_START(chunk);
4559  chunk->endfree = chunk->endptr;
4560 
4561  /*
4562  * If it's last chunk, must sync event list's tailfree too. Note
4563  * that delete_ok must NOT be passed as true if there could be
4564  * additional AfterTriggerEventList values pointing at this event
4565  * list, since we'd fail to fix their copies of tailfree.
4566  */
4567  if (chunk == events->tail)
4568  events->tailfree = chunk->freeptr;
4569  }
4570  }
4571  if (slot1 != NULL)
4572  {
4575  }
4576 
4577  /* Release working resources */
4578  MemoryContextDelete(per_tuple_context);
4579 
4580  if (local_estate)
4581  {
4582  ExecCleanUpTriggerState(estate);
4583  ExecResetTupleTable(estate->es_tupleTable, false);
4584  FreeExecutorState(estate);
4585  }
4586 
4587  return all_fired;
4588 }
4589 
4590 
4591 /*
4592  * GetAfterTriggersTableData
4593  *
4594  * Find or create an AfterTriggersTableData struct for the specified
4595  * trigger event (relation + operation type). Ignore existing structs
4596  * marked "closed"; we don't want to put any additional tuples into them,
4597  * nor change their stmt-triggers-fired state.
4598  *
4599  * Note: the AfterTriggersTableData list is allocated in the current
4600  * (sub)transaction's CurTransactionContext. This is OK because
4601  * we don't need it to live past AfterTriggerEndQuery.
4602  */
4603 static AfterTriggersTableData *
4605 {
4606  AfterTriggersTableData *table;
4608  MemoryContext oldcxt;
4609  ListCell *lc;
4610 
4611  /* Caller should have ensured query_depth is OK. */
4612  Assert(afterTriggers.query_depth >= 0 &&
4613  afterTriggers.query_depth < afterTriggers.maxquerydepth);
4614  qs = &afterTriggers.query_stack[afterTriggers.query_depth];
4615 
4616  foreach(lc, qs->tables)
4617  {
4618  table = (AfterTriggersTableData *) lfirst(lc);
4619  if (table->relid == relid && table->cmdType == cmdType &&
4620  !table->closed)
4621  return table;
4622  }
4623 
4625 
4627  table->relid = relid;
4628  table->cmdType = cmdType;
4629  qs->tables = lappend(qs->tables, table);
4630 
4631  MemoryContextSwitchTo(oldcxt);
4632 
4633  return table;
4634 }
4635 
4636 
4637 /*
4638  * MakeTransitionCaptureState
4639  *
4640  * Make a TransitionCaptureState object for the given TriggerDesc, target
4641  * relation, and operation type. The TCS object holds all the state needed
4642  * to decide whether to capture tuples in transition tables.
4643  *
4644  * If there are no triggers in 'trigdesc' that request relevant transition
4645  * tables, then return NULL.
4646  *
4647  * The resulting object can be passed to the ExecAR* functions. The caller
4648  * should set tcs_map or tcs_original_insert_tuple as appropriate when dealing
4649  * with child tables.
4650  *
4651  * Note that we copy the flags from a parent table into this struct (rather
4652  * than subsequently using the relation's TriggerDesc directly) so that we can
4653  * use it to control collection of transition tuples from child tables.
4654  *
4655  * Per SQL spec, all operations of the same kind (INSERT/UPDATE/DELETE)
4656  * on the same table during one query should share one transition table.
4657  * Therefore, the Tuplestores are owned by an AfterTriggersTableData struct
4658  * looked up using the table OID + CmdType, and are merely referenced by
4659  * the TransitionCaptureState objects we hand out to callers.
4660  */
4663 {
4665  bool need_old,
4666  need_new;
4667  AfterTriggersTableData *table;
4668  MemoryContext oldcxt;
4669  ResourceOwner saveResourceOwner;
4670 
4671  if (trigdesc == NULL)
4672  return NULL;
4673 
4674  /* Detect which table(s) we need. */
4675  switch (cmdType)
4676  {
4677  case CMD_INSERT:
4678  need_old = false;
4679  need_new = trigdesc->trig_insert_new_table;
4680  break;
4681  case CMD_UPDATE:
4682  need_old = trigdesc->trig_update_old_table;
4683  need_new = trigdesc->trig_update_new_table;
4684  break;
4685  case CMD_DELETE:
4686  need_old = trigdesc->trig_delete_old_table;
4687  need_new = false;
4688  break;
4689  default:
4690  elog(ERROR, "unexpected CmdType: %d", (int) cmdType);
4691  need_old = need_new = false; /* keep compiler quiet */
4692  break;
4693  }
4694  if (!need_old && !need_new)
4695  return NULL;
4696 
4697  /* Check state, like AfterTriggerSaveEvent. */
4698  if (afterTriggers.query_depth < 0)
4699  elog(ERROR, "MakeTransitionCaptureState() called outside of query");
4700 
4701  /* Be sure we have enough space to record events at this query depth. */
4702  if (afterTriggers.query_depth >= afterTriggers.maxquerydepth)
4704 
4705  /*
4706  * Find or create an AfterTriggersTableData struct to hold the
4707  * tuplestore(s). If there's a matching struct but it's marked closed,
4708  * ignore it; we need a newer one.
4709  *
4710  * Note: the AfterTriggersTableData list, as well as the tuplestores, are
4711  * allocated in the current (sub)transaction's CurTransactionContext, and
4712  * the tuplestores are managed by the (sub)transaction's resource owner.
4713  * This is sufficient lifespan because we do not allow triggers using
4714  * transition tables to be deferrable; they will be fired during
4715  * AfterTriggerEndQuery, after which it's okay to delete the data.
4716  */
4717  table = GetAfterTriggersTableData(relid, cmdType);
4718 
4719  /* Now create required tuplestore(s), if we don't have them already. */
4721  saveResourceOwner = CurrentResourceOwner;
4723 
4724  if (need_old && table->old_tuplestore == NULL)
4725  table->old_tuplestore = tuplestore_begin_heap(false, false, work_mem);
4726  if (need_new && table->new_tuplestore == NULL)
4727  table->new_tuplestore = tuplestore_begin_heap(false, false, work_mem);
4728 
4729  CurrentResourceOwner = saveResourceOwner;
4730  MemoryContextSwitchTo(oldcxt);
4731 
4732  /* Now build the TransitionCaptureState struct, in caller's context */
4734  state->tcs_delete_old_table = trigdesc->trig_delete_old_table;
4735  state->tcs_update_old_table = trigdesc->trig_update_old_table;
4736  state->tcs_update_new_table = trigdesc->trig_update_new_table;
4737  state->tcs_insert_new_table = trigdesc->trig_insert_new_table;
4738  state->tcs_private = table;
4739 
4740  return state;
4741 }
4742 
4743 
4744 /* ----------
4745  * AfterTriggerBeginXact()
4746  *
4747  * Called at transaction start (either BEGIN or implicit for single
4748  * statement outside of transaction block).
4749  * ----------
4750  */
4751 void
4753 {
4754  /*
4755  * Initialize after-trigger state structure to empty
4756  */
4757  afterTriggers.firing_counter = (CommandId) 1; /* mustn't be 0 */
4758  afterTriggers.query_depth = -1;
4759 
4760  /*
4761  * Verify that there is no leftover state remaining. If these assertions
4762  * trip, it means that AfterTriggerEndXact wasn't called or didn't clean
4763  * up properly.
4764  */
4765  Assert(afterTriggers.state == NULL);
4766  Assert(afterTriggers.query_stack == NULL);
4767  Assert(afterTriggers.maxquerydepth == 0);
4768  Assert(afterTriggers.event_cxt == NULL);
4769  Assert(afterTriggers.events.head == NULL);
4770  Assert(afterTriggers.trans_stack == NULL);
4771  Assert(afterTriggers.maxtransdepth == 0);
4772 }
4773 
4774 
4775 /* ----------
4776  * AfterTriggerBeginQuery()
4777  *
4778  * Called just before we start processing a single query within a
4779  * transaction (or subtransaction). Most of the real work gets deferred
4780  * until somebody actually tries to queue a trigger event.
4781  * ----------
4782  */
4783 void
4785 {
4786  /* Increase the query stack depth */
4787  afterTriggers.query_depth++;
4788 }
4789 
4790 
4791 /* ----------
4792  * AfterTriggerEndQuery()
4793  *
4794  * Called after one query has been completely processed. At this time
4795  * we invoke all AFTER IMMEDIATE trigger events queued by the query, and
4796  * transfer deferred trigger events to the global deferred-trigger list.
4797  *
4798  * Note that this must be called BEFORE closing down the executor
4799  * with ExecutorEnd, because we make use of the EState's info about
4800  * target relations. Normally it is called from ExecutorFinish.
4801  * ----------
4802  */
4803 void
4805 {
4807 
4808  /* Must be inside a query, too */
4809  Assert(afterTriggers.query_depth >= 0);
4810 
4811  /*
4812  * If we never even got as far as initializing the event stack, there
4813  * certainly won't be any events, so exit quickly.
4814  */
4815  if (afterTriggers.query_depth >= afterTriggers.maxquerydepth)
4816  {
4817  afterTriggers.query_depth--;
4818  return;
4819  }
4820 
4821  /*
4822  * Process all immediate-mode triggers queued by the query, and move the
4823  * deferred ones to the main list of deferred events.
4824  *
4825  * Notice that we decide which ones will be fired, and put the deferred
4826  * ones on the main list, before anything is actually fired. This ensures
4827  * reasonably sane behavior if a trigger function does SET CONSTRAINTS ...
4828  * IMMEDIATE: all events we have decided to defer will be available for it
4829  * to fire.
4830  *
4831  * We loop in case a trigger queues more events at the same query level.
4832  * Ordinary trigger functions, including all PL/pgSQL trigger functions,
4833  * will instead fire any triggers in a dedicated query level. Foreign key
4834  * enforcement triggers do add to the current query level, thanks to their
4835  * passing fire_triggers = false to SPI_execute_snapshot(). Other
4836  * C-language triggers might do likewise.
4837  *
4838  * If we find no firable events, we don't have to increment
4839  * firing_counter.
4840  */
4841  qs = &afterTriggers.query_stack[afterTriggers.query_depth];
4842 
4843  for (;;)
4844  {
4845  if (afterTriggerMarkEvents(&qs->events, &afterTriggers.events, true))
4846  {
4847  CommandId firing_id = afterTriggers.firing_counter++;
4848  AfterTriggerEventChunk *oldtail = qs->events.tail;
4849 
4850  if (afterTriggerInvokeEvents(&qs->events, firing_id, estate, false))
4851  break; /* all fired */
4852 
4853  /*
4854  * Firing a trigger could result in query_stack being repalloc'd,
4855  * so we must recalculate qs after each afterTriggerInvokeEvents
4856  * call. Furthermore, it's unsafe to pass delete_ok = true here,
4857  * because that could cause afterTriggerInvokeEvents to try to
4858  * access qs->events after the stack has been repalloc'd.
4859  */
4860  qs = &afterTriggers.query_stack[afterTriggers.query_depth];
4861 
4862  /*
4863  * We'll need to scan the events list again. To reduce the cost
4864  * of doing so, get rid of completely-fired chunks. We know that
4865  * all events were marked IN_PROGRESS or DONE at the conclusion of
4866  * afterTriggerMarkEvents, so any still-interesting events must
4867  * have been added after that, and so must be in the chunk that
4868  * was then the tail chunk, or in later chunks. So, zap all
4869  * chunks before oldtail. This is approximately the same set of
4870  * events we would have gotten rid of by passing delete_ok = true.
4871  */
4872  Assert(oldtail != NULL);
4873  while (qs->events.head != oldtail)
4875  }
4876  else
4877  break;
4878  }
4879 
4880  /* Release query-level-local storage, including tuplestores if any */
4881  AfterTriggerFreeQuery(&afterTriggers.query_stack[afterTriggers.query_depth]);
4882 
4883  afterTriggers.query_depth--;
4884 }
4885 
4886 
4887 /*
4888  * AfterTriggerFreeQuery
4889  * Release subsidiary storage for a trigger query level.
4890  * This includes closing down tuplestores.
4891  * Note: it's important for this to be safe if interrupted by an error
4892  * and then called again for the same query level.
4893  */
4894 static void
4896 {
4897  Tuplestorestate *ts;
4898  List *tables;
4899  ListCell *lc;
4900 
4901  /* Drop the trigger events */
4903 
4904  /* Drop FDW tuplestore if any */
4905  ts = qs->fdw_tuplestore;
4906  qs->fdw_tuplestore = NULL;
4907  if (ts)
4908  tuplestore_end(ts);
4909 
4910  /* Release per-table subsidiary storage */
4911  tables = qs->tables;
4912  foreach(lc, tables)
4913  {
4915 
4916  ts = table->old_tuplestore;
4917  table->old_tuplestore = NULL;
4918  if (ts)
4919  tuplestore_end(ts);
4920  ts = table->new_tuplestore;
4921  table->new_tuplestore = NULL;
4922  if (ts)
4923  tuplestore_end(ts);
4924  }
4925 
4926  /*
4927  * Now free the AfterTriggersTableData structs and list cells. Reset list
4928  * pointer first; if list_free_deep somehow gets an error, better to leak
4929  * that storage than have an infinite loop.
4930  */
4931  qs->tables = NIL;
4932  list_free_deep(tables);
4933 }
4934 
4935 
4936 /* ----------
4937  * AfterTriggerFireDeferred()
4938  *
4939  * Called just before the current transaction is committed. At this
4940  * time we invoke all pending DEFERRED triggers.
4941  *
4942  * It is possible for other modules to queue additional deferred triggers
4943  * during pre-commit processing; therefore xact.c may have to call this
4944  * multiple times.
4945  * ----------
4946  */
4947 void
4949 {
4950  AfterTriggerEventList *events;
4951  bool snap_pushed = false;
4952 
4953  /* Must not be inside a query */
4954  Assert(afterTriggers.query_depth == -1);
4955 
4956  /*
4957  * If there are any triggers to fire, make sure we have set a snapshot for
4958  * them to use. (Since PortalRunUtility doesn't set a snap for COMMIT, we
4959  * can't assume ActiveSnapshot is valid on entry.)
4960  */
4961  events = &afterTriggers.events;
4962  if (events->head != NULL)
4963  {
4965  snap_pushed = true;
4966  }
4967 
4968  /*
4969  * Run all the remaining triggers. Loop until they are all gone, in case
4970  * some trigger queues more for us to do.
4971  */
4972  while (afterTriggerMarkEvents(events, NULL, false))
4973  {
4974  CommandId firing_id = afterTriggers.firing_counter++;
4975 
4976  if (afterTriggerInvokeEvents(events, firing_id, NULL, true))
4977  break; /* all fired */
4978  }
4979 
4980  /*
4981  * We don't bother freeing the event list, since it will go away anyway
4982  * (and more efficiently than via pfree) in AfterTriggerEndXact.
4983  */
4984 
4985  if (snap_pushed)
4987 }
4988 
4989 
4990 /* ----------
4991  * AfterTriggerEndXact()
4992  *
4993  * The current transaction is finishing.
4994  *
4995  * Any unfired triggers are canceled so we simply throw
4996  * away anything we know.
4997  *
4998  * Note: it is possible for this to be called repeatedly in case of
4999  * error during transaction abort; therefore, do not complain if
5000  * already closed down.
5001  * ----------
5002  */
5003 void
5004 AfterTriggerEndXact(bool isCommit)
5005 {
5006  /*
5007  * Forget the pending-events list.
5008  *
5009  * Since all the info is in TopTransactionContext or children thereof, we
5010  * don't really need to do anything to reclaim memory. However, the
5011  * pending-events list could be large, and so it's useful to discard it as
5012  * soon as possible --- especially if we are aborting because we ran out
5013  * of memory for the list!
5014  */
5015  if (afterTriggers.event_cxt)
5016  {
5017  MemoryContextDelete(afterTriggers.event_cxt);
5018  afterTriggers.event_cxt = NULL;
5019  afterTriggers.events.head = NULL;
5020  afterTriggers.events.tail = NULL;
5021  afterTriggers.events.tailfree = NULL;
5022  }
5023 
5024  /*
5025  * Forget any subtransaction state as well. Since this can't be very
5026  * large, we let the eventual reset of TopTransactionContext free the
5027  * memory instead of doing it here.
5028  */
5029  afterTriggers.trans_stack = NULL;
5030  afterTriggers.maxtransdepth = 0;
5031 
5032 
5033  /*
5034  * Forget the query stack and constraint-related state information. As
5035  * with the subtransaction state information, we don't bother freeing the
5036  * memory here.
5037  */
5038  afterTriggers.query_stack = NULL;
5039  afterTriggers.maxquerydepth = 0;
5040  afterTriggers.state = NULL;
5041 
5042  /* No more afterTriggers manipulation until next transaction starts. */
5043  afterTriggers.query_depth = -1;
5044 }
5045 
5046 /*
5047  * AfterTriggerBeginSubXact()
5048  *
5049  * Start a subtransaction.
5050  */
5051 void
5053 {
5054  int my_level = GetCurrentTransactionNestLevel();
5055 
5056  /*
5057  * Allocate more space in the trans_stack if needed. (Note: because the
5058  * minimum nest level of a subtransaction is 2, we waste the first couple
5059  * entries of the array; not worth the notational effort to avoid it.)
5060  */
5061  while (my_level >= afterTriggers.maxtransdepth)
5062  {
5063  if (afterTriggers.maxtransdepth == 0)
5064  {
5065  /* Arbitrarily initialize for max of 8 subtransaction levels */
5066  afterTriggers.trans_stack = (AfterTriggersTransData *)
5068  8 * sizeof(AfterTriggersTransData));
5069  afterTriggers.maxtransdepth = 8;
5070  }
5071  else
5072  {
5073  /* repalloc will keep the stack in the same context */
5074  int new_alloc = afterTriggers.maxtransdepth * 2;
5075 
5076  afterTriggers.trans_stack = (AfterTriggersTransData *)
5077  repalloc(afterTriggers.trans_stack,
5078  new_alloc * sizeof(AfterTriggersTransData));
5079  afterTriggers.maxtransdepth = new_alloc;
5080  }
5081  }
5082 
5083  /*
5084  * Push the current information into the stack. The SET CONSTRAINTS state
5085  * is not saved until/unless changed. Likewise, we don't make a
5086  * per-subtransaction event context until needed.
5087  */
5088  afterTriggers.trans_stack[my_level].state = NULL;
5089  afterTriggers.trans_stack[my_level].events = afterTriggers.events;
5090  afterTriggers.trans_stack[my_level].query_depth = afterTriggers.query_depth;
5091  afterTriggers.trans_stack[my_level].firing_counter = afterTriggers.firing_counter;
5092 }
5093 
5094 /*
5095  * AfterTriggerEndSubXact()
5096  *
5097  * The current subtransaction is ending.
5098  */
5099 void
5101 {
5102  int my_level = GetCurrentTransactionNestLevel();
5104  AfterTriggerEvent event;
5105  AfterTriggerEventChunk *chunk;
5106  CommandId subxact_firing_id;
5107 
5108  /*
5109  * Pop the prior state if needed.
5110  */
5111  if (isCommit)
5112  {
5113  Assert(my_level < afterTriggers.maxtransdepth);
5114  /* If we saved a prior state, we don't need it anymore */
5115  state = afterTriggers.trans_stack[my_level].state;
5116  if (state != NULL)
5117  pfree(state);
5118  /* this avoids double pfree if error later: */
5119  afterTriggers.trans_stack[my_level].state = NULL;
5120  Assert(afterTriggers.query_depth ==
5121  afterTriggers.trans_stack[my_level].query_depth);
5122  }
5123  else
5124  {
5125  /*
5126  * Aborting. It is possible subxact start failed before calling
5127  * AfterTriggerBeginSubXact, in which case we mustn't risk touching
5128  * trans_stack levels that aren't there.
5129  */
5130  if (my_level >= afterTriggers.maxtransdepth)
5131  return;
5132 
5133  /*
5134  * Release query-level storage for queries being aborted, and restore
5135  * query_depth to its pre-subxact value. This assumes that a
5136  * subtransaction will not add events to query levels started in a
5137  * earlier transaction state.
5138  */
5139  while (afterTriggers.query_depth > afterTriggers.trans_stack[my_level].query_depth)
5140  {
5141  if (afterTriggers.query_depth < afterTriggers.maxquerydepth)
5142  AfterTriggerFreeQuery(&afterTriggers.query_stack[afterTriggers.query_depth]);
5143  afterTriggers.query_depth--;
5144  }
5145  Assert(afterTriggers.query_depth ==
5146  afterTriggers.trans_stack[my_level].query_depth);
5147 
5148  /*
5149  * Restore the global deferred-event list to its former length,
5150  * discarding any events queued by the subxact.
5151  */
5152  afterTriggerRestoreEventList(&afterTriggers.events,
5153  &afterTriggers.trans_stack[my_level].events);
5154 
5155  /*
5156  * Restore the trigger state. If the saved state is NULL, then this
5157  * subxact didn't save it, so it doesn't need restoring.
5158  */
5159  state = afterTriggers.trans_stack[my_level].state;
5160  if (state != NULL)
5161  {
5162  pfree(afterTriggers.state);
5163  afterTriggers.state = state;
5164  }
5165  /* this avoids double pfree if error later: */
5166  afterTriggers.trans_stack[my_level].state = NULL;
5167 
5168  /*
5169  * Scan for any remaining deferred events that were marked DONE or IN
5170  * PROGRESS by this subxact or a child, and un-mark them. We can
5171  * recognize such events because they have a firing ID greater than or
5172  * equal to the firing_counter value we saved at subtransaction start.
5173  * (This essentially assumes that the current subxact includes all
5174  * subxacts started after it.)
5175  */
5176  subxact_firing_id = afterTriggers.trans_stack[my_level].firing_counter;
5177  for_each_event_chunk(event, chunk, afterTriggers.events)
5178  {
5179  AfterTriggerShared evtshared = GetTriggerSharedData(event);
5180 
5181  if (event->ate_flags &
5183  {
5184  if (evtshared->ats_firing_id >= subxact_firing_id)
5185  event->ate_flags &=
5187  }
5188  }
5189  }
5190 }
5191 
5192 /* ----------
5193  * AfterTriggerEnlargeQueryState()
5194  *
5195  * Prepare the necessary state so that we can record AFTER trigger events
5196  * queued by a query. It is allowed to have nested queries within a
5197  * (sub)transaction, so we need to have separate state for each query
5198  * nesting level.
5199  * ----------
5200  */
5201 static void
5203 {
5204  int init_depth = afterTriggers.maxquerydepth;
5205 
5206  Assert(afterTriggers.query_depth >= afterTriggers.maxquerydepth);
5207 
5208  if (afterTriggers.maxquerydepth == 0)
5209  {
5210  int new_alloc = Max(afterTriggers.query_depth + 1, 8);
5211 
5212  afterTriggers.query_stack = (AfterTriggersQueryData *)
5214  new_alloc * sizeof(AfterTriggersQueryData));
5215  afterTriggers.maxquerydepth = new_alloc;
5216  }
5217  else
5218  {
5219  /* repalloc will keep the stack in the same context */
5220  int old_alloc = afterTriggers.maxquerydepth;
5221  int new_alloc = Max(afterTriggers.query_depth + 1,
5222  old_alloc * 2);
5223 
5224  afterTriggers.query_stack = (AfterTriggersQueryData *)
5225  repalloc(afterTriggers.query_stack,
5226  new_alloc * sizeof(AfterTriggersQueryData));
5227  afterTriggers.maxquerydepth = new_alloc;
5228  }
5229 
5230  /* Initialize new array entries to empty */
5231  while (init_depth < afterTriggers.maxquerydepth)
5232  {
5233  AfterTriggersQueryData *qs = &afterTriggers.query_stack[init_depth];
5234 
5235  qs->events.head = NULL;
5236  qs->events.tail = NULL;
5237  qs->events.tailfree = NULL;
5238  qs->fdw_tuplestore = NULL;
5239  qs->tables = NIL;
5240 
5241  ++init_depth;
5242  }
5243 }
5244 
5245 /*
5246  * Create an empty SetConstraintState with room for numalloc trigstates
5247  */
5248 static SetConstraintState
5250 {
5252 
5253  /* Behave sanely with numalloc == 0 */
5254  if (numalloc <= 0)
5255  numalloc = 1;
5256 
5257  /*
5258  * We assume that zeroing will correctly initialize the state values.
5259  */
5260  state = (SetConstraintState)
5262  offsetof(SetConstraintStateData, trigstates) +
5263  numalloc * sizeof(SetConstraintTriggerData));
5264 
5265  state->numalloc = numalloc;
5266 
5267  return state;
5268 }
5269 
5270 /*
5271  * Copy a SetConstraintState
5272  */
5273 static SetConstraintState
5275 {
5277 
5278  state = SetConstraintStateCreate(origstate->numstates);
5279 
5280  state->all_isset = origstate->all_isset;
5281  state->all_isdeferred = origstate->all_isdeferred;
5282  state->numstates = origstate->numstates;
5283  memcpy(state->trigstates, origstate->trigstates,
5284  origstate->numstates * sizeof(SetConstraintTriggerData));
5285 
5286  return state;
5287 }
5288 
5289 /*
5290  * Add a per-trigger item to a SetConstraintState. Returns possibly-changed
5291  * pointer to the state object (it will change if we have to repalloc).
5292  */
5293 static SetConstraintState
5295  Oid tgoid, bool tgisdeferred)
5296 {
5297  if (state->numstates >= state->numalloc)
5298  {
5299  int newalloc = state->numalloc * 2;
5300 
5301  newalloc = Max(newalloc, 8); /* in case original has size 0 */
5302  state = (SetConstraintState)
5303  repalloc(state,
5304  offsetof(SetConstraintStateData, trigstates) +
5305  newalloc * sizeof(SetConstraintTriggerData));
5306  state->numalloc = newalloc;
5307  Assert(state->numstates < state->numalloc);
5308  }
5309 
5310  state->trigstates[state->numstates].sct_tgoid = tgoid;
5311  state->trigstates[state->numstates].sct_tgisdeferred = tgisdeferred;
5312  state->numstates++;
5313 
5314  return state;
5315 }
5316 
5317 /* ----------
5318  * AfterTriggerSetState()
5319  *
5320  * Execute the SET CONSTRAINTS ... utility command.
5321  * ----------
5322  */
5323 void
5325 {
5326  int my_level = GetCurrentTransactionNestLevel();
5327 
5328  /* If we haven't already done so, initialize our state. */
5329  if (afterTriggers.state == NULL)
5330  afterTriggers.state = SetConstraintStateCreate(8);
5331 
5332  /*
5333  * If in a subtransaction, and we didn't save the current state already,
5334  * save it so it can be restored if the subtransaction aborts.
5335  */
5336  if (my_level > 1 &&
5337  afterTriggers.trans_stack[my_level].state == NULL)
5338  {
5339  afterTriggers.trans_stack[my_level].state =
5340  SetConstraintStateCopy(afterTriggers.state);
5341  }
5342 
5343  /*
5344  * Handle SET CONSTRAINTS ALL ...
5345  */
5346  if (stmt->constraints == NIL)
5347  {
5348  /*
5349  * Forget any previous SET CONSTRAINTS commands in this transaction.
5350  */
5351  afterTriggers.state->numstates = 0;
5352 
5353  /*
5354  * Set the per-transaction ALL state to known.
5355  */
5356  afterTriggers.state->all_isset = true;
5357  afterTriggers.state->all_isdeferred = stmt->deferred;
5358  }
5359  else
5360  {
5361  Relation conrel;
5362  Relation tgrel;
5363  List *conoidlist = NIL;
5364  List *tgoidlist = NIL;
5365  ListCell *lc;
5366 
5367  /*
5368  * Handle SET CONSTRAINTS constraint-name [, ...]
5369  *
5370  * First, identify all the named constraints and make a list of their
5371  * OIDs. Since, unlike the SQL spec, we allow multiple constraints of
5372  * the same name within a schema, the specifications are not
5373  * necessarily unique. Our strategy is to target all matching
5374  * constraints within the first search-path schema that has any
5375  * matches, but disregard matches in schemas beyond the first match.
5376  * (This is a bit odd but it's the historical behavior.)
5377  *
5378  * A constraint in a partitioned table may have corresponding
5379  * constraints in the partitions. Grab those too.
5380  */
5381  conrel = table_open(ConstraintRelationId, AccessShareLock);
5382 
5383  foreach(lc, stmt->constraints)
5384  {
5385  RangeVar *constraint = lfirst(lc);
5386  bool found;
5387  List *namespacelist;
5388  ListCell *nslc;
5389 
5390  if (constraint->catalogname)
5391  {
5392  if (strcmp(constraint->catalogname, get_database_name(MyDatabaseId)) != 0)
5393  ereport(ERROR,
5394  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
5395  errmsg("cross-database references are not implemented: \"%s.%s.%s\"",
5396  constraint->catalogname, constraint->schemaname,
5397  constraint->relname)));
5398  }
5399 
5400  /*
5401  * If we're given the schema name with the constraint, look only
5402  * in that schema. If given a bare constraint name, use the
5403  * search path to find the first matching constraint.
5404  */
5405  if (constraint->schemaname)
5406  {
5407  Oid namespaceId = LookupExplicitNamespace(constraint->schemaname,
5408  false);
5409 
5410  namespacelist = list_make1_oid(namespaceId);
5411  }
5412  else
5413  {
5414  namespacelist = fetch_search_path(true);
5415  }
5416 
5417  found = false;
5418  foreach(nslc, namespacelist)
5419  {
5420  Oid namespaceId = lfirst_oid(nslc);
5421  SysScanDesc conscan;
5422  ScanKeyData skey[2];
5423  HeapTuple tup;
5424 
5425  ScanKeyInit(&skey[0],
5426  Anum_pg_constraint_conname,
5427  BTEqualStrategyNumber, F_NAMEEQ,
5428  CStringGetDatum(constraint->relname));
5429  ScanKeyInit(&skey[1],
5430  Anum_pg_constraint_connamespace,
5431  BTEqualStrategyNumber, F_OIDEQ,
5432  ObjectIdGetDatum(namespaceId));
5433 
5434  conscan = systable_beginscan(conrel, ConstraintNameNspIndexId,
5435  true, NULL, 2, skey);
5436 
5437  while (HeapTupleIsValid(tup = systable_getnext(conscan)))
5438  {
5440 
5441  if (con->condeferrable)
5442  conoidlist = lappend_oid(conoidlist, con->oid);
5443  else if (stmt->deferred)
5444  ereport(ERROR,
5445  (errcode(ERRCODE_WRONG_OBJECT_TYPE),
5446  errmsg("constraint \"%s\" is not deferrable",
5447  constraint->relname)));
5448  found = true;
5449  }
5450 
5451  systable_endscan(conscan);
5452 
5453  /*
5454  * Once we've found a matching constraint we do not search
5455  * later parts of the search path.
5456  */
5457  if (found)
5458  break;
5459  }
5460 
5461  list_free(namespacelist);
5462 
5463  /*
5464  * Not found ?
5465  */
5466  if (!found)
5467  ereport(ERROR,
5468  (errcode(ERRCODE_UNDEFINED_OBJECT),
5469  errmsg("constraint \"%s\" does not exist",
5470  constraint->relname)));
5471  }
5472 
5473  /*
5474  * Scan for any possible descendants of the constraints. We append
5475  * whatever we find to the same list that we're scanning; this has the
5476  * effect that we create new scans for those, too, so if there are
5477  * further descendents, we'll also catch them.
5478  */
5479  foreach(lc, conoidlist)
5480  {
5481  Oid parent = lfirst_oid(lc);
5482  ScanKeyData key;
5483  SysScanDesc scan;
5484  HeapTuple tuple;
5485 
5486  ScanKeyInit(&key,
5487  Anum_pg_constraint_conparentid,
5488  BTEqualStrategyNumber, F_OIDEQ,
5489  ObjectIdGetDatum(parent));
5490 
5491  scan = systable_beginscan(conrel, ConstraintParentIndexId, true, NULL, 1, &key);
5492 
5493  while (HeapTupleIsValid(tuple = systable_getnext(scan)))
5494  {
5496 
5497  conoidlist = lappend_oid(conoidlist, con->oid);
5498  }
5499 
5500  systable_endscan(scan);
5501  }
5502 
5503  table_close(conrel, AccessShareLock);
5504 
5505  /*
5506  * Now, locate the trigger(s) implementing each of these constraints,
5507  * and make a list of their OIDs.
5508  */
5509  tgrel = table_open(TriggerRelationId, AccessShareLock);
5510 
5511  foreach(lc, conoidlist)
5512  {
5513  Oid conoid = lfirst_oid(lc);
5514  bool found;
5515  ScanKeyData skey;
5516  SysScanDesc tgscan;
5517  HeapTuple htup;
5518 
5519  found = false;
5520 
5521  ScanKeyInit(&skey,
5522  Anum_pg_trigger_tgconstraint,
5523  BTEqualStrategyNumber, F_OIDEQ,
5524  ObjectIdGetDatum(conoid));
5525 
5526  tgscan = systable_beginscan(tgrel, TriggerConstraintIndexId, true,
5527  NULL, 1, &skey);
5528 
5529  while (HeapTupleIsValid(htup = systable_getnext(tgscan)))
5530  {
5531  Form_pg_trigger pg_trigger = (Form_pg_trigger) GETSTRUCT(htup);
5532 
5533  /*
5534  * Silently skip triggers that are marked as non-deferrable in
5535  * pg_trigger. This is not an error condition, since a
5536  * deferrable RI constraint may have some non-deferrable
5537  * actions.
5538  */
5539  if (pg_trigger->tgdeferrable)
5540  tgoidlist = lappend_oid(tgoidlist, pg_trigger->oid);
5541 
5542  found = true;
5543  }
5544 
5545  systable_endscan(tgscan);
5546 
5547  /* Safety check: a deferrable constraint should have triggers */
5548  if (!found)
5549  elog(ERROR, "no triggers found for constraint with OID %u",
5550  conoid);
5551  }
5552 
5553  table_close(tgrel, AccessShareLock);
5554 
5555  /*
5556  * Now we can set the trigger states of individual triggers for this
5557  * xact.
5558  */
5559  foreach(lc, tgoidlist)
5560  {
5561  Oid tgoid = lfirst_oid(lc);
5562  SetConstraintState state = afterTriggers.state;
5563  bool found = false;
5564  int i;
5565 
5566  for (i = 0; i < state->numstates; i++)
5567  {
5568  if (state->trigstates[i].sct_tgoid == tgoid)
5569  {
5570  state->trigstates[i].sct_tgisdeferred = stmt->deferred;
5571  found = true;
5572  break;
5573  }
5574  }
5575  if (!found)
5576  {
5577  afterTriggers.state =
5578  SetConstraintStateAddItem(state, tgoid, stmt->deferred);
5579  }
5580  }
5581  }
5582 
5583  /*
5584  * SQL99 requires that when a constraint is set to IMMEDIATE, any deferred
5585  * checks against that constraint must be made when the SET CONSTRAINTS
5586  * command is executed -- i.e. the effects of the SET CONSTRAINTS command
5587  * apply retroactively. We've updated the constraints state, so scan the
5588  * list of previously deferred events to fire any that have now become
5589  * immediate.
5590  *
5591  * Obviously, if this was SET ... DEFERRED then it can't have converted
5592  * any unfired events to immediate, so we need do nothing in that case.
5593  */
5594  if (!stmt->deferred)
5595  {
5596  AfterTriggerEventList *events = &afterTriggers.events;
5597  bool snapshot_set = false;
5598 
5599  while (afterTriggerMarkEvents(events, NULL, true))
5600  {
5601  CommandId firing_id = afterTriggers.firing_counter++;
5602 
5603  /*
5604  * Make sure a snapshot has been established in case trigger
5605  * functions need one. Note that we avoid setting a snapshot if
5606  * we don't find at least one trigger that has to be fired now.
5607  * This is so that BEGIN; SET CONSTRAINTS ...; SET TRANSACTION
5608  * ISOLATION LEVEL SERIALIZABLE; ... works properly. (If we are
5609  * at the start of a transaction it's not possible for any trigger
5610  * events to be queued yet.)
5611  */
5612  if (!snapshot_set)
5613  {
5615  snapshot_set = true;
5616  }
5617 
5618  /*
5619  * We can delete fired events if we are at top transaction level,
5620  * but we'd better not if inside a subtransaction, since the
5621  * subtransaction could later get rolled back.
5622  */
5623  if (afterTriggerInvokeEvents(events, firing_id, NULL,
5624  !IsSubTransaction()))
5625  break; /* all fired */
5626  }
5627 
5628  if (snapshot_set)
5630  }
5631 }
5632 
5633 /* ----------
5634  * AfterTriggerPendingOnRel()
5635  * Test to see if there are any pending after-trigger events for rel.
5636  *
5637  * This is used by TRUNCATE, CLUSTER, ALTER TABLE, etc to detect whether
5638  * it is unsafe to perform major surgery on a relation. Note that only
5639  * local pending events are examined. We assume that having exclusive lock
5640  * on a rel guarantees there are no unserviced events in other backends ---
5641  * but having a lock does not prevent there being such events in our own.
5642  *
5643  * In some scenarios it'd be reasonable to remove pending events (more
5644  * specifically, mark them DONE by the current subxact) but without a lot
5645  * of knowledge of the trigger semantics we can't do this in general.
5646  * ----------
5647  */
5648 bool
5650 {
5651  AfterTriggerEvent event;
5652  AfterTriggerEventChunk *chunk;
5653  int depth;
5654 
5655  /* Scan queued events */
5656  for_each_event_chunk(event, chunk, afterTriggers.events)
5657  {
5658  AfterTriggerShared evtshared = GetTriggerSharedData(event);
5659 
5660  /*
5661  * We can ignore completed events. (Even if a DONE flag is rolled
5662  * back by subxact abort, it's OK because the effects of the TRUNCATE
5663  * or whatever must get rolled back too.)
5664  */
5665  if (event->ate_flags & AFTER_TRIGGER_DONE)
5666  continue;
5667 
5668  if (evtshared->ats_relid == relid)
5669  return true;
5670  }
5671 
5672  /*
5673  * Also scan events queued by incomplete queries. This could only matter
5674  * if TRUNCATE/etc is executed by a function or trigger within an updating
5675  * query on the same relation, which is pretty perverse, but let's check.
5676  */
5677  for (depth = 0; depth <= afterTriggers.query_depth && depth < afterTriggers.maxquerydepth; depth++)
5678  {
5679  for_each_event_chunk(event, chunk, afterTriggers.query_stack[depth].events)
5680  {
5681  AfterTriggerShared evtshared = GetTriggerSharedData(event);
5682 
5683  if (event->ate_flags & AFTER_TRIGGER_DONE)
5684  continue;
5685 
5686  if (evtshared->ats_relid == relid)
5687  return true;
5688  }
5689  }
5690 
5691  return false;
5692 }
5693 
5694 
5695 /* ----------
5696  * AfterTriggerSaveEvent()
5697  *
5698  * Called by ExecA[RS]...Triggers() to queue up the triggers that should
5699  * be fired for an event.
5700  *
5701  * NOTE: this is called whenever there are any triggers associated with
5702  * the event (even if they are disabled). This function decides which
5703  * triggers actually need to be queued. It is also called after each row,
5704  * even if there are no triggers for that event, if there are any AFTER
5705  * STATEMENT triggers for the statement which use transition tables, so that
5706  * the transition tuplestores can be built. Furthermore, if the transition
5707  * capture is happening for UPDATEd rows being moved to another partition due
5708  * to the partition-key being changed, then this function is called once when
5709  * the row is deleted (to capture OLD row), and once when the row is inserted
5710  * into another partition (to capture NEW row). This is done separately because
5711  * DELETE and INSERT happen on different tables.
5712  *
5713  * Transition tuplestores are built now, rather than when events are pulled
5714  * off of the queue because AFTER ROW triggers are allowed to select from the
5715  * transition tables for the statement.
5716  * ----------
5717  */
5718 static void
5720  int event, bool row_trigger,
5721  TupleTableSlot *oldslot, TupleTableSlot *newslot,
5722  List *recheckIndexes, Bitmapset *modifiedCols,
5723  TransitionCaptureState *transition_capture)
5724 {
5725  Relation rel = relinfo->ri_RelationDesc;
5726  TriggerDesc *trigdesc = relinfo->ri_TrigDesc;
5727  AfterTriggerEventData new_event;
5728  AfterTriggerSharedData new_shared;
5729  char relkind = rel->rd_rel->relkind;
5730  int tgtype_event;
5731  int tgtype_level;
5732  int i;