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