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