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