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