/*-------------------------------------------------------------------------
 *
 * trigger.c
 *	  PostgreSQL TRIGGERs support code.
 *
 * Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
 * Portions Copyright (c) 1994, Regents of the University of California
 *
 * IDENTIFICATION
 *	  $PostgreSQL: pgsql/src/backend/commands/trigger.c,v 1.210.2.4 2007/08/15 19:15:55 tgl Exp $
 *
 *-------------------------------------------------------------------------
 */
#include "postgres.h"

#include "access/genam.h"
#include "access/heapam.h"
#include "access/xact.h"
#include "catalog/catalog.h"
#include "catalog/catquery.h"
#include "catalog/dependency.h"
#include "catalog/indexing.h"
#include "catalog/pg_namespace.h"
#include "catalog/pg_proc.h"
#include "catalog/pg_trigger.h"
#include "catalog/pg_type.h"
#include "commands/dbcommands.h"
#include "commands/defrem.h"
#include "commands/trigger.h"
#include "executor/executor.h"
#include "executor/instrument.h"
#include "miscadmin.h"
#include "nodes/makefuncs.h"
#include "parser/parse_func.h"
#include "utils/acl.h"
#include "utils/builtins.h"
#include "utils/fmgroids.h"
#include "utils/inval.h"
#include "utils/lsyscache.h"
#include "utils/memutils.h"
#include "utils/syscache.h"
#include "cdb/cdbvars.h"
#include "cdb/cdbdisp.h"
#include "cdb/dispatcher.h"


static void InsertTrigger(TriggerDesc *trigdesc, Trigger *trigger, int indx);
static HeapTuple GetTupleForTrigger(EState *estate,
				   ResultRelInfo *relinfo,
				   ItemPointer tid,
				   CommandId cid,
				   TupleTableSlot **newSlot);

static void AfterTriggerSaveEvent(ResultRelInfo *relinfo, int event,
					  bool row_trigger, HeapTuple oldtup, HeapTuple newtup);


/*
 * Create a trigger.  Returns the OID of the created trigger.
 *
 * relOid, if nonzero, is the relation on which the trigger should be
 * created.  If zero, the name provided in the statement will be looked up.
 *
 * refRelOid, if nonzero, is the relation to which the constraint trigger
 * refers.  If zero, the constraint relation name provided in the statement
 * will be looked up as needed.
 *
 * forConstraint, if true, says that this trigger is being created to
 * implement a constraint.	The caller will then be expected to make
 * a pg_depend entry linking the trigger to that constraint (and thereby
 * to the owning relation(s)).
 */
Oid
CreateTrigger(CreateTrigStmt *stmt, Oid relOid, Oid refRelOid,
		      bool forConstraint)
{
	int16		tgtype;
	int2vector *tgattr;
	Datum		values[Natts_pg_trigger];
	bool		nulls[Natts_pg_trigger];
	Relation	rel;
	AclResult	aclresult;
	Relation	tgrel;
	cqContext  *pcqCtx;
	cqContext	cqc;
	cqContext  *pcqCtx2;
	cqContext	cqc2;
	Relation	pgrel;
	HeapTuple	tuple;
	Oid			fargtypes[1];	/* dummy */
	Oid			funcoid;
	Oid			funcrettype;
	Oid			trigoid;
	int			found = 0;
	int			i;
	char		constrtrigname[NAMEDATALEN];
	char	   *trigname;
	char	   *constrname;
	Oid			constrrelid = InvalidOid;
	ObjectAddress myself,
				referenced;

	if (OidIsValid(relOid))
	{
		rel = heap_open(relOid, AccessExclusiveLock);
	}
	else
	{
		rel = heap_openrv(stmt->relation, AccessExclusiveLock);
	}

	if (OidIsValid(refRelOid))
	{
		constrrelid = refRelOid;
	}
	else if (stmt->constrrel != NULL)
	{
		constrrelid = RangeVarGetRelid(stmt->constrrel, false, false /*allowHcatalog*/);
	}
	else if (stmt->isconstraint)
	{
		/*
		 * If this trigger is a constraint (and a foreign key one) then we
		 * really need a constrrelid.  Since we don't have one, we'll try to
		 * generate one from the argument information.
		 *
		 * This is really just a workaround for a long-ago pg_dump bug that
		 * omitted the FROM clause in dumped CREATE CONSTRAINT TRIGGER
		 * commands.  We don't want to bomb out completely here if we can't
		 * determine the correct relation, because that would prevent loading
		 * the dump file.  Instead, NOTICE here and ERROR in the trigger.
		 */
		bool		needconstrrelid = false;
		void	   *elem = NULL;

		if (strncmp(strVal(lfirst(list_tail((stmt->funcname)))), "RI_FKey_check_", 14) == 0)
		{
			/* A trigger on FK table. */
			needconstrrelid = true;
			if (list_length(stmt->args) > RI_PK_RELNAME_ARGNO)
				elem = list_nth(stmt->args, RI_PK_RELNAME_ARGNO);
		}
		else if (strncmp(strVal(lfirst(list_tail((stmt->funcname)))), "RI_FKey_", 8) == 0)
		{
			/* A trigger on PK table. */
			needconstrrelid = true;
			if (list_length(stmt->args) > RI_FK_RELNAME_ARGNO)
				elem = list_nth(stmt->args, RI_FK_RELNAME_ARGNO);
		}
		if (elem != NULL)
		{
			RangeVar   *rel = makeRangeVar(NULL /*catalogname*/, NULL, strVal(elem), -1);

			constrrelid = RangeVarGetRelid(rel, true, false /*allowHcatalog*/);
		}
		if (needconstrrelid && constrrelid == InvalidOid)
			if (Gp_role != GP_ROLE_EXECUTE)
			ereport(NOTICE,
					(errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
					 errmsg("could not determine referenced table for constraint \"%s\"",
							stmt->trigname)));
	}

	if (rel->rd_rel->relkind != RELKIND_RELATION)
		ereport(ERROR,
				(errcode(ERRCODE_WRONG_OBJECT_TYPE),
				 errmsg("\"%s\" is not a table",
						RelationGetRelationName(rel))));

	if (!allowSystemTableModsDDL && IsSystemRelation(rel))
		ereport(ERROR,
				(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
				 errmsg("permission denied: \"%s\" is a system catalog",
						RelationGetRelationName(rel))));

	/* permission checks */

	if (stmt->isconstraint)
	{
		/* foreign key constraint trigger */

		aclresult = pg_class_aclcheck(RelationGetRelid(rel), GetUserId(),
									  ACL_REFERENCES);
		if (aclresult != ACLCHECK_OK)
			aclcheck_error(aclresult, ACL_KIND_CLASS,
						   RelationGetRelationName(rel));
		if (constrrelid != InvalidOid)
		{
			aclresult = pg_class_aclcheck(constrrelid, GetUserId(),
										  ACL_REFERENCES);
			if (aclresult != ACLCHECK_OK)
				aclcheck_error(aclresult, ACL_KIND_CLASS,
							   get_rel_name(constrrelid));
		}
	}
	else
	{
		/* real trigger */
		aclresult = pg_class_aclcheck(RelationGetRelid(rel), GetUserId(),
									  ACL_TRIGGER);
		if (aclresult != ACLCHECK_OK)
			aclcheck_error(aclresult, ACL_KIND_CLASS,
						   RelationGetRelationName(rel));
	}

	/*
	 * Generate the trigger's OID now, so that we can use it in the name if
	 * needed.
	 */
	tgrel = heap_open(TriggerRelationId, RowExclusiveLock);

	pcqCtx = caql_beginscan(
			caql_addrel(cqclr(&cqc), tgrel),
			cql("INSERT INTO pg_trigger ",
				NULL));

	if (OidIsValid(stmt->trigOid))
		trigoid = stmt->trigOid;
	else
		trigoid = GetNewOid(tgrel);

	/*
	 * If trigger is an RI constraint, use specified trigger name as
	 * constraint name and build a unique trigger name instead. This is mainly
	 * for backwards compatibility with CREATE CONSTRAINT TRIGGER commands.
	 */
	if (stmt->isconstraint)
	{
		snprintf(constrtrigname, sizeof(constrtrigname),
				 "RI_ConstraintTrigger_%u", trigoid);
		trigname = constrtrigname;
		constrname = stmt->trigname;
	}
	else
	{
		trigname = stmt->trigname;
		constrname = "";
	}

	TRIGGER_CLEAR_TYPE(tgtype);
	if (stmt->before)
		TRIGGER_SETT_BEFORE(tgtype);
	if (stmt->row)
		TRIGGER_SETT_ROW(tgtype);

	for (i = 0; stmt->actions[i]; i++)
	{
		switch (stmt->actions[i])
		{
			case 'i':
				if (TRIGGER_FOR_INSERT(tgtype))
					ereport(ERROR,
							(errcode(ERRCODE_SYNTAX_ERROR),
							 errmsg("multiple INSERT events specified")));
				TRIGGER_SETT_INSERT(tgtype);
				break;
			case 'd':
				if (TRIGGER_FOR_DELETE(tgtype))
					ereport(ERROR,
							(errcode(ERRCODE_SYNTAX_ERROR),
							 errmsg("multiple DELETE events specified")));
				TRIGGER_SETT_DELETE(tgtype);
				break;
			case 'u':
				if (TRIGGER_FOR_UPDATE(tgtype))
					ereport(ERROR,
							(errcode(ERRCODE_SYNTAX_ERROR),
							 errmsg("multiple UPDATE events specified")));
				TRIGGER_SETT_UPDATE(tgtype);
				break;
			default:
				elog(ERROR, "unrecognized trigger event: %d",
					 (int) stmt->actions[i]);
				break;
		}
	}

	/*
	 * Scan pg_trigger for existing triggers on relation.  We do this mainly
	 * because we must count them; a secondary benefit is to give a nice error
	 * message if there's already a trigger of the same name. (The unique
	 * index on tgrelid/tgname would complain anyway.)
	 *
	 * NOTE that this is cool only because we have AccessExclusiveLock on the
	 * relation, so the trigger set won't be changing underneath us.
	 */
	pcqCtx2 = caql_beginscan(
			caql_addrel(cqclr(&cqc2), tgrel),
			cql("SELECT * FROM pg_trigger "
				" WHERE tgrelid = :1 ",
				ObjectIdGetDatum(RelationGetRelid(rel))));
	
	while (HeapTupleIsValid(tuple = caql_getnext(pcqCtx2)))
	{
		Form_pg_trigger pg_trigger = (Form_pg_trigger) GETSTRUCT(tuple);

		if (namestrcmp(&(pg_trigger->tgname), trigname) == 0)
			ereport(ERROR,
					(errcode(ERRCODE_DUPLICATE_OBJECT),
				  errmsg("trigger \"%s\" for relation \"%s\" already exists",
						 trigname, RelationGetRelationName(rel))));
		found++;
	}
	caql_endscan(pcqCtx2);

	/*
	 * Find and validate the trigger function.
	 */
	funcoid = LookupFuncName(stmt->funcname, 0, fargtypes, false);
	aclresult = pg_proc_aclcheck(funcoid, GetUserId(), ACL_EXECUTE);
	if (aclresult != ACLCHECK_OK)
		aclcheck_error(aclresult, ACL_KIND_PROC,
					   NameListToString(stmt->funcname));
	funcrettype = get_func_rettype(funcoid);
	if (funcrettype != TRIGGEROID)
	{
		/*
		 * We allow OPAQUE just so we can load old dump files.	When we see a
		 * trigger function declared OPAQUE, change it to TRIGGER.
		 */
		if (funcrettype == OPAQUEOID)
		{
			if (Gp_role != GP_ROLE_EXECUTE)
			ereport(WARNING,
					(errmsg("changing return type of function %s from \"opaque\" to \"trigger\"",
							NameListToString(stmt->funcname))));
			SetFunctionReturnType(funcoid, TRIGGEROID);
		}
		else
			ereport(ERROR,
					(errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
					 errmsg("function %s must return type \"trigger\"",
							NameListToString(stmt->funcname))));
	}

	/*
	 * Build the new pg_trigger tuple.
	 */
	MemSet(nulls, false, Natts_pg_trigger * sizeof(bool));

	values[Anum_pg_trigger_tgrelid - 1] = ObjectIdGetDatum(RelationGetRelid(rel));
	values[Anum_pg_trigger_tgname - 1] = DirectFunctionCall1(namein,
												  CStringGetDatum(trigname));
	values[Anum_pg_trigger_tgfoid - 1] = ObjectIdGetDatum(funcoid);
	values[Anum_pg_trigger_tgtype - 1] = Int16GetDatum(tgtype);
	
	/*
	 * Special for Greenplum Database: Ignore foreign keys for now
	 */
	if ((stmt->isconstraint) && (Gp_role == GP_ROLE_DISPATCH || Gp_role == GP_ROLE_EXECUTE))
	{
		/*
		 * Create the tigger as disabled 
		 */
		values[Anum_pg_trigger_tgenabled - 1] = BoolGetDatum(false);
	}
	else
		values[Anum_pg_trigger_tgenabled - 1] = BoolGetDatum(true);
	values[Anum_pg_trigger_tgisconstraint - 1] = BoolGetDatum(stmt->isconstraint);
	values[Anum_pg_trigger_tgconstrname - 1] = DirectFunctionCall1(namein,
												CStringGetDatum(constrname));
	values[Anum_pg_trigger_tgconstrrelid - 1] = ObjectIdGetDatum(constrrelid);
	values[Anum_pg_trigger_tgdeferrable - 1] = BoolGetDatum(stmt->deferrable);
	values[Anum_pg_trigger_tginitdeferred - 1] = BoolGetDatum(stmt->initdeferred);

	if (stmt->args)
	{
		ListCell   *le;
		char	   *args;
		int16		nargs = list_length(stmt->args);
		int			len = 0;

		foreach(le, stmt->args)
		{
			char	   *ar = strVal(lfirst(le));

			len += strlen(ar) + 4;
			for (; *ar; ar++)
			{
				if (*ar == '\\')
					len++;
			}
		}
		args = (char *) palloc(len + 1);
		args[0] = '\0';
		foreach(le, stmt->args)
		{
			char	   *s = strVal(lfirst(le));
			char	   *d = args + strlen(args);

			while (*s)
			{
				if (*s == '\\')
					*d++ = '\\';
				*d++ = *s++;
			}
			strcpy(d, "\\000");
		}
		values[Anum_pg_trigger_tgnargs - 1] = Int16GetDatum(nargs);
		values[Anum_pg_trigger_tgargs - 1] = DirectFunctionCall1(byteain,
													  CStringGetDatum(args));
	}
	else
	{
		values[Anum_pg_trigger_tgnargs - 1] = Int16GetDatum(0);
		values[Anum_pg_trigger_tgargs - 1] = DirectFunctionCall1(byteain,
														CStringGetDatum(""));
	}
	/* tgattr is currently always a zero-length array */
	tgattr = buildint2vector(NULL, 0);
	values[Anum_pg_trigger_tgattr - 1] = PointerGetDatum(tgattr);

	tuple = caql_form_tuple(pcqCtx, values, nulls);

	/* force tuple to have the desired OID */
	HeapTupleSetOid(tuple, trigoid);

	/*
	 * Insert tuple into pg_trigger.
	 */
	caql_insert(pcqCtx, tuple); /* implicit update of index as well */

	myself.classId = TriggerRelationId;
	myself.objectId = trigoid;
	myself.objectSubId = 0;

	heap_freetuple(tuple);
	caql_endscan(pcqCtx);
	heap_close(tgrel, RowExclusiveLock);

	pfree(DatumGetPointer(values[Anum_pg_trigger_tgname - 1]));
	pfree(DatumGetPointer(values[Anum_pg_trigger_tgargs - 1]));

	/*
	 * Update relation's pg_class entry.  Crucial side-effect: other backends
	 * (and this one too!) are sent SI message to make them rebuild relcache
	 * entries.
	 */
	pgrel = heap_open(RelationRelationId, RowExclusiveLock);

	pcqCtx = caql_addrel(cqclr(&cqc), pgrel);

	tuple  = caql_getfirst(
			pcqCtx,
			cql("SELECT * FROM pg_class "
				" WHERE oid = :1 "
				" FOR UPDATE ",
				ObjectIdGetDatum(RelationGetRelid(rel))));

	if (!HeapTupleIsValid(tuple))
		elog(ERROR, "cache lookup failed for relation %u",
			 RelationGetRelid(rel));

	((Form_pg_class) GETSTRUCT(tuple))->reltriggers = found + 1;

	caql_update_current(pcqCtx, tuple);
	/* and Update indexes (implicit) */

	heap_freetuple(tuple);
	heap_close(pgrel, RowExclusiveLock);

	/*
	 * We used to try to update the rel's relcache entry here, but that's
	 * fairly pointless since it will happen as a byproduct of the upcoming
	 * CommandCounterIncrement...
	 */

	/*
	 * Record dependencies for trigger.  Always place a normal dependency on
	 * the function.  If we are doing this in response to an explicit CREATE
	 * TRIGGER command, also make trigger be auto-dropped if its relation is
	 * dropped or if the FK relation is dropped.  (Auto drop is compatible
	 * with our pre-7.3 behavior.)	If the trigger is being made for a
	 * constraint, we can skip the relation links; the dependency on the
	 * constraint will indirectly depend on the relations.
	 */
	referenced.classId = ProcedureRelationId;
	referenced.objectId = funcoid;
	referenced.objectSubId = 0;
	recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);

	if (!forConstraint)
	{
		referenced.classId = RelationRelationId;
		referenced.objectId = RelationGetRelid(rel);
		referenced.objectSubId = 0;
		recordDependencyOn(&myself, &referenced, DEPENDENCY_AUTO);
		if (constrrelid != InvalidOid)
		{
			referenced.classId = RelationRelationId;
			referenced.objectId = constrrelid;
			referenced.objectSubId = 0;
			recordDependencyOn(&myself, &referenced, DEPENDENCY_AUTO);
		}
	}

	/* Keep lock on target rel until end of xact */
	heap_close(rel, NoLock);
	
	return trigoid;
}

/*
 * DropTrigger - drop an individual trigger by name
 */
void
DropTrigger(Oid relid, const char *trigname, DropBehavior behavior,
			bool missing_ok)
{
	int fetchCount;
	ObjectAddress object;

	/*
	 * Find the trigger, verify permissions, set up object address
	 */
	object.classId = TriggerRelationId;
	object.objectSubId = 0;

	object.objectId = caql_getoid_plus(
			NULL,
			&fetchCount,
			NULL,
			cql("SELECT oid FROM pg_trigger "
				" WHERE tgrelid = :1 "
				" AND tgname = :2 ",
				ObjectIdGetDatum(relid),
				CStringGetDatum((char *) trigname)));

	if (0 == fetchCount)
	{
		if (!missing_ok)
			ereport(ERROR,
					(errcode(ERRCODE_UNDEFINED_OBJECT),
					 errmsg("trigger \"%s\" for table \"%s\" does not exist",
							trigname, get_rel_name(relid))));
		else
			ereport(NOTICE,
					(errmsg("trigger \"%s\" for table \"%s\" does not exist, skipping",
							trigname, get_rel_name(relid))));
		/* cleanup */
		return;
	}

	if (!pg_class_ownercheck(relid, GetUserId()))
		aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_CLASS,
					   get_rel_name(relid));


	/*
	 * Do the deletion
	 */
	performDeletion(&object, behavior);
}

/*
 * Guts of trigger deletion.
 */
void
RemoveTriggerById(Oid trigOid)
{
	Relation	tgrel;
	cqContext	cqc;
	cqContext  *pcqCtx;
	HeapTuple	tup;
	Oid			relid;
	Relation	rel;
	Relation	pgrel;
	HeapTuple	tuple;
	Form_pg_class classForm;

	tgrel = heap_open(TriggerRelationId, RowExclusiveLock);

	pcqCtx = caql_addrel(cqclr(&cqc), tgrel);

	/*
	 * Find the trigger to delete.
	 */
	tup = caql_getfirst(
			pcqCtx,
			cql("SELECT * FROM pg_trigger "
				" WHERE oid = :1 "
				" FOR UPDATE ",
				ObjectIdGetDatum(trigOid)));

	if (!HeapTupleIsValid(tup))
		elog(ERROR, "could not find tuple for trigger %u", trigOid);

	/*
	 * Open and exclusive-lock the relation the trigger belongs to.
	 */
	relid = ((Form_pg_trigger) GETSTRUCT(tup))->tgrelid;

	rel = heap_open(relid, AccessExclusiveLock);

	if (rel->rd_rel->relkind != RELKIND_RELATION)
		ereport(ERROR,
				(errcode(ERRCODE_WRONG_OBJECT_TYPE),
				 errmsg("\"%s\" is not a table",
						RelationGetRelationName(rel))));

	if (!allowSystemTableModsDDL && IsSystemRelation(rel))
		ereport(ERROR,
				(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
				 errmsg("permission denied: \"%s\" is a system catalog",
						RelationGetRelationName(rel))));

	/*
	 * Delete the pg_trigger tuple.
	 */
	caql_delete_current(pcqCtx);

	heap_close(tgrel, RowExclusiveLock);

	/*
	 * Update relation's pg_class entry.  Crucial side-effect: other backends
	 * (and this one too!) are sent SI message to make them rebuild relcache
	 * entries.
	 *
	 * Note this is OK only because we have AccessExclusiveLock on the rel, so
	 * no one else is creating/deleting triggers on this rel at the same time.
	 */
	pgrel = heap_open(RelationRelationId, RowExclusiveLock);

	pcqCtx = caql_addrel(cqclr(&cqc), pgrel);

	tuple  = caql_getfirst(
			pcqCtx,
			cql("SELECT * FROM pg_class "
				" WHERE oid = :1 "
				" FOR UPDATE ",
				ObjectIdGetDatum(relid)));

	if (!HeapTupleIsValid(tuple))
		elog(ERROR, "cache lookup failed for relation %u", relid);
	classForm = (Form_pg_class) GETSTRUCT(tuple);

	if (classForm->reltriggers == 0)	/* should not happen */
		elog(ERROR, "relation \"%s\" has reltriggers = 0",
			 RelationGetRelationName(rel));
	classForm->reltriggers--;

	caql_update_current(pcqCtx, tuple);
	/* and Update indexes (implicit) */

	heap_freetuple(tuple);

	heap_close(pgrel, RowExclusiveLock);

	/* Keep lock on trigger's rel until end of xact */
	heap_close(rel, NoLock);
}

/*
 *		renametrig		- changes the name of a trigger on a relation
 *
 *		trigger name is changed in trigger catalog.
 *		No record of the previous name is kept.
 *
 *		get proper relrelation from relation catalog (if not arg)
 *		scan trigger catalog
 *				for name conflict (within rel)
 *				for original trigger (if not arg)
 *		modify tgname in trigger tuple
 *		update row in catalog
 */
void
renametrig(Oid relid,
		   const char *oldname,
		   const char *newname)
{
	Relation	targetrel;
	Relation	tgrel;
	HeapTuple	tuple;
	cqContext	cqc;
	cqContext  *pcqCtx;

	/*
	 * Grab an exclusive lock on the target table, which we will NOT release
	 * until end of transaction.
	 */
	targetrel = heap_open(relid, AccessExclusiveLock);

	/*
	 * Scan pg_trigger twice for existing triggers on relation.  We do this in
	 * order to ensure a trigger does not exist with newname (The unique index
	 * on tgrelid/tgname would complain anyway) and to ensure a trigger does
	 * exist with oldname.
	 *
	 * NOTE that this is cool only because we have AccessExclusiveLock on the
	 * relation, so the trigger set won't be changing underneath us.
	 */
	tgrel = heap_open(TriggerRelationId, RowExclusiveLock);

	/*
	 * First pass -- look for name conflict
	 */

	if (caql_getcount(
				caql_addrel(cqclr(&cqc), tgrel),
				cql("SELECT count(*) FROM pg_trigger "
					" WHERE tgrelid = :1 "
					" AND tgname = :2 ",
					ObjectIdGetDatum(relid),
					PointerGetDatum((char *) newname))))
	{
		ereport(ERROR,
				(errcode(ERRCODE_DUPLICATE_OBJECT),
				 errmsg("trigger \"%s\" for relation \"%s\" already exists",
						newname, RelationGetRelationName(targetrel))));
	}


	/*
	 * Second pass -- look for trigger existing with oldname and update
	 */
	pcqCtx = caql_beginscan(
			caql_addrel(cqclr(&cqc), tgrel),
			cql("SELECT * FROM pg_trigger "
				" WHERE tgrelid = :1 "
				" AND tgname = :2 "
				" FOR UPDATE ",
				ObjectIdGetDatum(relid),
				PointerGetDatum((char *) oldname)));

	if (HeapTupleIsValid(tuple = caql_getnext(pcqCtx)))
	{
		/*
		 * Update pg_trigger tuple with new tgname.
		 */
		tuple = heap_copytuple(tuple);	/* need a modifiable copy */

		namestrcpy(&((Form_pg_trigger) GETSTRUCT(tuple))->tgname, newname);

		caql_update_current(pcqCtx, tuple);

		/*
		 * Invalidate relation's relcache entry so that other backends (and
		 * this one too!) are sent SI message to make them rebuild relcache
		 * entries.  (Ideally this should happen automatically...)
		 */
		CacheInvalidateRelcache(targetrel);
	}
	else
	{
		ereport(ERROR,
				(errcode(ERRCODE_UNDEFINED_OBJECT),
				 errmsg("trigger \"%s\" for table \"%s\" does not exist",
						oldname, RelationGetRelationName(targetrel))));
	}

	caql_endscan(pcqCtx);

	heap_close(tgrel, RowExclusiveLock);

	/*
	 * Close rel, but keep exclusive lock!
	 */
	heap_close(targetrel, NoLock);
}


/*
 * EnableDisableTrigger()
 *
 *	Called by ALTER TABLE ENABLE/DISABLE TRIGGER
 *	to change 'tgenabled' flag for the specified trigger(s)
 *
 * rel: relation to process (caller must hold suitable lock on it)
 * tgname: trigger to process, or NULL to scan all triggers
 * enable: new value for tgenabled flag
 * skip_system: if true, skip "system" triggers (constraint triggers)
 *
 * Caller should have checked permissions for the table; here we also
 * enforce that superuser privilege is required to alter the state of
 * system triggers
 */
void
EnableDisableTrigger(Relation rel, const char *tgname,
					 bool enable, bool skip_system)
{
	Relation	tgrel;
	cqContext	cqc;
	cqContext  *pcqCtx;
	HeapTuple	tuple;
	bool		found;
	bool		changed;

	/* Scan the relevant entries in pg_triggers */
	tgrel = heap_open(TriggerRelationId, RowExclusiveLock);

	if (tgname)
	{
		pcqCtx = caql_beginscan(
				caql_addrel(cqclr(&cqc), tgrel),
				cql("SELECT * FROM pg_trigger "
					" WHERE tgrelid = :1 "
					" AND tgname = :2 "
					" FOR UPDATE ",
					ObjectIdGetDatum(RelationGetRelid(rel)),
					CStringGetDatum((char *) tgname)));
	}
	else
	{
		pcqCtx = caql_beginscan(
				caql_addrel(cqclr(&cqc), tgrel),
				cql("SELECT * FROM pg_trigger "
					" WHERE tgrelid = :1 "
					" FOR UPDATE ",
					ObjectIdGetDatum(RelationGetRelid(rel))));
	}

	found = changed = false;

	while (HeapTupleIsValid(tuple = caql_getnext(pcqCtx)))
	{
		Form_pg_trigger oldtrig = (Form_pg_trigger) GETSTRUCT(tuple);

		if (oldtrig->tgisconstraint)
		{
			/* system trigger ... ok to process? */
			if (skip_system)
				continue;
			if (!superuser())
				ereport(ERROR,
						(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
					  errmsg("permission denied: \"%s\" is a system trigger",
							 NameStr(oldtrig->tgname))));
		}

		found = true;

		if (oldtrig->tgenabled != enable)
		{
			/* need to change this one ... make a copy to scribble on */
			HeapTuple	newtup = heap_copytuple(tuple);
			Form_pg_trigger newtrig = (Form_pg_trigger) GETSTRUCT(newtup);

			newtrig->tgenabled = enable;

			caql_update_current(pcqCtx, newtup);
			/* and Update indexes (implicit) */

			heap_freetuple(newtup);

			changed = true;
		}
	}

	caql_endscan(pcqCtx);

	heap_close(tgrel, RowExclusiveLock);

	if (tgname && !found)
		ereport(ERROR,
				(errcode(ERRCODE_UNDEFINED_OBJECT),
				 errmsg("trigger \"%s\" for table \"%s\" does not exist",
						tgname, RelationGetRelationName(rel))));

	/*
	 * If we changed anything, broadcast a SI inval message to force each
	 * backend (including our own!) to rebuild relation's relcache entry.
	 * Otherwise they will fail to apply the change promptly.
	 */
	if (changed)
		CacheInvalidateRelcache(rel);
}


/*
 * Build trigger data to attach to the given relcache entry.
 *
 * Note that trigger data attached to a relcache entry must be stored in
 * CacheMemoryContext to ensure it survives as long as the relcache entry.
 * But we should be running in a less long-lived working context.  To avoid
 * leaking cache memory if this routine fails partway through, we build a
 * temporary TriggerDesc in working memory and then copy the completed
 * structure into cache memory.
 */
void
RelationBuildTriggers(Relation relation)
{
	TriggerDesc *trigdesc;
	int			ntrigs = relation->rd_rel->reltriggers;
	Trigger    *triggers;
	int			found = 0;
	Relation	tgrel;
	cqContext	cqc;
	cqContext  *pcqCtx;
	HeapTuple	htup;
	MemoryContext oldContext;

	Assert(ntrigs > 0);			/* else I should not have been called */

	triggers = (Trigger *) palloc(ntrigs * sizeof(Trigger));

	/*
	 * Note: since we scan the triggers using TriggerRelidNameIndexId, we will
	 * be reading the triggers in name order, except possibly during
	 * emergency-recovery operations (ie, IgnoreSystemIndexes). This in turn
	 * ensures that triggers will be fired in name order.
	 */

	/* XXX XXX: ORDER BY */
	tgrel = heap_open(TriggerRelationId, AccessShareLock);

	pcqCtx = caql_beginscan(
			caql_addrel(cqclr(&cqc), tgrel),
			cql("SELECT * FROM pg_trigger "
				" WHERE tgrelid = :1 "
				" ORDER BY tgrelid, tgname",
				ObjectIdGetDatum(RelationGetRelid(relation))));

	while (HeapTupleIsValid(htup = caql_getnext(pcqCtx)))
	{
		Form_pg_trigger pg_trigger = (Form_pg_trigger) GETSTRUCT(htup);
		Trigger    *build;

		if (found >= ntrigs)
			elog(ERROR, "too many trigger records found for relation \"%s\"",
				 RelationGetRelationName(relation));
		build = &(triggers[found]);

		build->tgoid = HeapTupleGetOid(htup);
		build->tgname = DatumGetCString(DirectFunctionCall1(nameout,
										 NameGetDatum(&pg_trigger->tgname)));
		build->tgfoid = pg_trigger->tgfoid;
		build->tgtype = pg_trigger->tgtype;
		build->tgenabled = pg_trigger->tgenabled;
		build->tgisconstraint = pg_trigger->tgisconstraint;
		build->tgconstrrelid = pg_trigger->tgconstrrelid;
		build->tgdeferrable = pg_trigger->tgdeferrable;
		build->tginitdeferred = pg_trigger->tginitdeferred;
		build->tgnargs = pg_trigger->tgnargs;
		/* tgattr is first var-width field, so OK to access directly */
		build->tgnattr = pg_trigger->tgattr.dim1;
		if (build->tgnattr > 0)
		{
			build->tgattr = (int2 *) palloc(build->tgnattr * sizeof(int2));
			memcpy(build->tgattr, &(pg_trigger->tgattr.values),
				   build->tgnattr * sizeof(int2));
		}
		else
			build->tgattr = NULL;
		if (build->tgnargs > 0)
		{
			bytea	   *val;
			bool		isnull;
			char	   *p;
			int			i;

			val = DatumGetByteaP(fastgetattr(htup,
										 Anum_pg_trigger_tgargs,
										 RelationGetDescr(tgrel), &isnull));
			if (isnull)
				elog(ERROR, "tgargs is null in trigger for relation \"%s\"",
					 RelationGetRelationName(relation));
			p = (char *) VARDATA(val);
			build->tgargs = (char **) palloc(build->tgnargs * sizeof(char *));
			for (i = 0; i < build->tgnargs; i++)
			{
				build->tgargs[i] = pstrdup(p);
				p += strlen(p) + 1;
			}
		}
		else
			build->tgargs = NULL;

		found++;
	}

	caql_endscan(pcqCtx);
	heap_close(tgrel, AccessShareLock);

	if (found != ntrigs)
		elog(ERROR, "%d trigger record(s) not found for relation \"%s\"",
			 ntrigs - found,
			 RelationGetRelationName(relation));

	/* Build trigdesc */
	trigdesc = (TriggerDesc *) palloc0(sizeof(TriggerDesc));
	trigdesc->triggers = triggers;
	trigdesc->numtriggers = ntrigs;
	for (found = 0; found < ntrigs; found++)
		InsertTrigger(trigdesc, &(triggers[found]), found);

	/* Copy completed trigdesc into cache storage */
	oldContext = MemoryContextSwitchTo(CacheMemoryContext);
	relation->trigdesc = CopyTriggerDesc(trigdesc);
	MemoryContextSwitchTo(oldContext);

	/* Release working memory */
	FreeTriggerDesc(trigdesc);
}

/*
 * Insert the given trigger into the appropriate index list(s) for it
 *
 * To simplify storage management, we allocate each index list at the max
 * possible size (trigdesc->numtriggers) if it's used at all.  This does
 * not waste space permanently since we're only building a temporary
 * trigdesc at this point.
 */
static void
InsertTrigger(TriggerDesc *trigdesc, Trigger *trigger, int indx)
{
	uint16	   *n;
	int		  **t,
			  **tp;

	if (TRIGGER_FOR_ROW(trigger->tgtype))
	{
		/* ROW trigger */
		if (TRIGGER_FOR_BEFORE(trigger->tgtype))
		{
			n = trigdesc->n_before_row;
			t = trigdesc->tg_before_row;
		}
		else
		{
			n = trigdesc->n_after_row;
			t = trigdesc->tg_after_row;
		}
	}
	else
	{
		/* STATEMENT trigger */
		if (TRIGGER_FOR_BEFORE(trigger->tgtype))
		{
			n = trigdesc->n_before_statement;
			t = trigdesc->tg_before_statement;
		}
		else
		{
			n = trigdesc->n_after_statement;
			t = trigdesc->tg_after_statement;
		}
	}

	if (TRIGGER_FOR_INSERT(trigger->tgtype))
	{
		tp = &(t[TRIGGER_EVENT_INSERT]);
		if (*tp == NULL)
			*tp = (int *) palloc(trigdesc->numtriggers * sizeof(int));
		(*tp)[n[TRIGGER_EVENT_INSERT]] = indx;
		(n[TRIGGER_EVENT_INSERT])++;
	}

	if (TRIGGER_FOR_DELETE(trigger->tgtype))
	{
		tp = &(t[TRIGGER_EVENT_DELETE]);
		if (*tp == NULL)
			*tp = (int *) palloc(trigdesc->numtriggers * sizeof(int));
		(*tp)[n[TRIGGER_EVENT_DELETE]] = indx;
		(n[TRIGGER_EVENT_DELETE])++;
	}

	if (TRIGGER_FOR_UPDATE(trigger->tgtype))
	{
		tp = &(t[TRIGGER_EVENT_UPDATE]);
		if (*tp == NULL)
			*tp = (int *) palloc(trigdesc->numtriggers * sizeof(int));
		(*tp)[n[TRIGGER_EVENT_UPDATE]] = indx;
		(n[TRIGGER_EVENT_UPDATE])++;
	}
}

/*
 * Copy a TriggerDesc data structure.
 *
 * The copy is allocated in the current memory context.
 */
TriggerDesc *
CopyTriggerDesc(TriggerDesc *trigdesc)
{
	TriggerDesc *newdesc;
	uint16	   *n;
	int		  **t,
			   *tnew;
	Trigger    *trigger;
	int			i;

	if (trigdesc == NULL || trigdesc->numtriggers <= 0)
		return NULL;

	newdesc = (TriggerDesc *) palloc(sizeof(TriggerDesc));
	memcpy(newdesc, trigdesc, sizeof(TriggerDesc));

	trigger = (Trigger *) palloc(trigdesc->numtriggers * sizeof(Trigger));
	memcpy(trigger, trigdesc->triggers,
		   trigdesc->numtriggers * sizeof(Trigger));
	newdesc->triggers = trigger;

	for (i = 0; i < trigdesc->numtriggers; i++)
	{
		trigger->tgname = pstrdup(trigger->tgname);
		if (trigger->tgnattr > 0)
		{
			int2	   *newattr;

			newattr = (int2 *) palloc(trigger->tgnattr * sizeof(int2));
			memcpy(newattr, trigger->tgattr,
				   trigger->tgnattr * sizeof(int2));
			trigger->tgattr = newattr;
		}
		if (trigger->tgnargs > 0)
		{
			char	  **newargs;
			int16		j;

			newargs = (char **) palloc(trigger->tgnargs * sizeof(char *));
			for (j = 0; j < trigger->tgnargs; j++)
				newargs[j] = pstrdup(trigger->tgargs[j]);
			trigger->tgargs = newargs;
		}
		trigger++;
	}

	n = newdesc->n_before_statement;
	t = newdesc->tg_before_statement;
	for (i = 0; i < TRIGGER_NUM_EVENT_CLASSES; i++)
	{
		if (n[i] > 0)
		{
			tnew = (int *) palloc(n[i] * sizeof(int));
			memcpy(tnew, t[i], n[i] * sizeof(int));
			t[i] = tnew;
		}
		else
			t[i] = NULL;
	}
	n = newdesc->n_before_row;
	t = newdesc->tg_before_row;
	for (i = 0; i < TRIGGER_NUM_EVENT_CLASSES; i++)
	{
		if (n[i] > 0)
		{
			tnew = (int *) palloc(n[i] * sizeof(int));
			memcpy(tnew, t[i], n[i] * sizeof(int));
			t[i] = tnew;
		}
		else
			t[i] = NULL;
	}
	n = newdesc->n_after_row;
	t = newdesc->tg_after_row;
	for (i = 0; i < TRIGGER_NUM_EVENT_CLASSES; i++)
	{
		if (n[i] > 0)
		{
			tnew = (int *) palloc(n[i] * sizeof(int));
			memcpy(tnew, t[i], n[i] * sizeof(int));
			t[i] = tnew;
		}
		else
			t[i] = NULL;
	}
	n = newdesc->n_after_statement;
	t = newdesc->tg_after_statement;
	for (i = 0; i < TRIGGER_NUM_EVENT_CLASSES; i++)
	{
		if (n[i] > 0)
		{
			tnew = (int *) palloc(n[i] * sizeof(int));
			memcpy(tnew, t[i], n[i] * sizeof(int));
			t[i] = tnew;
		}
		else
			t[i] = NULL;
	}

	return newdesc;
}

/*
 * Free a TriggerDesc data structure.
 */
void
FreeTriggerDesc(TriggerDesc *trigdesc)
{
	int		  **t;
	Trigger    *trigger;
	int			i;

	if (trigdesc == NULL)
		return;

	t = trigdesc->tg_before_statement;
	for (i = 0; i < TRIGGER_NUM_EVENT_CLASSES; i++)
		if (t[i] != NULL)
			pfree(t[i]);
	t = trigdesc->tg_before_row;
	for (i = 0; i < TRIGGER_NUM_EVENT_CLASSES; i++)
		if (t[i] != NULL)
			pfree(t[i]);
	t = trigdesc->tg_after_row;
	for (i = 0; i < TRIGGER_NUM_EVENT_CLASSES; i++)
		if (t[i] != NULL)
			pfree(t[i]);
	t = trigdesc->tg_after_statement;
	for (i = 0; i < TRIGGER_NUM_EVENT_CLASSES; i++)
		if (t[i] != NULL)
			pfree(t[i]);

	trigger = trigdesc->triggers;
	for (i = 0; i < trigdesc->numtriggers; i++)
	{
		pfree(trigger->tgname);
		if (trigger->tgnattr > 0)
			pfree(trigger->tgattr);
		if (trigger->tgnargs > 0)
		{
			while (--(trigger->tgnargs) >= 0)
				pfree(trigger->tgargs[trigger->tgnargs]);
			pfree(trigger->tgargs);
		}
		trigger++;
	}
	pfree(trigdesc->triggers);
	pfree(trigdesc);
}

/*
 * Compare two TriggerDesc structures for logical equality.
 */
#ifdef NOT_USED
bool
equalTriggerDescs(TriggerDesc *trigdesc1, TriggerDesc *trigdesc2)
{
	int			i,
				j;

	/*
	 * We need not examine the "index" data, just the trigger array itself; if
	 * we have the same triggers with the same types, the derived index data
	 * should match.
	 *
	 * As of 7.3 we assume trigger set ordering is significant in the
	 * comparison; so we just compare corresponding slots of the two sets.
	 */
	if (trigdesc1 != NULL)
	{
		if (trigdesc2 == NULL)
			return false;
		if (trigdesc1->numtriggers != trigdesc2->numtriggers)
			return false;
		for (i = 0; i < trigdesc1->numtriggers; i++)
		{
			Trigger    *trig1 = trigdesc1->triggers + i;
			Trigger    *trig2 = trigdesc2->triggers + i;

			if (trig1->tgoid != trig2->tgoid)
				return false;
			if (strcmp(trig1->tgname, trig2->tgname) != 0)
				return false;
			if (trig1->tgfoid != trig2->tgfoid)
				return false;
			if (trig1->tgtype != trig2->tgtype)
				return false;
			if (trig1->tgenabled != trig2->tgenabled)
				return false;
			if (trig1->tgisconstraint != trig2->tgisconstraint)
				return false;
			if (trig1->tgconstrrelid != trig2->tgconstrrelid)
				return false;
			if (trig1->tgdeferrable != trig2->tgdeferrable)
				return false;
			if (trig1->tginitdeferred != trig2->tginitdeferred)
				return false;
			if (trig1->tgnargs != trig2->tgnargs)
				return false;
			if (trig1->tgnattr != trig2->tgnattr)
				return false;
			if (trig1->tgnattr > 0 &&
				memcmp(trig1->tgattr, trig2->tgattr,
					   trig1->tgnattr * sizeof(int2)) != 0)
				return false;
			for (j = 0; j < trig1->tgnargs; j++)
				if (strcmp(trig1->tgargs[j], trig2->tgargs[j]) != 0)
					return false;
		}
	}
	else if (trigdesc2 != NULL)
		return false;
	return true;
}
#endif   /* NOT_USED */

/*
 * Call a trigger function.
 *
 *		trigdata: trigger descriptor.
 *		tgindx: trigger's index in finfo and instr arrays.
 *		finfo: array of cached trigger function call information.
 *		instr: optional array of EXPLAIN ANALYZE instrumentation state.
 *		per_tuple_context: memory context to execute the function in.
 *
 * Returns the tuple (or NULL) as returned by the function.
 */
HeapTuple
ExecCallTriggerFunc(TriggerData *trigdata,
					int tgindx,
					FmgrInfo *finfo,
					Instrumentation *instr,
					MemoryContext per_tuple_context)
{
	FunctionCallInfoData fcinfo;
	Datum		result;
	MemoryContext oldContext;

	finfo += tgindx;

	/*
	 * We cache fmgr lookup info, to avoid making the lookup again on each
	 * call.
	 */
	if (finfo->fn_oid == InvalidOid)
		fmgr_info(trigdata->tg_trigger->tgfoid, finfo);

	Assert(finfo->fn_oid == trigdata->tg_trigger->tgfoid);

	/*
	 * If doing EXPLAIN ANALYZE, start charging time to this trigger.
	 */
	if (instr)
		InstrStartNode(instr + tgindx);

	/*
	 * Do the function evaluation in the per-tuple memory context, so that
	 * leaked memory will be reclaimed once per tuple. Note in particular that
	 * any new tuple created by the trigger function will live till the end of
	 * the tuple cycle.
	 */
	oldContext = MemoryContextSwitchTo(per_tuple_context);

	/*
	 * Call the function, passing no arguments but setting a context.
	 */
	InitFunctionCallInfoData(fcinfo, finfo, 0, (Node *) trigdata, NULL);

	result = FunctionCallInvoke(&fcinfo);

	MemoryContextSwitchTo(oldContext);

	/*
	 * Trigger protocol allows function to return a null pointer, but NOT to
	 * set the isnull result flag.
	 */
	if (fcinfo.isnull)
		ereport(ERROR,
				(errcode(ERRCODE_E_R_I_E_TRIGGER_PROTOCOL_VIOLATED),
				 errmsg("trigger function %u returned null value",
						fcinfo.flinfo->fn_oid)));

	/*
	 * If doing EXPLAIN ANALYZE, stop charging time to this trigger, and count
	 * one "tuple returned" (really the number of firings).
	 */
	if (instr)
		InstrStopNode(instr + tgindx, 1);

	return (HeapTuple) DatumGetPointer(result);
}

void
ExecBSInsertTriggers(EState *estate, ResultRelInfo *relinfo)
{
	TriggerDesc *trigdesc;
	int			ntrigs;
	int		   *tgindx;
	int			i;
	TriggerData LocTriggerData;

	trigdesc = relinfo->ri_TrigDesc;

	if (trigdesc == NULL)
		return;

	ntrigs = trigdesc->n_before_statement[TRIGGER_EVENT_INSERT];
	tgindx = trigdesc->tg_before_statement[TRIGGER_EVENT_INSERT];

	if (ntrigs == 0)
		return;

	LocTriggerData.type = T_TriggerData;
	LocTriggerData.tg_event = TRIGGER_EVENT_INSERT |
		TRIGGER_EVENT_BEFORE;
	LocTriggerData.tg_relation = relinfo->ri_RelationDesc;
	LocTriggerData.tg_trigtuple = NULL;
	LocTriggerData.tg_newtuple = NULL;
	LocTriggerData.tg_trigtuplebuf = InvalidBuffer;
	LocTriggerData.tg_newtuplebuf = InvalidBuffer;
	for (i = 0; i < ntrigs; i++)
	{
		Trigger    *trigger = &trigdesc->triggers[tgindx[i]];
		HeapTuple	newtuple;

		if (!trigger->tgenabled)
			continue;
		LocTriggerData.tg_trigger = trigger;
		newtuple = ExecCallTriggerFunc(&LocTriggerData,
									   tgindx[i],
									   relinfo->ri_TrigFunctions,
									   relinfo->ri_TrigInstrument,
									   GetPerTupleMemoryContext(estate));

		if (newtuple)
			ereport(ERROR,
					(errcode(ERRCODE_E_R_I_E_TRIGGER_PROTOCOL_VIOLATED),
				  errmsg("BEFORE STATEMENT trigger cannot return a value")));
	}
}

void
ExecASInsertTriggers(EState *estate, ResultRelInfo *relinfo)
{
	TriggerDesc *trigdesc = relinfo->ri_TrigDesc;

	if (trigdesc && trigdesc->n_after_statement[TRIGGER_EVENT_INSERT] > 0)
		AfterTriggerSaveEvent(relinfo, TRIGGER_EVENT_INSERT,
							  false, NULL, NULL);
}

HeapTuple
ExecBRInsertTriggers(EState *estate, ResultRelInfo *relinfo,
					 HeapTuple trigtuple)
{
	TriggerDesc *trigdesc = relinfo->ri_TrigDesc;
	int			ntrigs = trigdesc->n_before_row[TRIGGER_EVENT_INSERT];
	int		   *tgindx = trigdesc->tg_before_row[TRIGGER_EVENT_INSERT];
	HeapTuple	newtuple = trigtuple;
	HeapTuple	oldtuple;
	TriggerData LocTriggerData;
	int			i;

	LocTriggerData.type = T_TriggerData;
	LocTriggerData.tg_event = TRIGGER_EVENT_INSERT |
		TRIGGER_EVENT_ROW |
		TRIGGER_EVENT_BEFORE;
	LocTriggerData.tg_relation = relinfo->ri_RelationDesc;
	LocTriggerData.tg_newtuple = NULL;
	LocTriggerData.tg_newtuplebuf = InvalidBuffer;
	for (i = 0; i < ntrigs; i++)
	{
		Trigger    *trigger = &trigdesc->triggers[tgindx[i]];

		if (!trigger->tgenabled)
			continue;
		LocTriggerData.tg_trigtuple = oldtuple = newtuple;
		LocTriggerData.tg_trigtuplebuf = InvalidBuffer;
		LocTriggerData.tg_trigger = trigger;
		newtuple = ExecCallTriggerFunc(&LocTriggerData,
									   tgindx[i],
									   relinfo->ri_TrigFunctions,
									   relinfo->ri_TrigInstrument,
									   GetPerTupleMemoryContext(estate));
		if (oldtuple != newtuple && oldtuple != trigtuple)
			heap_freetuple(oldtuple);
		if (newtuple == NULL)
			break;
	}
	return newtuple;
}

void
ExecARInsertTriggers(EState *estate, ResultRelInfo *relinfo,
					 HeapTuple trigtuple)
{
	TriggerDesc *trigdesc = relinfo->ri_TrigDesc;

	if (trigdesc && trigdesc->n_after_row[TRIGGER_EVENT_INSERT] > 0)
	{
		if(RelationIsParquet(relinfo->ri_RelationDesc))
			elog(ERROR, "Trigger is not supported on Parquet yet");

		AfterTriggerSaveEvent(relinfo, TRIGGER_EVENT_INSERT,
								true, NULL, trigtuple);
		}
}

void
ExecBSDeleteTriggers(EState *estate, ResultRelInfo *relinfo)
{
	TriggerDesc *trigdesc;
	int			ntrigs;
	int		   *tgindx;
	int			i;
	TriggerData LocTriggerData;

	trigdesc = relinfo->ri_TrigDesc;

	if (trigdesc == NULL)
		return;

	ntrigs = trigdesc->n_before_statement[TRIGGER_EVENT_DELETE];
	tgindx = trigdesc->tg_before_statement[TRIGGER_EVENT_DELETE];

	if (ntrigs == 0)
		return;

	LocTriggerData.type = T_TriggerData;
	LocTriggerData.tg_event = TRIGGER_EVENT_DELETE |
		TRIGGER_EVENT_BEFORE;
	LocTriggerData.tg_relation = relinfo->ri_RelationDesc;
	LocTriggerData.tg_trigtuple = NULL;
	LocTriggerData.tg_newtuple = NULL;
	LocTriggerData.tg_trigtuplebuf = InvalidBuffer;
	LocTriggerData.tg_newtuplebuf = InvalidBuffer;
	for (i = 0; i < ntrigs; i++)
	{
		Trigger    *trigger = &trigdesc->triggers[tgindx[i]];
		HeapTuple	newtuple;

		if (!trigger->tgenabled)
			continue;
		LocTriggerData.tg_trigger = trigger;
		newtuple = ExecCallTriggerFunc(&LocTriggerData,
									   tgindx[i],
									   relinfo->ri_TrigFunctions,
									   relinfo->ri_TrigInstrument,
									   GetPerTupleMemoryContext(estate));

		if (newtuple)
			ereport(ERROR,
					(errcode(ERRCODE_E_R_I_E_TRIGGER_PROTOCOL_VIOLATED),
				  errmsg("BEFORE STATEMENT trigger cannot return a value")));
	}
}

void
ExecASDeleteTriggers(EState *estate, ResultRelInfo *relinfo)
{
	TriggerDesc *trigdesc = relinfo->ri_TrigDesc;

	if (trigdesc && trigdesc->n_after_statement[TRIGGER_EVENT_DELETE] > 0)
		AfterTriggerSaveEvent(relinfo, TRIGGER_EVENT_DELETE,
							  false, NULL, NULL);
}

bool
ExecBRDeleteTriggers(EState *estate, ResultRelInfo *relinfo,
					 ItemPointer tupleid,
					 CommandId cid)
{
	TriggerDesc *trigdesc = relinfo->ri_TrigDesc;
	int			ntrigs = trigdesc->n_before_row[TRIGGER_EVENT_DELETE];
	int		   *tgindx = trigdesc->tg_before_row[TRIGGER_EVENT_DELETE];
	bool		result = true;
	TriggerData LocTriggerData;
	HeapTuple	trigtuple;
	HeapTuple	newtuple;
	TupleTableSlot *newSlot;
	int			i;

	trigtuple = GetTupleForTrigger(estate, relinfo, tupleid, cid, &newSlot);
	if (trigtuple == NULL)
		return false;

	LocTriggerData.type = T_TriggerData;
	LocTriggerData.tg_event = TRIGGER_EVENT_DELETE |
		TRIGGER_EVENT_ROW |
		TRIGGER_EVENT_BEFORE;
	LocTriggerData.tg_relation = relinfo->ri_RelationDesc;
	LocTriggerData.tg_newtuple = NULL;
	LocTriggerData.tg_newtuplebuf = InvalidBuffer;
	for (i = 0; i < ntrigs; i++)
	{
		Trigger    *trigger = &trigdesc->triggers[tgindx[i]];

		if (!trigger->tgenabled)
			continue;
		LocTriggerData.tg_trigtuple = trigtuple;
		LocTriggerData.tg_trigtuplebuf = InvalidBuffer;
		LocTriggerData.tg_trigger = trigger;
		newtuple = ExecCallTriggerFunc(&LocTriggerData,
									   tgindx[i],
									   relinfo->ri_TrigFunctions,
									   relinfo->ri_TrigInstrument,
									   GetPerTupleMemoryContext(estate));
		if (newtuple == NULL)
		{
			result = false;		/* tell caller to suppress delete */
			break;
		}
		if (newtuple != trigtuple)
			heap_freetuple(newtuple);
	}
	heap_freetuple(trigtuple);

	return result;
}

void
ExecARDeleteTriggers(EState *estate, ResultRelInfo *relinfo,
					 ItemPointer tupleid)
{
	TriggerDesc *trigdesc = relinfo->ri_TrigDesc;

	if (trigdesc && trigdesc->n_after_row[TRIGGER_EVENT_DELETE] > 0)
	{
		HeapTuple	trigtuple = GetTupleForTrigger(estate, relinfo,
												   tupleid,
												   (CommandId) 0,
												   NULL);

		AfterTriggerSaveEvent(relinfo, TRIGGER_EVENT_DELETE,
							  true, trigtuple, NULL);
		heap_freetuple(trigtuple);
	}
}

void
ExecBSUpdateTriggers(EState *estate, ResultRelInfo *relinfo)
{
	TriggerDesc *trigdesc;
	int			ntrigs;
	int		   *tgindx;
	int			i;
	TriggerData LocTriggerData;

	trigdesc = relinfo->ri_TrigDesc;

	if (trigdesc == NULL)
		return;

	ntrigs = trigdesc->n_before_statement[TRIGGER_EVENT_UPDATE];
	tgindx = trigdesc->tg_before_statement[TRIGGER_EVENT_UPDATE];

	if (ntrigs == 0)
		return;

	LocTriggerData.type = T_TriggerData;
	LocTriggerData.tg_event = TRIGGER_EVENT_UPDATE |
		TRIGGER_EVENT_BEFORE;
	LocTriggerData.tg_relation = relinfo->ri_RelationDesc;
	LocTriggerData.tg_trigtuple = NULL;
	LocTriggerData.tg_newtuple = NULL;
	LocTriggerData.tg_trigtuplebuf = InvalidBuffer;
	LocTriggerData.tg_newtuplebuf = InvalidBuffer;
	for (i = 0; i < ntrigs; i++)
	{
		Trigger    *trigger = &trigdesc->triggers[tgindx[i]];
		HeapTuple	newtuple;

		if (!trigger->tgenabled)
			continue;
		LocTriggerData.tg_trigger = trigger;
		newtuple = ExecCallTriggerFunc(&LocTriggerData,
									   tgindx[i],
									   relinfo->ri_TrigFunctions,
									   relinfo->ri_TrigInstrument,
									   GetPerTupleMemoryContext(estate));

		if (newtuple)
			ereport(ERROR,
					(errcode(ERRCODE_E_R_I_E_TRIGGER_PROTOCOL_VIOLATED),
				  errmsg("BEFORE STATEMENT trigger cannot return a value")));
	}
}

void
ExecASUpdateTriggers(EState *estate, ResultRelInfo *relinfo)
{
	TriggerDesc *trigdesc = relinfo->ri_TrigDesc;

	if (trigdesc && trigdesc->n_after_statement[TRIGGER_EVENT_UPDATE] > 0)
		AfterTriggerSaveEvent(relinfo, TRIGGER_EVENT_UPDATE,
							  false, NULL, NULL);
}

HeapTuple
ExecBRUpdateTriggers(EState *estate, ResultRelInfo *relinfo,
					 ItemPointer tupleid, HeapTuple newtuple,
					 CommandId cid)
{
	TriggerDesc *trigdesc = relinfo->ri_TrigDesc;
	int			ntrigs = trigdesc->n_before_row[TRIGGER_EVENT_UPDATE];
	int		   *tgindx = trigdesc->tg_before_row[TRIGGER_EVENT_UPDATE];
	TriggerData LocTriggerData;
	HeapTuple	trigtuple;
	HeapTuple	oldtuple;
	HeapTuple	intuple = newtuple;
	TupleTableSlot *newSlot;
	int			i;

	trigtuple = GetTupleForTrigger(estate, relinfo, tupleid, cid, &newSlot);
	if (trigtuple == NULL)
		return NULL;

	/*
	 * In READ COMMITTED isolation level it's possible that newtuple was
	 * changed due to concurrent update.
	 */
	if (newSlot != NULL)
		intuple = newtuple = ExecRemoveJunk(estate->es_junkFilter, newSlot);

	LocTriggerData.type = T_TriggerData;
	LocTriggerData.tg_event = TRIGGER_EVENT_UPDATE |
		TRIGGER_EVENT_ROW |
		TRIGGER_EVENT_BEFORE;
	LocTriggerData.tg_relation = relinfo->ri_RelationDesc;
	for (i = 0; i < ntrigs; i++)
	{
		Trigger    *trigger = &trigdesc->triggers[tgindx[i]];

		if (!trigger->tgenabled)
			continue;
		LocTriggerData.tg_trigtuple = trigtuple;
		LocTriggerData.tg_newtuple = oldtuple = newtuple;
		LocTriggerData.tg_trigtuplebuf = InvalidBuffer;
		LocTriggerData.tg_newtuplebuf = InvalidBuffer;
		LocTriggerData.tg_trigger = trigger;
		newtuple = ExecCallTriggerFunc(&LocTriggerData,
									   tgindx[i],
									   relinfo->ri_TrigFunctions,
									   relinfo->ri_TrigInstrument,
									   GetPerTupleMemoryContext(estate));
		if (oldtuple != newtuple && oldtuple != intuple)
			heap_freetuple(oldtuple);
		if (newtuple == NULL)
			break;
	}
	heap_freetuple(trigtuple);
	return newtuple;
}

void
ExecARUpdateTriggers(EState *estate, ResultRelInfo *relinfo,
					 ItemPointer tupleid, HeapTuple newtuple)
{
	TriggerDesc *trigdesc = relinfo->ri_TrigDesc;

	if (trigdesc && trigdesc->n_after_row[TRIGGER_EVENT_UPDATE] > 0)
	{
		HeapTuple	trigtuple = GetTupleForTrigger(estate, relinfo,
												   tupleid,
												   (CommandId) 0,
												   NULL);

		AfterTriggerSaveEvent(relinfo, TRIGGER_EVENT_UPDATE,
							  true, trigtuple, newtuple);
		heap_freetuple(trigtuple);
	}
}


static HeapTuple
GetTupleForTrigger(EState *estate, ResultRelInfo *relinfo,
				   ItemPointer tid, CommandId cid,
				   TupleTableSlot **newSlot)
{
	MIRROREDLOCK_BUFMGR_DECLARE;

	Relation	relation = relinfo->ri_RelationDesc;
	HeapTupleData tuple;
	HeapTuple	result;
	Buffer		buffer;

	if (newSlot != NULL)
	{
		HTSU_Result test;
		ItemPointerData update_ctid;
		TransactionId update_xmax;

		*newSlot = NULL;

		/*
		 * lock tuple for update
		 */
ltrmark:;
		tuple.t_self = *tid;
		test = heap_lock_tuple(relation, &tuple, &buffer,
							   &update_ctid, &update_xmax, cid,
							   LockTupleExclusive, LockTupleWait);
		switch (test)
		{
			case HeapTupleSelfUpdated:
				/* treat it as deleted; do not process */
				ReleaseBuffer(buffer);
				return NULL;

			case HeapTupleMayBeUpdated:
				break;

			case HeapTupleUpdated:
				ReleaseBuffer(buffer);
				if (IsXactIsoLevelSerializable)
					ereport(ERROR,
							(errcode(ERRCODE_T_R_SERIALIZATION_FAILURE),
							 errmsg("could not serialize access due to concurrent update")));
				else if (!ItemPointerEquals(&update_ctid, &tuple.t_self))
				{
					/* it was updated, so look at the updated version */
					TupleTableSlot *epqslot;

					epqslot = EvalPlanQual(estate,
										   relinfo->ri_RangeTableIndex,
										   &update_ctid,
										   update_xmax,
										   cid);
					if (!TupIsNull(epqslot))
					{
						*tid = update_ctid;
						*newSlot = epqslot;
						goto ltrmark;
					}
				}

				/*
				 * if tuple was deleted or PlanQual failed for updated tuple -
				 * we have not process this tuple!
				 */
				return NULL;

			default:
				ReleaseBuffer(buffer);
				elog(ERROR, "unrecognized heap_lock_tuple status: %u", test);
				return NULL;	/* keep compiler quiet */
		}
	}
	else
	{
		PageHeader	dp;
		ItemId		lp;
		
		// -------- MirroredLock ----------
		MIRROREDLOCK_BUFMGR_LOCK;
		
		buffer = ReadBuffer(relation, ItemPointerGetBlockNumber(tid));
		
		MIRROREDLOCK_BUFMGR_UNLOCK;
		// -------- MirroredLock ----------
		
		dp = (PageHeader) BufferGetPage(buffer);
		lp = PageGetItemId(dp, ItemPointerGetOffsetNumber(tid));

		Assert(ItemIdIsUsed(lp));

		tuple.t_data = (HeapTupleHeader) PageGetItem((Page) dp, lp);
		tuple.t_len = ItemIdGetLength(lp);
		tuple.t_self = *tid;
	}

	result = heap_copytuple(&tuple);
	ReleaseBuffer(buffer);

	return result;
}


/* ----------
 * After-trigger stuff
 *
 * The AfterTriggersData struct holds data about pending AFTER trigger events
 * during the current transaction tree.  (BEFORE triggers are fired
 * immediately so we don't need any persistent state about them.)  The struct
 * and most of its subsidiary data are kept in TopTransactionContext; however
 * the individual event records are kept in separate contexts, to make them
 * easy to delete during subtransaction abort.
 *
 * Because the list of pending events can grow large, we go to some effort
 * to minimize memory consumption.	We do not use the generic List mechanism
 * but thread the events manually.
 *
 * XXX We need to be able to save the per-event data in a file if it grows too
 * large.
 * ----------
 */

/* Per-trigger SET CONSTRAINT status */
typedef struct SetConstraintTriggerData
{
	Oid			sct_tgoid;
	bool		sct_tgisdeferred;
} SetConstraintTriggerData;

typedef struct SetConstraintTriggerData *SetConstraintTrigger;

/*
 * SET CONSTRAINT intra-transaction status.
 *
 * We make this a single palloc'd object so it can be copied and freed easily.
 *
 * all_isset and all_isdeferred are used to keep track
 * of SET CONSTRAINTS ALL {DEFERRED, IMMEDIATE}.
 *
 * trigstates[] stores per-trigger tgisdeferred settings.
 */
typedef struct SetConstraintStateData
{
	bool		all_isset;
	bool		all_isdeferred;
	int			numstates;		/* number of trigstates[] entries in use */
	int			numalloc;		/* allocated size of trigstates[] */
	SetConstraintTriggerData trigstates[1];		/* VARIABLE LENGTH ARRAY */
} SetConstraintStateData;

typedef SetConstraintStateData *SetConstraintState;


/*
 * Per-trigger-event data
 *
 * Note: ate_firing_id is meaningful when either AFTER_TRIGGER_DONE
 * or AFTER_TRIGGER_IN_PROGRESS is set.  It indicates which trigger firing
 * cycle the trigger was or will be fired in.
 */
typedef struct AfterTriggerEventData *AfterTriggerEvent;

typedef struct AfterTriggerEventData
{
	AfterTriggerEvent ate_next; /* list link */
	TriggerEvent ate_event;		/* event type and status bits */
	CommandId	ate_firing_id;	/* ID for firing cycle */
	Oid			ate_tgoid;		/* the trigger's ID */
	Oid			ate_relid;		/* the relation it's on */
	ItemPointerData ate_oldctid;	/* specific tuple(s) involved */
	ItemPointerData ate_newctid;
} AfterTriggerEventData;

/* A list of events */
typedef struct AfterTriggerEventList
{
	AfterTriggerEvent head;
	AfterTriggerEvent tail;
} AfterTriggerEventList;


/*
 * All per-transaction data for the AFTER TRIGGERS module.
 *
 * AfterTriggersData has the following fields:
 *
 * firing_counter is incremented for each call of afterTriggerInvokeEvents.
 * We mark firable events with the current firing cycle's ID so that we can
 * tell which ones to work on.	This ensures sane behavior if a trigger
 * function chooses to do SET CONSTRAINTS: the inner SET CONSTRAINTS will
 * only fire those events that weren't already scheduled for firing.
 *
 * state keeps track of the transaction-local effects of SET CONSTRAINTS.
 * This is saved and restored across failed subtransactions.
 *
 * events is the current list of deferred events.  This is global across
 * all subtransactions of the current transaction.	In a subtransaction
 * abort, we know that the events added by the subtransaction are at the
 * end of the list, so it is relatively easy to discard them.  The event
 * structs themselves are stored in event_cxt if generated by the top-level
 * transaction, else in per-subtransaction contexts identified by the
 * entries in cxt_stack.
 *
 * query_depth is the current depth of nested AfterTriggerBeginQuery calls
 * (-1 when the stack is empty).
 *
 * query_stack[query_depth] is a list of AFTER trigger events queued by the
 * current query (and the query_stack entries below it are lists of trigger
 * events queued by calling queries).  None of these are valid until the
 * matching AfterTriggerEndQuery call occurs.  At that point we fire
 * immediate-mode triggers, and append any deferred events to the main events
 * list.
 *
 * maxquerydepth is just the allocated length of query_stack.
 *
 * state_stack is a stack of pointers to saved copies of the SET CONSTRAINTS
 * state data; each subtransaction level that modifies that state first
 * saves a copy, which we use to restore the state if we abort.
 *
 * events_stack is a stack of copies of the events head/tail pointers,
 * which we use to restore those values during subtransaction abort.
 *
 * depth_stack is a stack of copies of subtransaction-start-time query_depth,
 * which we similarly use to clean up at subtransaction abort.
 *
 * firing_stack is a stack of copies of subtransaction-start-time
 * firing_counter.	We use this to recognize which deferred triggers were
 * fired (or marked for firing) within an aborted subtransaction.
 *
 * We use GetCurrentTransactionNestLevel() to determine the correct array
 * index in these stacks.  maxtransdepth is the number of allocated entries in
 * each stack.	(By not keeping our own stack pointer, we can avoid trouble
 * in cases where errors during subxact abort cause multiple invocations
 * of AfterTriggerEndSubXact() at the same nesting depth.)
 */
typedef struct AfterTriggersData
{
	CommandId	firing_counter; /* next firing ID to assign */
	SetConstraintState state;	/* the active S C state */
	AfterTriggerEventList events;		/* deferred-event list */
	int			query_depth;	/* current query list index */
	AfterTriggerEventList *query_stack; /* events pending from each query */
	int			maxquerydepth;	/* allocated len of above array */
	MemoryContext event_cxt;	/* top transaction's event context, if any */
	MemoryContext *cxt_stack;	/* per-subtransaction event contexts */

	/* these fields are just for resetting at subtrans abort: */

	SetConstraintState *state_stack;	/* stacked S C states */
	AfterTriggerEventList *events_stack;		/* stacked list pointers */
	int		   *depth_stack;	/* stacked query_depths */
	CommandId  *firing_stack;	/* stacked firing_counters */
	int			maxtransdepth;	/* allocated len of above arrays */
} AfterTriggersData;

typedef AfterTriggersData *AfterTriggers;

static AfterTriggers afterTriggers;


static void AfterTriggerExecute(AfterTriggerEvent event,
					Relation rel, TriggerDesc *trigdesc,
					FmgrInfo *finfo,
					Instrumentation *instr,
					MemoryContext per_tuple_context);
static SetConstraintState SetConstraintStateCreate(int numalloc);
static SetConstraintState SetConstraintStateCopy(SetConstraintState state);
static SetConstraintState SetConstraintStateAddItem(SetConstraintState state,
						  Oid tgoid, bool tgisdeferred);


/* ----------
 * afterTriggerCheckState()
 *
 *	Returns true if the trigger identified by tgoid is actually
 *	in state DEFERRED.
 * ----------
 */
static bool
afterTriggerCheckState(Oid tgoid, TriggerEvent eventstate)
{
	SetConstraintState state = afterTriggers->state;
	int			i;

	/*
	 * For not-deferrable triggers (i.e. normal AFTER ROW triggers and
	 * constraints declared NOT DEFERRABLE), the state is always false.
	 */
	if ((eventstate & AFTER_TRIGGER_DEFERRABLE) == 0)
		return false;

	/*
	 * Check if SET CONSTRAINTS has been executed for this specific trigger.
	 */
	for (i = 0; i < state->numstates; i++)
	{
		if (state->trigstates[i].sct_tgoid == tgoid)
			return state->trigstates[i].sct_tgisdeferred;
	}

	/*
	 * Check if SET CONSTRAINTS ALL has been executed; if so use that.
	 */
	if (state->all_isset)
		return state->all_isdeferred;

	/*
	 * Otherwise return the default state for the trigger.
	 */
	return ((eventstate & AFTER_TRIGGER_INITDEFERRED) != 0);
}


/* ----------
 * afterTriggerAddEvent()
 *
 *	Add a new trigger event to the current query's queue.
 * ----------
 */
static void
afterTriggerAddEvent(AfterTriggerEvent event)
{
	AfterTriggerEventList *events;

	Assert(event->ate_next == NULL);

	/* Must be inside a query */
	Assert(afterTriggers->query_depth >= 0);

	events = &afterTriggers->query_stack[afterTriggers->query_depth];
	if (events->tail == NULL)
	{
		/* first list entry */
		events->head = event;
		events->tail = event;
	}
	else
	{
		events->tail->ate_next = event;
		events->tail = event;
	}
}


/* ----------
 * AfterTriggerExecute()
 *
 *	Fetch the required tuples back from the heap and fire one
 *	single trigger function.
 *
 *	Frequently, this will be fired many times in a row for triggers of
 *	a single relation.	Therefore, we cache the open relation and provide
 *	fmgr lookup cache space at the caller level.  (For triggers fired at
 *	the end of a query, we can even piggyback on the executor's state.)
 *
 *	event: event currently being fired.
 *	rel: open relation for event.
 *	trigdesc: working copy of rel's trigger info.
 *	finfo: array of fmgr lookup cache entries (one per trigger in trigdesc).
 *	instr: array of EXPLAIN ANALYZE instrumentation nodes (one per trigger),
 *		or NULL if no instrumentation is wanted.
 *	per_tuple_context: memory context to call trigger function in.
 * ----------
 */
static void
AfterTriggerExecute(AfterTriggerEvent event,
					Relation rel, TriggerDesc *trigdesc,
					FmgrInfo *finfo, Instrumentation *instr,
					MemoryContext per_tuple_context)
{
	Oid			tgoid = event->ate_tgoid;
	TriggerData LocTriggerData;
	HeapTupleData oldtuple;
	HeapTupleData newtuple;
	HeapTuple	rettuple;
	Buffer		oldbuffer = InvalidBuffer;
	Buffer		newbuffer = InvalidBuffer;
	int			tgindx;

	/*
	 * Locate trigger in trigdesc.
	 */
	LocTriggerData.tg_trigger = NULL;
	for (tgindx = 0; tgindx < trigdesc->numtriggers; tgindx++)
	{
		if (trigdesc->triggers[tgindx].tgoid == tgoid)
		{
			LocTriggerData.tg_trigger = &(trigdesc->triggers[tgindx]);
			break;
		}
	}
	if (LocTriggerData.tg_trigger == NULL)
		elog(ERROR, "could not find trigger %u", tgoid);

	/*
	 * If doing EXPLAIN ANALYZE, start charging time to this trigger. We want
	 * to include time spent re-fetching tuples in the trigger cost.
	 */
	if (instr)
		InstrStartNode(instr + tgindx);

	/*
	 * Fetch the required OLD and NEW tuples.
	 */
	LocTriggerData.tg_trigtuple = NULL;
	LocTriggerData.tg_newtuple = NULL;
	LocTriggerData.tg_trigtuplebuf = InvalidBuffer;
	LocTriggerData.tg_newtuplebuf = InvalidBuffer;

	if (ItemPointerIsValid(&(event->ate_oldctid)))
	{
		ItemPointerCopy(&(event->ate_oldctid), &(oldtuple.t_self));
		if (!heap_fetch(rel, SnapshotAny, &oldtuple, &oldbuffer, false, NULL))
			elog(ERROR, "failed to fetch old tuple for AFTER trigger");
		LocTriggerData.tg_trigtuple = &oldtuple;
		LocTriggerData.tg_trigtuplebuf = oldbuffer;
	}

	if (ItemPointerIsValid(&(event->ate_newctid)))
	{
		ItemPointerCopy(&(event->ate_newctid), &(newtuple.t_self));
		if (!heap_fetch(rel, SnapshotAny, &newtuple, &newbuffer, false, NULL))
			elog(ERROR, "failed to fetch new tuple for AFTER trigger");
		if (LocTriggerData.tg_trigtuple != NULL)
		{
			LocTriggerData.tg_newtuple = &newtuple;
			LocTriggerData.tg_newtuplebuf = newbuffer;
		}
		else
		{
			LocTriggerData.tg_trigtuple = &newtuple;
			LocTriggerData.tg_trigtuplebuf = newbuffer;
		}
	}

	/*
	 * Setup the remaining trigger information
	 */
	LocTriggerData.type = T_TriggerData;
	LocTriggerData.tg_event =
		event->ate_event & (TRIGGER_EVENT_OPMASK | TRIGGER_EVENT_ROW);
	LocTriggerData.tg_relation = rel;

	MemoryContextReset(per_tuple_context);

	/*
	 * Call the trigger and throw away any possibly returned updated tuple.
	 * (Don't let ExecCallTriggerFunc measure EXPLAIN time.)
	 */
	rettuple = ExecCallTriggerFunc(&LocTriggerData,
								   tgindx,
								   finfo,
								   NULL,
								   per_tuple_context);
	if (rettuple != NULL && rettuple != &oldtuple && rettuple != &newtuple)
		heap_freetuple(rettuple);

	/*
	 * Release buffers
	 */
	if (oldbuffer != InvalidBuffer)
		ReleaseBuffer(oldbuffer);
	if (newbuffer != InvalidBuffer)
		ReleaseBuffer(newbuffer);

	/*
	 * If doing EXPLAIN ANALYZE, stop charging time to this trigger, and count
	 * one "tuple returned" (really the number of firings).
	 */
	if (instr)
		InstrStopNode(instr + tgindx, 1);
}


/*
 * afterTriggerMarkEvents()
 *
 *	Scan the given event list for not yet invoked events.  Mark the ones
 *	that can be invoked now with the current firing ID.
 *
 *	If move_list isn't NULL, events that are not to be invoked now are
 *	removed from the given list and appended to move_list.
 *
 *	When immediate_only is TRUE, do not invoke currently-deferred triggers.
 *	(This will be FALSE only at main transaction exit.)
 *
 *	Returns TRUE if any invokable events were found.
 */
static bool
afterTriggerMarkEvents(AfterTriggerEventList *events,
					   AfterTriggerEventList *move_list,
					   bool immediate_only)
{
	bool		found = false;
	AfterTriggerEvent event,
				prev_event;

	prev_event = NULL;
	event = events->head;

	while (event != NULL)
	{
		bool		defer_it = false;
		AfterTriggerEvent next_event;

		if (!(event->ate_event &
			  (AFTER_TRIGGER_DONE | AFTER_TRIGGER_IN_PROGRESS)))
		{
			/*
			 * This trigger hasn't been called or scheduled yet. Check if we
			 * should call it now.
			 */
			if (immediate_only &&
				afterTriggerCheckState(event->ate_tgoid, event->ate_event))
			{
				defer_it = true;
			}
			else
			{
				/*
				 * Mark it as to be fired in this firing cycle.
				 */
				event->ate_firing_id = afterTriggers->firing_counter;
				event->ate_event |= AFTER_TRIGGER_IN_PROGRESS;
				found = true;
			}
		}

		/*
		 * If it's deferred, move it to move_list, if requested.
		 */
		next_event = event->ate_next;

		if (defer_it && move_list != NULL)
		{
			/* Delink it from input list */
			if (prev_event)
				prev_event->ate_next = next_event;
			else
				events->head = next_event;
			/* and add it to move_list */
			event->ate_next = NULL;
			if (move_list->tail == NULL)
			{
				/* first list entry */
				move_list->head = event;
				move_list->tail = event;
			}
			else
			{
				move_list->tail->ate_next = event;
				move_list->tail = event;
			}
		}
		else
		{
			/* Keep it in input list */
			prev_event = event;
		}

		event = next_event;
	}

	/* Update list tail pointer in case we moved tail event */
	events->tail = prev_event;

	return found;
}

/* ----------
 * afterTriggerInvokeEvents()
 *
 *	Scan the given event list for events that are marked as to be fired
 *	in the current firing cycle, and fire them.
 *
 *	If estate isn't NULL, then we expect that all the firable events are
 *	for triggers of the relations included in the estate's result relation
 *	array.	This allows us to re-use the estate's open relations and
 *	trigger cache info.  When estate is NULL, we have to find the relations
 *	the hard way.
 *
 *	When delete_ok is TRUE, it's okay to delete fully-processed events.
 *	The events list pointers are updated.
 * ----------
 */
static void
afterTriggerInvokeEvents(AfterTriggerEventList *events,
						 CommandId firing_id,
						 EState *estate,
						 bool delete_ok)
{
	AfterTriggerEvent event,
				prev_event;
	MemoryContext per_tuple_context;
	bool		locally_opened = false;
	Relation	rel = NULL;
	TriggerDesc *trigdesc = NULL;
	FmgrInfo   *finfo = NULL;
	Instrumentation *instr = NULL;

	/* Make a per-tuple memory context for trigger function calls */
	per_tuple_context =
		AllocSetContextCreate(CurrentMemoryContext,
							  "AfterTriggerTupleContext",
							  ALLOCSET_DEFAULT_MINSIZE,
							  ALLOCSET_DEFAULT_INITSIZE,
							  ALLOCSET_DEFAULT_MAXSIZE);

	prev_event = NULL;
	event = events->head;

	while (event != NULL)
	{
		AfterTriggerEvent next_event;

		/*
		 * Is it one for me to fire?
		 */
		if ((event->ate_event & AFTER_TRIGGER_IN_PROGRESS) &&
			event->ate_firing_id == firing_id)
		{
			/*
			 * So let's fire it... but first, open the correct relation if
			 * this is not the same relation as before.
			 */
			if (rel == NULL || rel->rd_id != event->ate_relid)
			{
				if (locally_opened)
				{
					/* close prior rel if any */
					if (rel)
						heap_close(rel, NoLock);
					if (trigdesc)
						FreeTriggerDesc(trigdesc);
					if (finfo)
						pfree(finfo);
					Assert(instr == NULL);		/* never used in this case */
				}
				locally_opened = true;

				if (estate)
				{
					/* Find target relation among estate's result rels */
					ResultRelInfo *rInfo;
					int			nr;

					rInfo = estate->es_result_relations;
					nr = estate->es_num_result_relations;
					while (nr > 0)
					{
						if (rInfo->ri_RelationDesc->rd_id == event->ate_relid)
						{
							rel = rInfo->ri_RelationDesc;
							trigdesc = rInfo->ri_TrigDesc;
							finfo = rInfo->ri_TrigFunctions;
							instr = rInfo->ri_TrigInstrument;
							locally_opened = false;
							break;
						}
						rInfo++;
						nr--;
					}
				}

				if (locally_opened)
				{
					/* Hard way: open target relation for ourselves */

					/*
					 * We assume that an appropriate lock is still held by the
					 * executor, so grab no new lock here.
					 */
					rel = heap_open(event->ate_relid, NoLock);

					/*
					 * Copy relation's trigger info so that we have a stable
					 * copy no matter what the called triggers do.
					 */
					trigdesc = CopyTriggerDesc(rel->trigdesc);

					if (trigdesc == NULL)		/* should not happen */
						elog(ERROR, "relation %u has no triggers",
							 event->ate_relid);

					/*
					 * Allocate space to cache fmgr lookup info for triggers.
					 */
					finfo = (FmgrInfo *)
						palloc0(trigdesc->numtriggers * sizeof(FmgrInfo));

					/* Never any EXPLAIN info in this case */
					instr = NULL;
				}
			}

			/*
			 * Fire it.  Note that the AFTER_TRIGGER_IN_PROGRESS flag is still
			 * set, so recursive examinations of the event list won't try to
			 * re-fire it.
			 */
			AfterTriggerExecute(event, rel, trigdesc, finfo, instr,
								per_tuple_context);

			/*
			 * Mark the event as done.
			 */
			event->ate_event &= ~AFTER_TRIGGER_IN_PROGRESS;
			event->ate_event |= AFTER_TRIGGER_DONE;
		}

		/*
		 * If it's now done, throw it away, if allowed.
		 *
		 * NB: it's possible the trigger call above added more events to the
		 * queue, or that calls we will do later will want to add more, so we
		 * have to be careful about maintaining list validity at all points
		 * here.
		 */
		next_event = event->ate_next;

		if ((event->ate_event & AFTER_TRIGGER_DONE) && delete_ok)
		{
			/* Delink it from list and free it */
			if (prev_event)
				prev_event->ate_next = next_event;
			else
				events->head = next_event;
			pfree(event);
		}
		else
		{
			/* Keep it in list */
			prev_event = event;
		}

		event = next_event;
	}

	/* Update list tail pointer in case we just deleted tail event */
	events->tail = prev_event;

	/* Release working resources */
	if (locally_opened)
	{
		if (rel)
			heap_close(rel, NoLock);
		if (trigdesc)
			FreeTriggerDesc(trigdesc);
		if (finfo)
			pfree(finfo);
		Assert(instr == NULL);	/* never used in this case */
	}
	MemoryContextDelete(per_tuple_context);
}


/* ----------
 * AfterTriggerBeginXact()
 *
 *	Called at transaction start (either BEGIN or implicit for single
 *	statement outside of transaction block).
 * ----------
 */
void
AfterTriggerBeginXact(void)
{
	Assert(afterTriggers == NULL);

	/*
	 * Build empty after-trigger state structure
	 */
	afterTriggers = (AfterTriggers)
		MemoryContextAlloc(TopTransactionContext,
						   sizeof(AfterTriggersData));

	afterTriggers->firing_counter = FirstCommandId;
	afterTriggers->state = SetConstraintStateCreate(8);
	afterTriggers->events.head = NULL;
	afterTriggers->events.tail = NULL;
	afterTriggers->query_depth = -1;

	/* We initialize the query stack to a reasonable size */
	afterTriggers->query_stack = (AfterTriggerEventList *)
		MemoryContextAlloc(TopTransactionContext,
						   8 * sizeof(AfterTriggerEventList));
	afterTriggers->maxquerydepth = 8;

	/* Context for events is created only when needed */
	afterTriggers->event_cxt = NULL;

	/* Subtransaction stack is empty until/unless needed */
	afterTriggers->cxt_stack = NULL;
	afterTriggers->state_stack = NULL;
	afterTriggers->events_stack = NULL;
	afterTriggers->depth_stack = NULL;
	afterTriggers->firing_stack = NULL;
	afterTriggers->maxtransdepth = 0;
}


/* ----------
 * AfterTriggerBeginQuery()
 *
 *	Called just before we start processing a single query within a
 *	transaction (or subtransaction).  Set up to record AFTER trigger
 *	events queued by the query.  Note that it is allowed to have
 *	nested queries within a (sub)transaction.
 * ----------
 */
void
AfterTriggerBeginQuery(void)
{
	/* Must be inside a transaction */
	Assert(afterTriggers != NULL);

	/* Increase the query stack depth */
	afterTriggers->query_depth++;

	/*
	 * Allocate more space in the query stack if needed.
	 */
	if (afterTriggers->query_depth >= afterTriggers->maxquerydepth)
	{
		/* repalloc will keep the stack in the same context */
		int			new_alloc = afterTriggers->maxquerydepth * 2;

		afterTriggers->query_stack = (AfterTriggerEventList *)
			repalloc(afterTriggers->query_stack,
					 new_alloc * sizeof(AfterTriggerEventList));
		afterTriggers->maxquerydepth = new_alloc;
	}

	/* Initialize this query's list to empty */
	afterTriggers->query_stack[afterTriggers->query_depth].head = NULL;
	afterTriggers->query_stack[afterTriggers->query_depth].tail = NULL;
}


/* ----------
 * AfterTriggerEndQuery()
 *
 *	Called after one query has been completely processed. At this time
 *	we invoke all AFTER IMMEDIATE trigger events queued by the query, and
 *	transfer deferred trigger events to the global deferred-trigger list.
 *
 *	Note that this should be called just BEFORE closing down the executor
 *	with ExecutorEnd, because we make use of the EState's info about
 *	target relations.
 * ----------
 */
void
AfterTriggerEndQuery(EState *estate)
{
	AfterTriggerEventList *events;

	/* Must be inside a transaction */
	Assert(afterTriggers != NULL);

	/* Must be inside a query, too */
	Assert(afterTriggers->query_depth >= 0);

	/*
	 * Process all immediate-mode triggers queued by the query, and move the
	 * deferred ones to the main list of deferred events.
	 *
	 * Notice that we decide which ones will be fired, and put the deferred
	 * ones on the main list, before anything is actually fired.  This ensures
	 * reasonably sane behavior if a trigger function does SET CONSTRAINTS ...
	 * IMMEDIATE: all events we have decided to defer will be available for it
	 * to fire.
	 *
	 * We loop in case a trigger queues more events.
	 *
	 * If we find no firable events, we don't have to increment
	 * firing_counter.
	 */
	events = &afterTriggers->query_stack[afterTriggers->query_depth];
	while (afterTriggerMarkEvents(events, &afterTriggers->events, true))
	{
		CommandId	firing_id = afterTriggers->firing_counter++;

		/* OK to delete the immediate events after processing them */
		afterTriggerInvokeEvents(events, firing_id, estate, true);
	}

	afterTriggers->query_depth--;
}


/* ----------
 * AfterTriggerFireDeferred()
 *
 *	Called just before the current transaction is committed. At this
 *	time we invoke all pending DEFERRED triggers.
 *
 *	It is possible for other modules to queue additional deferred triggers
 *	during pre-commit processing; therefore xact.c may have to call this
 *	multiple times.
 * ----------
 */
void
AfterTriggerFireDeferred(void)
{
	AfterTriggerEventList *events;

	/* Must be inside a transaction */
	Assert(afterTriggers != NULL);

	/* ... but not inside a query */
	Assert(afterTriggers->query_depth == -1);

	/*
	 * If there are any triggers to fire, make sure we have set a snapshot for
	 * them to use.  (Since PortalRunUtility doesn't set a snap for COMMIT, we
	 * can't assume ActiveSnapshot is valid on entry.)
	 */
	events = &afterTriggers->events;
	if (events->head != NULL)
		ActiveSnapshot = CopySnapshot(GetTransactionSnapshot());

	/*
	 * Run all the remaining triggers.	Loop until they are all gone, in
	 * case some trigger queues more for us to do.
	 */
	while (afterTriggerMarkEvents(events, NULL, false))
	{
		CommandId	firing_id = afterTriggers->firing_counter++;

		afterTriggerInvokeEvents(events, firing_id, NULL, true);
	}

	Assert(events->head == NULL);
}


/* ----------
 * AfterTriggerEndXact()
 *
 *	The current transaction is finishing.
 *
 *	Any unfired triggers are canceled so we simply throw
 *	away anything we know.
 *
 *	Note: it is possible for this to be called repeatedly in case of
 *	error during transaction abort; therefore, do not complain if
 *	already closed down.
 * ----------
 */
void
AfterTriggerEndXact(bool isCommit)
{
	/*
	 * Forget everything we know about AFTER triggers.
	 *
	 * Since all the info is in TopTransactionContext or children thereof, we
	 * don't really need to do anything to reclaim memory.  However, the
	 * pending-events list could be large, and so it's useful to discard
	 * it as soon as possible --- especially if we are aborting because we
	 * ran out of memory for the list!
	 *
	 * (Note: any event_cxts of child subtransactions could also be
	 * deleted here, but we have no convenient way to find them, so we
	 * leave it to TopTransactionContext reset to clean them up.)
	 */
	if (afterTriggers && afterTriggers->event_cxt)
		MemoryContextDelete(afterTriggers->event_cxt);

	afterTriggers = NULL;
}

/*
 * AfterTriggerBeginSubXact()
 *
 *	Start a subtransaction.
 */
void
AfterTriggerBeginSubXact(void)
{
	int			my_level = GetCurrentTransactionNestLevel();

	/*
	 * Ignore call if the transaction is in aborted state.	(Probably
	 * shouldn't happen?)
	 */
	if (afterTriggers == NULL)
		return;

	/*
	 * Allocate more space in the stacks if needed.  (Note: because the
	 * minimum nest level of a subtransaction is 2, we waste the first
	 * couple entries of each array; not worth the notational effort to
	 * avoid it.)
	 */
	while (my_level >= afterTriggers->maxtransdepth)
	{
		if (afterTriggers->maxtransdepth == 0)
		{
			MemoryContext old_cxt;

			old_cxt = MemoryContextSwitchTo(TopTransactionContext);

#define DEFTRIG_INITALLOC 8
			afterTriggers->cxt_stack = (MemoryContext *)
				palloc(DEFTRIG_INITALLOC * sizeof(MemoryContext));
			afterTriggers->state_stack = (SetConstraintState *)
				palloc(DEFTRIG_INITALLOC * sizeof(SetConstraintState));
			afterTriggers->events_stack = (AfterTriggerEventList *)
				palloc(DEFTRIG_INITALLOC * sizeof(AfterTriggerEventList));
			afterTriggers->depth_stack = (int *)
				palloc(DEFTRIG_INITALLOC * sizeof(int));
			afterTriggers->firing_stack = (CommandId *)
				palloc(DEFTRIG_INITALLOC * sizeof(CommandId));
			afterTriggers->maxtransdepth = DEFTRIG_INITALLOC;

			MemoryContextSwitchTo(old_cxt);
		}
		else
		{
			/* repalloc will keep the stacks in the same context */
			int			new_alloc = afterTriggers->maxtransdepth * 2;

			afterTriggers->cxt_stack = (MemoryContext *)
				repalloc(afterTriggers->cxt_stack,
						 new_alloc * sizeof(MemoryContext));
			afterTriggers->state_stack = (SetConstraintState *)
				repalloc(afterTriggers->state_stack,
						 new_alloc * sizeof(SetConstraintState));
			afterTriggers->events_stack = (AfterTriggerEventList *)
				repalloc(afterTriggers->events_stack,
						 new_alloc * sizeof(AfterTriggerEventList));
			afterTriggers->depth_stack = (int *)
				repalloc(afterTriggers->depth_stack,
						 new_alloc * sizeof(int));
			afterTriggers->firing_stack = (CommandId *)
				repalloc(afterTriggers->firing_stack,
						 new_alloc * sizeof(CommandId));
			afterTriggers->maxtransdepth = new_alloc;
		}
	}

	/*
	 * Push the current information into the stack.  The SET CONSTRAINTS state
	 * is not saved until/unless changed.  Likewise, we don't make a
	 * per-subtransaction event context until needed.
	 */
	afterTriggers->cxt_stack[my_level] = NULL;
	afterTriggers->state_stack[my_level] = NULL;
	afterTriggers->events_stack[my_level] = afterTriggers->events;
	afterTriggers->depth_stack[my_level] = afterTriggers->query_depth;
	afterTriggers->firing_stack[my_level] = afterTriggers->firing_counter;
}

/*
 * AfterTriggerEndSubXact()
 *
 *	The current subtransaction is ending.
 */
void
AfterTriggerEndSubXact(bool isCommit)
{
	int			my_level = GetCurrentTransactionNestLevel();
	SetConstraintState state;
	AfterTriggerEvent event;
	CommandId	subxact_firing_id;

	/*
	 * Ignore call if the transaction is in aborted state.	(Probably
	 * unneeded)
	 */
	if (afterTriggers == NULL)
		return;

	/*
	 * Pop the prior state if needed.
	 */
	Assert(my_level < afterTriggers->maxtransdepth);

	if (isCommit)
	{
		/* If we saved a prior state, we don't need it anymore */
		state = afterTriggers->state_stack[my_level];
		if (state != NULL)
			pfree(state);
		/* this avoids double pfree if error later: */
		afterTriggers->state_stack[my_level] = NULL;
		Assert(afterTriggers->query_depth ==
			   afterTriggers->depth_stack[my_level]);
		/*
		 * It's entirely possible that the subxact created an event_cxt but
		 * there is not anything left in it (because all the triggers were
		 * fired at end-of-statement).  If so, we should release the context
		 * to prevent memory leakage in a long sequence of subtransactions.
		 * We can detect whether there's anything of use in the context by
		 * seeing if anything was added to the global events list since
		 * subxact start.  (This test doesn't catch every case where the
		 * context is deletable; for instance maybe the only additions were
		 * from a sub-sub-xact.  But it handles the common case.)
		 */
		if (afterTriggers->cxt_stack[my_level] &&
			afterTriggers->events.tail == afterTriggers->events_stack[my_level].tail)
		{
			MemoryContextDelete(afterTriggers->cxt_stack[my_level]);
			/* avoid double delete if abort later */
			afterTriggers->cxt_stack[my_level] = NULL;
		}
	}
	else
	{
		/*
		 * Aborting.  We don't really need to release the subxact's event_cxt,
		 * since it will go away anyway when CurTransactionContext gets reset,
		 * but doing so early in subxact abort helps free space we might need.
		 *
		 * (Note: any event_cxts of child subtransactions could also be
		 * deleted here, but we have no convenient way to find them, so we
		 * leave it to CurTransactionContext reset to clean them up.)
		 */
		if (afterTriggers->cxt_stack[my_level])
		{
			MemoryContextDelete(afterTriggers->cxt_stack[my_level]);
			/* avoid double delete if repeated aborts */
			afterTriggers->cxt_stack[my_level] = NULL;
		}

		/*
		 * Restore the pointers from the stacks.
		 */
		afterTriggers->events = afterTriggers->events_stack[my_level];
		afterTriggers->query_depth = afterTriggers->depth_stack[my_level];

		/*
		 * Cleanup the tail of the list.
		 */
		if (afterTriggers->events.tail != NULL)
			afterTriggers->events.tail->ate_next = NULL;

		/*
		 * Restore the trigger state.  If the saved state is NULL, then this
		 * subxact didn't save it, so it doesn't need restoring.
		 */
		state = afterTriggers->state_stack[my_level];
		if (state != NULL)
		{
			pfree(afterTriggers->state);
			afterTriggers->state = state;
		}
		/* this avoids double pfree if error later: */
		afterTriggers->state_stack[my_level] = NULL;

		/*
		 * Scan for any remaining deferred events that were marked DONE or IN
		 * PROGRESS by this subxact or a child, and un-mark them. We can
		 * recognize such events because they have a firing ID greater than or
		 * equal to the firing_counter value we saved at subtransaction start.
		 * (This essentially assumes that the current subxact includes all
		 * subxacts started after it.)
		 */
		subxact_firing_id = afterTriggers->firing_stack[my_level];
		for (event = afterTriggers->events.head;
			 event != NULL;
			 event = event->ate_next)
		{
			if (event->ate_event &
				(AFTER_TRIGGER_DONE | AFTER_TRIGGER_IN_PROGRESS))
			{
				if (event->ate_firing_id >= subxact_firing_id)
					event->ate_event &=
						~(AFTER_TRIGGER_DONE | AFTER_TRIGGER_IN_PROGRESS);
			}
		}
	}
}

/*
 * Create an empty SetConstraintState with room for numalloc trigstates
 */
static SetConstraintState
SetConstraintStateCreate(int numalloc)
{
	SetConstraintState state;

	/* Behave sanely with numalloc == 0 */
	if (numalloc <= 0)
		numalloc = 1;

	/*
	 * We assume that zeroing will correctly initialize the state values.
	 */
	state = (SetConstraintState)
		MemoryContextAllocZero(TopTransactionContext,
							   sizeof(SetConstraintStateData) +
						   (numalloc - 1) *sizeof(SetConstraintTriggerData));

	state->numalloc = numalloc;

	return state;
}

/*
 * Copy a SetConstraintState
 */
static SetConstraintState
SetConstraintStateCopy(SetConstraintState origstate)
{
	SetConstraintState state;

	state = SetConstraintStateCreate(origstate->numstates);

	state->all_isset = origstate->all_isset;
	state->all_isdeferred = origstate->all_isdeferred;
	state->numstates = origstate->numstates;
	memcpy(state->trigstates, origstate->trigstates,
		   origstate->numstates * sizeof(SetConstraintTriggerData));

	return state;
}

/*
 * Add a per-trigger item to a SetConstraintState.	Returns possibly-changed
 * pointer to the state object (it will change if we have to repalloc).
 */
static SetConstraintState
SetConstraintStateAddItem(SetConstraintState state,
						  Oid tgoid, bool tgisdeferred)
{
	if (state->numstates >= state->numalloc)
	{
		int			newalloc = state->numalloc * 2;

		newalloc = Max(newalloc, 8);	/* in case original has size 0 */
		state = (SetConstraintState)
			repalloc(state,
					 sizeof(SetConstraintStateData) +
					 (newalloc - 1) *sizeof(SetConstraintTriggerData));
		state->numalloc = newalloc;
		Assert(state->numstates < state->numalloc);
	}

	state->trigstates[state->numstates].sct_tgoid = tgoid;
	state->trigstates[state->numstates].sct_tgisdeferred = tgisdeferred;
	state->numstates++;

	return state;
}

/* ----------
 * AfterTriggerSetState()
 *
 *	Execute the SET CONSTRAINTS ... utility command.
 * ----------
 */
void
AfterTriggerSetState(ConstraintsSetStmt *stmt)
{
	int			my_level = GetCurrentTransactionNestLevel();

	/*
	 * Ignore call if we aren't in a transaction.  (Shouldn't happen?)
	 */
	if (afterTriggers == NULL)
		return;

	/*
	 * If in a subtransaction, and we didn't save the current state already,
	 * save it so it can be restored if the subtransaction aborts.
	 */
	if (my_level > 1 &&
		afterTriggers->state_stack[my_level] == NULL)
	{
		afterTriggers->state_stack[my_level] =
			SetConstraintStateCopy(afterTriggers->state);
	}

	/*
	 * Handle SET CONSTRAINTS ALL ...
	 */
	if (stmt->constraints == NIL)
	{
		/*
		 * Forget any previous SET CONSTRAINTS commands in this transaction.
		 */
		afterTriggers->state->numstates = 0;

		/*
		 * Set the per-transaction ALL state to known.
		 */
		afterTriggers->state->all_isset = true;
		afterTriggers->state->all_isdeferred = stmt->deferred;
	}
	else
	{
		Relation	tgrel;
		ListCell   *l;
		List	   *oidlist = NIL;

		/* ----------
		 * Handle SET CONSTRAINTS constraint-name [, ...]
		 * First lookup all trigger Oid's for the constraint names.
		 * ----------
		 */
		tgrel = heap_open(TriggerRelationId, AccessShareLock);

		foreach(l, stmt->constraints)
		{
			RangeVar   *constraint = lfirst(l);
			cqContext	cqc;
			cqContext  *pcqCtx;
			HeapTuple	htup;
			bool		found;
			List	   *namespaceSearchList;
			ListCell   *namespaceSearchCell;

			if (constraint->catalogname)
			{
				if (strcmp(constraint->catalogname, get_database_name(MyDatabaseId)) != 0)
					ereport(ERROR,
							(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
							 errmsg("cross-database references are not implemented: \"%s.%s.%s\"",
							 constraint->catalogname, constraint->schemaname,
									constraint->relname)));
			}

			/*
			 * If we're given the schema name with the constraint, look only
			 * in that schema.	If given a bare constraint name, use the
			 * search path to find the first matching constraint.
			 */
			if (constraint->schemaname)
			{
				Oid			namespaceId = LookupExplicitNamespace(constraint->schemaname, NSPDBOID_CURRENT);

				namespaceSearchList = list_make1_oid(namespaceId);
			}
			else
			{
				namespaceSearchList = fetch_search_path(true);
			}

			found = false;
			foreach(namespaceSearchCell, namespaceSearchList)
			{
				Oid			searchNamespaceId = lfirst_oid(namespaceSearchCell);

				/*
				 * Setup to scan pg_trigger by tgconstrname ...
				 */
				pcqCtx = caql_beginscan(
						caql_addrel(cqclr(&cqc), tgrel),
						cql("SELECT * FROM pg_trigger "
							" WHERE tgconstrname = :1 ",
							PointerGetDatum(constraint->relname)));

				/*
				 * ... and search for the constraint trigger row
				 */
				while (HeapTupleIsValid(htup = caql_getnext(pcqCtx)))
				{
					Form_pg_trigger pg_trigger = (Form_pg_trigger) GETSTRUCT(htup);
					Oid			constraintNamespaceId;

					/*
					 * Foreign key constraints have triggers on both the
					 * parent and child tables.  Since these tables may be in
					 * different schemas we must pick the child table because
					 * that table "owns" the constraint.
					 *
					 * Referential triggers on the parent table other than
					 * NOACTION_DEL and NOACTION_UPD are ignored below, so it
					 * is possible to not check them here, but it seems safer
					 * to always check.
					 */
					if (pg_trigger->tgfoid == F_RI_FKEY_NOACTION_DEL ||
						pg_trigger->tgfoid == F_RI_FKEY_NOACTION_UPD ||
						pg_trigger->tgfoid == F_RI_FKEY_RESTRICT_UPD ||
						pg_trigger->tgfoid == F_RI_FKEY_RESTRICT_DEL ||
						pg_trigger->tgfoid == F_RI_FKEY_CASCADE_UPD ||
						pg_trigger->tgfoid == F_RI_FKEY_CASCADE_DEL ||
						pg_trigger->tgfoid == F_RI_FKEY_SETNULL_UPD ||
						pg_trigger->tgfoid == F_RI_FKEY_SETNULL_DEL ||
						pg_trigger->tgfoid == F_RI_FKEY_SETDEFAULT_UPD ||
						pg_trigger->tgfoid == F_RI_FKEY_SETDEFAULT_DEL)
						constraintNamespaceId = get_rel_namespace(pg_trigger->tgconstrrelid);
					else
						constraintNamespaceId = get_rel_namespace(pg_trigger->tgrelid);

					/*
					 * If this constraint is not in the schema we're currently
					 * searching for, keep looking.
					 */
					if (constraintNamespaceId != searchNamespaceId)
						continue;

					/*
					 * If we found some, check that they fit the deferrability
					 * but skip referential action ones, since they are
					 * silently never deferrable.
					 */
					if (pg_trigger->tgfoid != F_RI_FKEY_RESTRICT_UPD &&
						pg_trigger->tgfoid != F_RI_FKEY_RESTRICT_DEL &&
						pg_trigger->tgfoid != F_RI_FKEY_CASCADE_UPD &&
						pg_trigger->tgfoid != F_RI_FKEY_CASCADE_DEL &&
						pg_trigger->tgfoid != F_RI_FKEY_SETNULL_UPD &&
						pg_trigger->tgfoid != F_RI_FKEY_SETNULL_DEL &&
						pg_trigger->tgfoid != F_RI_FKEY_SETDEFAULT_UPD &&
						pg_trigger->tgfoid != F_RI_FKEY_SETDEFAULT_DEL)
					{
						if (stmt->deferred && !pg_trigger->tgdeferrable)
							ereport(ERROR,
									(errcode(ERRCODE_WRONG_OBJECT_TYPE),
								errmsg("constraint \"%s\" is not deferrable",
									   constraint->relname)));
						oidlist = lappend_oid(oidlist, HeapTupleGetOid(htup));
					}
					found = true;
				}

				caql_endscan(pcqCtx);

				/*
				 * Once we've found a matching constraint we do not search
				 * later parts of the search path.
				 */
				if (found)
					break;

			}

			list_free(namespaceSearchList);

			/*
			 * Not found ?
			 */
			if (!found)
				ereport(ERROR,
						(errcode(ERRCODE_UNDEFINED_OBJECT),
						 errmsg("constraint \"%s\" does not exist",
								constraint->relname)));
		}
		heap_close(tgrel, AccessShareLock);

		/*
		 * Set the trigger states of individual triggers for this xact.
		 */
		foreach(l, oidlist)
		{
			Oid			tgoid = lfirst_oid(l);
			SetConstraintState state = afterTriggers->state;
			bool		found = false;
			int			i;

			for (i = 0; i < state->numstates; i++)
			{
				if (state->trigstates[i].sct_tgoid == tgoid)
				{
					state->trigstates[i].sct_tgisdeferred = stmt->deferred;
					found = true;
					break;
				}
			}
			if (!found)
			{
				afterTriggers->state =
					SetConstraintStateAddItem(state, tgoid, stmt->deferred);
			}
		}
	}

	/*
	 * SQL99 requires that when a constraint is set to IMMEDIATE, any deferred
	 * checks against that constraint must be made when the SET CONSTRAINTS
	 * command is executed -- i.e. the effects of the SET CONSTRAINTS command
	 * apply retroactively.  We've updated the constraints state, so scan the
	 * list of previously deferred events to fire any that have now become
	 * immediate.
	 *
	 * Obviously, if this was SET ... DEFERRED then it can't have converted
	 * any unfired events to immediate, so we need do nothing in that case.
	 */
	if (!stmt->deferred)
	{
		AfterTriggerEventList *events = &afterTriggers->events;

		while (afterTriggerMarkEvents(events, NULL, true))
		{
			CommandId	firing_id = afterTriggers->firing_counter++;

			/*
			 * We can delete fired events if we are at top transaction level,
			 * but we'd better not if inside a subtransaction, since the
			 * subtransaction could later get rolled back.
			 */
			afterTriggerInvokeEvents(events, firing_id, NULL,
									 !IsSubTransaction());
		}
	}
	
	if (Gp_role == GP_ROLE_DISPATCH)
	{
		dispatch_statement_node((Node *) stmt, NULL, NULL, NULL);
	}
}

/* ----------
 * AfterTriggerPendingOnRel()
 *		Test to see if there are any pending after-trigger events for rel.
 *
 * This is used by TRUNCATE, CLUSTER, ALTER TABLE, etc to detect whether
 * it is unsafe to perform major surgery on a relation.  Note that only
 * local pending events are examined.  We assume that having exclusive lock
 * on a rel guarantees there are no unserviced events in other backends ---
 * but having a lock does not prevent there being such events in our own.
 *
 * In some scenarios it'd be reasonable to remove pending events (more
 * specifically, mark them DONE by the current subxact) but without a lot
 * of knowledge of the trigger semantics we can't do this in general.
 * ----------
 */
bool
AfterTriggerPendingOnRel(Oid relid)
{
	AfterTriggerEvent event;
	int			depth;

	/* No-op if we aren't in a transaction.  (Shouldn't happen?) */
	if (afterTriggers == NULL)
		return false;

	/* Scan queued events */
	for (event = afterTriggers->events.head;
		 event != NULL;
		 event = event->ate_next)
	{
		/*
		 * We can ignore completed events.	(Even if a DONE flag is rolled
		 * back by subxact abort, it's OK because the effects of the TRUNCATE
		 * or whatever must get rolled back too.)
		 */
		if (event->ate_event & AFTER_TRIGGER_DONE)
			continue;

		if (event->ate_relid == relid)
			return true;
	}

	/*
	 * Also scan events queued by incomplete queries.  This could only matter
	 * if TRUNCATE/etc is executed by a function or trigger within an updating
	 * query on the same relation, which is pretty perverse, but let's check.
	 */
	for (depth = 0; depth <= afterTriggers->query_depth; depth++)
	{
		for (event = afterTriggers->query_stack[depth].head;
			 event != NULL;
			 event = event->ate_next)
		{
			if (event->ate_event & AFTER_TRIGGER_DONE)
				continue;

			if (event->ate_relid == relid)
				return true;
		}
	}

	return false;
}


/* ----------
 * AfterTriggerSaveEvent()
 *
 *	Called by ExecA[RS]...Triggers() to add the event to the queue.
 *
 *	NOTE: should be called only if we've determined that an event must
 *	be added to the queue.
 * ----------
 */
static void
AfterTriggerSaveEvent(ResultRelInfo *relinfo, int event, bool row_trigger,
					  HeapTuple oldtup, HeapTuple newtup)
{
	Relation	rel = relinfo->ri_RelationDesc;
	TriggerDesc *trigdesc = relinfo->ri_TrigDesc;
	int			my_level = GetCurrentTransactionNestLevel();
	MemoryContext *cxtptr;
	AfterTriggerEvent new_event;
	int			i;
	int			ntriggers;
	int		   *tgindx;
	ItemPointerData oldctid;
	ItemPointerData newctid;

	if (afterTriggers == NULL)
		elog(ERROR, "AfterTriggerSaveEvent() called outside of transaction");

	/*
	 * Get the CTID's of OLD and NEW
	 */
	if (oldtup != NULL)
		ItemPointerCopy(&(oldtup->t_self), &(oldctid));
	else
		ItemPointerSetInvalid(&(oldctid));
	if (newtup != NULL)
		ItemPointerCopy(&(newtup->t_self), &(newctid));
	else
		ItemPointerSetInvalid(&(newctid));

	/*
	 * Scan the appropriate set of triggers
	 */
	if (row_trigger)
	{
		ntriggers = trigdesc->n_after_row[event];
		tgindx = trigdesc->tg_after_row[event];
	}
	else
	{
		ntriggers = trigdesc->n_after_statement[event];
		tgindx = trigdesc->tg_after_statement[event];
	}

	for (i = 0; i < ntriggers; i++)
	{
		Trigger    *trigger = &trigdesc->triggers[tgindx[i]];

		/* Ignore disabled triggers */
		if (!trigger->tgenabled)
			continue;

		/*
		 * If this is an UPDATE of a PK table or FK table that does not change
		 * the PK or FK respectively, we can skip queuing the event: there is
		 * no need to fire the trigger.
		 */
		if ((event & TRIGGER_EVENT_OPMASK) == TRIGGER_EVENT_UPDATE)
		{
			switch (RI_FKey_trigger_type(trigger->tgfoid))
			{
				case RI_TRIGGER_PK:
					/* Update on PK table */
					if (RI_FKey_keyequal_upd_pk(trigger, rel, oldtup, newtup))
					{
						/* key unchanged, so skip queuing this event */
						continue;
					}
					break;

				case RI_TRIGGER_FK:

					/*
					 * Update on FK table
					 *
					 * There is one exception when updating FK tables: if the
					 * updated row was inserted by our own transaction and the
					 * FK is deferred, we still need to fire the trigger. This
					 * is because our UPDATE will invalidate the INSERT so the
					 * end-of-transaction INSERT RI trigger will not do
					 * anything, so we have to do the check for the UPDATE
					 * anyway.
					 */
					if (!TransactionIdIsCurrentTransactionId(HeapTupleHeaderGetXmin(oldtup->t_data)) &&
						RI_FKey_keyequal_upd_fk(trigger, rel, oldtup, newtup))
					{
						continue;
					}
					break;

				case RI_TRIGGER_NONE:
					/* Not an FK trigger */
					break;
			}
		}

		/*
		 * If we don't yet have an event context for the current (sub)xact,
		 * create one.  Make it a child of CurTransactionContext to ensure it
		 * will go away if the subtransaction aborts.
		 */
		if (my_level > 1)			/* subtransaction? */
		{
			Assert(my_level < afterTriggers->maxtransdepth);
			cxtptr = &afterTriggers->cxt_stack[my_level];
		}
		else
			cxtptr = &afterTriggers->event_cxt;
		if (*cxtptr == NULL)
			*cxtptr = AllocSetContextCreate(CurTransactionContext,
											"AfterTriggerEvents",
											ALLOCSET_DEFAULT_MINSIZE,
											ALLOCSET_DEFAULT_INITSIZE,
											ALLOCSET_DEFAULT_MAXSIZE);

		/*
		 * Create a new event.
		 */
		new_event = (AfterTriggerEvent)
			MemoryContextAlloc(*cxtptr, sizeof(AfterTriggerEventData));
		new_event->ate_next = NULL;
		new_event->ate_event =
			(event & TRIGGER_EVENT_OPMASK) |
			(row_trigger ? TRIGGER_EVENT_ROW : 0) |
			(trigger->tgdeferrable ? AFTER_TRIGGER_DEFERRABLE : 0) |
			(trigger->tginitdeferred ? AFTER_TRIGGER_INITDEFERRED : 0);
		new_event->ate_firing_id = 0;
		new_event->ate_tgoid = trigger->tgoid;
		new_event->ate_relid = rel->rd_id;
		ItemPointerCopy(&oldctid, &(new_event->ate_oldctid));
		ItemPointerCopy(&newctid, &(new_event->ate_newctid));

		/*
		 * Add the new event to the queue.
		 */
		afterTriggerAddEvent(new_event);
	}
}
