/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/*-------------------------------------------------------------------------
 *
 * tablecmds.c
 *	  Commands for creating and altering table structures and settings
 *
 * Portions Copyright (c) 2005-2010, Greenplum inc
 * 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/tablecmds.c,v 1.206.2.5 2008/05/09 22:37:41 tgl Exp $
 *
 *-------------------------------------------------------------------------
 */
#include "postgres.h"

#include <math.h>
#include <fcntl.h>
#include <locale.h>
#include <unistd.h>

#include "access/appendonlywriter.h"
#include "access/bitmap.h"
#include "access/genam.h"
#include "access/hash.h"
#include "access/heapam.h"
#include "access/extprotocol.h"
#include "access/filesplit.h"
#include "access/nbtree.h"
#include "access/reloptions.h"
#include "access/xact.h"
#include "access/transam.h"
#include "catalog/catalog.h"
#include "catalog/catquery.h"
#include "catalog/dependency.h"
#include "catalog/heap.h"
#include "catalog/index.h"
#include "catalog/indexing.h"
#include "catalog/namespace.h"
#include "catalog/pg_appendonly.h"
#include "catalog/pg_attribute_encoding.h"
#include "catalog/pg_compression.h"
#include "catalog/pg_constraint.h"
#include "catalog/pg_depend.h"
#include "catalog/pg_exttable.h"
#include "catalog/pg_extprotocol.h"
#include "catalog/pg_foreign_table.h"
#include "catalog/pg_foreign_server.h"
#include "catalog/pg_inherits.h"
#include "catalog/pg_namespace.h"
#include "catalog/pg_operator.h"
#include "catalog/pg_trigger.h"
#include "catalog/pg_type.h"
#include "catalog/pg_tablespace.h"
#include "catalog/pg_resqueue.h"
#include "catalog/pg_authid.h"
#include "catalog/pg_partition.h"
#include "catalog/pg_partition_rule.h"
#include "catalog/toasting.h"
#include "cdb/cdbappendonlyam.h"
#include "cdb/cdbparquetam.h"
#include "cdb/cdbpartition.h"
#include "cdb/cdbsharedstorageop.h"
#include "commands/cluster.h"
#include "commands/copy.h"
#include "commands/dbcommands.h"
#include "commands/defrem.h"
#include "commands/tablecmds.h"
#include "commands/tablespace.h"
#include "commands/trigger.h"
#include "commands/typecmds.h"
#include "executor/executor.h"
#include "foreign/foreign.h"
#include "miscadmin.h"
#include "nodes/makefuncs.h"
#include "nodes/print.h"
#include "nodes/relation.h"
#include "optimizer/clauses.h"
#include "optimizer/plancat.h"
#include "optimizer/planner.h"
#include "optimizer/prep.h"
#include "parser/analyze.h"
#include "parser/gramparse.h"
#include "parser/parse_agg.h"
#include "parser/parse_clause.h"
#include "parser/parse_coerce.h"
#include "parser/parse_expr.h"
#include "parser/parse_oper.h"
#include "parser/parse_relation.h"
#include "parser/parse_target.h"
#include "parser/parse_type.h"
#include "parser/parser.h"
#include "postmaster/identity.h"
#include "rewrite/rewriteHandler.h"
#include "storage/backendid.h"
#include "storage/smgr.h"
#include "tcop/utility.h"
#include "utils/acl.h"
#include "utils/builtins.h"
#include "utils/datum.h"
#include "utils/fmgroids.h"
#include "utils/inval.h"
#include "utils/lsyscache.h"
#include "utils/memutils.h"
#include "utils/numeric.h"
#include "utils/relcache.h"
#include "utils/syscache.h"
#include "utils/tqual.h"
#include "utils/uri.h"
#include "mb/pg_wchar.h"

#include "cdb/cdbdisp.h"
#include "cdb/cdbsrlz.h"
#include "cdb/cdbvars.h"
#include "cdb/cdbcat.h"
#include "cdb/cdbrelsize.h"
#include "cdb/cdboidsync.h"
#include "cdb/cdbsreh.h"

#include "cdb/cdbmirroredfilesysobj.h"
#include "cdb/cdbmirroredbufferpool.h"
#include "cdb/cdbmirroredappendonly.h"
#include "cdb/cdbpersistentfilesysobj.h"
#include "cdb/cdbquerycontextdispatching.h"
#include "cdb/dispatcher.h"
#include "cdb/cdbdispatchresult.h"

/*
 * ON COMMIT action list
 */
typedef struct OnCommitItem
{
	Oid			relid;			/* relid of relation */
	OnCommitAction oncommit;	/* what to do at end of xact */

	/*
	 * If this entry was created during the current transaction,
	 * creating_subid is the ID of the creating subxact; if created in a prior
	 * transaction, creating_subid is zero.  If deleted during the current
	 * transaction, deleting_subid is the ID of the deleting subxact; if no
	 * deletion request is pending, deleting_subid is zero.
	 */
	SubTransactionId creating_subid;
	SubTransactionId deleting_subid;
} OnCommitItem;

static List *on_commits = NIL;

/*
 * State information for ALTER TABLE
 *
 * The pending-work queue for an ALTER TABLE is a List of AlteredTableInfo
 * structs, one for each table modified by the operation (the named table
 * plus any child tables that are affected).  We save lists of subcommands
 * to apply to this table (possibly modified by parse transformation steps);
 * these lists will be executed in Phase 2.  If a Phase 3 step is needed,
 * necessary information is stored in the constraints and newvals lists.
 *
 * Phase 2 is divided into multiple passes; subcommands are executed in
 * a pass determined by subcommand type.
 */

#define AT_PASS_DROP			0		/* DROP (all flavors) */
#define AT_PASS_ALTER_TYPE		1		/* ALTER COLUMN TYPE */
#define AT_PASS_OLD_INDEX		2		/* re-add existing indexes */
#define AT_PASS_OLD_CONSTR		3		/* re-add existing constraints */
#define AT_PASS_COL_ATTRS		4		/* set other column attributes */
/* We could support a RENAME COLUMN pass here, but not currently used */
#define AT_PASS_ADD_COL			5		/* ADD COLUMN */
#define AT_PASS_ADD_INDEX		6		/* ADD indexes */
#define AT_PASS_ADD_CONSTR		7		/* ADD constraints, defaults */
#define AT_PASS_MISC			8		/* other stuff */
#define AT_NUM_PASSES			9

typedef struct AlteredTableInfo
{
	/* Information saved before any work commences: */
	Oid			relid;			/* Relation to work on */
	char		relkind;		/* Its relkind */
	TupleDesc	oldDesc;		/* Pre-modification tuple descriptor */
	/* Information saved by Phase 1 for Phase 2: */
	List	   *subcmds[AT_NUM_PASSES]; /* Lists of AlterTableCmd */
	/* Information saved by Phases 1/2 for Phase 3: */
	List	   *constraints;	/* List of NewConstraint */
	List	   *newvals;		/* List of NewColumnValue */
	bool		new_notnull;	/* T if we added new NOT NULL constraints */
	bool		new_dropoids;	/* T if we dropped the OID column */
	Oid			newTableSpace;	/* new tablespace; 0 means no change */
	Oid			exchange_relid;	/* for EXCHANGE, the exchanged in rel */
	/* Objects to rebuild after completing ALTER TYPE operations */
	List	   *changedConstraintOids;	/* OIDs of constraints to rebuild */
	List	   *changedConstraintDefs;	/* string definitions of same */
	List	   *changedIndexOids;		/* OIDs of indexes to rebuild */
	List	   *changedIndexDefs;		/* string definitions of same */
	List *scantable_splits;     /* split information for scan */
	List *ao_segnos;            /* segment file number for the new relation */
} AlteredTableInfo;

/*
 * Struct describing one new column value that needs to be computed during
 * Phase 3 copy (this could be either a new column with a non-null default, or
 * a column that we're changing the type of).  Columns without such an entry
 * are just copied from the old table during ATRewriteTable.  Note that the
 * expr is an expression over *old* table values.
 */
typedef struct NewColumnValue
{
	AttrNumber	attnum;			/* which column */
	Expr	   *expr;			/* expression to compute */
	ExprState  *exprstate;		/* execution state */
} NewColumnValue;

static void truncate_check_rel(Relation rel);
static void MergeConstraintsIntoExisting(Relation child_rel, Relation parent_rel);
static void MergeAttributesIntoExisting(Relation child_rel, Relation parent_rel, List *inhAttrNameList,
										bool is_partition);

static Datum AddDefaultPageRowGroupSize(Datum relOptions, List *options);
static bool add_nonduplicate_cooked_constraint(Constraint *cdef, List *stmtConstraints);
static bool change_varattnos_varno_walker(Node *node, const AttrMapContext *attrMapCxt);

static void StoreCatalogInheritance(Oid relationId, List *supers);
static void StoreCatalogInheritance1(Oid relationId, Oid parentOid,
						 int16 seqNumber, Relation inhRelation,
						 bool is_partition);
static int	findAttrByName(const char *attributeName, List *schema);
static void setRelhassubclassInRelation(Oid relationId, bool relhassubclass);
static void AlterIndexNamespaces(Relation classRel, Relation rel,
					 Oid oldNspOid, Oid newNspOid);
static void AlterSeqNamespaces(Relation classRel, Relation rel,
				   Oid oldNspOid, Oid newNspOid,
				   const char *newNspName);
static int transformColumnNameList(Oid relId, List *colList,
						int16 *attnums, Oid *atttypids);
static int transformFkeyGetPrimaryKey(Relation pkrel, Oid *indexOid,
						   List **attnamelist,
						   int16 *attnums, Oid *atttypids,
						   Oid *opclasses);
static void validateForeignKeyConstraint(FkConstraint *fkconstraint,
							 Relation rel, Relation pkrel);
static void createForeignKeyTriggers(Relation rel, Oid refRelOid,
                        			 FkConstraint *fkconstraint, Oid constraintOid);
static char *fkMatchTypeToString(char match_type);
static void ATController(Relation rel, List *cmds, bool recurse, 
						 int * oidInfoCount, TableOidInfo ** oidInfo, List **poidmap);
static void ATPrepCmd(List **wqueue, Relation rel, AlterTableCmd *cmd,
		  bool recurse, bool recursing);
static void ATRewriteCatalogs(List **wqueue);
static void ATAddToastIfNeeded(List **wqueue, 
							   int oidInfoCount,TableOidInfo * oidInfo, List **poidmap);
static void ATExecCmd(List **wqueue,
					  AlteredTableInfo *tab, Relation rel, AlterTableCmd *cmd);
static void ATRewriteTables(List **wqueue, 
							int oidInfoCount, TableOidInfo * oidInfo, List **poidmap);
static void ATRewriteTable(AlteredTableInfo *tab, Oid OIDNewHeap);
static AlteredTableInfo *ATGetQueueEntry(List **wqueue, Relation rel);
static void ATSimplePermissions(Relation rel, bool allowView);
static void ATSimplePermissionsRelationOrIndex(Relation rel);
static void ATSimpleRecursion(List **wqueue, Relation rel,
				  AlterTableCmd *cmd, bool recurse);
/* static void ATOneLevelRecursion(List **wqueue, Relation rel,
					AlterTableCmd *cmd); */
static void ATPrepAddColumn(Relation rel, bool recurse, AlterTableCmd *cmd);
static void ATExecAddColumn(AlteredTableInfo *tab, Relation rel,
				ColumnDef *colDef);
static void add_column_datatype_dependency(Oid relid, int32 attnum, Oid typid);
static void ATExecDropNotNull(Relation rel, const char *colName);
static void ATExecSetNotNull(AlteredTableInfo *tab, Relation rel,
				 const char *colName);
static void ATExecColumnDefault(Relation rel, const char *colName,
					Node *newDefault);
static void ATPrepSetStatistics(Relation rel, const char *colName,
					Node *flagValue);
static void ATExecSetStatistics(Relation rel, const char *colName,
					Node *newValue);
static void ATExecSetStorage(Relation rel, const char *colName,
				 Node *newValue);
static void ATExecDropColumn(List **wqueue, Relation rel, const char *colName,
				 DropBehavior behavior,
				 bool recurse, bool recursing);
static void ATExecAddIndex(AlteredTableInfo *tab, Relation rel,
			   IndexStmt *stmt, bool is_rebuild, bool part_expanded);
static void ATExecAddConstraint(AlteredTableInfo *tab, Relation rel, Node *newConstraint, bool recurse);
static void ATAddCheckConstraint(AlteredTableInfo *tab, Relation rel, Constraint *constr, bool recurse);

static void ATAddForeignKeyConstraint(AlteredTableInfo *tab, Relation rel,
						  FkConstraint *fkconstraint);
static void ATPrepDropConstraint(List **wqueue, Relation rel,
					 bool recurse, AlterTableCmd *cmd);
static void ATExecDropConstraint(Relation rel, const char *constrName,
					 DropBehavior behavior, bool quiet);
static void ATPrepAlterColumnType(List **wqueue,
					  AlteredTableInfo *tab, Relation rel,
					  bool recurse, bool recursing,
					  AlterTableCmd *cmd);
static void ATExecAlterColumnType(AlteredTableInfo *tab, Relation rel,
					  const char *colName, TypeName *typname);
static void ATPostAlterTypeCleanup(List **wqueue, AlteredTableInfo *tab);
static void ATPostAlterTypeParse(Oid oldRelId, Oid refRelId, char *cmd,
                    			 List **wqueue, Oid constrOid);
static void change_owner_recurse_to_sequences(Oid relationOid,
								  Oid newOwnerId);
static void ATExecClusterOn(Relation rel, const char *indexName);
static void ATExecDropCluster(Relation rel);
static void ATPrepSetTableSpace(AlteredTableInfo *tab, Relation rel,
					char *tablespacename);
static void ATPartsPrepSetTableSpace(List **wqueue, Relation rel, AlterTableCmd *cmd, 
									 List *oids);
static void ATExecSetTableSpace(Oid tableOid, Oid newTableSpace, 
								TableOidInfo *oidInfo);
static void ATExecSetRelOptions(Relation rel, List *defList, bool isReset);
static void ATExecEnableDisableTrigger(Relation rel, char *trigname,
						   bool enable, bool skip_system);
static void ATExecAddInherit(Relation rel, Node *node);
static void ATExecDropInherit(Relation rel, RangeVar *parent, bool is_partition);
static void ATExecSetDistributedBy(Relation rel, Node *node,
								   AlterTableCmd *cmd);
static void ATPrepExchange(Relation rel, AlterPartitionCmd *pc);

const char* synthetic_sql = "(internally generated SQL command)";

/* ALTER TABLE ... PARTITION */


static void ATPExecPartAdd(AlteredTableInfo *tab,
						   Relation rel,
                           AlterPartitionCmd *pc,
						   AlterTableType att);				/* Add */
static void ATPExecPartAlter(List **wqueue, AlteredTableInfo *tab, 
							 Relation rel,
                             AlterPartitionCmd *pc);		/* Alter */
static void ATPExecPartCoalesce(Relation rel,
                                AlterPartitionCmd *pc);		/* Coalesce */
static void ATPExecPartDrop(Relation rel,
                            AlterPartitionCmd *pc);			/* Drop */
static void ATPExecPartExchange(AlteredTableInfo *tab,
								Relation rel,
                                AlterPartitionCmd *pc);		/* Exchange */
static void ATPExecPartMerge(Relation rel,
                             AlterPartitionCmd *pc);		/* Merge */
static void ATPExecPartModify(Relation rel,
                              AlterPartitionCmd *pc);		/* Modify */
static void ATPExecPartRename(Relation rel,
                              AlterPartitionCmd *pc);		/* Rename */

static void ATPExecPartSetTemplate(AlteredTableInfo *tab,   /* Set */
								   Relation rel,            /* Subpartition */
                                   AlterPartitionCmd *pc);	/* Template */
static List *
atpxTruncateList(Relation rel, PartitionNode *pNode);
static void ATPExecPartTruncate(Relation rel,
                                AlterPartitionCmd *pc);		/* Truncate */
static void
copy_buffer_pool_data(
	Relation 	rel,

	SMgrRelation dst,

	ItemPointer persistentTid,

	int64 		persistentSerialNum,

	bool		useWal);

static bool TypeTupleExists(Oid typeId);
static void update_ri_trigger_args(Oid relid,
					   const char *oldname,
					   const char *newname,
					   bool fk_scan,
					   bool update_relname);
static Datum transformLocationUris(List *locs, List* fmtopts, bool isweb, bool iswritable, bool* isCustom);
static Datum transformExecOnClause(List	*on_clause, int *preferred_segment_num, bool iswritable);
static char transformFormatType(char *formatname);
static Datum transformFormatOpts(char formattype, List *formatOpts, int numcols, bool iswritable);

static Oid DefineRelation_int(CreateStmt *stmt, char relkind, char relstorage);

static void ATExecPartAddInternal(Relation rel, Node *def);

static void
AlterRelationNamespaceInternalTwo(Relation rel,
								  Oid relid,
								  Oid oldNspOid, Oid newNspOid,
								  bool hasDependEntry,
								  const char *newschema);

static RangeVar *make_temp_table_name(Relation rel, BackendId id);
static bool prebuild_temp_table(Relation rel, RangeVar *tmpname, List *distro,
								List *opts, List **hidden_types, bool isTmpTableAo);
static void ATPartitionCheck(AlterTableType subtype, Relation rel, bool rejectroot, bool recursing);
static void InvokeProtocolValidation(Oid procOid, char *procName, bool iswritable, List *locs, List* fmtopts);

static char *alterTableCmdString(AlterTableType subtype);

static bool isPgDefaultTablespace(const char *tablespacename);

bool
isPgDefaultTablespace(const char *tablespacename){
	if(tablespacename == NULL)
		return false;
	else if(strcmp(tablespacename, "pg_default") == 0)
		return true;
	else
		return false;
}


/* ----------------------------------------------------------------
 *		DefineRelation
 *				Creates a new relation.
 *
 * If successful, returns the OID of the new relation.
 * ----------------------------------------------------------------
 */
Oid
DefineRelation(CreateStmt *stmt, char relkind, char relstorage)
{
    Oid reloid = 0;
    Assert(stmt->relation->schemaname == NULL || strlen(stmt->relation->schemaname)>0);

    /* forbid create non-system table on tablespace pg_default */
    if((!IsBootstrapProcessingMode()) && (isPgDefaultTablespace(stmt->tablespacename)))
    {
    	ereport(ERROR,
    					(errcode(ERRCODE_CDB_FEATURE_NOT_YET),
    					errmsg("Creating table on tablespace 'pg_default' is not allowed")));
    }

    reloid = DefineRelation_int(stmt, relkind, relstorage);

    return reloid;
}


Oid
DefineRelation_int(CreateStmt *stmt,
                   char relkind,
                   char relstorage)
{
	char		relname[NAMEDATALEN];
	Oid			namespaceId;
	List	   *schema = stmt->tableElts;
	Oid			relationId = InvalidOid;
	Oid			tablespaceId;
	Relation	rel;
	TupleDesc	descriptor;
	List	   *inheritOids;
	List	   *old_constraints;
	bool		localHasOids;
	int			parentOidCount;
	List	   *rawDefaults;
	Datum		reloptions;
	ListCell   *listptr;
	AttrNumber	attnum;
	bool		isPartitioned;

	ItemPointerData	persistentTid;
	int64			persistentSerialNum;

	TidycatOptions *tidycatOptions = NULL;

	/*
	 * Truncate relname to appropriate length (probably a waste of time, as
	 * parser should have done this already).
	 */
	StrNCpy(relname, stmt->relation->relname, NAMEDATALEN);

	/*
	 * Check consistency of arguments
	 */
	if (stmt->oncommit != ONCOMMIT_NOOP && !stmt->relation->istemp)
		ereport(ERROR,
				(errcode(ERRCODE_INVALID_TABLE_DEFINITION),
				 errmsg("ON COMMIT can only be used on temporary tables"),
						   errOmitLocation(true)));

	/*
	 * Look up the namespace in which we are supposed to create the relation.
	 * Check we have permission to create there. Skip check if bootstrapping,
	 * since permissions machinery may not be working yet.
	 */
	namespaceId = RangeVarGetCreationNamespace(stmt->relation);

	if (!IsBootstrapProcessingMode())
	{
		AclResult	aclresult;

		aclresult = pg_namespace_aclcheck(namespaceId, GetUserId(),
										  ACL_CREATE);
		if (aclresult != ACLCHECK_OK)
			aclcheck_error(aclresult, ACL_KIND_NAMESPACE,
						   get_namespace_name(namespaceId));
	}

	/*
	 * Select tablespace to use.  If not specified, use default_tablespace
	 * (which may in turn default to database's default).
	 *
	 * Note: This code duplicates code in indexcmds.c
	 */
	if (relkind == RELKIND_SEQUENCE || 
		relkind == RELKIND_VIEW ||
		relkind == RELKIND_COMPOSITE_TYPE ||
		(relkind == RELKIND_RELATION && (
			relstorage == RELSTORAGE_EXTERNAL ||
			relstorage == RELSTORAGE_FOREIGN  ||
			relstorage == RELSTORAGE_VIRTUAL)))
	{
		/* 
		 * MPP-8262: unable to create sequence with default_tablespace
		 *
		 * These relkinds have no storage, and thus do not support tablespaces.
		 * We shouldn't go through the regular default case for these because we
		 * don't want to pick up the value from the default_tablespace guc.
		 */
		Assert(!stmt->tablespacename);
		tablespaceId = InvalidOid;
	}
	else if (stmt->tablespacename)
	{
		/*
		 * Tablespace specified on the command line, or was passed down by
		 * dispatch.
		 */
		tablespaceId = get_tablespace_oid(stmt->tablespacename);
		if (!OidIsValid(tablespaceId))
			ereport(ERROR,
					(errcode(ERRCODE_UNDEFINED_OBJECT),
					 errmsg("tablespace \"%s\" does not exist",
							stmt->tablespacename),
					 errOmitLocation(true)));
	}
	else
	{
		/*
		 * Get the default tablespace specified via default_tablespace, or fall
		 * back on the database tablespace.
		 */
        
		tablespaceId = (gp_upgrade_mode) ? DEFAULTTABLESPACE_OID : GetDefaultTablespace();

		/* Need the real tablespace id for dispatch */
		if (!OidIsValid(tablespaceId))
			tablespaceId = get_database_dts(MyDatabaseId);
	}

	/* Goh tablespace check. */
	/*
	 * temporaty disable this check for dispatching matedata test.
	 * TODO
	CheckCrossAccessTablespace(tablespaceId);
	*/

	/*
	 * Parse and validate reloptions, if any.
	 */
	reloptions = transformRelOptions((Datum) 0, stmt->options, true, false);

	/*
	 * Accept and only accept tidycat option during upgrade.
	 *
	 * All other storage option will be discarded during upgrade.
	 * During bootstrap, we don't have any storage option. So, during
	 * upgrade, we don't need it as well because we're just creating
	 * catalog objects. Further, we overload the WITH clause to pass-in
	 * the index oid. So, if we don't strip it out, it'll appear in
	 * the pg_class.reloptions, and we don't want that.
	 *
	 */
	if (gp_upgrade_mode)
	{
		tidycatOptions = tidycat_reloptions(reloptions);
		reloptions = 0;
	}

	/* Check permissions except when using database's default */
	if (OidIsValid(tablespaceId) && tablespaceId != MyDatabaseTableSpace &&
			tablespaceId != get_database_dts(MyDatabaseId))
	{
		AclResult	aclresult;

		aclresult = pg_tablespace_aclcheck(tablespaceId, GetUserId(),
										   ACL_CREATE);
		if (aclresult != ACLCHECK_OK)
			aclcheck_error(aclresult, ACL_KIND_TABLESPACE,
						   get_tablespace_name(tablespaceId));
	}

	/*
	 * Look up inheritance ancestors and generate relation schema, including
	 * inherited attributes. Update the offsets of the distribution attributes
	 * in GpPolicy if necessary.
	 */
	isPartitioned = stmt->partitionBy ? true : false;
	schema = MergeAttributes(schema, stmt->inhRelations,
							 stmt->relation->istemp, isPartitioned,
							 &inheritOids, &old_constraints, &parentOidCount, stmt->policy);

	/*
	 * If a partition table, and user not specify pagesize and rowgroupsize, specify the default
	 * pagesize to 1MB, rowgroupsize to 8MB.
	 */
	if((stmt->partitionBy) || (stmt->is_part_child)){
		reloptions = AddDefaultPageRowGroupSize(reloptions, stmt->options);
	}

	/*
	 * Create a relation descriptor from the relation schema and create the
	 * relation.  Note that in this stage only inherited (pre-cooked) defaults
	 * and constraints will be included into the new relation.
	 * (BuildDescForRelation takes care of the inherited defaults, but we have
	 * to copy inherited constraints here.)
	 */
	descriptor = BuildDescForRelation(schema);

	localHasOids = interpretOidsOption(stmt->options);
	descriptor->tdhasoid = (localHasOids || parentOidCount > 0);

	/*
	 * old_constraints: pre-cooked constraints from CREATE TABLE ... INHERIT ...
	 * stmt->constraints: might have some pre-cooked constraints passed by analyze.c,
	 * 		due to LIKE tab INCLUDING CONSTRAINTS
	 *
	 * We no longer add these cooked constraints during heap_create_with_catalog.
	 * Instead, we add them along with raw constraints so that we can specify
	 * pg_constraint oid to use on segments.
	 */
	if (old_constraints)
	{
		/* deal with constraints from MergeAttributes */
		foreach(listptr, old_constraints)
		{
			Constraint *cdef = (Constraint *) lfirst(listptr);
			if (cdef->contype == CONSTR_CHECK &&
					add_nonduplicate_cooked_constraint(cdef, stmt->constraints))
				stmt->constraints = lappend(stmt->constraints, cdef);
		}
	}

     stmt->oidInfo.toastOid = InvalidOid;
     stmt->oidInfo.toastIndexOid = InvalidOid;
     stmt->oidInfo.aosegOid = InvalidOid;
     stmt->oidInfo.aosegIndexOid = InvalidOid;
     stmt->oidInfo.aoblkdirOid = InvalidOid;
     stmt->oidInfo.aoblkdirIndexOid = InvalidOid;
     stmt->ownerid = GetUserId();

    if(gp_upgrade_mode && tidycatOptions && (tidycatOptions->relid != InvalidOid))
    {
        stmt->oidInfo.relOid = tidycatOptions->relid;
        stmt->oidInfo.comptypeOid = tidycatOptions->reltype_oid;
        stmt->oidInfo.toastOid = tidycatOptions->toast_oid;
        stmt->oidInfo.toastIndexOid = tidycatOptions->toast_index;
        stmt->oidInfo.toastComptypeOid = tidycatOptions->toast_reltype;
    }

	/* MPP-8405: disallow OIDS on partitioned tables */
	if ((stmt->partitionBy ||
		 stmt->is_part_child) &&
		descriptor->tdhasoid && 
		IsNormalProcessingMode() &&
        (Gp_role == GP_ROLE_DISPATCH))
			ereport(ERROR,
					(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
					 errmsg(
							 "OIDS=TRUE is not allowed on partitioned tables. "
							 "Use OIDS=FALSE"
							 ),
					 errOmitLocation(true)));

    if (stmt->oidInfo.relOid)
        elog(DEBUG4, "DefineRelation relOid=%d schemaname=%s ",
             stmt->oidInfo.relOid,
             stmt->relation->schemaname ? stmt->relation->schemaname : "");

	relationId = heap_create_with_catalog(relname,
										  namespaceId,
										  tablespaceId,
										  stmt->oidInfo.relOid,
										  stmt->ownerid,
										  descriptor,
										  /* relam */ InvalidOid,
										  relkind,
										  relstorage,
										  tablespaceId==GLOBALTABLESPACE_OID,
										  localHasOids,
										  /* bufferPoolBulkLoad */ false,
										  parentOidCount,
										  stmt->oncommit,
                                          stmt->policy,  /*CDB*/
                                          reloptions,
										  allowSystemTableModsDDL,
										  &stmt->oidInfo.comptypeOid,
										  &persistentTid,
										  &persistentSerialNum);

	StoreCatalogInheritance(relationId, inheritOids);

	/*
	 * We must bump the command counter to make the newly-created relation
	 * tuple visible for opening.
	 */
	CommandCounterIncrement();

	/*
	 * Open the new relation and acquire exclusive lock on it, unless we're
	 * doing partition.
	 *
	 * This isn't even necessary in the case of normal relations since other
	 * backends can't see the new rel anyway until we commit), but it keeps
	 * the lock manager from complaining about deadlock risks.
	 */
	if (stmt->is_part_child)
		rel = relation_open(relationId, NoLock);
	else
		rel = relation_open(relationId, AccessExclusiveLock);

	/*
	 * For some reason, even though we have bumped the command counter above, 
	 * occasionally we are not able to see the persistent info just stored in gp_relation_node
	 * at the XLOG level.  So, we save the values here for debugging purposes.
	 */
	rel->rd_haveCreateDebugInfo = true;
	rel->rd_createDebugIsZeroTid = PersistentStore_IsZeroTid(&persistentTid);
	rel->rd_createDebugPersistentTid = persistentTid;
	rel->rd_createDebugPersistentSerialNum = persistentSerialNum;

	/*
	 * Now add any newly specified column default values and CHECK constraints
	 * to the new relation.  These are passed to us in the form of raw
	 * parsetrees; we need to transform them to executable expression trees
	 * before they can be added. The most convenient way to do that is to
	 * apply the parser's transformExpr routine, but transformExpr doesn't
	 * work unless we have a pre-existing relation. So, the transformation has
	 * to be postponed to this final step of CREATE TABLE.
	 *
	 * First, scan schema to find new column defaults.
	 */
	rawDefaults = NIL;
	attnum = 0;

	foreach(listptr, schema)
	{
		ColumnDef  *colDef = lfirst(listptr);

		attnum++;

		if (colDef->raw_default != NULL)
		{
			RawColumnDefault *rawEnt;

			Assert(colDef->cooked_default == NULL);

			rawEnt = (RawColumnDefault *) palloc(sizeof(RawColumnDefault));
			rawEnt->attnum = attnum;
			rawEnt->raw_default = colDef->raw_default;
			rawDefaults = lappend(rawDefaults, rawEnt);
		}
	}

	/*
	 * Parse and add the defaults/constraints, if any.
	 */
	if (rawDefaults || stmt->constraints)
		AddRelationConstraints(rel, rawDefaults, stmt->constraints);

	if (stmt->attr_encodings)
		AddRelationAttributeEncodings(rel, stmt->attr_encodings);

	/*
	 * Clean up.  We keep lock on new relation (although it shouldn't be
	 * visible to anyone else anyway, until commit).
	 */
	relation_close(rel, NoLock);

	return relationId;
}


/*
 * Add Default page size and rowgroup size to relation options
 */
static Datum AddDefaultPageRowGroupSize(Datum relOptions, List *defList){
	Datum result = 0;
	ListCell   *cell = NULL;
	bool pageSizeSet = false;
	bool rowgroupSizeSet = false;
	bool parquetTable = false;
	bool need_free_arg = false;
	if(defList == NIL)
		return relOptions;

	foreach(cell, defList)
	{
		DefElem    *def = lfirst(cell);

		if(pg_strcasecmp("pagesize", def->defname) == 0)
		{
			pageSizeSet = true;
		}
		if(pg_strcasecmp("rowgroupsize", def->defname) == 0)
		{
			rowgroupSizeSet = true;
		}
		if(pg_strcasecmp("orientation", def->defname) == 0)
		{
			if(def->arg == NULL)
			{
				insist_log(false, "syntax not correct, orientation should has corresponding value");
			}

			if(pg_strcasecmp("parquet", defGetString(def, &need_free_arg)) == 0)
			{
				parquetTable = true;
			}
		}
	}

	if (!parquetTable)
		return relOptions;

	if ((pageSizeSet == true) && (rowgroupSizeSet == true)){
		return relOptions;
	}
	else
	{
		/*set default page size*/
		ArrayBuildState *astate = NULL;
		if(DatumGetPointer(relOptions) != 0){
			ArrayType  *array = DatumGetArrayTypeP(relOptions);
			Datum	   *options;
			int			noptions;
			int			i;

			Assert(ARR_ELEMTYPE(array) == TEXTOID);
			deconstruct_array(array, TEXTOID, -1, false, 'i',
							   &options, NULL, &noptions);

			/* copy the existing rel options*/
			for (i = 0; i < noptions; i++)
			{
				astate = accumArrayResult(astate, options[i],
										  false, TEXTOID,
										  CurrentMemoryContext);
			}
		}

		/* append page size*/
		if (pageSizeSet == false){
			text *t;
			const char *name = "pagesize";
			Size len;
			char value[INT32_CHAR_SIZE];
			pg_ltoa(DEFAULT_PARQUET_PAGE_SIZE_PARTITION, value);

			len = VARHDRSZ + strlen(name) + 1 + strlen(value);
			t = (text *) palloc(len + 1);
			SET_VARSIZE(t, len);
			sprintf(VARDATA(t), "%s=%s", name, value);

			astate = accumArrayResult(astate, PointerGetDatum(t),
									  false, TEXTOID,
									  CurrentMemoryContext);
		}

		if(rowgroupSizeSet == false){
			text *t;
			const char *name = "rowgroupsize";
			char value[INT32_CHAR_SIZE];
			Size len;

			pg_ltoa(DEFAULT_PARQUET_ROWGROUP_SIZE_PARTITION, value);
			len = VARHDRSZ + strlen(name) + 1 + strlen(value);
			t = (text *) palloc(len + 1);
			SET_VARSIZE(t, len);
			sprintf(VARDATA(t), "%s=%s", name, value);

			astate = accumArrayResult(astate, PointerGetDatum(t),
									  false, TEXTOID,
									  CurrentMemoryContext);
		}

		if (astate)
			result = makeArrayResult(astate, CurrentMemoryContext);

		return result;
	}
}

/* ----------------------------------------------------------------
*		DefineExternalRelation
*				Creates a new external relation.
*
* In here we first dispatch a normal DefineRelation() (with relstorage
* external) in order to create the external relation entries in pg_class
* pg_type etc. Then once this is done we dispatch ourselves (DefineExternalRelation)
* in order to create the pg_exttable entry across the gp array and we
* also record a dependency with the error table, if one exists.
*
* Why don't we just do all of this in one dispatch run? because that
* involves duplicating the DefineRelation() code or severely modifying it
* to have special cases for external tables. IMHO it's better and cleaner
* to leave it intact and do another dispatch.
* ----------------------------------------------------------------
*/
extern void
DefineExternalRelation(CreateExternalStmt *createExtStmt)
{
	/*volatile struct CdbDispatcherState ds = {NULL, NULL};*/
	CreateStmt				  *createStmt = makeNode(CreateStmt);
	ExtTableTypeDesc 		  *exttypeDesc = (ExtTableTypeDesc *)createExtStmt->exttypedesc;
	SingleRowErrorDesc 		  *singlerowerrorDesc = NULL;
	DefElem    				  *dencoding = NULL;
	ListCell				  *option;
	Oid						  reloid = 0;
	Oid						  fmtErrTblOid = InvalidOid;
	Datum					  formatOptStr;
	Datum					  locationUris = 0;
	Datum					  locationExec = 0;
	char*					  commandString = NULL;
	char					  rejectlimittype = '\0';
	char					  formattype;
	int						  rejectlimit = -1;
	int						  encoding = -1;
	int preferred_segment_num = -1;
	bool					  issreh = false; /* is single row error handling requested? */
	bool					  iswritable = createExtStmt->iswritable;
	bool					  isweb = createExtStmt->isweb;

	/*
	 * now set the parameters for keys/inheritance etc. Most of these are
	 * uninteresting for external relations...
	 */
	createStmt->relation = createExtStmt->relation;
	createStmt->tableElts = createExtStmt->tableElts;
	createStmt->inhRelations = NIL;
	createStmt->constraints = NIL;
	createStmt->options = NIL;
	createStmt->oncommit = ONCOMMIT_NOOP;
	createStmt->tablespacename = NULL;
	createStmt->policy = createExtStmt->policy; /* policy was set in transform */
	
	bool isCustom = false;
	switch(exttypeDesc->exttabletype)
	{
		case EXTTBL_TYPE_LOCATION:

			/* Parse and validate URI strings (LOCATION clause) */
			locationUris = transformLocationUris(exttypeDesc->location_list,
									 createExtStmt->formatOpts,
									 isweb, iswritable,&isCustom);
			if(!isCustom){
				int locLength = list_length(exttypeDesc->location_list);
				if (createStmt->policy && locLength > 0 && locLength > createStmt->policy->bucketnum)
				{
					createStmt->policy->bucketnum = locLength;
				}
			}

			break;

		case EXTTBL_TYPE_EXECUTE:
			locationExec = transformExecOnClause(exttypeDesc->on_clause, &preferred_segment_num, iswritable);
			if (createStmt->policy)
			{
			  createStmt->policy->bucketnum = preferred_segment_num;
			}
			commandString = exttypeDesc->command_string;

			if(strlen(commandString) == 0)
				ereport(ERROR,
						(errcode(ERRCODE_SYNTAX_ERROR),
						 errmsg("Invalid EXECUTE clause. Found an empty command string"),
								   errOmitLocation(true)));

			break;

		default:
			ereport(ERROR,
					(errcode(ERRCODE_GP_INTERNAL_ERROR),
					 errmsg("Internal error: unknown external table type"),
							   errOmitLocation(true)));
	}

	/*
	 * check permissions to create this external table.
	 *
	 * - Always allow if superuser.
	 * - Never allow EXECUTE or 'file' exttables if not superuser.
	 * - Allow http, gpfdist or gpfdists tables if pg_auth has the right permissions
	 *   for this role and for this type of table, or if gp_external_grant_privileges 
	 *   is on (gp_external_grant_privileges should be deprecated at some point).
	 */
	if(!superuser() && Gp_role == GP_ROLE_DISPATCH)
	{		
		if(exttypeDesc->exttabletype == EXTTBL_TYPE_EXECUTE)
		{
			ereport(ERROR,
					(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
					 errmsg("must be superuser to create an EXECUTE external web table"),
							   errOmitLocation(true)));
		}
		else
		{
			ListCell   *first_uri = list_head(exttypeDesc->location_list);
			Value		*v = lfirst(first_uri);
			char		*uri_str = pstrdup(v->val.str);
			Uri			*uri = ParseExternalTableUri(uri_str);

			Assert(exttypeDesc->exttabletype == EXTTBL_TYPE_LOCATION);

			if(uri->protocol == URI_FILE)
			{
				ereport(ERROR,
						(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
						 errmsg("must be superuser to create an external table with a file protocol"),
								   errOmitLocation(true)));
			}
			else if(!gp_external_grant_privileges)
			{
				/*
				 * Check if this role has the proper 'gpfdist', 'gpfdists' or 'http'
				 * permissions in pg_auth for creating this table.
				 */

				bool		 isnull;				
				Oid			 userid = GetUserId();
				cqContext	*pcqCtx;
				HeapTuple	 tuple;

				pcqCtx = caql_beginscan(
						NULL,
						cql("SELECT * FROM pg_authid "
							 " WHERE oid = :1 "
							 " FOR UPDATE ",
							 ObjectIdGetDatum(userid)));

				tuple = caql_getnext(pcqCtx);
								
				if (!HeapTupleIsValid(tuple))
					ereport(ERROR,
							(errcode(ERRCODE_UNDEFINED_OBJECT),
							 errmsg("role \"%s\" does not exist (in DefineExternalRelation)", 
									 GetUserNameFromId(userid))));

				if ( (uri->protocol == URI_GPFDIST || uri->protocol == URI_GPFDISTS) && iswritable)
				{
					Datum 	d_wextgpfd = caql_getattr(pcqCtx, Anum_pg_authid_rolcreatewextgpfd, 
													  &isnull);
					bool	createwextgpfd = (isnull ? false : DatumGetBool(d_wextgpfd));

					if (!createwextgpfd)
						ereport(ERROR,
								(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
								errmsg("permission denied: no privilege to create a writable gpfdist(s) external table"),
										errOmitLocation(true)));
				}
				else if ( (uri->protocol == URI_GPFDIST || uri->protocol == URI_GPFDISTS) && !iswritable)
				{
					Datum 	d_rextgpfd = caql_getattr(pcqCtx, Anum_pg_authid_rolcreaterextgpfd, 
													  &isnull);
					bool	createrextgpfd = (isnull ? false : DatumGetBool(d_rextgpfd));

					if (!createrextgpfd)
						ereport(ERROR,
								(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
								errmsg("permission denied: no privilege to create a readable gpfdist(s) external table"),
										errOmitLocation(true)));

				}
				else if (uri->protocol == URI_HTTP && !iswritable)
				{
					Datum 	d_exthttp = caql_getattr(pcqCtx, Anum_pg_authid_rolcreaterexthttp, 
													 &isnull);
					bool	createrexthttp = (isnull ? false : DatumGetBool(d_exthttp));

					if (!createrexthttp)
						ereport(ERROR,
								(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
								errmsg("permission denied: no privilege to create an http external table"),
										errOmitLocation(true)));
				}
				else if (uri->protocol == URI_CUSTOM)
				{
					Oid			ownerId = GetUserId();
					char*		protname = uri->customprotocol;
					Oid			ptcId = LookupExtProtocolOid(protname, false);
					AclResult	aclresult;
					
					/* Check we have the right permissions on this protocol */
					if (!pg_extprotocol_ownercheck(ptcId, ownerId))
					{	
						AclMode mode = (iswritable ? ACL_INSERT : ACL_SELECT);
						
						aclresult = pg_extprotocol_aclcheck(ptcId, ownerId, mode);
						
						if (aclresult != ACLCHECK_OK)
							aclcheck_error(aclresult, ACL_KIND_EXTPROTOCOL, protname);
					}
				}
				else
				{
					ereport(ERROR,
							(errcode(ERRCODE_INTERNAL_ERROR),
							errmsg("internal error in DefineExternalRelation. "
								   "protocol is %d, writable is %d", 
								   uri->protocol, iswritable)));
				}
				
				caql_endscan(pcqCtx);
			}
			FreeExternalTableUri(uri);
			pfree(uri_str);
		}
	}

	/*
	 * Parse and validate FORMAT clause.
	 */
	formattype = transformFormatType(createExtStmt->format);
	
	formatOptStr = transformFormatOpts(formattype,
									   createExtStmt->formatOpts,
									   list_length(createExtStmt->tableElts),
									   iswritable);

	/*
	 * Parse single row error handling info if available
	 */
	singlerowerrorDesc = (SingleRowErrorDesc *)createExtStmt->sreh;

	if(singlerowerrorDesc)
	{
		Assert(!iswritable);
		
		issreh = true;

		/* get reject limit, and reject limit type */
		rejectlimit = singlerowerrorDesc->rejectlimit;
		rejectlimittype = (singlerowerrorDesc->is_limit_in_rows ? 'r' : 'p');
		VerifyRejectLimit(rejectlimittype, rejectlimit);

		/* KEEP only allowed for COPY */
		if(singlerowerrorDesc->is_keep)
			ereport(ERROR,
					(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
					 errmsg("KEEP is not supported in the external table definition. "
							"Error table will be dropped when its external table is "
							"dropped."),
									   errOmitLocation(true)));

		if(singlerowerrorDesc->errtable)
			fmtErrTblOid = RangeVarGetRelid(singlerowerrorDesc->errtable, true, false /*allowHcatalog*/);
		else
			fmtErrTblOid = InvalidOid; /* no err tbl was requested */
	}

	/*
	 * Parse external table data encoding
	 */
	foreach(option, createExtStmt->encoding)
	{
		DefElem    *defel = (DefElem *) lfirst(option);

		Assert(strcmp(defel->defname, "encoding") == 0);

		if (dencoding)
			ereport(ERROR,
					(errcode(ERRCODE_SYNTAX_ERROR),
					 errmsg("conflicting or redundant ENCODING specification"),
							   errOmitLocation(true)));
		dencoding = defel;
	}

	if (dencoding && dencoding->arg)
	{
		const char *encoding_name;

		if (IsA(dencoding->arg, Integer))
		{
			encoding = intVal(dencoding->arg);
			encoding_name = pg_encoding_to_char(encoding);
			if (strcmp(encoding_name, "") == 0 ||
				pg_valid_client_encoding(encoding_name) < 0)
				ereport(ERROR,
						(errcode(ERRCODE_UNDEFINED_OBJECT),
						 errmsg("%d is not a valid encoding code",
								encoding),
										   errOmitLocation(true)));
		}
		else if (IsA(dencoding->arg, String))
		{
			encoding_name = strVal(dencoding->arg);
			if (pg_valid_client_encoding(encoding_name) < 0)
				ereport(ERROR,
						(errcode(ERRCODE_UNDEFINED_OBJECT),
						 errmsg("%s is not a valid encoding name",
								encoding_name),
										   errOmitLocation(true)));
			encoding = pg_char_to_encoding(encoding_name);
		}
		else
			elog(ERROR, "unrecognized node type: %d",
				 nodeTag(dencoding->arg));
	}

	/* If encoding is defaulted, use database encoding */
	if (encoding < 0)
		encoding = pg_get_client_encoding();


    /*
	 * First, create the pg_class and other regular relation catalog entries.
	 * Under the covers this will dispatch a CREATE TABLE statement to all the
	 * QEs.
	 */
	Assert(Gp_role == GP_ROLE_DISPATCH || Gp_role == GP_ROLE_UTILITY);

	reloid = DefineRelation(createStmt, RELKIND_RELATION, RELSTORAGE_EXTERNAL);

	/*
	 * Now we take care of pg_exttable and dependency with error table (if any).
	 */

	/*
	 * get our pg_class external rel OID. If we're the QD we just created
	 * it above. If we're a QE DefineRelation() was already dispatched to
	 * us and therefore we have a local entry in pg_class. get the OID
	 * from cache.
	 */
	if (Gp_role == GP_ROLE_DISPATCH || Gp_role == GP_ROLE_UTILITY)
		Assert(reloid != InvalidOid);
	else
		reloid = RangeVarGetRelid(createExtStmt->relation, true, false /*allowHcatalog*/);

	/*
	 * create a pg_exttable entry for this external table.
	 */
	InsertExtTableEntry(reloid,
						iswritable,
						isweb,
						issreh,
						formattype,
						rejectlimittype,
						commandString,
						rejectlimit,
						fmtErrTblOid,
						encoding,
						formatOptStr,
						locationExec,
						locationUris);

	/*
	 * record a dependency between the external table and its error table (if one exists)
	 */
	if(singlerowerrorDesc && singlerowerrorDesc->errtable)
	{
		ObjectAddress	myself,
		referenced;
		Oid		fmtErrTblOid = RangeVarGetRelid(((SingleRowErrorDesc *)createExtStmt->sreh)->errtable, true, false /*allowHcatalog*/);

		Assert(!createExtStmt->iswritable);
		Assert(fmtErrTblOid != InvalidOid);

		myself.classId = RelationRelationId;
		myself.objectId = reloid;
		myself.objectSubId = 0;
		referenced.classId = RelationRelationId;
		referenced.objectId = fmtErrTblOid;
		referenced.objectSubId = 0;
		recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
	}
}

extern void
DefineForeignRelation(CreateForeignStmt *createForeignStmt)
{
	CreateStmt				  *createStmt = makeNode(CreateStmt);
	Oid						  reloid = 0;
	bool					  shouldDispatch = (Gp_role == GP_ROLE_DISPATCH &&
												IsNormalProcessingMode());
	
	/*
	 * now set the parameters for keys/inheritance etc. Most of these are
	 * uninteresting for external relations...
	 */
	createStmt->relation = createForeignStmt->relation;
	createStmt->tableElts = createForeignStmt->tableElts;
	createStmt->inhRelations = NIL;
	createStmt->constraints = NIL;
	createStmt->options = NIL;
	createStmt->oncommit = ONCOMMIT_NOOP;
	createStmt->tablespacename = NULL;
	createStmt->policy = NULL; /* for now, we use "master only" type of distribution */
	
	/* (permissions are checked in foreigncmd.c:InsertForeignTableEntry() ) */

  /*
	 * First, create the pg_class and other regular relation catalog entries.
	 * Under the covers this will dispatch a CREATE TABLE statement to all the
	 * QEs.
	 */
	if(Gp_role == GP_ROLE_DISPATCH || Gp_role == GP_ROLE_UTILITY)
		reloid = DefineRelation(createStmt, RELKIND_RELATION, RELSTORAGE_FOREIGN);

	/*
	 * Now we take care of pg_foreign_table
	 */
  ObjectAddress myself;
  ObjectAddress referenced;
  Oid	ownerId = GetUserId();
  ForeignServer *srv = GetForeignServerByName(createForeignStmt->srvname, false);

  /*
   * get our pg_class foreign rel OID. If we're the QD we just created
   * it above. If we're a QE DefineRelation() was already dispatched to
   * us and therefore we have a local entry in pg_class. get the OID
   * from cache.
   */
  if(Gp_role == GP_ROLE_DISPATCH || Gp_role == GP_ROLE_UTILITY)
    Assert(reloid != InvalidOid);
  else
    reloid = RangeVarGetRelid(createForeignStmt->relation, true, false);

  /* Add dependency on SERVER and owner */
  myself.classId = RelationRelationId;
  myself.objectId = reloid;
  myself.objectSubId = 0;

  referenced.classId = ForeignServerRelationId;
  referenced.objectId = srv->serverid;
  referenced.objectSubId = 0;
  recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);

  recordDependencyOnOwner(RelationRelationId, reloid, ownerId);

  /* create a pg_exttable entry for this foreign table.*/
  InsertForeignTableEntry(reloid,
              createForeignStmt->srvname,
              createForeignStmt->options);


  if (shouldDispatch)
  {

    /* Dispatch the statement tree to all primary and mirror segdbs.
     * Doesn't wait for the QEs to finish execution.
     */
    dispatch_statement_node((Node *) createForeignStmt, NULL, NULL, NULL);
  }
}

/* ----------------------------------------------------------------
*		DefinePartitionedRelation
*				Create the rewrite rule for a partitioned table
*
* parse/analyze.c/transformPartitionBy does the bulk of the work for
* partitioned tables, converting a single CREATE TABLE into a series
* of statements to create the child tables for each partition.  Each
* child table has a check constraint and a rewrite rule to ensure that
* INSERTs to the parent end up in the correct child table (partition).
* However, we cannot add a RuleStmt for a non-existent table to the
* a(fter)list for the Create statement (believe me, I tried, really
* hard).  Thus, we create the "parsed" RuleStmt in analyze, and
* finally parse_analyze it here *after* the relation is created, the
* use process_utility to dispatch.
* ----------------------------------------------------------------
*/
void
DefinePartitionedRelation(CreateStmt *stmt, Oid relOid)
{

	if (stmt->postCreate)
	{
		List *pQry;
		Node *pUtl;
		DestReceiver *dest = None_Receiver;
		List *pL1 = (List *)stmt->postCreate;

		pQry = parse_analyze(linitial(pL1), NULL, NULL, 0);

		if (pQry)
		{
			/* just grab the first guy - "There Can Be Only One"(TM) */
			pUtl = linitial(pQry);

			if (pUtl)
			{
				Assert(IsA(pUtl, Query));
				Assert(((Query *)pUtl)->commandType == CMD_UTILITY);

				ProcessUtility((Node *)(((Query *)pUtl)->utilityStmt),
							   synthetic_sql,
							   NULL, 
							   false, /* not top level */
							   dest,
							   NULL);
			}
		}
	}
}

/*
 * Run deferred statements generated by internal operations around
 * partition addition/split.
 */
void
EvaluateDeferredStatements(List *deferredStmts)
{
	ListCell	   *lc;

	/***
	 *** XXX: Fix MPP-13750, however this fails to address the similar bug
	 ***      with ordinary inheritance and partial indexes.  When that bug,
	 ***      is fixed, this section should become unnecessary!
	 ***/
	
	foreach( lc, deferredStmts )
	{
		ListCell *ulc;
		List *analyzedStmts = NIL;
		DestReceiver *dest = None_Receiver;
		
		Node *dstmt = lfirst(lc);
		
		analyzedStmts = parse_analyze(dstmt, NULL, NULL, 0);
		foreach (ulc, analyzedStmts)
		{
			Query *uquery = NULL;
			Node *utilityStmt = lfirst(ulc);
			
			Insist(IsA(utilityStmt, Query));
			uquery = (Query*)utilityStmt;
			Insist(uquery->commandType == CMD_UTILITY);
			
			ereport(DEBUG1, 
					(errmsg("processing deferred utility statement")));
			
			ProcessUtility((Node*)uquery->utilityStmt,
						   synthetic_sql,
						   NULL,
						   false,
						   dest,
						   NULL);
		}
	}
}

/* Don't track internal namespaces for toast, bitmap, aoseg */
#define METATRACK_VALIDNAMESPACE(namespaceId) \
	(namespaceId != PG_TOAST_NAMESPACE &&	\
	 namespaceId != PG_BITMAPINDEX_NAMESPACE && \
	 namespaceId != PG_AOSEGMENT_NAMESPACE )

/* check for valid namespace and valid relkind */
static 
bool
MetaTrackValidKindNsp(Form_pg_class rd_rel)
{
	Oid nsp = rd_rel->relnamespace;

	if (PG_CATALOG_NAMESPACE == nsp)
	{
		/* MPP-7773: don't track objects in system namespace
		 * if modifying system tables (eg during upgrade)  
		 */
		if (allowSystemTableModsDDL)
			return (false);
	}

	/* MPP-7599: watch out for toast indexes */
	return (METATRACK_VALIDNAMESPACE(nsp)
			&& MetaTrackValidRelkind(rd_rel->relkind)
			/* MPP-7572: not valid if in any temporary namespace */
			&& (!(isAnyTempNamespace(nsp))));
}

/*
 * RemoveRelation
 *		Deletes a relation.
 */
void
RemoveRelation(const RangeVar *relation, DropBehavior behavior,
			   DropStmt *stmt)
{
	Oid			relOid;
	ObjectAddress object;
	HeapTuple tuple;
	cqContext  *pcqCtx;

	AcceptInvalidationMessages();

	relOid = RangeVarGetRelid(relation, false, false /*allowHcatalog*/);

	if (Gp_role == GP_ROLE_DISPATCH)
	{
		LockRelationOid(RelationRelationId, RowExclusiveLock);
		LockRelationOid(TypeRelationId, RowExclusiveLock);
		LockRelationOid(DependRelationId, RowExclusiveLock);
	}

	LockRelationOid(relOid, AccessExclusiveLock);

	pcqCtx = caql_beginscan(
			NULL,
			cql("SELECT * FROM pg_class "
				" WHERE oid = :1 "
				" FOR UPDATE ",
				ObjectIdGetDatum(relOid)));

	tuple = caql_getnext(pcqCtx);

	if (!HeapTupleIsValid(tuple))
		elog(ERROR, "relation \"%s\" does not exist", relation->relname);

	/* MPP-3260: disallow direct DROP TABLE of a partition */
	if (stmt && rel_is_child_partition(relOid) && !stmt->bAllowPartn)
	{
		Oid		 master = rel_partition_get_master(relOid);
		char	*pretty	= rel_get_part_path_pretty(relOid,
												   " ALTER PARTITION ",
												   " DROP PARTITION ");

		ereport(ERROR,
				(errcode(ERRCODE_DEPENDENT_OBJECTS_STILL_EXIST),
				errmsg("cannot drop partition \"%s\" directly",
					   get_rel_name(relOid)),
				errhint("Table \"%s\" is a child partition of table "
						"\"%s\".  To drop it, use ALTER TABLE \"%s\"%s...",
						get_rel_name(relOid), get_rel_name(master),
						get_rel_name(master), pretty ? pretty : "" ),
								   errOmitLocation(true)));

	}

	object.classId = RelationRelationId;
	object.objectId = relOid;
	object.objectSubId = 0;

	caql_endscan(pcqCtx);

	/* if we got here then we should proceed. */
	performDeletion(&object, behavior);
}

/*
 * RelationToRemoveIsTemp
 *		Checks if an object being targeted for drop is a temporary table.
 */
bool
RelationToRemoveIsTemp(const RangeVar *relation, DropBehavior behavior)
{
	Oid			relOid;
	HeapTuple	relTup;
	Form_pg_class relForm;
	char	   *nspname;
	char	   *relname;
	bool		isTemp;
	cqContext  *pcqCtx;

	elog(DEBUG5, "Relation to remove catalogname %s, schemaname %s, relname %s",
		 (relation->catalogname == NULL ? "<empty>" : relation->catalogname),
		 (relation->schemaname == NULL ? "<empty>" : relation->schemaname),
		 (relation->relname == NULL ? "<empty>" : relation->relname));

	// UNDONE: Not sure how to interpret 'behavior'...

	relOid = RangeVarGetRelid(relation, false, false /*allowHcatalog*/);

	/*
	 * Lock down the object to stablize it before we examine its
	 * charactistics.
	 */
	if (Gp_role == GP_ROLE_DISPATCH)
	{
		LockRelationOid(RelationRelationId, RowExclusiveLock);
		LockRelationOid(TypeRelationId, RowExclusiveLock);
		LockRelationOid(DependRelationId, RowExclusiveLock);
	}

	/* Lock the relation to be dropped */
	LockRelationOid(relOid, AccessExclusiveLock);

	/*
	 * When we got the relOid lock, it is possible that the relation has gone away.
	 * this will throw Error if the relation is already deleted.
	 */
	RangeVarGetRelid(relation, false, false /*allowHcatalog*/);

	/* if we got here then we should proceed. */

	pcqCtx = caql_beginscan(
			NULL,
			cql("SELECT * FROM pg_class "
				" WHERE oid = :1 ",
				ObjectIdGetDatum(relOid)));

	relTup = caql_getnext(pcqCtx);

	if (!HeapTupleIsValid(relTup))
		elog(ERROR, "cache lookup failed for relation %u", relOid);
	relForm = (Form_pg_class) GETSTRUCT(relTup);

	/* Qualify the name if not visible in search path */
	if (RelationIsVisible(relOid))
		nspname = NULL;
	else
		nspname = get_namespace_name(relForm->relnamespace);

	/* XXX XXX: is this all just for debugging?  could just be simplified to:
	   SELECT relnamespace from pg_class 
	*/

	relname = quote_qualified_identifier(nspname, NameStr(relForm->relname));

	isTemp = isTempNamespace(relForm->relnamespace);

	elog(DEBUG5, "Relation name is %s, namespace %s, isTemp = %s",
	     relname,
	     (nspname == NULL ? "<null>" : nspname),
	     (isTemp ? "true" : "false"));

	caql_endscan(pcqCtx);

	return isTemp;
}


/*
 * ExecuteTruncate
 *		Executes a TRUNCATE command.
 *
 * This is a multi-relation truncate.  We first open and grab exclusive
 * lock on all relations involved, checking permissions and otherwise
 * verifying that the relation is OK for truncation.  In CASCADE mode,
 * relations having FK references to the targeted relations are automatically
 * added to the group; in RESTRICT mode, we check that all FK references are
 * internal to the group that's being truncated.  Finally all the relations
 * are truncated and reindexed.
 */
void
ExecuteTruncate(TruncateStmt *stmt)
{
	List	   *rels = NIL;
	List	   *relids = NIL;
	List	   *meta_relids = NIL;
	ListCell   *cell;
    int partcheck = 2;
	List *partList = NIL;

	/*
	 * Open, exclusive-lock, and check all the explicitly-specified relations
	 *
	 * Check if table has partitions and add them too
	 */
	while (partcheck)
	{
		foreach(cell, stmt->relations)
		{
			RangeVar   *rv = lfirst(cell);
			Relation	rel;
			PartitionNode *pNode;

			PG_TRY();
			{
				rel = heap_openrv(rv, AccessExclusiveLock);
			}
			
			PG_CATCH();
			{
				/* 
				 * In the case of the table being dropped concurrently, 
				 * throw a friendlier error than:
				 * 
				 * "could not open relation with relid 1234"
				 */
				if (rv->schemaname)
					ereport(ERROR,
							(errcode(ERRCODE_UNDEFINED_TABLE),
							 errmsg("relation \"%s.%s\" does not exist",
									rv->schemaname, rv->relname),
							 errOmitLocation(true)));
				else
					ereport(ERROR,
							(errcode(ERRCODE_UNDEFINED_TABLE),
							 errmsg("relation \"%s\" does not exist",
									rv->relname),
							 errOmitLocation(true)));
				PG_RE_THROW();
			}
			PG_END_TRY();
			
			truncate_check_rel(rel);

			if (partcheck == 2)
			{
				pNode = RelationBuildPartitionDesc(rel, false);

				if (pNode)
				{
					List *plist = atpxTruncateList(rel, pNode);

					if (plist)
					{
						if (partList)
							partList = list_concat(partList, plist);
						else
							partList = plist;
					}
				}
			}
			heap_close(rel, NoLock);
		}

		partcheck--;

		if (partList)
		{
			/* add the partitions to the relation list and try again */
			if (partcheck == 1)
				stmt->relations = list_concat(partList, stmt->relations);
		}
		else
			/* no partitions - no need to try again */
			partcheck = 0;
	} /* end while partcheck */

	/*
	 * Open, exclusive-lock, and check all the explicitly-specified relations
	 */
	foreach(cell, stmt->relations)
	{
		RangeVar   *rv = lfirst(cell);
		Relation	rel;

		rel = heap_openrv(rv, AccessExclusiveLock);
		truncate_check_rel(rel);
		rels = lappend(rels, rel);
		relids = lappend_oid(relids, RelationGetRelid(rel));

		if (MetaTrackValidKindNsp(rel->rd_rel))
			meta_relids = lappend_oid(meta_relids, RelationGetRelid(rel));
	}


	/*
	 * In CASCADE mode, suck in all referencing relations as well.	This
	 * requires multiple iterations to find indirectly-dependent relations. At
	 * each phase, we need to exclusive-lock new rels before looking for their
	 * dependencies, else we might miss something.	Also, we check each rel as
	 * soon as we open it, to avoid a faux pas such as holding lock for a long
	 * time on a rel we have no permissions for.
	 */
	if (stmt->behavior == DROP_CASCADE)
	{
		for (;;)
		{
			List	   *newrelids;

			newrelids = heap_truncate_find_FKs(relids);
			if (newrelids == NIL)
				break;			/* nothing else to add */

			foreach(cell, newrelids)
			{
				Oid			relid = lfirst_oid(cell);
				Relation	rel;

				rel = heap_open(relid, AccessExclusiveLock);
				ereport(NOTICE,
						(errmsg("truncate cascades to table \"%s\"",
								RelationGetRelationName(rel)),
										   errOmitLocation(true)));
				truncate_check_rel(rel);
				rels = lappend(rels, rel);
				relids = lappend_oid(relids, relid);

				if (MetaTrackValidKindNsp(rel->rd_rel))
					meta_relids = lappend_oid(meta_relids, 
											  RelationGetRelid(rel));
			}
		}
	}


	/*
	 * Check foreign key references.  In CASCADE mode, this should be
	 * unnecessary since we just pulled in all the references; but as a
	 * cross-check, do it anyway if in an Assert-enabled build.
	 */
#ifdef USE_ASSERT_CHECKING
	heap_truncate_check_FKs(rels, false);
#else
	if (stmt->behavior == DROP_RESTRICT)
		heap_truncate_check_FKs(rels, false);
#endif

	/*
	 * OK, truncate each table.
	 */
	foreach(cell, rels)
	{
		Relation	rel = (Relation) lfirst(cell);
		Oid			heap_relid;
		Oid			toast_relid;
		Oid			aoseg_relid = InvalidOid;
		Oid			aoblkdir_relid = InvalidOid;
		List	   *indoids = NIL;

		/*
		 * Create a new empty storage file for the relation, and assign it
		 * as the relfilenode value. The old storage file is scheduled for
		 * deletion at commit.
		 */
		setNewRelfilenode(rel);

		heap_relid = RelationGetRelid(rel);
		toast_relid = rel->rd_rel->reltoastrelid;
		heap_close(rel, NoLock);

		if (RelationIsAoRows(rel) || RelationIsParquet(rel)){
			GetAppendOnlyEntryAuxOids(heap_relid, SnapshotNow,
											  &aoseg_relid, NULL,
											  &aoblkdir_relid, NULL);
			AORelRemoveHashEntryOnCommit(RelationGetRelid(rel));
		}
		else{
			ereport(ERROR,
								( errcode(ERRCODE_GP_COMMAND_ERROR),
										errmsg("TRUNCATE on heap table is not supported.")));
		}

		/*
		 * The same for the toast table, if any.
		 */
		if (OidIsValid(toast_relid))
		{
			rel = relation_open(toast_relid, AccessExclusiveLock);
			setNewRelfilenode(rel);
			heap_close(rel, NoLock);
		}

		/*
		 * The same for the aoseg table, if any.
		 */
		if (OidIsValid(aoseg_relid))
		{
			rel = relation_open(aoseg_relid, AccessExclusiveLock);
			setNewRelfilenode(rel);
			heap_close(rel, NoLock);
		}

		if (OidIsValid(aoblkdir_relid))
		{
			rel = relation_open(aoblkdir_relid, AccessExclusiveLock);
			setNewRelfilenode(rel);
			heap_close(rel, NoLock);
		}

		/*
		 * Reconstruct the indexes to match, and we're done.
		 */
		reindex_relation(heap_relid, true, true, true, &indoids, true);
	}
}

/*
 * Check that a given rel is safe to truncate.	Subroutine for ExecuteTruncate
 */
static void
truncate_check_rel(Relation rel)
{
	/* Only allow truncate on regular or append-only tables */
	if (rel->rd_rel->relkind != RELKIND_RELATION)
			ereport(ERROR,
					(errcode(ERRCODE_WRONG_OBJECT_TYPE),
					 errmsg("\"%s\" is not a table",
							RelationGetRelationName(rel)),
									   errOmitLocation(true)));

	if (RelationIsExternal(rel))
		ereport(ERROR,
				(errcode(ERRCODE_WRONG_OBJECT_TYPE),
				 errmsg("\"%s\" is an external relation and can't be truncated",
						RelationGetRelationName(rel)),
								   errOmitLocation(true)));


	/* Permissions checks */
	if (!pg_class_ownercheck(RelationGetRelid(rel), GetUserId()))
		aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_CLASS,
					   RelationGetRelationName(rel));

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

	/*
	 * We can never allow truncation of shared or nailed-in-cache relations,
	 * because we can't support changing their relfilenode values.
	 */
	if (rel->rd_rel->relisshared || rel->rd_isnailed)
		ereport(ERROR,
				(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
				 errmsg("cannot truncate system relation \"%s\"",
						RelationGetRelationName(rel)),
								   errOmitLocation(true)));

	/*
	 * Don't allow truncate on temp tables of other backends ... their local
	 * buffer manager is not going to cope.
	 */
	if (isOtherTempNamespace(RelationGetNamespace(rel)))
		ereport(ERROR,
				(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
			  errmsg("cannot truncate temporary tables of other sessions"),
					   errOmitLocation(true)));

	/*
	 * Also check for active uses of the relation in the current transaction,
	 * including open scans and pending AFTER trigger events.
	 */
	CheckTableNotInUse(rel, "TRUNCATE");
}

/*----------
 * MergeAttributes
 *		Returns new schema given initial schema and superclasses.
 *
 * Input arguments:
 * 'schema' is the column/attribute definition for the table. (It's a list
 *		of ColumnDef's.) It is destructively changed.
 * 'supers' is a list of names (as RangeVar nodes) of parent relations.
 * 'istemp' is TRUE if we are creating a temp relation.
 * 'GpPolicy *' is NULL if the distribution policy is not to be updated
 *
 * Output arguments:
 * 'supOids' receives a list of the OIDs of the parent relations.
 * 'supconstr' receives a list of constraints belonging to the parents,
 *		updated as necessary to be valid for the child.
 * 'supOidCount' is set to the number of parents that have OID columns.
 * 'GpPolicy' is updated with the offsets of the distribution
 *      attributes in the new schema
 *
 * Return value:
 * Completed schema list.
 *
 * Notes:
 *	  The order in which the attributes are inherited is very important.
 *	  Intuitively, the inherited attributes should come first. If a table
 *	  inherits from multiple parents, the order of those attributes are
 *	  according to the order of the parents specified in CREATE TABLE.
 *
 *	  Here's an example:
 *
 *		create table person (name text, age int4, location point);
 *		create table emp (salary int4, manager text) inherits(person);
 *		create table student (gpa float8) inherits (person);
 *		create table stud_emp (percent int4) inherits (emp, student);
 *
 *	  The order of the attributes of stud_emp is:
 *
 *							person {1:name, 2:age, 3:location}
 *							/	 \
 *			   {6:gpa}	student   emp {4:salary, 5:manager}
 *							\	 /
 *						   stud_emp {7:percent}
 *
 *	   If the same attribute name appears multiple times, then it appears
 *	   in the result table in the proper location for its first appearance.
 *
 *	   Constraints (including NOT NULL constraints) for the child table
 *	   are the union of all relevant constraints, from both the child schema
 *	   and parent tables.
 *
 *	   The default value for a child column is defined as:
 *		(1) If the child schema specifies a default, that value is used.
 *		(2) If neither the child nor any parent specifies a default, then
 *			the column will not have a default.
 *		(3) If conflicting defaults are inherited from different parents
 *			(and not overridden by the child), an error is raised.
 *		(4) Otherwise the inherited default is used.
 *		Rule (3) is new in Postgres 7.1; in earlier releases you got a
 *		rather arbitrary choice of which parent default to use.
 *----------
 */
List *
MergeAttributes(List *schema, List *supers, bool istemp, bool isPartitioned,
				List **supOids, List **supconstr, int *supOidCount, GpPolicy *policy)
{
	ListCell   *entry;
	List	   *inhSchema = NIL;
	List	   *parentOids = NIL;
	List	   *constraints = NIL;
	int			parentsWithOids = 0;
	bool		have_bogus_defaults = false;
	char	   *bogus_marker = "Bogus!";		/* marks conflicting defaults */
	int			child_attno;

	/*
	 * Check for and reject tables with too many columns. We perform this
	 * check relatively early for two reasons: (a) we don't run the risk of
	 * overflowing an AttrNumber in subsequent code (b) an O(n^2) algorithm is
	 * okay if we're processing <= 1600 columns, but could take minutes to
	 * execute if the user attempts to create a table with hundreds of
	 * thousands of columns.
	 *
	 * Note that we also need to check that any we do not exceed this figure
	 * after including columns from inherited relations.
	 */
	if (list_length(schema) > MaxHeapAttributeNumber)
		ereport(ERROR,
				(errcode(ERRCODE_TOO_MANY_COLUMNS),
				 errmsg("tables can have at most %d columns",
						MaxHeapAttributeNumber)));

	/*
	 * Check for duplicate names in the explicit list of attributes.
	 *
	 * Although we might consider merging such entries in the same way that we
	 * handle name conflicts for inherited attributes, it seems to make more
	 * sense to assume such conflicts are errors.
	 */
	foreach(entry, schema)
	{
		ColumnDef  *coldef = lfirst(entry);
		ListCell   *rest;

		for_each_cell(rest, lnext(entry))
		{
			ColumnDef  *restdef = lfirst(rest);

			if (strcmp(coldef->colname, restdef->colname) == 0)
				ereport(ERROR,
						(errcode(ERRCODE_DUPLICATE_COLUMN),
						 errmsg("column \"%s\" duplicated",
								coldef->colname),
										   errOmitLocation(true)));
		}
	}

	/*
	 * Scan the parents left-to-right, and merge their attributes to form a
	 * list of inherited attributes (inhSchema).  Also check to see if we need
	 * to inherit an OID column.
	 */
	child_attno = 0;
	foreach(entry, supers)
	{
		RangeVar   *parent = (RangeVar *) lfirst(entry);
		Relation	relation;
		TupleDesc	tupleDesc;
		TupleConstr *constr;
		AttrNumber *newattno;
		AttrNumber	parent_attno;

		relation = heap_openrv(parent, AccessShareLock);

		if (relation->rd_rel->relkind != RELKIND_RELATION)
			ereport(ERROR,
					(errcode(ERRCODE_WRONG_OBJECT_TYPE),
					 errmsg("inherited relation \"%s\" is not a table",
							parent->relname),
									   errOmitLocation(true)));
		/* Permanent rels cannot inherit from temporary ones */
		if (!istemp && isTempNamespace(RelationGetNamespace(relation)))
			ereport(ERROR,
					(errcode(ERRCODE_WRONG_OBJECT_TYPE),
					 errmsg("cannot inherit from temporary relation \"%s\"",
							parent->relname),
									   errOmitLocation(true)));

		/*
		 * We should have an UNDER permission flag for this, but for now,
		 * demand that creator of a child table own the parent.
		 */
		if (!pg_class_ownercheck(RelationGetRelid(relation), GetUserId()))
			aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_CLASS,
						   RelationGetRelationName(relation));

		/*
		 * Reject duplications in the list of parents.
		 */
		if (list_member_oid(parentOids, RelationGetRelid(relation)))
			ereport(ERROR,
					(errcode(ERRCODE_DUPLICATE_TABLE),
					 errmsg("inherited relation \"%s\" duplicated",
							parent->relname),
									   errOmitLocation(true)));

		parentOids = lappend_oid(parentOids, RelationGetRelid(relation));

		if (relation->rd_rel->relhasoids)
			parentsWithOids++;

		tupleDesc = RelationGetDescr(relation);
		constr = tupleDesc->constr;

		/*
		 * newattno[] will contain the child-table attribute numbers for the
		 * attributes of this parent table.  (They are not the same for
		 * parents after the first one, nor if we have dropped columns.)
		 */
		newattno = (AttrNumber *)
			palloc(tupleDesc->natts * sizeof(AttrNumber));

		for (parent_attno = 1; parent_attno <= tupleDesc->natts;
			 parent_attno++)
		{
			Form_pg_attribute attribute = tupleDesc->attrs[parent_attno - 1];
			char	   *attributeName = NameStr(attribute->attname);
			int			exist_attno;
			ColumnDef  *def;

			/*
			 * Ignore dropped columns in the parent.
			 */
			if (attribute->attisdropped)
			{
				/*
				 * change_varattnos_of_a_node asserts that this is greater
				 * than zero, so if anything tries to use it, we should find
				 * out.
				 */
				newattno[parent_attno - 1] = 0;
				continue;
			}

			/*
			 * Does it conflict with some previously inherited column?
			 */
			exist_attno = findAttrByName(attributeName, inhSchema);
			if (exist_attno > 0)
			{
				/*
				 * Yes, try to merge the two column definitions. They must
				 * have the same type and typmod.
				 */
				if (Gp_role == GP_ROLE_EXECUTE)
				{
					ereport(DEBUG1,
						(errmsg("merging multiple inherited definitions of column \"%s\"",
								attributeName)));
				}
				else
				ereport(NOTICE,
						(errmsg("merging multiple inherited definitions of column \"%s\"",
								attributeName)));
				def = (ColumnDef *) list_nth(inhSchema, exist_attno - 1);
				if (typenameTypeId(NULL, def->typname) != attribute->atttypid ||
					def->typname->typmod != attribute->atttypmod)
					ereport(ERROR,
							(errcode(ERRCODE_DATATYPE_MISMATCH),
						errmsg("inherited column \"%s\" has a type conflict",
							   attributeName),
							 errdetail("%s versus %s",
									   TypeNameToString(def->typname),
									   format_type_be(attribute->atttypid)),
											   errOmitLocation(true)));
				def->inhcount++;
				/* Merge of NOT NULL constraints = OR 'em together */
				def->is_not_null |= attribute->attnotnull;
				/* Default and other constraints are handled below */
				newattno[parent_attno - 1] = exist_attno;

				/*
				 * Update GpPolicy
				 */
				if (policy != NULL)
				{
					int attr_ofst = 0;

					Assert(policy->nattrs >= 0 && "the number of distribution attributes is not negative");

					/* Iterate over all distribution attribute offsets */
					for (attr_ofst = 0; attr_ofst < policy->nattrs; attr_ofst++)
					{
						/* Check if any distribution attribute has higher offset than the current */
						if (policy->attrs[attr_ofst] > child_attno)
						{
							Assert(policy->attrs[attr_ofst] > 0 && "index should not become negative");
							policy->attrs[attr_ofst]--;
						}
					}
				}

			}
			else
			{
				/*
				 * No, create a new inherited column
				 */
				def = makeNode(ColumnDef);
				def->colname = pstrdup(attributeName);
				def->typname = makeTypeNameFromOid(attribute->atttypid,
													attribute->atttypmod);
				def->inhcount = 1;
				def->is_local = false;
				def->is_not_null = attribute->attnotnull;
				def->raw_default = NULL;
				def->cooked_default = NULL;
				def->constraints = NIL;
				inhSchema = lappend(inhSchema, def);
				newattno[parent_attno - 1] = ++child_attno;
			}

			/*
			 * Copy default if any
			 */
			if (attribute->atthasdef)
			{
				char	   *this_default = NULL;
				AttrDefault *attrdef;
				int			i;

				/* Find default in constraint structure */
				Assert(constr != NULL);
				attrdef = constr->defval;
				for (i = 0; i < constr->num_defval; i++)
				{
					if (attrdef[i].adnum == parent_attno)
					{
						this_default = attrdef[i].adbin;
						break;
					}
				}
				Assert(this_default != NULL);

				/*
				 * If default expr could contain any vars, we'd need to fix
				 * 'em, but it can't; so default is ready to apply to child.
				 *
				 * If we already had a default from some prior parent, check
				 * to see if they are the same.  If so, no problem; if not,
				 * mark the column as having a bogus default. Below, we will
				 * complain if the bogus default isn't overridden by the child
				 * schema.
				 */
				Assert(def->raw_default == NULL);
				if (def->cooked_default == NULL)
					def->cooked_default = pstrdup(this_default);
				else if (strcmp(def->cooked_default, this_default) != 0)
				{
					def->cooked_default = bogus_marker;
					have_bogus_defaults = true;
				}
			}
		}

		/*
		 * Now copy the constraints of this parent, adjusting attnos using the
		 * completed newattno[] map
		 */
		if (constr && constr->num_check > 0)
		{
			ConstrCheck *check = constr->check;
			int			i;

			for (i = 0; i < constr->num_check; i++)
			{
				Constraint *cdef = makeNode(Constraint);
				Node	   *expr;

				cdef->contype = CONSTR_CHECK;
				cdef->name = pstrdup(check[i].ccname);
				cdef->raw_expr = NULL;
				/* adjust varattnos of ccbin here */
				expr = stringToNode(check[i].ccbin);
				change_varattnos_of_a_node(expr, newattno);
				cdef->cooked_expr = nodeToString(expr);
				constraints = lappend(constraints, cdef);
			}
		}

		pfree(newattno);

		/*
		 * Close the parent rel, but keep our AccessShareLock on it until xact
		 * commit.	That will prevent someone else from deleting or ALTERing
		 * the parent before the child is committed.
		 */
		heap_close(relation, NoLock);
	}

	/*
	 * If we had no inherited attributes, the result schema is just the
	 * explicitly declared columns.  Otherwise, we need to merge the declared
	 * columns into the inherited schema list.
	 */
	if (inhSchema != NIL)
	{
		foreach(entry, schema)
		{
			ColumnDef  *newdef = lfirst(entry);
			char	   *attributeName = newdef->colname;
			int			exist_attno;

			/*
			 * Does it conflict with some previously inherited column?
			 */
			exist_attno = findAttrByName(attributeName, inhSchema);
			if (exist_attno > 0)
			{
				ColumnDef  *def;

				/*
				 * Yes, try to merge the two column definitions. They must
				 * have the same type and typmod.
				 */
				if (Gp_role == GP_ROLE_EXECUTE)
				{
					ereport(DEBUG1,
					   (errmsg("merging column \"%s\" with inherited definition",
							   attributeName)));
				}
				else
				ereport(NOTICE,
				   (errmsg("merging column \"%s\" with inherited definition",
						   attributeName)));
				def = (ColumnDef *) list_nth(inhSchema, exist_attno - 1);
				if (typenameTypeId(NULL, def->typname) != typenameTypeId(NULL, newdef->typname) ||
					def->typname->typmod != newdef->typname->typmod)
					ereport(ERROR,
							(errcode(ERRCODE_DATATYPE_MISMATCH),
							 errmsg("column \"%s\" has a type conflict",
									attributeName),
							 errdetail("%s versus %s",
									   TypeNameToString(def->typname),
									   TypeNameToString(newdef->typname))));
				/* Mark the column as locally defined */
				def->is_local = true;
				/* Merge of NOT NULL constraints = OR 'em together */
				def->is_not_null |= newdef->is_not_null;
				/* If new def has a default, override previous default */
				if (newdef->raw_default != NULL)
				{
					def->raw_default = newdef->raw_default;
					def->cooked_default = newdef->cooked_default;
				}
			}
			else
			{
				/*
				 * No, attach new column to result schema
				 */
				inhSchema = lappend(inhSchema, newdef);
			}
		}

		schema = inhSchema;

		/*
		 * Check that we haven't exceeded the legal # of columns after merging
		 * in inherited columns.
		 */
		if (list_length(schema) > MaxHeapAttributeNumber)
			ereport(ERROR,
					(errcode(ERRCODE_TOO_MANY_COLUMNS),
					 errmsg("tables can have at most %d columns",
							MaxHeapAttributeNumber)));
	}

	/*
	 * If we found any conflicting parent default values, check to make sure
	 * they were overridden by the child.
	 */
	if (have_bogus_defaults)
	{
		foreach(entry, schema)
		{
			ColumnDef  *def = lfirst(entry);

			if (def->cooked_default == bogus_marker)
				ereport(ERROR,
						(errcode(ERRCODE_INVALID_COLUMN_DEFINITION),
				  errmsg("column \"%s\" inherits conflicting default values",
						 def->colname),
						 errhint("To resolve the conflict, specify a default explicitly.")));
		}
	}

	*supOids = parentOids;
	*supconstr = constraints;
	*supOidCount = parentsWithOids;
	return schema;
}


/*
 * In multiple-inheritance situations, it's possible to inherit
 * the same grandparent constraint through multiple parents.
 * Hence, we want to discard inherited constraints that match as to
 * both name and expression.  Otherwise, gripe if there are conflicting
 * names. Nonconflicting constraints are added back to the CreateStmt->constraints
 */
static bool
add_nonduplicate_cooked_constraint(Constraint *cdef, List *stmtConstraints)
{
	/* Should only see precooked constraints here */
	Assert(cdef->contype == CONSTR_CHECK);
	Assert(cdef->name != NULL);
	Assert(cdef->raw_expr == NULL && cdef->cooked_expr != NULL);

	ListCell 	*listptr;

	foreach(listptr, stmtConstraints)
	{
		Constraint *stmtCdef = (Constraint *) lfirst(listptr);

		/* Constraint in CreateStmt may be raw and maynot be a check constraint */
		if (stmtCdef->cooked_expr == NULL || stmtCdef->contype != CONSTR_CHECK)
			continue;
		if (strcmp(stmtCdef->name, cdef->name) != 0)
			continue;
		if (strcmp(stmtCdef->cooked_expr, cdef->cooked_expr) == 0)
			return false;
	}
	return true;
}


/*
 * Replace varattno values in an expression tree according to the given
 * map array, that is, varattno N is replaced by newattno[N-1].  It is
 * caller's responsibility to ensure that the array is long enough to
 * define values for all user varattnos present in the tree.  System column
 * attnos remain unchanged. For historical reason, we only map varattno of the first
 * range table entry from this method. So, we call the more general
 * change_varattnos_of_a_varno() with varno set to 1
 *
 * Note that the passed node tree is modified in-place!
 */
void
change_varattnos_of_a_node(Node *node, const AttrNumber *newattno)
{
	/* Only attempt re-mapping if re-mapping is necessary (i.e., non-null newattno map) */
	if (newattno)
	{
		change_varattnos_of_a_varno(node, newattno, 1 /* varno is hard-coded to 1 (i.e., only first RTE) */);
	}
}

/*
 * Replace varattno values for a given varno RTE index in an expression
 * tree according to the given map array, that is, varattno N is replaced
 * by newattno[N-1].  It is caller's responsibility to ensure that the array
 * is long enough to define values for all user varattnos present in the tree.
 * System column attnos remain unchanged.
 *
 * Note that the passed node tree is modified in-place!
 */
void
change_varattnos_of_a_varno(Node *node, const AttrNumber *newattno, Index varno)
{
	AttrMapContext attrMapCxt;

	attrMapCxt.newattno = newattno;
	attrMapCxt.varno = varno;

	(void) change_varattnos_varno_walker(node, &attrMapCxt);
}

/*
 * Remaps the varattno of a varattno in a Var node using an attribute map.
 */
static bool
change_varattnos_varno_walker(Node *node, const AttrMapContext *attrMapCxt)
{
	if (node == NULL)
		return false;
	if (IsA(node, Var))
	{
		Var		   *var = (Var *) node;

		if (var->varlevelsup == 0 && (var->varno == attrMapCxt->varno) &&
			var->varattno > 0)
		{
			/*
			 * ??? the following may be a problem when the node is multiply
			 * referenced though stringToNode() doesn't create such a node
			 * currently.
			 */
			Assert(attrMapCxt->newattno[var->varattno - 1] > 0);
			var->varattno = var->varoattno = attrMapCxt->newattno[var->varattno - 1];
		}
		return false;
	}
	return expression_tree_walker(node, change_varattnos_varno_walker,
								  (void *) attrMapCxt);
}

/*
 * Generate a map for change_varattnos_of_a_node from old and new TupleDesc's,
 * matching according to column name. This function returns a NULL pointer (i.e.
 * null map) if no mapping is necessary (i.e., old and new TupleDesc are already
 * aligned).
 */
AttrNumber *
varattnos_map(TupleDesc old, TupleDesc new)
{
	AttrNumber *attmap;
	int			i,
				j;

	bool mapRequired = false;

	attmap = (AttrNumber *) palloc0(sizeof(AttrNumber) * old->natts);
	for (i = 1; i <= old->natts; i++)
	{
		if (old->attrs[i - 1]->attisdropped)
			continue;			/* leave the entry as zero */

		for (j = 1; j <= new->natts; j++)
		{
			if (strcmp(NameStr(old->attrs[i - 1]->attname),
					   NameStr(new->attrs[j - 1]->attname)) == 0)
			{
				attmap[i - 1] = j;

				if (i != j)
				{
					mapRequired = true;
				}
				break;
			}
		}
	}

	if (!mapRequired)
	{
		pfree(attmap);

		/* No mapping required, so return NULL */
		attmap = NULL;
	}

	return attmap;
}

/*
 * Generate a map for change_varattnos_of_a_node from a TupleDesc and a list
 * of ColumnDefs
 */
AttrNumber *
varattnos_map_schema(TupleDesc old, List *schema)
{
	AttrNumber *attmap;
	int			i;

	attmap = (AttrNumber *) palloc0(sizeof(AttrNumber) * old->natts);
	for (i = 1; i <= old->natts; i++)
	{
		if (old->attrs[i - 1]->attisdropped)
			continue;			/* leave the entry as zero */

		attmap[i - 1] = findAttrByName(NameStr(old->attrs[i - 1]->attname),
									   schema);
	}
	return attmap;
}


/*
 * StoreCatalogInheritance
 *		Updates the system catalogs with proper inheritance information.
 *
 * supers is a list of the OIDs of the new relation's direct ancestors.
 */
static void
StoreCatalogInheritance(Oid relationId, List *supers)
{
	Relation	relation;
	int16		seqNumber;
	ListCell   *entry;

	/*
	 * sanity checks
	 */
	AssertArg(OidIsValid(relationId));

	if (supers == NIL)
		return;

	/*
	 * Store INHERITS information in pg_inherits using direct ancestors only.
	 * Also enter dependencies on the direct ancestors, and make sure they are
	 * marked with relhassubclass = true.
	 *
	 * (Once upon a time, both direct and indirect ancestors were found here
	 * and then entered into pg_ipl.  Since that catalog doesn't exist
	 * anymore, there's no need to look for indirect ancestors.)
	 */
	relation = heap_open(InheritsRelationId, RowExclusiveLock);

	seqNumber = 1;
	foreach(entry, supers)
	{
		Oid			parentOid = lfirst_oid(entry);

		StoreCatalogInheritance1(relationId, parentOid, seqNumber, relation,
								 false);
		seqNumber++;
	}

	heap_close(relation, RowExclusiveLock);
}

/*
 * Make catalog entries showing relationId as being an inheritance child
 * of parentOid.  inhRelation is the already-opened pg_inherits catalog.
 */
static void
StoreCatalogInheritance1(Oid relationId, Oid parentOid,
						 int16 seqNumber, Relation inhRelation,
						 bool is_partition)
{
	Datum		datum[Natts_pg_inherits];
	bool		nullarr[Natts_pg_inherits];
	ObjectAddress childobject,
				parentobject;
	HeapTuple	tuple;
	cqContext	cqc;
	cqContext  *pcqCtx;

	Assert(RelationGetRelid(inhRelation) == InheritsRelationId);

	/*
	 * Make the pg_inherits entry
	 */
	datum[0] = ObjectIdGetDatum(relationId);	/* inhrelid */
	datum[1] = ObjectIdGetDatum(parentOid);		/* inhparent */
	datum[2] = Int16GetDatum(seqNumber);		/* inhseqno */

	nullarr[0] = false;
	nullarr[1] = false;
	nullarr[2] = false;

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

	tuple = caql_form_tuple(pcqCtx, datum, nullarr);

	caql_insert(pcqCtx, tuple); /* implicit update of index as well */

	heap_freetuple(tuple);
	caql_endscan(pcqCtx);

	/*
	 * Store a dependency too
	 */
	parentobject.classId = RelationRelationId;
	parentobject.objectId = parentOid;
	parentobject.objectSubId = 0;
	childobject.classId = RelationRelationId;
	childobject.objectId = relationId;
	childobject.objectSubId = 0;

	recordDependencyOn(&childobject, &parentobject,
					   is_partition ? DEPENDENCY_AUTO : DEPENDENCY_NORMAL);

	/*
	 * Mark the parent as having subclasses.
	 */
	setRelhassubclassInRelation(parentOid, true);
}

/*
 * Look for an existing schema entry with the given name.
 *
 * Returns the index (starting with 1) if attribute already exists in schema,
 * 0 if it doesn't.
 */
static int
findAttrByName(const char *attributeName, List *schema)
{
	ListCell   *s;
	int			i = 1;

	foreach(s, schema)
	{
		ColumnDef  *def = lfirst(s);

		if (strcmp(attributeName, def->colname) == 0)
			return i;

		i++;
	}
	return 0;
}

/*
 * Update a relation's pg_class.relhassubclass entry to the given value
 */
static void
setRelhassubclassInRelation(Oid relationId, bool relhassubclass)
{
	Relation	relationRelation;
	HeapTuple	tuple;
	Form_pg_class classtuple;
	cqContext	cqc;
	cqContext  *pcqCtx;

	/*
	 * Fetch a modifiable copy of the tuple, modify it, update pg_class.
	 *
	 * If the tuple already has the right relhassubclass setting, we don't
	 * need to update it, but we still need to issue an SI inval message.
	 */
	relationRelation = heap_open(RelationRelationId, RowExclusiveLock);
	
	pcqCtx = caql_addrel(cqclr(&cqc), relationRelation);

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

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

	if (classtuple->relhassubclass != relhassubclass)
	{
		classtuple->relhassubclass = relhassubclass;
		caql_update_current(pcqCtx, tuple);
		/* and Update indexes (implicit) */

	}
	else
	{
		/* no need to change tuple, but force relcache rebuild anyway */
		CacheInvalidateRelcacheByTuple(tuple);
	}

	heap_freetuple(tuple);
	heap_close(relationRelation, NoLock);
}


/*
 *		renameatt		- changes the name of a attribute in a relation
 *
 *		Attname attribute is changed in attribute catalog.
 *		No record of the previous attname is kept (correct?).
 *
 *		get proper relrelation from relation catalog (if not arg)
 *		scan attribute catalog
 *				for name conflict (within rel)
 *				for original attribute (if not arg)
 *		modify attname in attribute tuple
 *		insert modified attribute in attribute catalog
 *		delete original attribute from attribute catalog
 */
void
renameatt(Oid myrelid,
		  const char *oldattname,
		  const char *newattname,
		  bool recurse,
		  bool recursing)
{
	Relation	targetrelation;
	Relation	attrelation;
	HeapTuple	atttup;
	Form_pg_attribute attform;
	int			attnum;
	List	   *indexoidlist;
	ListCell   *indexoidscan;
	cqContext	cqc;
	cqContext	cqc2;
	cqContext  *pcqCtx;

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

	/*
	 * permissions checking.  this would normally be done in utility.c, but
	 * this particular routine is recursive.
	 *
	 * normally, only the owner of a class can change its schema.
	 */
	if (!pg_class_ownercheck(myrelid, GetUserId()))
		aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_CLASS,
					   RelationGetRelationName(targetrelation));
	if (!allowSystemTableModsDDL && IsSystemRelation(targetrelation))
		ereport(ERROR,
				(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
				 errmsg("permission denied: \"%s\" is a system catalog",
						RelationGetRelationName(targetrelation))));

	if (RelationIsParquet(targetrelation))
		ereport(ERROR,
				(errcode(ERRCODE_CDB_FEATURE_NOT_SUPPORTED),
				 errmsg("Unsupported Rename column command for table type parquet"),
				 errOmitLocation(true)));

	/*
	 * if the 'recurse' flag is set then we are supposed to rename this
	 * attribute in all classes that inherit from 'relname' (as well as in
	 * 'relname').
	 *
	 * any permissions or problems with duplicate attributes will cause the
	 * whole transaction to abort, which is what we want -- all or nothing.
	 */
	if (recurse)
	{
		ListCell   *child;
		List	   *children;

		/* this routine is actually in the planner */
		children = find_all_inheritors(myrelid);

		/*
		 * find_all_inheritors does the recursive search of the inheritance
		 * hierarchy, so all we have to do is process all of the relids in the
		 * list that it returns.
		 */
		foreach(child, children)
		{
			Oid			childrelid = lfirst_oid(child);

			if (childrelid == myrelid)
				continue;
			/* note we need not recurse again */
			renameatt(childrelid, oldattname, newattname, false, true);
		}
	}
	else
	{
		/*
		 * If we are told not to recurse, there had better not be any child
		 * tables; else the rename would put them out of step.
		 */
		if (!recursing &&
			find_inheritance_children(myrelid) != NIL)
			ereport(ERROR,
					(errcode(ERRCODE_INVALID_TABLE_DEFINITION),
					 errmsg("inherited column \"%s\" must be renamed in child tables too",
							oldattname)));
	}

	attrelation = heap_open(AttributeRelationId, RowExclusiveLock);

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

	atttup = caql_getattname(pcqCtx, myrelid, oldattname);
	if (!HeapTupleIsValid(atttup))
		ereport(ERROR,
				(errcode(ERRCODE_UNDEFINED_COLUMN),
				 errmsg("column \"%s\" does not exist",
						oldattname),
				 errOmitLocation(true)));
	attform = (Form_pg_attribute) GETSTRUCT(atttup);

	attnum = attform->attnum;
	if (attnum <= 0)
		ereport(ERROR,
				(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
				 errmsg("cannot rename system column \"%s\"",
						oldattname)));

	/*
	 * if the attribute is inherited, forbid the renaming, unless we are
	 * already inside a recursive rename.
	 */
	if (attform->attinhcount > 0 && !recursing)
		ereport(ERROR,
				(errcode(ERRCODE_INVALID_TABLE_DEFINITION),
				 errmsg("cannot rename inherited column \"%s\"",
						oldattname)));

	/* should not already exist */
	/* this test is deliberately not attisdropped-aware */
	if (caql_getcount(
				caql_addrel(cqclr(&cqc2), attrelation),
				cql("SELECT COUNT(*) FROM pg_attribute "
					" WHERE attrelid = :1 "
					" AND attname = :2 ",
					ObjectIdGetDatum(myrelid),
					PointerGetDatum((char *) newattname))))
	{
		ereport(ERROR,
				(errcode(ERRCODE_DUPLICATE_COLUMN),
				 errmsg("column \"%s\" of relation \"%s\" already exists",
					  newattname, RelationGetRelationName(targetrelation)),
				 errOmitLocation(true)));
	}
	namestrcpy(&(attform->attname), newattname);

	caql_update_current(pcqCtx, atttup); /* implicit update of index as well */

	heap_freetuple(atttup);

	/*
	 * Update column names of indexes that refer to the column being renamed.
	 */
	indexoidlist = RelationGetIndexList(targetrelation);

	foreach(indexoidscan, indexoidlist)
	{
		Oid			indexoid = lfirst_oid(indexoidscan);
		HeapTuple	indextup;
		Form_pg_index indexform;
		int			i;
		cqContext  *pidxCtx;

		/*
		 * Scan through index columns to see if there's any simple index
		 * entries for this attribute.	We ignore expressional entries.
		 */

		pidxCtx = caql_beginscan(
				NULL,
				cql("SELECT * FROM pg_index "
					" WHERE indexrelid = :1 ",
					ObjectIdGetDatum(indexoid)));

		indextup = caql_getnext(pidxCtx);

		if (!HeapTupleIsValid(indextup))
			elog(ERROR, "cache lookup failed for index %u", indexoid);
		indexform = (Form_pg_index) GETSTRUCT(indextup);

		for (i = 0; i < indexform->indnatts; i++)
		{
			if (attnum != indexform->indkey.values[i])
				continue;

			/*
			 * Found one, rename it.
			 */
			pcqCtx = caql_addrel(cqclr(&cqc), attrelation);
			
			atttup = caql_getfirst(
					pcqCtx,
					cql("SELECT * FROM pg_attribute "
						" WHERE attrelid = :1 "
						" AND attnum = :2 "
						" FOR UPDATE ",
						ObjectIdGetDatum(indexoid),
						Int16GetDatum(i + 1)));

			if (!HeapTupleIsValid(atttup))
				continue;		/* should we raise an error? */

			/*
			 * Update the (copied) attribute tuple.
			 */
			namestrcpy(&(((Form_pg_attribute) GETSTRUCT(atttup))->attname),
					   newattname);

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

			heap_freetuple(atttup);
		}

		caql_endscan(pidxCtx);
	}

	list_free(indexoidlist);

	heap_close(attrelation, RowExclusiveLock);

	/*
	 * Update att name in any RI triggers associated with the relation.
	 */
	if (targetrelation->rd_rel->reltriggers > 0)
	{
		/* update tgargs column reference where att is primary key */
		update_ri_trigger_args(RelationGetRelid(targetrelation),
							   oldattname, newattname,
							   false, false);
		/* update tgargs column reference where att is foreign key */
		update_ri_trigger_args(RelationGetRelid(targetrelation),
							   oldattname, newattname,
							   true, false);
	}

	/* MPP-6929, MPP-7600: metadata tracking */
	if ((Gp_role == GP_ROLE_DISPATCH)
		&& MetaTrackValidKindNsp(targetrelation->rd_rel))
		MetaTrackUpdObject(RelationRelationId,
						   RelationGetRelid(targetrelation),
						   GetUserId(),
						   "ALTER", "RENAME COLUMN"
				);


	relation_close(targetrelation, NoLock);		/* close rel but keep lock */
}

/*
 *		renamerel		- change the name of a relation
 *
 *		XXX - When renaming sequences, we don't bother to modify the
 *			  sequence name that is stored within the sequence itself
 *			  (this would cause problems with MVCC). In the future,
 *			  the sequence name should probably be removed from the
 *			  sequence, AFAIK there's no need for it to be there.
 */
void
renamerel(Oid myrelid, const char *newrelname, RenameStmt *stmt)
{
	Relation		pg_class_desc;
	HeapTuple		tuple;
	Oid				typeId;
	Oid				namespaceId;
	char			relkind;
	char			oldrelname[NAMEDATALEN];
	bool			relhastriggers;
	Form_pg_class	form;
	bool __MAYBE_UNUSED	isSystemRelation;
	cqContext		cqc;
	cqContext	   *pcqCtx;

	/* if this is a child table of a partitioning configuration, complain */
	if (stmt && rel_is_child_partition(myrelid) && !stmt->bAllowPartn)
	{
		Oid		 master = rel_partition_get_master(myrelid);
		char	*pretty	= rel_get_part_path_pretty(myrelid,
												   " ALTER PARTITION ",
												   " RENAME PARTITION ");
		ereport(ERROR,
				(errcode(ERRCODE_DEPENDENT_OBJECTS_STILL_EXIST),
				errmsg("cannot rename partition \"%s\" directly",
					   get_rel_name(myrelid)),
				errhint("Table \"%s\" is a child partition of table "
						"\"%s\".  To rename it, use ALTER TABLE \"%s\"%s...",
						get_rel_name(myrelid), get_rel_name(master),
						get_rel_name(master), pretty ? pretty : "" ),
				errOmitLocation(true)));
	}

	pg_class_desc = heap_open(RelationRelationId, RowExclusiveLock);

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

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

	if (!HeapTupleIsValid(tuple))
		ereport(ERROR,
				(errcode(ERRCODE_UNDEFINED_OBJECT),
				 errmsg("relation \"%d\" does not exist", myrelid)));

	form = (Form_pg_class) GETSTRUCT(tuple);
	relkind = form->relkind;
	namespaceId = form->relnamespace;
	relhastriggers = form->reltriggers;
	typeId = form->reltype;
	strncpy(&oldrelname[0], (form->relname).data, NAMEDATALEN);

	isSystemRelation = IsSystemNamespace(namespaceId) ||
					   IsToastNamespace(namespaceId) ||
					   IsAoSegmentNamespace(namespaceId);

	Assert (allowSystemTableModsDDL || !isSystemRelation);

	/*
	 * Find relation's pg_class tuple, and make sure newrelname isn't in use.
	 */
	if (get_relname_relid(newrelname, namespaceId) != InvalidOid)
		ereport(ERROR,
				(errcode(ERRCODE_DUPLICATE_TABLE),
				 errmsg("relation \"%s\" already exists",
						newrelname),
				 errOmitLocation(true)));

	/*
	 * Update pg_class tuple with new relname.  (Scribbling on tuple is OK
	 * because it's a copy...)
	 */
	namestrcpy(&(form->relname), newrelname);

	caql_update_current(pcqCtx, tuple); /* implicit update of index as well */

	heap_freetuple(tuple);
	heap_close(pg_class_desc, NoLock);

	/*
	 * Also rename the associated type, if any.
	 */
	if (relkind != RELKIND_INDEX)
	{
		if (!TypeTupleExists(typeId))
			ereport(WARNING,
					(errcode(ERRCODE_UNDEFINED_OBJECT),
					 errmsg("type \"%s\" does not exist", oldrelname)));
		else
			TypeRename(typeId, newrelname);
	}

	/*
	 * Update rel name in any RI triggers associated with the relation.
	 */
	if (relhastriggers)
	{
		/* update tgargs where relname is primary key */
		update_ri_trigger_args(myrelid,
							   oldrelname,
							   newrelname,
							   false, true);

		/* update tgargs where relname is foreign key */
		update_ri_trigger_args(myrelid,
							   oldrelname,
							   newrelname,
							   true, true);
	}


	/* MPP-3059: recursive rename of partitioned table */
	/* Note: the top-level RENAME has bAllowPartn=FALSE, while the
	 * generated statements from this block set it to TRUE.  That way,
	 * the rename of each partition is allowed, but this block doesn't
	 * get invoked recursively.
	 */
	if (stmt && !rel_is_child_partition(myrelid) && !stmt->bAllowPartn &&
		(Gp_role == GP_ROLE_DISPATCH))
	{
		PartitionNode *pNode;
		pNode = RelationBuildPartitionDescByOid(myrelid, false);

		if (pNode)
		{
			RenameStmt 			   	*renStmt 	 = makeNode(RenameStmt);
			DestReceiver 		   	*dest  		 = None_Receiver;
			List 					*renList 	 = NIL;
			int 					 skipped 	 = 0;
			int 					 renamed 	 = 0;

			renStmt->renameType = OBJECT_TABLE;
			renStmt->subname = NULL;
			renStmt->bAllowPartn = true; /* allow rename of partitions */

			/* rename the children as well */
			renList = atpxRenameList(pNode, oldrelname, newrelname, &skipped);

			/* process children if there are any */
			if (renList)
			{
				ListCell 		*lc;

				foreach(lc, renList)
				{
					ListCell 		*lc2;
					List  			*lpair = lfirst(lc);

					lc2 = list_head(lpair);

					renStmt->relation = (RangeVar *)lfirst(lc2);
					lc2 = lnext(lc2);
					renStmt->newname = (char *)lfirst(lc2);

					ProcessUtility((Node *) renStmt,
								   synthetic_sql,
								   NULL,
								   false, /* not top level */
								   dest,
								   NULL);
					renamed++;
				}

				/* MPP-3542: warn when skip child partitions */
				if (skipped)
				{
					ereport(WARNING,
							(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
							 errmsg("renamed %d partitions, "
									"skipped %d child partitions "
									"due to name truncation",
									renamed, skipped),
							 errOmitLocation(true)));
				}
			}
		}
	}

	/* MPP-6929: metadata tracking */
	if ((Gp_role == GP_ROLE_DISPATCH)
		&&
		/* MPP-7773: don't track objects in system namespace
		 * if modifying system tables (eg during upgrade)
		 */
		( ! ( (PG_CATALOG_NAMESPACE == namespaceId) && (allowSystemTableModsDDL)))
		&& (   MetaTrackValidRelkind(relkind)
			&& METATRACK_VALIDNAMESPACE(namespaceId)
			   && (!(isAnyTempNamespace(namespaceId)))
				))
		MetaTrackUpdObject(RelationRelationId,
						   myrelid,
						   GetUserId(),
						   "ALTER", "RENAME"
				);
}

static bool
TypeTupleExists(Oid typeId)
{
	Relation	pg_type_desc;
	cqContext	cqc;
	bool		bExists;

	pg_type_desc = heap_open(TypeRelationId, AccessShareLock);

	bExists = (0 < 
			   caql_getcount(
					   caql_addrel(cqclr(&cqc), pg_type_desc),
					   cql("SELECT COUNT(*) FROM pg_type "
						   " WHERE oid = :1 ",
						   ObjectIdGetDatum(typeId))));

	heap_close(pg_type_desc, AccessShareLock);

	return (bExists);
}

/*
 * Scan pg_trigger for RI triggers that are on the specified relation
 * (if fk_scan is false) or have it as the tgconstrrel (if fk_scan
 * is true).  Update RI trigger args fields matching oldname to contain
 * newname instead.  If update_relname is true, examine the relname
 * fields; otherwise examine the attname fields.
 */
static void
update_ri_trigger_args(Oid relid,
					   const char *oldname,
					   const char *newname,
					   bool fk_scan,
					   bool update_relname)
{
	cqContext  *pcqCtx;
	HeapTuple	tuple;
	Datum		values[Natts_pg_trigger];
	bool		nulls[Natts_pg_trigger];
	bool		replaces[Natts_pg_trigger];

	if (fk_scan)
	{
		pcqCtx = caql_beginscan(
				NULL,
				cql("SELECT * FROM pg_trigger "
					" WHERE tgconstrrelid = :1 "
					" FOR UPDATE ",
					ObjectIdGetDatum(relid)));
	}
	else
	{
		pcqCtx = caql_beginscan(
				NULL,
				cql("SELECT * FROM pg_trigger "
					" WHERE tgrelid = :1 "
					" FOR UPDATE ",
					ObjectIdGetDatum(relid)));
	}

	while (HeapTupleIsValid(tuple = caql_getnext(pcqCtx)))
	{
		Form_pg_trigger pg_trigger = (Form_pg_trigger) GETSTRUCT(tuple);
		bytea	   *val;
		bytea	   *newtgargs;
		bool		isnull;
		int			tg_type;
		bool		examine_pk;
		bool		changed;
		int			tgnargs;
		int			i;
		int			newlen;
		const char *arga[RI_MAX_ARGUMENTS];
		const char *argp;

		tg_type = RI_FKey_trigger_type(pg_trigger->tgfoid);
		if (tg_type == RI_TRIGGER_NONE)
		{
			/* Not an RI trigger, forget it */
			continue;
		}

		/*
		 * It is an RI trigger, so parse the tgargs bytea.
		 *
		 * NB: we assume the field will never be compressed or moved out of
		 * line; so does trigger.c ...
		 */
		tgnargs = pg_trigger->tgnargs;
		val = DatumGetByteaP(caql_getattr(pcqCtx,
										  Anum_pg_trigger_tgargs,
										  &isnull));
		if (isnull || tgnargs < RI_FIRST_ATTNAME_ARGNO ||
			tgnargs > RI_MAX_ARGUMENTS)
		{
			/* This probably shouldn't happen, but ignore busted triggers */
			continue;
		}
		argp = (const char *) VARDATA(val);
		for (i = 0; i < tgnargs; i++)
		{
			arga[i] = argp;
			argp += strlen(argp) + 1;
		}

		/*
		 * Figure out which item(s) to look at.  If the trigger is primary-key
		 * type and attached to my rel, I should look at the PK fields; if it
		 * is foreign-key type and attached to my rel, I should look at the FK
		 * fields.	But the opposite rule holds when examining triggers found
		 * by tgconstrrel search.
		 */
		examine_pk = (tg_type == RI_TRIGGER_PK) == (!fk_scan);

		changed = false;
		if (update_relname)
		{
			/* Change the relname if needed */
			i = examine_pk ? RI_PK_RELNAME_ARGNO : RI_FK_RELNAME_ARGNO;
			if (strcmp(arga[i], oldname) == 0)
			{
				arga[i] = newname;
				changed = true;
			}
		}
		else
		{
			/* Change attname(s) if needed */
			i = examine_pk ? RI_FIRST_ATTNAME_ARGNO + RI_KEYPAIR_PK_IDX :
				RI_FIRST_ATTNAME_ARGNO + RI_KEYPAIR_FK_IDX;
			for (; i < tgnargs; i += 2)
			{
				if (strcmp(arga[i], oldname) == 0)
				{
					arga[i] = newname;
					changed = true;
				}
			}
		}

		if (!changed)
		{
			/* Don't need to update this tuple */
			continue;
		}

		/*
		 * Construct modified tgargs bytea.
		 */
		newlen = VARHDRSZ;
		for (i = 0; i < tgnargs; i++)
			newlen += strlen(arga[i]) + 1;
		newtgargs = (bytea *) palloc(newlen);
		SET_VARSIZE(newtgargs, newlen);
		newlen = VARHDRSZ;
		for (i = 0; i < tgnargs; i++)
		{
			strcpy(((char *) newtgargs) + newlen, arga[i]);
			newlen += strlen(arga[i]) + 1;
		}

		/*
		 * Build modified tuple.
		 */
		for (i = 0; i < Natts_pg_trigger; i++)
		{
			values[i] = (Datum) 0;
			replaces[i] = false;
			nulls[i] = false;
		}
		values[Anum_pg_trigger_tgargs - 1] = PointerGetDatum(newtgargs);
		replaces[Anum_pg_trigger_tgargs - 1] = true;

		tuple = caql_modify_current(pcqCtx, values, nulls, replaces);

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

		/*
		 * Invalidate trigger's 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...)
		 *
		 * We can skip this for triggers on relid itself, since that relcache
		 * flush will happen anyway due to the table or column rename.	We
		 * just need to catch the far ends of RI relationships.
		 */
		pg_trigger = (Form_pg_trigger) GETSTRUCT(tuple);
		if (pg_trigger->tgrelid != relid)
			CacheInvalidateRelcacheByRelid(pg_trigger->tgrelid);

		/* free up our scratch memory */
		pfree(newtgargs);
		heap_freetuple(tuple);
	}
	
	caql_endscan(pcqCtx);

	/*
	 * Increment cmd counter to make updates visible; this is needed in case
	 * the same tuple has to be updated again by next pass (can happen in case
	 * of a self-referential FK relationship).
	 */
	CommandCounterIncrement();
}

/*
 * Disallow ALTER TABLE (and similar commands) when the current backend has
 * any open reference to the target table besides the one just acquired by
 * the calling command; this implies there's an open cursor or active plan.
 * We need this check because our AccessExclusiveLock doesn't protect us
 * against stomping on our own foot, only other people's feet!
 *
 * For ALTER TABLE, the only case known to cause serious trouble is ALTER
 * COLUMN TYPE, and some changes are obviously pretty benign, so this could
 * possibly be relaxed to only error out for certain types of alterations.
 * But the use-case for allowing any of these things is not obvious, so we
 * won't work hard at it for now.
 *
 * We also reject these commands if there are any pending AFTER trigger events
 * for the rel.  This is certainly necessary for the rewriting variants of
 * ALTER TABLE, because they don't preserve tuple TIDs and so the pending
 * events would try to fetch the wrong tuples.  It might be overly cautious
 * in other cases, but again it seems better to err on the side of paranoia.
 *
 * REINDEX calls this with "rel" referencing the index to be rebuilt; here
 * we are worried about active indexscans on the index.  The trigger-event
 * check can be skipped, since we are doing no damage to the parent table.
 *
 * The statement name (eg, "ALTER TABLE") is passed for use in error messages.
 */
void
CheckTableNotInUse(Relation rel, const char *stmt)
{
	int			expected_refcnt;

	expected_refcnt = rel->rd_isnailed ? 2 : 1;

	/*
	 * XXX For a bitmap index, since vacuum (or vacuum full) is currently done through
	 * reindex_index, the reference count could be 2 (or 3). We set it
	 * here until vacuum is done properly.
	 */
	if (expected_refcnt == 1 &&
		RelationIsBitmapIndex(rel) &&
		(rel->rd_refcnt == 2 || rel->rd_refcnt == 3))
		expected_refcnt = rel->rd_refcnt;

	if (rel->rd_refcnt != expected_refcnt)
		ereport(ERROR,
				(errcode(ERRCODE_OBJECT_IN_USE),
				 /* translator: first %s is a SQL command, eg ALTER TABLE */
				 errmsg("cannot %s \"%s\" because "
						"it is being used by active queries in this session",
						stmt, RelationGetRelationName(rel))));

	if (rel->rd_rel->relkind != RELKIND_INDEX &&
		AfterTriggerPendingOnRel(RelationGetRelid(rel)))
		ereport(ERROR,
				(errcode(ERRCODE_OBJECT_IN_USE),
				 /* translator: first %s is a SQL command, eg ALTER TABLE */
				 errmsg("cannot %s \"%s\" because "
						"it has pending trigger events",
						stmt, RelationGetRelationName(rel))));
}

static
void ATVerifyObject(AlterTableStmt *stmt, Relation rel)
{

	/* Nothing to check for ALTER INDEX */
	if(stmt->relkind == OBJECT_INDEX)
		return;
	

	/* 
	 * Verify the object specified against relstorage in the catalog.
	 * Enforce correct syntax usage. 
	 */
	if (RelationIsForeign(rel) && stmt->relkind != OBJECT_FOREIGNTABLE)
	{
		ereport(ERROR,
				(errcode(ERRCODE_WRONG_OBJECT_TYPE),
				 errmsg("\"%s\" is a foreign table", RelationGetRelationName(rel)),
				 errhint("Use ALTER FOREIGN TABLE instead"),
				 errOmitLocation(true)));
	}
	else if (RelationIsExternal(rel) && stmt->relkind != OBJECT_EXTTABLE)
	{
		ereport(ERROR,
				(errcode(ERRCODE_WRONG_OBJECT_TYPE),
				 errmsg("\"%s\" is an external table", RelationGetRelationName(rel)),
				 errhint("Use ALTER EXTERNAL TABLE instead"),
				 errOmitLocation(true)));
	}
	else if (!RelationIsExternal(rel) && !RelationIsForeign(rel) && stmt->relkind != OBJECT_TABLE)
	{
		ereport(ERROR,
				(errcode(ERRCODE_WRONG_OBJECT_TYPE),
				 errmsg("\"%s\" is a base table", RelationGetRelationName(rel)),
				 errhint("Use ALTER TABLE instead"),
				 errOmitLocation(true)));
	}
	
	/*
	 * Check the ALTER command type is supported for this object
	 */
	if (RelationIsForeign(rel) || RelationIsExternal(rel))
	{
		ListCell *lcmd;
		
		foreach(lcmd, stmt->cmds)
		{
			AlterTableCmd *cmd = (AlterTableCmd *) lfirst(lcmd);

			switch(cmd->subtype)
			{
				/* FOREIGN and EXTERNAL tables doesn't support the following AT */
				case AT_ColumnDefault:		
				case AT_DropNotNull:			
				case AT_SetNotNull:			
				case AT_SetStatistics:		
				case AT_SetStorage:			
				case AT_AddIndex:			
				case AT_ReAddIndex:			
				case AT_AddConstraint:		
				case AT_AddConstraintRecurse:
				case AT_ProcessedConstraint:	
				case AT_DropConstraint:		
				case AT_DropConstraintQuietly:			
				case AT_ClusterOn:			
				case AT_DropCluster:			
				case AT_DropOids:			
				case AT_SetTableSpace:		
				case AT_SetRelOptions:		
				case AT_ResetRelOptions:		
				case AT_EnableTrig:			
				case AT_DisableTrig:			
				case AT_EnableTrigAll:		
				case AT_DisableTrigAll:		
				case AT_EnableTrigUser:		
				case AT_DisableTrigUser:		
				case AT_AddInherit:			
				case AT_DropInherit:			
				case AT_SetDistributedBy:	
				case AT_PartAdd:				
				case AT_PartAlter:			
				case AT_PartCoalesce:		
				case AT_PartDrop:			
				case AT_PartExchange:		
				case AT_PartMerge:			
				case AT_PartModify:			
				case AT_PartRename:			
				case AT_PartSetTemplate:		
				case AT_PartSplit:			
				case AT_PartTruncate:		
				case AT_PartAddInternal:		
					ereport(ERROR,
							(errcode(ERRCODE_INVALID_COLUMN_DEFINITION),
							 errmsg("Unsupported ALTER command for table type %s", 
									 (RelationIsExternal(rel) ? "external" : "foreign")),
							 errOmitLocation(true)));
					break;
				
				case AT_AddColumn: /* check no constraint is added too */
					if(((ColumnDef *) cmd->def)->constraints != NIL ||
					   ((ColumnDef *) cmd->def)->is_not_null ||
					   ((ColumnDef *) cmd->def)->raw_default)
						ereport(ERROR,
								(errcode(ERRCODE_INVALID_COLUMN_DEFINITION),
								 errmsg("Unsupported ALTER command for table type %s. No constraints allowed.", 
										 (RelationIsExternal(rel) ? "external" : "foreign")),
								 errOmitLocation(true)));
					break;
					
				default:
					/* ALTER type supported */
					break;
			}
		}
	}

	/*
	 * Check the ALTER command type is supported for this object
	 */
	/*
	 * Check whether the relation or its sub partition table is parquet table, if yes,
	 * check whether the command is supported
	 */
	List *children = find_all_inheritors(RelationGetRelid(rel));
	ListCell *lc;
	foreach(lc, children)
	{
		Oid relid = lfirst_oid(lc);
		Relation crel;
		if (relid == RelationGetRelid(rel))
			crel = rel;
		else
			crel = heap_open(relid, AccessShareLock);

		if (RelationIsParquet(crel)) {
			ListCell *lcmd;

			foreach(lcmd, stmt->cmds)
			{
				AlterTableCmd *cmd = (AlterTableCmd *) lfirst(lcmd);

				switch (cmd->subtype) {
				/* FOREIGN and EXTERNAL tables doesn't support the following AT */
				case AT_AddColumn:
				case AT_AddColumnRecurse:
				case AT_ColumnDefault:
				case AT_DropNotNull:
				case AT_SetNotNull:
				case AT_SetStorage:
				case AT_DropColumn:
				case AT_DropColumnRecurse:
				case AT_AddIndex:
				case AT_ReAddIndex:
				case AT_AlterColumnType:
				case AT_ClusterOn:
				case AT_DropCluster:
				case AT_DropOids:
				case AT_EnableTrig:
				case AT_DisableTrig:
				case AT_EnableTrigAll:
				case AT_DisableTrigAll:
				case AT_EnableTrigUser:
				case AT_DisableTrigUser:
					ereport(ERROR,
							(errcode(ERRCODE_INVALID_COLUMN_DEFINITION),
									errmsg("Unsupported ALTER command for parquet table \"%s\"",
									NameStr(crel->rd_rel->relname)),
									errOmitLocation(true)));
					break;
				default:
					/* ALTER type supported */
					break;
				}
			}
		}

		/*close sub partition table*/
		if (relid != RelationGetRelid(rel))
			heap_close(crel, AccessShareLock);
	}
	list_free(children);
}

/*
 * Copy the AlteredTableInfo to a serializeable AlterRewriteTableInfo, to dispatch
 * ATRewriteTable work to segments.
 */
static AlterRewriteTableInfo *
prepareAlteredTableInfo(AlteredTableInfo *tab)
{
	AlterRewriteTableInfo  *ar_tab = makeNode(AlterRewriteTableInfo);
	ListCell			   *l;

	ar_tab->relid = tab->relid;
	ar_tab->relkind = tab->relkind;
	ar_tab->oldDesc = tab->oldDesc;
	ar_tab->new_notnull = tab->new_notnull;
	ar_tab->new_dropoids = tab->new_dropoids;
	ar_tab->newTableSpace = tab->newTableSpace;
	ar_tab->exchange_relid = tab->exchange_relid;

	/* Copy constraints */
	foreach (l, tab->constraints)
	{
		NewConstraint	   *con = lfirst(l);
		AlterRewriteNewConstraint	   *ar_con =
					makeNode(AlterRewriteNewConstraint);

		ar_con->name = pstrdup(con->name);
		ar_con->contype = con->contype;
		ar_con->refrelid = con->refrelid;
		ar_con->qual = copyObject(con->qual);

		ar_tab->constraints = lappend(ar_tab->constraints, ar_con);
	}

	/* Copy newvals */
	foreach (l, tab->newvals)
	{
		NewColumnValue	   *ex = lfirst(l);
		AlterRewriteNewColumnValue *ar_ex =
					makeNode(AlterRewriteNewColumnValue);

		ar_ex->attnum = ex->attnum;
		ar_ex->expr = copyObject(ex->expr);

		ar_tab->newvals = lappend(ar_tab->newvals, ar_ex);
	}

	return ar_tab;
}

/*
 * Copy back the AlteredTableInfo from a serializeable AlterRewriteTableInfo.
 */
static AlteredTableInfo *
rebuildAlteredTableInfo(AlterRewriteTableInfo *ar_tab)
{
	AlteredTableInfo	   *tab =
			(AlteredTableInfo *) palloc0(sizeof(AlteredTableInfo));
	ListCell			   *l;

	tab->relid = ar_tab->relid;
	tab->relkind = ar_tab->relkind;
	tab->oldDesc = ar_tab->oldDesc;
	tab->new_notnull = ar_tab->new_notnull;
	tab->new_dropoids = ar_tab->new_dropoids;
	tab->newTableSpace = ar_tab->newTableSpace;
	tab->exchange_relid = ar_tab->exchange_relid;
	tab->scantable_splits = ar_tab->scantable_splits;
	tab->ao_segnos = ar_tab->ao_segnos;

	/* Copy constraints */
	foreach (l, ar_tab->constraints)
	{
		AlterRewriteNewConstraint	   *ar_con = lfirst(l);
		NewConstraint	   *con =
				(NewConstraint *) palloc0(sizeof(NewConstraint));

		con->name = pstrdup(ar_con->name);
		con->contype = ar_con->contype;
		con->refrelid = ar_con->refrelid;
		con->qual = copyObject(ar_con->qual);

		tab->constraints = lappend(tab->constraints, con);
	}

	/* Copy newvals */
	foreach (l, ar_tab->newvals)
	{
		AlterRewriteNewColumnValue *ar_ex = lfirst(l);
		NewColumnValue	   *ex =
				(NewColumnValue *) palloc0(sizeof(NewColumnValue));

		ex->attnum = ar_ex->attnum;
		ex->expr = copyObject(ar_ex->expr);

		tab->newvals = lappend(tab->newvals, ex);
	}

	return tab;
}

/*
 * AlterTable
 *		Execute ALTER TABLE, which can be a list of subcommands
 *
 * ALTER TABLE is performed in three phases:
 *		1. Examine subcommands and perform pre-transformation checking.
 *		2. Update system catalogs.
 *		3. Scan table(s) to check new constraints, and optionally recopy
 *		   the data into new table(s).
 * Phase 3 is not performed unless one or more of the subcommands requires
 * it.	The intention of this design is to allow multiple independent
 * updates of the table schema to be performed with only one pass over the
 * data.
 *
 * ATPrepCmd performs phase 1.	A "work queue" entry is created for
 * each table to be affected (there may be multiple affected tables if the
 * commands traverse a table inheritance hierarchy).  Also we do preliminary
 * validation of the subcommands, including parse transformation of those
 * expressions that need to be evaluated with respect to the old table
 * schema.
 *
 * ATRewriteCatalogs performs phase 2 for each affected table (note that
 * phases 2 and 3 do no explicit recursion, since phase 1 already did it).
 * Certain subcommands need to be performed before others to avoid
 * unnecessary conflicts; for example, DROP COLUMN should come before
 * ADD COLUMN.	Therefore phase 1 divides the subcommands into multiple
 * lists, one for each logical "pass" of phase 2.
 *
 * ATRewriteTables performs phase 3 for those tables that need it.
 *
 * Thanks to the magic of MVCC, an error anywhere along the way rolls back
 * the whole operation; we don't have to do anything special to clean up.
 */
void
AlterTable(Oid relid, AlterTableStmt *stmt)
{
	GpRoleValue oldrole = GP_ROLE_UNDEFINED;

    if(gp_upgrade_mode)
    {
    	oldrole = Gp_role;
    	Gp_role = GP_ROLE_UTILITY;
    }

	if (stmt->relkind == OBJECT_INDEX)
	{
		if (!gp_called_by_pgdump)
			ereport(ERROR,
				(errcode(ERRCODE_CDB_FEATURE_NOT_YET), errmsg("Cannot support alter index statement yet") ));
	}
	else if (stmt->relkind == OBJECT_FOREIGNTABLE)
	{
		if (!gp_called_by_pgdump)
			ereport(ERROR,
				(errcode(ERRCODE_CDB_FEATURE_NOT_YET), errmsg("Cannot support alter foreign table statement yet") ));
	}
	else if (stmt->relkind == OBJECT_EXTTABLE)
	{
		if (!gp_called_by_pgdump)
			ereport(ERROR,
				(errcode(ERRCODE_CDB_FEATURE_NOT_YET), errmsg("Cannot support alter external table statement yet") ));
	}

	/* check if this is an hcatalog table */
#ifdef USE_ASSERT_CHECKING
	Oid oidRel = 
#endif //USE_ASSERT_CHECKING
	RangeVarGetRelid(stmt->relation, false /*failOk*/, false /*allowHcatalog*/);
	Assert(OidIsValid(oidRel));
	Assert(OidIsValid(relid));

	Relation rel;

	/* Caller is required to provide an adequate lock. */
	rel = relation_open(relid, NoLock);
	int			expected_refcnt;

	ATVerifyObject(stmt, rel);
	
	/*
	 * Disallow ALTER TABLE when the current backend has any open reference
	 * to it besides the one we just got (such as an open cursor or active
	 * plan); our AccessExclusiveLock doesn't protect us against stomping on
	 * our own foot, only other people's feet!
	 *
	 * Note: the only case known to cause serious trouble is ALTER COLUMN TYPE,
	 * and some changes are obviously pretty benign, so this could possibly
	 * be relaxed to only error out for certain types of alterations.  But
	 * the use-case for allowing any of these things is not obvious, so we
	 * won't work hard at it for now.
	 */
	expected_refcnt = rel->rd_isnailed ? 2 : 1;
	if (rel->rd_refcnt != expected_refcnt)
		ereport(ERROR,
				(errcode(ERRCODE_OBJECT_IN_USE),
				 errmsg("relation \"%s\" is being used by active queries in this session",
						RelationGetRelationName(rel))));

	if (Gp_role == GP_ROLE_DISPATCH)
	{
		LockRelationOid(RelationRelationId, RowExclusiveLock);
		LockRelationOid(TypeRelationId, RowExclusiveLock);
		LockRelationOid(DependRelationId, RowExclusiveLock);
	}

	ATController(rel,
				 stmt->cmds,
				 interpretInhOption(stmt->relation->inhOpt),
				 &stmt->oidInfoCount,
				 &stmt->oidInfo,
				 &stmt->oidmap);

    if(gp_upgrade_mode)
    	Gp_role = oldrole;
}

/*
 * AlterTableInternal
 *
 * ALTER TABLE with target specified by OID
 *
 * We do not reject if the relation is already open, because it's quite likely
 * that one or more layers of caller have it open.  That means it is unsafe to
 * use this entry point for alterations that could break existing query plans.
 * On the assumption it's not used for such, we don't have to reject pending
 * AFTER triggers, either.
 *
 * It is also unsafe to use this function for any Alter Table subcommand that
 * requires rewriting the table or creating toast tables, because that requires
 * creating relfilenodes outside of a context that understands dispatch.
 * Commands that rewrite the table include: adding or altering columns, changing
 * the tablespace, etc.
 */
void
AlterTableInternal(Oid relid, List *cmds, bool recurse)
{
	ATController(relation_open(relid, AccessExclusiveLock),
				 cmds,
				 recurse,
				 0,
				 NULL,
				 NULL);
}

static void
ATController(Relation rel, List *cmds, bool recurse, 
			 int * oidInfoCount, TableOidInfo ** oidInfo, List **poidmap)
{
	List	   *wqueue = NIL;
	ListCell   *lcmd;
	int			ocount = 0;
	TableOidInfo * oids = NULL;
	bool is_partition = false;
	bool is_data_remote = (RelationIsExternal(rel) || RelationIsForeign(rel));
#ifdef USE_ASSERT_CHECKING
	Oid			relid = RelationGetRelid(rel);
#endif

	/*
	 * In HAWQ, only the master has the catalog information.
	 * So, no need to sync oid to segments.
	 */
	/* cdb_sync_oid_to_segments(); */

	/* Phase 1: preliminary examination of commands, create work queue */
	foreach(lcmd, cmds)
	{
		AlterTableCmd *cmd = (AlterTableCmd *) lfirst(lcmd);

		if (cmd->subtype == AT_PartAddInternal)
			is_partition = true;

		ATPrepCmd(&wqueue, rel, cmd, recurse, false);
	}

	if (is_partition)
		relation_close(rel, AccessExclusiveLock);
	else
		/* Close the relation, but keep lock until commit */
		relation_close(rel, NoLock);

	/* Phase 2: update system catalogs */
	ATRewriteCatalogs(&wqueue);

	if (Gp_role == GP_ROLE_DISPATCH && oidInfoCount != NULL)
	{
		*oidInfoCount = list_length(wqueue);
		*oidInfo = palloc0(sizeof(TableOidInfo)*(*oidInfoCount));
	}

	if (oidInfoCount != NULL)
		ocount = *oidInfoCount;
	if (oidInfo != NULL)
		oids = *oidInfo;

	/*
	 * Build OID map info.
	 *
	 * If we've recursed (i.e., expanded) an ALTER TABLE SET DISTRIBUTED
	 * command from a master table to its children, then we need to extract
	 * the OID map (used to ensure that all segments map old index OIDs to
	 * new index OIDs) for each of the sub commands and put them in the
	 * master command. This is because we only dispatch the command on the
	 * master table to the segments, not each expanded command. We expect
	 * the segments to do the same expansion.
	 */
	if (Gp_role == GP_ROLE_DISPATCH)
	{
		List *umap = NIL; /* the full OID map for all relations */
		ListCell *lc;
		AlterTableCmd *mastercmd = NULL; /* the command which was expanded */

		/* 
		 * Iterate over the work queue looking for SET WITH DISTRIBUTED
		 * statements.
		 */
		foreach(lc, wqueue)
		{
			ListCell *lc2;
			AlteredTableInfo *tab = (AlteredTableInfo *) lfirst(lc);

			/* AT_PASS_MISC is used for SET DISTRIBUTED BY */
			List *subcmds = (List *)tab->subcmds[AT_PASS_MISC];

			foreach(lc2, subcmds)
			{
				AlterTableCmd *cmd = (AlterTableCmd *) lfirst(lc2);

				if (cmd->subtype == AT_SetDistributedBy)
				{
					if (!mastercmd)
					{
						Assert(tab->relid == relid);
						mastercmd = cmd;
					}

					/*
					 * cmd->def stores the data we're sending to the QEs.
					 * The second element is where we stash QE data to drive
					 * the command. The second element of qe_data is our
					 * OID map. See ATExecSetDistributedBy().
					 *
					 * Yes, this is begging to be improved.
					 */
					List *data = (List *)cmd->def;
					List *qe_data = lsecond(data);

					if (qe_data && list_length(qe_data) >= 2)
					{
						List *oidmap = lsecond(qe_data);

						umap = list_concat(umap, oidmap);
					}
				}
			}
		}

		/* Finally, push it all back into the master command */
		if (mastercmd && umap)
		{
			List *qe_data = lsecond((List *)mastercmd->def);

			if (list_length(qe_data) >= 2)
				lsecond(qe_data) = umap;
			else if (list_length(qe_data) == 1)
			{
				qe_data = lappend(qe_data, umap);

				/* 
				 * We've changed the pointer, save it back to the master
				 * definition.
				 */
				lsecond((List *)mastercmd->def) = qe_data;
			}
		}
	}

	/* 
	 * Phase 3: scan/rewrite tables as needed. If the data is in an external
	 * table, no need to rewrite it or to add toast.
	 */
	if (!is_data_remote)
	{
		ATRewriteTables(&wqueue, ocount, oids, poidmap);

		ATAddToastIfNeeded(&wqueue, ocount, oids, poidmap);		
	}

}

/*
 * This is the execution work of the phase 3 of ALTER TABLE.  The piece of
 * information should be dispatched from master.
 */
void
AlterRewriteTable(AlterRewriteTableInfo *ar_tab)
{
	AlteredTableInfo	   *tab;

	Assert(Gp_role == GP_ROLE_EXECUTE);

	tab = rebuildAlteredTableInfo(ar_tab);
	ATRewriteTable(tab, ar_tab->newheap_oid);
}

/*
 * ATPrepCmd
 *
 * Traffic cop for ALTER TABLE Phase 1 operations, including simple
 * recursion and permission checks.
 *
 * Caller must have acquired AccessExclusiveLock on relation already.
 * This lock should be held until commit.
 */
static void
ATPrepCmd(List **wqueue, Relation rel, AlterTableCmd *cmd,
		  bool recurse, bool recursing)
{
	AlteredTableInfo *tab;
	int			pass = 0;

	/* Find or create work queue entry for this table */
	tab = ATGetQueueEntry(wqueue, rel);

	/*
	 * Copy the original subcommand for each table.  This avoids conflicts
	 * when different child tables need to make different parse
	 * transformations (for example, the same column may have different column
	 * numbers in different children).
	 */
	if (recursing)
		cmd = copyObject(cmd);

	/*
	 * Do permissions checking, recursion to child tables if needed, and any
	 * additional phase-1 processing needed.
	 */
	switch (cmd->subtype)
	{
		case AT_AddColumn:		/* ADD COLUMN */
			ATSimplePermissions(rel, false);
			/*
			 * test that this is allowed for partitioning, but only if we aren't
			 * recursing.
			 */
			ATPartitionCheck(cmd->subtype, rel, false, recursing);
			/* Performs own recursion */
			ATPrepAddColumn(rel, recurse, cmd);
			pass = AT_PASS_ADD_COL;
			break;
		case AT_AddColumnRecurse:		/* ADD COLUMN internal */
			ATSimplePermissions(rel, false);
			/* No need to do ATPartitionCheck */
			/* Performs own recursion */
			ATPrepAddColumn(rel, recurse, cmd);
			pass = AT_PASS_ADD_COL;
			break;
		case AT_ColumnDefault:	/* ALTER COLUMN DEFAULT */
			/*
			 * We allow defaults on views so that INSERT into a view can have
			 * default-ish behavior.  This works because the rewriter
			 * substitutes default values into INSERTs before it expands
			 * rules.
			 */
			ATSimplePermissions(rel, true);
			ATPartitionCheck(cmd->subtype, rel, false, recursing);
			ATSimpleRecursion(wqueue, rel, cmd, recurse);
			/* No command-specific prep needed */
			pass = cmd->def ? AT_PASS_ADD_CONSTR : AT_PASS_DROP;
			break;
		case AT_DropNotNull:	/* ALTER COLUMN DROP NOT NULL */
			ATSimplePermissions(rel, false);
			ATPartitionCheck(cmd->subtype, rel, false, recursing);
			ATSimpleRecursion(wqueue, rel, cmd, recurse);
			/* No command-specific prep needed */
			pass = AT_PASS_DROP;
			break;
		case AT_SetNotNull:		/* ALTER COLUMN SET NOT NULL */
			ATSimplePermissions(rel, false);
			ATSimpleRecursion(wqueue, rel, cmd, recurse);
			if (!cmd->part_expanded)
				ATPartitionCheck(cmd->subtype, rel, false, recursing);
			/* No command-specific prep needed */
			pass = AT_PASS_ADD_CONSTR;
			break;
		case AT_SetStatistics:	/* ALTER COLUMN STATISTICS */
			ATSimpleRecursion(wqueue, rel, cmd, recurse);
			/* Performs own permission checks */
			ATPrepSetStatistics(rel, cmd->name, cmd->def);
			pass = AT_PASS_COL_ATTRS;
			break;
		case AT_SetStorage:		/* ALTER COLUMN STORAGE */
			ATSimplePermissions(rel, false);
			ATSimpleRecursion(wqueue, rel, cmd, recurse);
			/* No command-specific prep needed */
			pass = AT_PASS_COL_ATTRS;
			break;
		case AT_DropColumn:		/* DROP COLUMN */
		case AT_DropColumnRecurse:
			ATSimplePermissions(rel, false);
			ATPartitionCheck(cmd->subtype, rel, false, recursing);
			/* Recursion occurs during execution phase */
			/* No command-specific prep needed except saving recurse flag */
			if (recurse)
				cmd->subtype = AT_DropColumnRecurse;
			pass = AT_PASS_DROP;
			break;
		case AT_AddIndex:		/* ADD INDEX */
			ereport(ERROR,
					(errcode(ERRCODE_CDB_FEATURE_NOT_YET),
					 errmsg("ALTER TABLE ... ADD INDEX is not supported")));
			ATSimplePermissions(rel, false);
			/* Any recursion for partitioning is done in ATExecAddIndex() itself */
			/* However, if the index supports a PK or UNIQUE constraint and the
			 * relation is partitioned, we need to assure the constraint is named
			 * in a reasonable way. */
			{
				ConstrType contype = CONSTR_NULL; /* name picker will reject this */
				IndexStmt *topindexstmt = (IndexStmt*)cmd->def;
				Insist(IsA(topindexstmt, IndexStmt));
				if ( topindexstmt->isconstraint )
				{
					if ( !topindexstmt->altconname )
 					{
 						if ( topindexstmt->primary )
							contype = CONSTR_PRIMARY;
						else if ( topindexstmt->unique )
							contype = CONSTR_UNIQUE;
							 						 						
						/* Pick and install a constraint name. */
						topindexstmt->altconname =
							ChooseConstraintNameForPartitionEarly(rel, 
																  contype,
																  (Node*)topindexstmt->indexParams);
					}

					switch ( rel_part_status(RelationGetRelid(rel)) )
					{
						case PART_STATUS_ROOT:
 							break;
 						case PART_STATUS_INTERIOR:
 						case PART_STATUS_LEAF:
							/* Don't do this check for child parts (= internal requests). */
 							if ( ! topindexstmt->is_part_child )
 							{
 								char *what = "UNIQUE";
 								if ( contype == CONSTR_PRIMARY )
 									what = "PRIMARY KEY";
 								ereport(ERROR,
 										(errcode(ERRCODE_WRONG_OBJECT_TYPE),
 										 errmsg("can't place a %s constraint on just part of "
 												"partitioned table \"%s\"", 
 												what,RelationGetRelationName(rel)),
 										 errhint("Constrain the whole table or create a "
 												 "part-wise UNIQUE index instead.")));
 							}
 							break;
 						default:
 							break;
 					}
				}
			}
			pass = AT_PASS_ADD_INDEX;
			break;
		case AT_AddConstraint:	/* ADD CONSTRAINT */
			ATSimplePermissions(rel, false);
			/* (!recurse &&  !recursing) is supposed to detect the ONLY clause.
			 * We allow operations on the root of a partitioning hierarchy, but
			 * not ONLY the root.
			 */
			ATPartitionCheck(cmd->subtype, rel, (!recurse && !recursing), recursing);
			/*
			 * Currently we recurse only for CHECK constraints, never for
			 * foreign-key constraints.  UNIQUE/PKEY constraints won't be seen
			 * here.
			 */
			/* Any recursion for partitioning/inheritance is done in ATExecAddConstraint() itself */
			if (recurse)
				cmd->subtype = AT_AddConstraintRecurse;
			pass = AT_PASS_ADD_CONSTR;
			break;
		case AT_AddConstraintRecurse: /* ADD check CONSTRAINT internal */
			/* Parent/Base CHECK constraints apply to child/part tables here.
			 * No need for ATPartitionCheck
			 */
			ATSimplePermissions(rel, false);
			pass = AT_PASS_ADD_CONSTR;
			break;
		case AT_DropConstraint:	/* DROP CONSTRAINT */
			ATSimplePermissions(rel, false);
			/* (!recurse &&  !recursing) is supposed to detect the ONLY clause.
			 * We allow operations on the root of a partitioning hierarchy, but
			 * not ONLY the root.
			 */
			ATPartitionCheck(cmd->subtype, rel, (!recurse && !recursing), recursing);
			/* Performs own recursion */
			ATPrepDropConstraint(wqueue, rel, recurse, cmd);
			pass = AT_PASS_DROP;
			break;
		case AT_DropConstraintQuietly:	/* DROP CONSTRAINT for child */
			ATSimplePermissions(rel, false);
			ATSimpleRecursion(wqueue, rel, cmd, recurse);
			/* No command-specific prep needed */
			pass = AT_PASS_DROP;
			break;
		case AT_AlterColumnType:		/* ALTER COLUMN TYPE */
			ATSimplePermissions(rel, false);
			ATPartitionCheck(cmd->subtype, rel, false, recursing);
			/* Performs own recursion */
			ATPrepAlterColumnType(wqueue, tab, rel, recurse, recursing, cmd);
			pass = AT_PASS_ALTER_TYPE;
			break;
		case AT_ChangeOwner:	/* ALTER OWNER */
			{
				bool do_recurse = false;

				if (Gp_role == GP_ROLE_DISPATCH)
				{
					ATPartitionCheck(cmd->subtype, rel, false, recursing);
					if (rel_is_partitioned(RelationGetRelid(rel)))
					{
						do_recurse = true;
						/* tell QE to recurse */
						cmd->def = (Node *)makeInteger(1);
					}
				}
				else if (Gp_role == GP_ROLE_EXECUTE)
				{
					if (cmd->def && intVal(cmd->def))
						do_recurse = true;
				}

				if (do_recurse)
					ATSimpleRecursion(wqueue, rel, cmd, recurse);

				pass = AT_PASS_MISC;
			}
			break;
		case AT_ClusterOn:		/* CLUSTER ON */
			ereport(ERROR,
					(errcode(ERRCODE_CDB_FEATURE_NOT_YET),
					 errmsg("ALTER TABLE ... CLUSTER is not supported")));
		case AT_DropCluster:	/* SET WITHOUT CLUSTER */
			ereport(ERROR,
					(errcode(ERRCODE_CDB_FEATURE_NOT_YET),
					 errmsg("ALTER TABLE ... SET WITHOUT CLUSTER is not supported")));
			ATSimplePermissions(rel, false);
			/* These commands never recurse */
			/* No command-specific prep needed */
			pass = AT_PASS_MISC;
			break;
		case AT_DropOids:		/* SET WITHOUT OIDS */
			ATSimplePermissions(rel, false);
			ATPartitionCheck(cmd->subtype, rel, false, recursing);
			/* Performs own recursion */
			if (rel->rd_rel->relhasoids)
			{
				AlterTableCmd *dropCmd = makeNode(AlterTableCmd);

				dropCmd->subtype = AT_DropColumn;
				dropCmd->name = pstrdup("oid");
				dropCmd->behavior = cmd->behavior;
				ATPrepCmd(wqueue, rel, dropCmd, recurse, false);
			}
			pass = AT_PASS_DROP;
			break;
		case AT_SetTableSpace:	/* SET TABLESPACE */
			ereport(ERROR,
					(errcode(ERRCODE_CDB_FEATURE_NOT_YET),
					 errmsg("ALTER TABLE ... SET TABLESPACE is not supported")));
			ATSimplePermissionsRelationOrIndex(rel);
			/* This command never recurses, but the offered relation may be partitioned, 
			 * in which case, we need to act as if the command specified the top-level
			 * list of parts.
			 */
			if (Gp_role == GP_ROLE_DISPATCH && rel_is_partitioned(RelationGetRelid(rel)) )
			{
				PartitionNode *pnode = NULL;
				List *all_oids = NIL;
				
				pnode = get_parts(RelationGetRelid(rel), 
								  0, /**/
								  InvalidOid, /**/
								  false, /**/
								  CurrentMemoryContext,
								  true /*includesubparts*/);
				
				all_oids = lcons_oid(RelationGetRelid(rel), all_partition_relids(pnode));
				
				Assert( cmd->partoids == NIL );
				cmd->partoids = all_oids;
				
				ATPartsPrepSetTableSpace(wqueue, rel, cmd, all_oids);
			}
			else if (Gp_role == GP_ROLE_EXECUTE && cmd->partoids)
			{
				ATPartsPrepSetTableSpace(wqueue, rel, cmd, cmd->partoids);
			}
			else if (Gp_role == GP_ROLE_UTILITY)
			{
				ereport(ERROR,
						(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
 						 errmsg("SET TABLESPACE is not supported in utility mode")));
			}
			else
				ATPrepSetTableSpace(tab, rel, cmd->name);
			pass = AT_PASS_MISC;	/* doesn't actually matter */
			break;
		case AT_SetRelOptions:	/* SET (...) */
		case AT_ResetRelOptions:		/* RESET (...) */
			ATSimplePermissionsRelationOrIndex(rel);
			/* This command never recurses */
			/* No command-specific prep needed */
			pass = AT_PASS_MISC;
			break;
		case AT_SetDistributedBy:	/* SET DISTRIBUTED BY */
			if ( !recursing ) /* MPP-5772, MPP-5784 */
			{
				Oid relid = RelationGetRelid(rel);
				PartStatus ps = rel_part_status(relid);

				if ( recurse ) /* Normal ALTER TABLE */
				{
					switch (ps)
					{
						case PART_STATUS_NONE:
						case PART_STATUS_ROOT:
						case PART_STATUS_LEAF:
							break;

						case PART_STATUS_INTERIOR:
							/*Reject interior branches of partitioned tables.*/
							ereport(ERROR,
									(errcode(ERRCODE_WRONG_OBJECT_TYPE),
									 errmsg("can't set the distribution"
											" policy of \"%s\"",
											RelationGetRelationName(rel)),
									 errhint("Distribution policy may be set"
											 " for an entire partitioned table"
											 " or one of its leaf parts;"
											 " not for an interior branch."
											 ),
									 errOmitLocation(true)));
							break; /* tidy */
					}
				}
				else /* ALTER TABLE ONLY */
				{
					switch (ps)
					{
						case PART_STATUS_NONE:
						case PART_STATUS_LEAF:
							break;

						case PART_STATUS_ROOT:
						case PART_STATUS_INTERIOR:
							ereport(ERROR,
									(errcode(ERRCODE_WRONG_OBJECT_TYPE),
									 errmsg("can't set the distribution policy "
											"of ONLY \"%s\"",
											RelationGetRelationName(rel)),
									 errhint("Distribution policy may be set "
											 "for an entire partitioned table"
											 " or one of its leaf parts."
											 ),
									 errOmitLocation(true)));
							break; /* tidy */
					}
				}

				if ( ps == PART_STATUS_LEAF )
				{
					Oid ptrelid = rel_partition_get_master(relid);
					List *dist_cnames = lsecond((List*)cmd->def);

					/*	might be null if no policy set, e.g. just
					 *  a change of storage options...
					 */
					if (dist_cnames)
					{
						Relation ptrel = heap_open(ptrelid,
												   AccessShareLock);
						Assert(IsA(dist_cnames, List));

						if (! can_implement_dist_on_part(ptrel,
														 dist_cnames) )
							ereport(ERROR,
									(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
									 errmsg("cannot SET DISTRIBUTED BY for %s",
											RelationGetRelationName(rel)),
									 errhint("Leaf distribution policy must be"
											 " random or match that of the"
											 " entire partitioned table."),
									 errOmitLocation(true)
									 ));
						heap_close(ptrel, AccessShareLock);
					}
				}
			}
			ATSimplePermissions(rel, false);
			ATSimpleRecursion(wqueue, rel, cmd, recurse);
			pass = AT_PASS_MISC;
			break;
		case AT_EnableTrig:		/* ENABLE TRIGGER variants */
		case AT_EnableTrigAll:
		case AT_EnableTrigUser:
			ereport(ERROR,
					(errcode(ERRCODE_CDB_FEATURE_NOT_YET),
					 errmsg("ALTER TABLE ... ENABLE TRIGGER is not supported")));
		case AT_DisableTrig:	/* DISABLE TRIGGER variants */
		case AT_DisableTrigAll:
		case AT_DisableTrigUser:
			ereport(ERROR,
					(errcode(ERRCODE_CDB_FEATURE_NOT_YET),
					 errmsg("ALTER TABLE ... DISABLE TRIGGER is not supported")));
			ATSimplePermissions(rel, false);
			ATPartitionCheck(cmd->subtype, rel, false, recursing);
			/* These commands never recurse */
			/* No command-specific prep needed */
			pass = AT_PASS_MISC;
			break;
		case AT_AddInherit:		/* INHERIT / NO INHERIT */
		case AT_DropInherit:
			ATSimplePermissions(rel, false);
			ATPartitionCheck(cmd->subtype, rel, true, recursing);
			/* These commands never recurse */
			/* No command-specific prep needed */
			pass = AT_PASS_MISC;
			break;
			/* CDB: Partitioned Table commands */
		case AT_PartExchange:			/* Exchange */
			ATPartitionCheck(cmd->subtype, rel, false, recursing);
			
			if (Gp_role == GP_ROLE_UTILITY)
				ereport(ERROR,
						(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
 						 errmsg("EXCHANGE is not supported in utility mode")));
			
			pass = AT_PASS_MISC;
			
			ATPrepExchange(rel, (AlterPartitionCmd *)cmd->def);
			
			break;
		case AT_PartMerge:
			ereport(ERROR,
					(errcode(ERRCODE_CDB_FEATURE_NOT_YET),
					 errmsg("ALTER TABLE ... MERGE PARTITION is not supported")));
		{
			AlterPartitionCmd  *pc    	= (AlterPartitionCmd *) cmd->def;
			PgPartRule   	   *prule1	= NULL;
			PgPartRule		   *prule2	= NULL;
			PgPartRule		   *prule3	= NULL;
			ListCell		   *lc;
			List			   *source_rels = NIL;
			Relation			target = NULL;

			ATPartitionCheck(cmd->subtype, rel, false, recursing);

			if (Gp_role == GP_ROLE_UTILITY)
				ereport(ERROR,
						(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
 						 errmsg("MERGE is not supported in utility mode")));
			else if (Gp_role == GP_ROLE_DISPATCH)
			{
				Relation srel;
				AlterPartitionId *pid = (AlterPartitionId *) pc->partid;

				prule1 = get_part_rule(rel, pid, true, true,
									   CurrentMemoryContext, NULL, false);

				prule2 = get_part_rule(rel, (AlterPartitionId *)pc->arg1,
									   true, true,
									   CurrentMemoryContext, NULL, false);

				if (pc->arg2)
				{
					AlterPartitionCmd *pc2 = (AlterPartitionCmd *)pc->arg2;

					prule3 = get_part_rule(rel,
										   (AlterPartitionId *)pc2->partid,
										   true, true,
										   CurrentMemoryContext, NULL, false);
				}

				if (prule1)
				{
					/* cannot exchange a hash partition */
					if ('h' == prule1->pNode->part->parkind)
						ereport(ERROR,
							(errcode(ERRCODE_DEPENDENT_OBJECTS_STILL_EXIST),
								 errmsg("cannot merge HASH partition%s "
									    "of relation \"%s\"",
										prule1->partIdStr,
										RelationGetRelationName(rel))));
				}

				srel = heap_open(prule1->topRule->parchildrelid,
								 AccessExclusiveLock);
				source_rels = lappend(source_rels, srel);

				srel = heap_open(prule2->topRule->parchildrelid,
								 AccessExclusiveLock);
				if (prule3)
				{
					source_rels = lappend(source_rels, srel);
					target = heap_open(prule3->topRule->parchildrelid,
									   AccessExclusiveLock);
				}
				else
					target = srel;
			}
			else
			{
				Relation srel;
				srel = heap_openrv((RangeVar *)pc->partid,
								   AccessExclusiveLock);
				source_rels = lappend(source_rels, srel);

				srel = heap_openrv((RangeVar *)pc->arg1, AccessExclusiveLock);

				if (pc->arg2)
				{
					source_rels = lappend(source_rels, srel);
					target = heap_openrv((RangeVar *)pc->arg2,
										 AccessExclusiveLock);
				}
				else
					target = heap_openrv((RangeVar *)pc->arg1,
										 AccessExclusiveLock);
			}

			ATSimplePermissions(rel, false);

			foreach(lc, source_rels)
				ATSimplePermissions(lfirst(lc), false);

			ATSimplePermissions(target, false);

			foreach(lc, source_rels)
				heap_close(lfirst(lc), NoLock);

			heap_close(target, NoLock);

			pass = AT_PASS_MISC;
			break;
		}

		case AT_PartSplit:				/* Split */
		{
			AlterPartitionCmd	*pc    	= (AlterPartitionCmd *) cmd->def;

			ATPartitionCheck(cmd->subtype, rel, false, recursing);

			if (Gp_role == GP_ROLE_UTILITY)
				ereport(ERROR,
						(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
 						 errmsg("SPLIT is not supported in utility mode")));
			else if (Gp_role == GP_ROLE_DISPATCH)
			{
				PgPartRule			*prule1	= NULL;
				PgPartRule			*prule2	= NULL;
				PgPartRule			*prule3	= NULL;
				PgPartRule			*prule_specified	= NULL;
				Relation			 target = NULL;
				
				AlterPartitionId *pid = (AlterPartitionId *) pc->partid;
				AlterPartitionCmd *cmd2;
				Node *at;
				bool is_at = true;
				List *todo;
				ListCell *l;
				bool rollup_vals = false;

				/*
				 * Need to do a bunch of validation:
				 * 0) Target exists
				 * 0.5) Shouldn't have children
				 * 1) The usual permissions checks
				 * 2) Not called on HASH
				 * 3) AT () parameter falls into constraint specified
				 * 4) INTO partitions don't exist except for the one being split
				 */

				/* We'll error out if it doesn't exist */
				prule1 = get_part_rule(rel, pid, true, true,
									   CurrentMemoryContext, NULL, false);

				if (prule1->topRule->children)
					ereport(ERROR,
							(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
							 errmsg("cannot split partition with child "
									"partitions"),
							 errhint("Try splitting the child partitions."),
							 errOmitLocation(true)));

				target = heap_open(prule1->topRule->parchildrelid,
								   AccessExclusiveLock);

				if (linitial((List *)pc->arg1))
					is_at = false;

				if (prule1->topRule->parisdefault &&
					prule1->pNode->part->parkind == 'r' &&
					is_at)
				{
					ereport(ERROR,
							(errcode(ERRCODE_SYNTAX_ERROR),
							 errmsg("AT clause cannot be used when splitting "
									"a default RANGE partition"),
							 errOmitLocation(true)));
				}
				else if (prule1->pNode->part->parkind == 'l' && !is_at)
				{
					ereport(ERROR,
							(errcode(ERRCODE_SYNTAX_ERROR),
							 errmsg("cannot SPLIT DEFAULT PARTITION "
									"with LIST"),
							errhint("Use SPLIT with the AT clause instead."),
							errOmitLocation(true)));

				}

				if (prule1->pNode->part->parkind == 'h')
					ereport(ERROR,
							(errcode(ERRCODE_WRONG_OBJECT_TYPE),
							 errmsg("SPLIT is not supported for "
									"HASH partitions"),
							 errOmitLocation(true)));

				if (linitial((List *)pc->arg1))
					is_at = false;

				todo = (List *)pc->arg1;

				pc->arg1 = (Node *)NIL;
				foreach(l, todo)
				{
					List *l1 = NIL;
					ListCell *lc;
					Node *t = lfirst(l);

					if (!t)
					{
						pc->arg1 = (Node *)lappend((List *)pc->arg1, NULL);
						continue;
					}
					else if (is_at)
						l1 = (List *)t;
					else if (!is_at)
					{
						Node *n = t;
						PartitionRangeItem *ri = (PartitionRangeItem *)n;

						Assert(IsA(n, PartitionRangeItem));

						l1 = ri->partRangeVal;
					}

					if (IsA(linitial(l1), A_Const) ||
						IsA(linitial(l1), TypeCast) ||
						IsA(linitial(l1), FuncExpr) ||
						IsA(linitial(l1), OpExpr))
					{
						List *new = NIL;
						ListCell *lc;

						foreach(lc, l1)
							new = lappend(new, list_make1(lfirst(lc)));

						l1 = new;
						rollup_vals = true;
					}
					else
						Insist(IsA(linitial(l1), List));

					foreach(lc, l1)
					{
						List *vals = lfirst(lc);
						ListCell *lc2;
						int i = 0;
						ParseState *pstate = make_parsestate(NULL);

						if (prule1->pNode->part->parnatts != list_length(vals))
						{
							AttrNumber parnatts = prule1->pNode->part->parnatts;
							ereport(ERROR,
									(errcode(ERRCODE_SYNTAX_ERROR),
									 errmsg("partition being split has "
											"%i column%s but parameter "
											"has %i column%s",
											parnatts,
											parnatts > 1 ? "s" : "",
											list_length(vals),
										   list_length(vals) > 1 ? "s" : ""),
									  errOmitLocation(true)));
						}

						vals = (List *)transformExpressionList(pstate, vals);

						free_parsestate(&pstate);

						foreach(lc2, vals)
						{
							Node *n = lfirst(lc2);
							AttrNumber attnum =
									prule1->pNode->part->paratts[i];
							Oid typid =
									rel->rd_att->attrs[attnum - 1]->atttypid;
							int32 typmod =
									rel->rd_att->attrs[attnum - 1]->atttypmod;
							char parkind = prule1->pNode->part->parkind;
							PartitionByType t = (parkind == 'r') ?
												 PARTTYP_RANGE : PARTTYP_LIST;

							n = coerce_partition_value(n, typid, typmod, t);

							lfirst(lc2) = n;

							i++;
						}
						lfirst(lc) = vals;
					}

					if (rollup_vals)
					{
						/* now, unroll */
						if (prule1->pNode->part->parkind == 'r')
						{
							List *new = NIL;
							ListCell *lc;
							Node *n;

							foreach(lc, l1)
								new = lappend(new, linitial(lfirst(lc)));

							if (is_at)
								n = (Node *)new;
							else
							{
								PartitionRangeItem *ri = lfirst(l);

								ri->partRangeVal = new;
								n = (Node *)ri;
							}
							pc->arg1 = (Node *)lappend((List *)pc->arg1, n);
						}
						else
						{
							/* for LIST, leave it as is */
							pc->arg1 = (Node *)lappend((List *)pc->arg1,
														l1);
						}
					}
					else
						pc->arg1 = (Node *)lappend((List *)pc->arg1, l1);
				}

				at = lsecond((List *)pc->arg1);
				if (prule1->pNode->part->parkind == 'l')
				{

					if (prule1->topRule->parisdefault)
					{
						/*
						 * Check that AT() value doesn't exist in any existing
						 * definition.
						 */

					}
					else
					{
						/* all elements in AT() must match */
						ListCell *lcat;
						List *lv = (List *)prule1->topRule->parlistvalues;
						int16 nkeys = prule1->pNode->part->parnatts;
						List *atlist = (List *)at;
						int nmatches = 0;

						foreach(lcat, atlist)
						{
							List *cols = lfirst(lcat);
							ListCell *parvals = list_head(lv);
							bool found = false;

							Assert(list_length(cols) == nkeys);

							while (parvals)
							{
								List *vals = lfirst(parvals);
								ListCell *lcv = list_head(vals);
								ListCell *lcc = list_head(cols);
								int parcol;
								bool matched = true;

								for (parcol = 0; parcol < nkeys; parcol++)
								{
									Oid opclass =
										prule1->pNode->part->parclass[parcol];
									Oid funcid = get_opclass_proc(opclass, 0,
																 BTORDER_PROC);
									Const *v = lfirst(lcv);
									Const *c = lfirst(lcc);
									Datum d;

									if (v->constisnull && c->constisnull)
										continue;
									else if (v->constisnull || c->constisnull)
									{
										matched = false;
										break;
									}

									d = OidFunctionCall2(funcid, c->constvalue,
														 v->constvalue);

									if (DatumGetInt32(d) != 0)
									{
										matched = false;
										break;
									}

									lcv = lnext(lcv);
									lcc = lnext(lcc);
								}

								if (!matched)
								{
									parvals = lnext(parvals);
									continue;
								}
								else
								{
									found = true;
									nmatches++;
									break;
								}
							}
							if (!found)
								ereport(ERROR,
										(errcode(ERRCODE_WRONG_OBJECT_TYPE),
										errmsg("AT clause parameter is not "
											   "a member of the target "
											   "partition specification"),
										errOmitLocation(true)));


						}

						if (nmatches >= list_length(lv))
							ereport(ERROR,
									(errcode(ERRCODE_SYNTAX_ERROR),
									 errmsg("AT clause cannot contain all "
											"values in partition%s",
											prule1->partIdStr),
									 errOmitLocation(true)));

					}
				}
				else
				{
					/* XXX: handle split of default */
					if (prule1->topRule->parisdefault)
					{
					}
					else
					{
						/* at must be in range */
						Const	*start	  = NULL;
						Const	*end	  = NULL;
						Const	*atval	  = NULL;
						Oid		 opclass  = prule1->pNode->part->parclass[0];
						Oid		 funcid	  = get_opclass_proc(opclass, 0,
															 BTORDER_PROC);
						Node	*n;
						Datum	 res;
						int32	 ret;
						bool	 in_range = true;

						n = (Node *)linitial((List *)at);

						Assert(IsA(n, Const));

						atval = (Const *)n;

						/* XXX: ignore composite key range for now */
						if (prule1->topRule->parrangestart)
							start = linitial((List *)prule1->topRule->parrangestart);

						/* MPP-6589: allow "open" start or end */
						if (start)
						{
							Insist(exprType((Node *)n) == exprType((Node *)start));
							res = OidFunctionCall2(funcid, start->constvalue,
												   atval->constvalue);

							ret = DatumGetInt32(res);
						}
						else
						{
							/* MPP-6589: no start - check end */
							Assert(prule1->topRule->parrangeend);
							ret = -1;
						}

						if (ret > 0)
							in_range = false;
						else if (ret == 0)
						{
							if (!prule1->topRule->parrangestartincl)
								in_range = false;
						}
						else
						{
							/* in the range, test end */
							if (prule1->topRule->parrangeend)
							{
								end = linitial((List *)prule1->topRule->parrangeend);
								res = OidFunctionCall2(funcid,
													   atval->constvalue,
											   		   end->constvalue);

								ret = DatumGetInt32(res);

								if (ret > 0)
									in_range = false;
								else if (ret == 0)
									if (!prule1->topRule->parrangeendincl)
										in_range = false;
							}
							/* if no end, remains "in range" */
						}

						if (!in_range)
						{
							ereport(ERROR,
									(errcode(ERRCODE_WRONG_OBJECT_TYPE),
									errmsg("AT clause parameter is not "
										   "a member of the target "
										   "partition specification"),
									errOmitLocation(true)));
						}
					}
				}

				/*
				 * pc->partid == target
				 * pc->arg1 == AT
				 * pc->arg2 == AlterPartitionCmd (partid == 1, arg1 = 2)
				 */
				if (PointerIsValid(pc->arg2))
				{
					cmd2 = (AlterPartitionCmd *)pc->arg2;

					prule2 = get_part_rule(rel,
										   (AlterPartitionId *)cmd2->partid,
										   false, false, CurrentMemoryContext,
										   NULL, false);

					prule3 = get_part_rule(rel, (AlterPartitionId *)cmd2->arg1,
										   false, false, CurrentMemoryContext,
										   NULL, false);
					/* both can't exist */
					if (prule2 && prule3)
					{
						ereport(ERROR,
								(errcode(ERRCODE_DUPLICATE_OBJECT),
								 errmsg("both INTO partitions "
										"already exist"),
								 errOmitLocation(true)));
					}
					else if (prule1->topRule->parisdefault &&
							 !prule2 && !prule3)
					{
						ereport(ERROR,
								(errcode(ERRCODE_SYNTAX_ERROR),
								 errmsg("default partition name missing "
										"from INTO clause"),
								 errOmitLocation(true)));

					}
				}
				
				/* MPP-18395 begs for a last minute check that we aren't about to
				 * split into an existing partition.  The case that prompts the check
				 * has to do with specifying an existing partition by name, but it
				 * may (someday) be possible to specify one by rank or constraint,
				 * so lets just refuse to use an existing partition that isn't the
				 * one we're splitting.  (We're going to drop this one, so it's okay
				 * recycle it.)
				 *
				 * Examples: 
				 *    t is target part to split, 
				 *    n, m are new parts,
				 *    x, y are existing parts != t
				 *
				 * t -> t, n -- ok
				 * t -> n, t -- ok
				 * t -> n, m -- ok
				 * t -> n, x -- no
				 * t -> x, n -- no
				 * t -> x, y -- no (unexpected)
				 *
				 * By the way, at this point
				 *   prule1 refers to the part to split
				 *   prule2 refers to the first INTO part
				 *   prule3 refers to the seconde INTO part
				 */
				Insist( prule2 == NULL || prule3 == NULL );
				
				if ( prule2 != NULL )
				    prule_specified = prule2;
				else if ( prule3 != NULL )
					prule_specified = prule3;
				else
					prule_specified = NULL;
					
				if ( prule_specified &&
					 prule_specified->topRule->parruleid != prule1->topRule->parruleid 
					 )
				{
					ereport(ERROR,
							(errcode(ERRCODE_DUPLICATE_OBJECT),
							 errmsg("cannot split into an existing partition"),
							 errOmitLocation(true)));
				}
				
				ATSimplePermissions(target, false);
				heap_close(target, NoLock);
			}
			else
			{
				Insist(IsA(pc->partid, Integer));
				Insist(IsA(pc->arg1, RangeVar));
				Insist(IsA(pc->arg2, RangeVar));
			}
			pass = AT_PASS_MISC;
			break;
		}

		case AT_PartAlter:				/* Alter */
			if ( Gp_role == GP_ROLE_DISPATCH && recurse && ! recursing )
			{
				AlterTableCmd *basecmd = basic_AT_cmd(cmd);
				
				switch ( basecmd->subtype )
				{
					case AT_SetTableSpace:
						cmd->partoids = basic_AT_oids(rel,cmd);
						ATPartsPrepSetTableSpace(wqueue, rel, basecmd, cmd->partoids);
						break;
					
					default:
						/* Not a for-each-subsumed-part-type command. */
						break;
				}
			}
			else if (Gp_role == GP_ROLE_EXECUTE && cmd->partoids)
			{
				AlterTableCmd *basecmd = basic_AT_cmd(cmd);

				switch ( basecmd->subtype )
				{
					case AT_SetTableSpace:
						ATPartsPrepSetTableSpace(wqueue, rel, basecmd, cmd->partoids);
						break;
						
					default:
						/* Not a for-each-subsumed-part-type command. */
						break;
				}
			}
			else if (Gp_role == GP_ROLE_UTILITY)
			{
				if (basic_AT_cmd(cmd)->subtype == AT_SetTableSpace)
					ereport(ERROR,
							(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
							 errmsg("SET TABLESPACE is not supported in utility mode")));
			}
			pass = AT_PASS_MISC;
			break;				

		case AT_PartSetTemplate:		/* Set Subpartition Template */
			if (!gp_allow_non_uniform_partitioning_ddl)
			{
				ereport(ERROR,
					   (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
						errmsg("Cannot modify subpartition template for partitioned table")));
			}
		case AT_PartAdd:				/* Add */
		case AT_PartCoalesce:			/* Coalesce */
		case AT_PartDrop:				/* Drop */
		case AT_PartRename:				/* Rename */

		case AT_PartTruncate:			/* Truncate */
		case AT_PartAddInternal:		/* internal partition creation */
			ATSimplePermissions(rel, false);
			ATPartitionCheck(cmd->subtype, rel, false, recursing);
				/* XXX XXX XXX */
			/* This command never recurses */
			/* No command-specific prep needed */
			/* XXX: check permissions */
			pass = AT_PASS_MISC;
			break;

		case AT_PartModify:             /* Modify */
			ereport(ERROR,
					(errcode(ERRCODE_CDB_FEATURE_NOT_YET),
					 errmsg("ALTER TABLE ... MODIFY PARTITION is not supported")));
			break;

		default:				/* oops */
			elog(ERROR, "unrecognized alter table type: %d",
				 (int) cmd->subtype);
			pass = 0;			/* keep compiler quiet */
			break;
	}

	/* Add the subcommand to the appropriate list for phase 2 */
	tab->subcmds[pass] = lappend(tab->subcmds[pass], cmd);
}

/*
 * ATRewriteCatalogs
 *
 * Traffic cop for ALTER TABLE Phase 2 operations.	Subcommands are
 * dispatched in a "safe" execution order (designed to avoid unnecessary
 * conflicts).
 */
static void
ATRewriteCatalogs(List **wqueue)
{
	int			pass;
	ListCell   *ltab;

	/*
	 * We process all the tables "in parallel", one pass at a time.  This is
	 * needed because we may have to propagate work from one table to another
	 * (specifically, ALTER TYPE on a foreign key's PK has to dispatch the
	 * re-adding of the foreign key constraint to the other table).  Work can
	 * only be propagated into later passes, however.
	 */
	for (pass = 0; pass < AT_NUM_PASSES; pass++)
	{
		/* Go through each table that needs to be processed */
		foreach(ltab, *wqueue)
		{
			AlteredTableInfo *tab = (AlteredTableInfo *) lfirst(ltab);
			List	   *subcmds = tab->subcmds[pass];
			Relation	rel;
			ListCell   *lcmd;

			if (subcmds == NIL)
				continue;

			/*
			 * Exclusive lock was obtained by phase 1, needn't get it again
			 */
			rel = relation_open(tab->relid, NoLock);

			foreach(lcmd, subcmds)
			{
				AlterTableCmd *atc = lfirst(lcmd);

				ATExecCmd(wqueue, tab, rel, atc);

				/*
				 * SET DISTRIBUTED BY() calls RelationForgetRelation(),
				 * which will scribble on rel, so we must re-open it.
				 */
				if (atc->subtype == AT_SetDistributedBy)
					rel = relation_open(tab->relid, NoLock);
			}
			/*
			 * After the ALTER TYPE pass, do cleanup work (this is not done in
			 * ATExecAlterColumnType since it should be done only once if
			 * multiple columns of a table are altered).
			 */
			if (pass == AT_PASS_ALTER_TYPE)
				ATPostAlterTypeCleanup(wqueue, tab);

			relation_close(rel, NoLock);
		}
	}

}

static void
ATAddToastIfNeeded(List **wqueue, 
				   int oidInfoCount, TableOidInfo * oidInfo, List **poidmap)
{

	ListCell   *ltab;
	int			m = 0;
	
	/*
	 * Check to see if a toast table must be added, if we executed any
	 * subcommands that might have added a column or changed column storage.
	 */
	foreach(ltab, *wqueue)
	{
		Oid tOid = InvalidOid;
		Oid tiOid = InvalidOid;
		Oid	*toastComptypeOid = NULL;
		AlteredTableInfo *tab = (AlteredTableInfo *) lfirst(ltab);
		bool is_part = !rel_needs_long_lock(tab->relid);

		if (tab->relkind == RELKIND_RELATION &&
			(tab->subcmds[AT_PASS_ADD_COL] ||
			 tab->subcmds[AT_PASS_ALTER_TYPE] ||
			 tab->subcmds[AT_PASS_COL_ATTRS]))
		{
			Relation rel;
			Oid reltablespace;

			/*
			 * For upgrade, don't create a toast table.
			 */
			if (gp_upgrade_mode)
				continue;

			/* 
			 * Determine if we need to create a toast table.
			 */
			rel = heap_open(tab->relid, NoLock);
			if (rel->rd_rel->reltoastrelid != InvalidOid)
			{  /* Already have one */
				heap_close(rel, NoLock);
				continue;
			}
			if (!RelationNeedsToastTable(rel))
			{  /* Don't need one */
				heap_close(rel, NoLock);
				continue;
			}
			reltablespace = rel->rd_rel->reltablespace;
			heap_close(rel, NoLock);
			
			/* 
			 * We do not currently have a toast table, but we need one.  If we
			 * have not already allocated oids in the oidinfo then we need to do
			 * so now.
			 */
			if (Gp_role == GP_ROLE_DISPATCH)
			{
				Relation	pg_class_desc = NULL;
				Relation    pg_type_desc = NULL;

				Assert(oidInfo);
				Assert(m < oidInfoCount);

				if (oidInfo[m].toastOid == InvalidOid)
				{
					pg_class_desc = heap_open(RelationRelationId, RowExclusiveLock);
					oidInfo[m].toastOid = GetNewRelFileNode(reltablespace, false, pg_class_desc, false);
				}
				if (oidInfo[m].toastIndexOid == InvalidOid)
				{
					if (!pg_class_desc)
						pg_class_desc = heap_open(RelationRelationId, RowExclusiveLock);
					oidInfo[m].toastIndexOid = GetNewRelFileNode(reltablespace, false, pg_class_desc, false);
				}
				if (oidInfo[m].toastComptypeOid == InvalidOid)
				{
					pg_type_desc = heap_open(RelationRelationId, RowExclusiveLock);
					oidInfo[m].toastIndexOid = GetNewRelFileNode(reltablespace, false, pg_type_desc, false);
				}
				if (pg_class_desc)
					heap_close(pg_class_desc, NoLock);
				if (pg_type_desc)
					heap_close(pg_type_desc, NoLock);
			}

			/*
			 * Normal dispatch/execute mode will always have an oidInfo, but if
			 * we are in utility mode or bootstrap then we might not.  In this
			 * event we fall back to the InvalidOid as initialized above.
			 */
			if (oidInfo != NULL)
			{
				Assert(m < oidInfoCount);
				tOid = oidInfo[m].toastOid;
				tiOid = oidInfo[m].toastIndexOid;
				toastComptypeOid = &oidInfo[m].toastComptypeOid;
			}

			/* Finally create the toast table */
			elog(DEBUG2,"Create Toast %d with Oid %u", m, tOid);
			AlterTableCreateToastTableWithOid(tab->relid, tOid, tiOid, 
											  toastComptypeOid, is_part);
			m++;

		}
	}
}

/*
 * ATExecCmd: dispatch a subcommand to appropriate execution routine
 */
static void
ATExecCmd(List **wqueue, AlteredTableInfo *tab, Relation rel, AlterTableCmd *cmd)
{
	switch (cmd->subtype)
	{
		case AT_AddColumn:		/* ADD COLUMN */
		case AT_AddColumnRecurse:
			ATExecAddColumn(tab, rel, (ColumnDef *) cmd->def);
			break;
		case AT_ColumnDefault:	/* ALTER COLUMN DEFAULT */
			ATExecColumnDefault(rel, cmd->name, cmd->def);
			break;
		case AT_DropNotNull:	/* ALTER COLUMN DROP NOT NULL */
			ATExecDropNotNull(rel, cmd->name);
			break;
		case AT_SetNotNull:		/* ALTER COLUMN SET NOT NULL */
			ATExecSetNotNull(tab, rel, cmd->name);
			break;
		case AT_SetStatistics:	/* ALTER COLUMN STATISTICS */
			ATExecSetStatistics(rel, cmd->name, cmd->def);
			break;
		case AT_SetStorage:		/* ALTER COLUMN STORAGE */
			ATExecSetStorage(rel, cmd->name, cmd->def);
			break;
		case AT_DropColumn:		/* DROP COLUMN */
			ATExecDropColumn(wqueue, rel, cmd->name, cmd->behavior, false, false);
			break;
		case AT_DropColumnRecurse:		/* DROP COLUMN with recursion */
			ATExecDropColumn(wqueue, rel, cmd->name, cmd->behavior, true, false);
			break;
		case AT_AddIndex:		/* ADD INDEX */
			ATExecAddIndex(tab, rel, (IndexStmt *) cmd->def, false,
						   cmd->part_expanded);
			break;
		case AT_ReAddIndex:		/* ADD INDEX */
			ATExecAddIndex(tab, rel, (IndexStmt *) cmd->def, true,
						   cmd->part_expanded);
			break;
		case AT_AddConstraint:	/* ADD CONSTRAINT */
			ATExecAddConstraint(tab, rel, cmd->def, false);
			break;
		case AT_AddConstraintRecurse: /* ADD CONSTRAINT with recursion: internal */
			ATExecAddConstraint(tab, rel, cmd->def, true);
			break;
		case AT_DropConstraint:	/* DROP CONSTRAINT */
			ATExecDropConstraint(rel, cmd->name, cmd->behavior, false);
			break;
		case AT_DropConstraintQuietly:	/* DROP CONSTRAINT for child */
			ATExecDropConstraint(rel, cmd->name, cmd->behavior, true);
			break;
		case AT_AlterColumnType:		/* ALTER COLUMN TYPE */
			ATExecAlterColumnType(tab, rel, cmd->name, (TypeName *) cmd->def);
			break;
		case AT_ChangeOwner:	/* ALTER OWNER */
			ATExecChangeOwner(RelationGetRelid(rel),
							  get_roleid_checked(cmd->name),
							  false);
			break;
		case AT_ClusterOn:		/* CLUSTER ON */
			ATExecClusterOn(rel, cmd->name);
			break;
		case AT_DropCluster:	/* SET WITHOUT CLUSTER */
			ATExecDropCluster(rel);
			break;
		case AT_DropOids:		/* SET WITHOUT OIDS */

			/*
			 * Nothing to do here; we'll have generated a DropColumn
			 * subcommand to do the real work
			 */
			break;
		case AT_SetTableSpace:	/* SET TABLESPACE */

			/*
			 * Nothing to do here; Phase 3 does the work
			 */
			break;
		case AT_SetRelOptions:	/* SET (...) */
			ATExecSetRelOptions(rel, (List *) cmd->def, false);
			break;
		case AT_ResetRelOptions:		/* RESET (...) */
			ATExecSetRelOptions(rel, (List *) cmd->def, true);
			break;
		case AT_EnableTrig:		/* ENABLE TRIGGER name */
			ATExecEnableDisableTrigger(rel, cmd->name, true, false);
			break;
		case AT_DisableTrig:	/* DISABLE TRIGGER name */
			ATExecEnableDisableTrigger(rel, cmd->name, false, false);
			break;
		case AT_EnableTrigAll:	/* ENABLE TRIGGER ALL */
			ATExecEnableDisableTrigger(rel, NULL, true, false);
			break;
		case AT_DisableTrigAll:	/* DISABLE TRIGGER ALL */
			ATExecEnableDisableTrigger(rel, NULL, false, false);
			break;
		case AT_EnableTrigUser:	/* ENABLE TRIGGER USER */
			ATExecEnableDisableTrigger(rel, NULL, true, true);
			break;
		case AT_DisableTrigUser:		/* DISABLE TRIGGER USER */
			ATExecEnableDisableTrigger(rel, NULL, false, true);
			break;
		case AT_AddInherit:
			ATExecAddInherit(rel, (Node *) cmd->def);
			break;
		case AT_DropInherit:
			ATExecDropInherit(rel, (RangeVar *) cmd->def, false);
			break;
		case AT_SetDistributedBy:	/* SET DISTRIBUTED BY */
			ATExecSetDistributedBy(rel, (Node *) cmd->def, cmd);
			break;
			/* CDB: Partitioned Table commands */
		case AT_PartAdd:				/* Add */
			ATPExecPartAdd(tab, rel, (AlterPartitionCmd *) cmd->def,
						   cmd->subtype);
            break;
		case AT_PartAlter:				/* Alter */
            ATPExecPartAlter(wqueue, tab, rel, (AlterPartitionCmd *) cmd->def);
            break;
		case AT_PartCoalesce:			/* Coalesce */
            ATPExecPartCoalesce(rel, (AlterPartitionCmd *) cmd->def);
            break;
		case AT_PartDrop:				/* Drop */
            ATPExecPartDrop(rel, (AlterPartitionCmd *) cmd->def);
            break;
		case AT_PartExchange:			/* Exchange */
            ATPExecPartExchange(tab, rel, (AlterPartitionCmd *) cmd->def);
            break;
		case AT_PartMerge:				/* Merge */
            ATPExecPartMerge(rel, (AlterPartitionCmd *) cmd->def);
            break;
		case AT_PartModify:				/* Modify */
            ATPExecPartModify(rel, (AlterPartitionCmd *) cmd->def);
            break;
		case AT_PartRename:				/* Rename */
            ATPExecPartRename(rel, (AlterPartitionCmd *) cmd->def);
            break;
		case AT_PartSetTemplate:		/* Set Subpartition Template */
			ATPExecPartSetTemplate(tab, rel, (AlterPartitionCmd *) cmd->def);
            break;
		case AT_PartSplit:				/* Split */
            ATPExecPartSplit(rel, (AlterPartitionCmd *) cmd->def);
            break;
		case AT_PartTruncate:			/* Truncate */
			ATPExecPartTruncate(rel, (AlterPartitionCmd *) cmd->def);
            break;
		case AT_PartAddInternal:
			ATExecPartAddInternal(rel, cmd->def);
			break;
		default:				/* oops */
			elog(ERROR, "unrecognized alter table type: %d",
				 (int) cmd->subtype);
			break;
	}

	/*
	 * Bump the command counter to ensure the next subcommand in the sequence
	 * can see the changes so far
	 */
	CommandCounterIncrement();
}

/*
 * ATRewriteTables: ALTER TABLE phase 3
 */
static void
ATRewriteTables(List **wqueue, 
				int oidInfoCount, TableOidInfo * oidInfo, List **poidmap)
{
	ListCell   *ltab;
	int			m = 0;

	/* Go through each table that needs to be checked or rewritten */
	foreach(ltab, *wqueue)
	{
		AlteredTableInfo *tab = (AlteredTableInfo *) lfirst(ltab);
		Relation rel;
		bool relisshared;
		bool relisnailed;
		Oid  newTableSpace;
		Oid  oldTableSpace;
		Oid  relNamespace;

		/* We will lock the table iff we decide to actually rewrite it */
		rel = relation_open(tab->relid, NoLock);
		relisshared   = rel->rd_rel->relisshared;
		relisnailed   = rel->rd_isnailed;
		relNamespace  = RelationGetNamespace(rel);
		oldTableSpace = rel->rd_rel->reltablespace;
		newTableSpace = tab->newTableSpace ? tab->newTableSpace : oldTableSpace;

		if (tab->newTableSpace) {
			RejectAccessTablespace(oldTableSpace, "cannot move from shared tablespace %s");
			RejectAccessTablespace(newTableSpace, "cannot move to shared tablespace %s");
			/* If this is an index and we are in a shared storage database, reject change index tablespace */
			if (rel->rd_rel->relkind == RELKIND_INDEX && is_tablespace_shared_master(get_database_dts(MyDatabaseId)))
				RejectAccessTablespace(get_database_dts(MyDatabaseId), "cannot change tablespace on shared storage");
		}
		/*
		 * There are two cases where we will rewrite the table, for these cases
		 * run the necessary sanity checks.
		 */
		if (tab->newvals != NIL || tab->newTableSpace)
		{
			/* 
			 * AlterTableInternal is not allowed to execute alter table
			 * subcommands that require allocating new relfilenodes since it is
			 * executed in a context that doesn't dispatch the Alter Table.
			 *
			 * This should never occur.
			 */
			if (!oidInfo)
				elog(ERROR, 
					 "internal alter table cannot allocate new relfilenodes");
			Assert(m < oidInfoCount);

			/*
			 * We can never allow rewriting of shared or nailed-in-cache
			 * relations, because we can't support changing their relfilenode
			 * values.
			 */
			if (relisshared || relisnailed)
				ereport(ERROR,
						(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
						 errmsg("cannot rewrite system relation \"%s\"",
								RelationGetRelationName(rel))));

			/*
			 * Don't allow rewrite on temp tables of other backends ... their
			 * local buffer manager is not going to cope.
			 */
			if (isOtherTempNamespace(relNamespace))
				ereport(ERROR,
						(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
				errmsg("cannot rewrite temporary tables of other sessions")));

		}
		heap_close(rel, NoLock);

		/*
		 * We only need to rewrite the table if at least one column needs to be
		 * recomputed, or we are removing the OID column.
		 */
		if (tab->newvals != NIL || tab->new_dropoids)
		{
			/* Sanity check of oidInfoCount */
			Insist(oidInfoCount==list_length(*wqueue));

			/* Build a temporary relation and copy data */
			char		NewHeapName[NAMEDATALEN];
			Oid         OIDNewHeap;
			ObjectAddress object;

			/*
			 * Create the new heap, using a temporary name in the same
			 * namespace as the existing table.  NOTE: there is some risk of
			 * collision with user relnames.  Working around this seems more
			 * trouble than it's worth; in particular, we can't create the new
			 * heap in a different namespace from the old, or we will have
			 * problems with the TEMP status of temp tables.
			 */
			snprintf(NewHeapName, sizeof(NewHeapName),
					 "pg_temp_%u", tab->relid);

            List *indexIds = RelationGetIndexList(rel);
            OIDNewHeap = make_new_heap(tab->relid, NewHeapName, newTableSpace,
                                       &oidInfo[m], list_length(indexIds) > 0);
            list_free(indexIds);

			/*
			 * Copy the heap data into the new table with the desired
			 * modifications, and test the current data within the table
			 * against new constraints generated by ALTER TABLE commands.
			 */
			ATRewriteTable(tab, OIDNewHeap);

			/* 
			 * Swap the physical files of the old and new heaps. 
			 *
			 * MPP-17516 - The third argument to swap_relation_files is 
			 * "swap_stats", and it dictates whether the relpages and 
			 * reltuples of the fake relfile should be copied over to our 
			 * original pg_class tuple. We do not want to do this in the case 
			 * of ALTER TABLE rewrites as the temp relfile will not have correct 
			 * stats.
			 */
			swap_relation_files(tab->relid, OIDNewHeap, false);

			CommandCounterIncrement();

			/* Destroy new heap with old filenode */
			object.classId = RelationRelationId;
			object.objectId = OIDNewHeap;
			object.objectSubId = 0;

			/*
			 * The new relation is local to our transaction and we know
			 * nothing depends on it, so DROP_RESTRICT should be OK.
			 */
			performDeletion(&object, DROP_RESTRICT);
			/* performDeletion does CommandCounterIncrement at end */

			/*
			 * Rebuild each index on the relation (but not the toast table,
			 * which is all-new anyway).  We do not need
			 * CommandCounterIncrement() because reindex_relation does it.
			 * reindex_relation also checks for non-NULL poidmap, so we don't
			 * need to.
			 *	
			 * It is not legal to reindex without dispatch of the associated
			 * oids!
			 */
			reindex_relation(tab->relid, false, false, false, 
							 poidmap, poidmap && Gp_role == GP_ROLE_DISPATCH);
		}
		else
		{
			/*
			 * Test the current data within the table against new constraints
			 * generated by ALTER TABLE commands, but don't rebuild data.
			 */
			if (tab->constraints != NIL || tab->new_notnull)
				ATRewriteTable(tab, InvalidOid);

			/*
			 * If we had SET TABLESPACE but no reason to reconstruct tuples,
			 * just do a block-by-block copy.
			 */
			if (tab->newTableSpace)
			{
				populate_oidInfo(&oidInfo[m], newTableSpace, relisshared, 
								 false);
				
				ATExecSetTableSpace(tab->relid, tab->newTableSpace, 
									&oidInfo[m]);
			}
		}
		m++;

	}

	/*
	 * Foreign key constraints are checked in a final pass, since (a) it's
	 * generally best to examine each one separately, and (b) it's at least
	 * theoretically possible that we have changed both relations of the
	 * foreign key, and we'd better have finished both rewrites before we try
	 * to read the tables.
	 */
	foreach(ltab, *wqueue)
	{
		AlteredTableInfo *tab = (AlteredTableInfo *) lfirst(ltab);
		Relation	rel = NULL;
		ListCell   *lcon;

		foreach(lcon, tab->constraints)
		{
			NewConstraint *con = lfirst(lcon);

			if (con->contype == CONSTR_FOREIGN)
			{
				FkConstraint *fkconstraint = (FkConstraint *) con->qual;
				Relation	refrel;

				if (rel == NULL)
				{
					/* Long since locked, no need for another */
					rel = heap_open(tab->relid, NoLock);
				}

				refrel = heap_open(con->refrelid, RowShareLock);

				validateForeignKeyConstraint(fkconstraint, rel, refrel);

				heap_close(refrel, NoLock);
			}
		}

		if (rel)
			heap_close(rel, NoLock);
	}
}

/*
 * ATRewriteTable: scan or rewrite one table
 *
 * OIDNewHeap is InvalidOid if we don't need to rewrite
 */
static void
ATRewriteTable(AlteredTableInfo *tab, Oid OIDNewHeap)
{
	Relation	oldrel;
	Relation	newrel;
	TupleDesc	oldTupDesc;
	TupleDesc	newTupDesc;
	bool		needscan = false;
	List	   *notnull_attrs;
	int			i;
	ListCell   *l;
	EState	   *estate;

	/*
	 * Open the relation(s).  We have surely already locked the existing table.
	 * In EXCHANGE of partition case, we only need to validate the content
	 * based on new constraints.  oldTupDesc should point to the oldrel's tuple
	 * descriptor since tab->oldDesc comes from the parent partition.
	 */
	if (OidIsValid(tab->exchange_relid))
	{
		oldrel = heap_open(tab->exchange_relid, NoLock);
		oldTupDesc = RelationGetDescr(oldrel);
	}
	else
	{
		oldrel = heap_open(tab->relid, NoLock);
		oldTupDesc = tab->oldDesc;
	}

	newTupDesc = RelationGetDescr(oldrel);		/* includes all mods */

	if (OidIsValid(OIDNewHeap))
		newrel = heap_open(OIDNewHeap, AccessExclusiveLock);
	else
		newrel = NULL;

	/*
	 * If we need to rewrite the table, the operation has to be propagated to
	 * tables that use this table's rowtype as a column type.
	 *
	 * (Eventually this will probably become true for scans as well, but at
	 * the moment a composite type does not enforce any constraints, so it's
	 * not necessary/appropriate to enforce them just during ALTER.)
	 */
	if (newrel)
		find_composite_type_dependencies(oldrel->rd_rel->reltype,
										 RelationGetRelationName(oldrel),
										 NULL);

	/*
	 * Generate the constraint and default execution states
	 */

	estate = CreateExecutorState();

	/* Build the needed expression execution states */
	foreach(l, tab->constraints)
	{
		NewConstraint *con = lfirst(l);

		switch (con->contype)
		{
			case CONSTR_CHECK:
				needscan = true;
				con->qualstate = (List *)
					ExecPrepareExpr((Expr *) con->qual, estate);
				break;
			case CONSTR_FOREIGN:
				/* Nothing to do here */
				break;
			default:
				elog(ERROR, "unrecognized constraint type: %d",
					 (int) con->contype);
		}
	}

	foreach(l, tab->newvals)
	{
		NewColumnValue *ex = lfirst(l);

		needscan = true;

		ex->exprstate = ExecPrepareExpr((Expr *) ex->expr, estate);
	}

	notnull_attrs = NIL;
	if (newrel || tab->new_notnull)
	{
		/*
		 * If we are rebuilding the tuples OR if we added any new NOT NULL
		 * constraints, check all not-null constraints.  This is a bit of
		 * overkill but it minimizes risk of bugs, and heap_attisnull is a
		 * pretty cheap test anyway.
		 */
		for (i = 0; i < newTupDesc->natts; i++)
		{
			if (newTupDesc->attrs[i]->attnotnull &&
				!newTupDesc->attrs[i]->attisdropped)
				notnull_attrs = lappend_int(notnull_attrs, i);
		}
		if (notnull_attrs)
			needscan = true;
	}

	if (newrel || needscan)
	{
		ExprContext *econtext;
		Datum	   *values;
		bool	   *isnull;
		TupleTableSlot *oldslot;
		TupleTableSlot *newslot;
		HeapScanDesc heapscan = NULL;
		AppendOnlyScanDesc aoscan = NULL;
		HeapTuple	htuple = NULL;
		MemTuple	mtuple = NULL;
		MemoryContext oldCxt;
		List	   *dropped_attrs = NIL;
		ListCell   *lc;
		char		relstorage = oldrel->rd_rel->relstorage;

		econtext = GetPerTupleExprContext(estate);

		/*
		 * Make tuple slots for old and new tuples.  Note that even when the
		 * tuples are the same, the tupDescs might not be (consider ADD COLUMN
		 * without a default).
		 */
		oldslot = MakeSingleTupleTableSlot(oldTupDesc);
		newslot = MakeSingleTupleTableSlot(newTupDesc);

		/* Preallocate values/isnull arrays */
		i = Max(newTupDesc->natts, oldTupDesc->natts);
		values = (Datum *) palloc0(i * sizeof(Datum));
		isnull = (bool *) palloc(i * sizeof(bool));
		memset(isnull, true, i * sizeof(bool));

		/*
		 * Any attributes that are dropped according to the new tuple
		 * descriptor can be set to NULL. We precompute the list of dropped
		 * attributes to avoid needing to do so in the per-tuple loop.
		 */
		for (i = 0; i < newTupDesc->natts; i++)
		{
			if (newTupDesc->attrs[i]->attisdropped)
				dropped_attrs = lappend_int(dropped_attrs, i);
		}


		/*
		 * Scan through the rows, generating a new row if needed and then
		 * checking all the constraints.
		 */
		if(relstorage == RELSTORAGE_HEAP)
		{
			heapscan = heap_beginscan(oldrel, SnapshotNow, 0, NULL);

			/*
			 * Switch to per-tuple memory context and reset it for each tuple
			 * produced, so we don't leak memory.
			 */
			oldCxt = MemoryContextSwitchTo(GetPerTupleMemoryContext(estate));

			while ((htuple = heap_getnext(heapscan, ForwardScanDirection)) != NULL)
			{
				if (newrel)
				{
					Oid			tupOid = InvalidOid;

					/* Extract data from old tuple */
					heap_deform_tuple(htuple, oldTupDesc, values, isnull);
					if (oldTupDesc->tdhasoid)
						tupOid = HeapTupleGetOid(htuple);

					/* Set dropped attributes to null in new tuple */
					foreach(lc, dropped_attrs)
						isnull[lfirst_int(lc)] = true;

					/*
					 * Process supplied expressions to replace selected columns.
					 * Expression inputs come from the old tuple.
					 */
					ExecStoreHeapTuple(htuple, oldslot, InvalidBuffer, false);
					econtext->ecxt_scantuple = oldslot;

					foreach(l, tab->newvals)
					{
						NewColumnValue *ex = lfirst(l);

						values[ex->attnum - 1] = ExecEvalExpr(ex->exprstate,
															  econtext,
															  &isnull[ex->attnum - 1],
															  NULL);
					}

					/*
					 * Form the new tuple. Note that we don't explicitly pfree it,
					 * since the per-tuple memory context will be reset shortly.
					 */
					htuple = heap_form_tuple(newTupDesc, values, isnull);

					/* Preserve OID, if any */
					if (newTupDesc->tdhasoid)
						HeapTupleSetOid(htuple, tupOid);
				}

				/* Now check any constraints on the possibly-changed tuple */
				ExecStoreHeapTuple(htuple, newslot, InvalidBuffer, false);
				econtext->ecxt_scantuple = newslot;

				foreach(l, notnull_attrs)
				{
					int			attn = lfirst_int(l);

					if (heap_attisnull(htuple, attn + 1))
						ereport(ERROR,
								(errcode(ERRCODE_NOT_NULL_VIOLATION),
								 errmsg("column \"%s\" contains null values",
										NameStr(newTupDesc->attrs[attn]->attname)),
								 errOmitLocation(true)));
				}

				foreach(l, tab->constraints)
				{
					NewConstraint *con = lfirst(l);

					switch (con->contype)
					{
						case CONSTR_CHECK:
							if (!ExecQual(con->qualstate, econtext, true))
							{
								if (OidIsValid(tab->exchange_relid))
									ereport(ERROR,
											(errcode(ERRCODE_CHECK_VIOLATION),
											 errmsg("exchange table contains "
													"a row which violates the "
													"partitioning "
													"specification of \"%s\"",
													get_rel_name(tab->relid)),
											 errOmitLocation(true)));
								else
									ereport(ERROR,
											(errcode(ERRCODE_CHECK_VIOLATION),
											 errmsg("check constraint \"%s\" is violated by some row",
												con->name),
											 errOmitLocation(true)));
							}
							break;
						case CONSTR_FOREIGN:
							/* Nothing to do here */
							break;
						default:
							elog(ERROR, "unrecognized constraint type: %d",
								 (int) con->contype);
					}
				}

				/* Write the tuple out to the new relation */
				if (newrel)
					simple_heap_insert(newrel, htuple);

				ResetExprContext(econtext);

				CHECK_FOR_INTERRUPTS();
			}

			MemoryContextSwitchTo(oldCxt);
			heap_endscan(heapscan);

		}
		else if(relstorage == RELSTORAGE_AOROWS && Gp_role != GP_ROLE_DISPATCH)
		{
			/*
			 * When rewriting an appendonly table we choose to always insert
			 * into the segfile reserved for special purposes (segno #0).
			 */
			int 					segno = list_nth_int(tab->ao_segnos, GetQEIndex());;
			AppendOnlyInsertDesc 	aoInsertDesc = NULL;
			MemTupleBinding*		mt_bind;

			if(newrel)
			{
			  ResultRelSegFileInfo *segfileinfo = InitResultRelSegFileInfo(segno, RELSTORAGE_AOROWS, 1);
				aoInsertDesc = appendonly_insert_init(newrel, segfileinfo);
			}

			mt_bind = (newrel ? aoInsertDesc->mt_bind : create_memtuple_binding(newTupDesc));

			aoscan = appendonly_beginscan(oldrel, SnapshotNow, 0, NULL);
		  aoscan->splits = GetFileSplitsOfSegment(tab->scantable_splits,
		          oldrel->rd_id, GetQEIndex());
			/*
			 * Switch to per-tuple memory context and reset it for each tuple
			 * produced, so we don't leak memory.
			 */
			oldCxt = MemoryContextSwitchTo(GetPerTupleMemoryContext(estate));

			while ((mtuple = appendonly_getnext(aoscan, ForwardScanDirection, oldslot)) != NULL)
			{
				if (newrel)
				{
					Oid			tupOid = InvalidOid;

					TupClearShouldFree(oldslot);
					econtext->ecxt_scantuple = oldslot;

					/* Extract data from old tuple */
					for(i = 0; i < oldslot->tts_tupleDescriptor->natts ; i++)
						values[i] = slot_getattr(oldslot, i+1, &isnull[i]);

					if (oldTupDesc->tdhasoid)
						tupOid = MemTupleGetOid(mtuple, mt_bind);

					/* Set dropped attributes to null in new tuple */
					foreach(lc, dropped_attrs)
						isnull[lfirst_int(lc)] = true;

					/*
					 * Process supplied expressions to replace selected columns.
					 * Expression inputs come from the old tuple.
					 */
					foreach(l, tab->newvals)
					{
						NewColumnValue *ex = lfirst(l);

						values[ex->attnum - 1] = ExecEvalExpr(ex->exprstate,
															  econtext,
															  &isnull[ex->attnum - 1],
															  NULL);
					}

					/*
					 * Form the new tuple. Note that we don't explicitly pfree it,
					 * since the per-tuple memory context will be reset shortly.
					 */
					mtuple = memtuple_form_to(mt_bind,
											  values, isnull,
											  NULL, NULL, false);


					/* Preserve OID, if any */
					if (newTupDesc->tdhasoid)
						MemTupleSetOid(mtuple, mt_bind, tupOid);
				}

				/* Now check any constraints on the possibly-changed tuple */
				ExecStoreMemTuple(mtuple, newslot, false);
				econtext->ecxt_scantuple = newslot;

				foreach(l, notnull_attrs)
				{
					int					attn = lfirst_int(l);
					
					if (memtuple_attisnull(mtuple, mt_bind, attn + 1))
						ereport(ERROR,
								(errcode(ERRCODE_NOT_NULL_VIOLATION),
								 errmsg("column \"%s\" contains null values",
										NameStr(newTupDesc->attrs[attn]->attname)),
								 errOmitLocation(true)));
				}

				foreach(l, tab->constraints)
				{
					NewConstraint *con = lfirst(l);

					switch (con->contype)
					{
						case CONSTR_CHECK:
							if (!ExecQual(con->qualstate, econtext, true))
								ereport(ERROR,
										(errcode(ERRCODE_CHECK_VIOLATION),
										 errmsg("check constraint \"%s\" is violated by some row",
												con->name),
										 errOmitLocation(true)));
							break;
						case CONSTR_FOREIGN:
							/* Nothing to do here */
							break;
						default:
							elog(ERROR, "unrecognized constraint type: %d",
								 (int) con->contype);
					}
				}

				/* Write the tuple out to the new relation */
				if (newrel)
				{
					Oid 		tupleOid;
					AOTupleId	aoTupleId;
					
					appendonly_insert(aoInsertDesc, mtuple, &tupleOid, &aoTupleId);
				}

				ResetExprContext(econtext);

				CHECK_FOR_INTERRUPTS();

			}

			MemoryContextSwitchTo(oldCxt);
			appendonly_endscan(aoscan);

			if(newrel)
			{
				StringInfo buf = NULL;
				QueryContextDispatchingSendBack sendback = NULL;

				if (Gp_role == GP_ROLE_EXECUTE)
					buf = PreSendbackChangedCatalog(1);

				sendback = CreateQueryContextDispatchingSendBack(1);
				aoInsertDesc->sendback = sendback;
				sendback->relid = RelationGetRelid(aoInsertDesc->aoi_rel);

				appendonly_insert_finish(aoInsertDesc);

				if (Gp_role == GP_ROLE_EXECUTE)
					AddSendbackChangedCatalogContent(buf, sendback);

				DropQueryContextDispatchingSendBack(sendback);

				if (Gp_role == GP_ROLE_EXECUTE)
					FinishSendbackChangedCatalog(buf);
			}
		}
		else if(relstorage == RELSTORAGE_PARQUET && Gp_role != GP_ROLE_DISPATCH)
		{
			int segno = list_nth_int(tab->ao_segnos, GetQEIndex());
			ParquetInsertDesc idesc = NULL;
			ParquetScanDesc sdesc = NULL;
			int nvp = oldrel->rd_att->natts;
			bool *proj = palloc0(sizeof(bool) * nvp);

			/*
			 * We use the old tuple descriptor instead of oldrel's tuple descriptor,
			 * which may already contain altered column.
			 */
			if (oldTupDesc)
			{
				Assert(oldTupDesc->natts <= nvp);
				memset(proj, true, oldTupDesc->natts);
			}
			else
				memset(proj, true, nvp);

			if(newrel)
			{
			  ResultRelSegFileInfo *segfileinfo = InitResultRelSegFileInfo(segno, RELSTORAGE_PARQUET, 1);
				idesc = parquet_insert_init(newrel, segfileinfo);
			}

			sdesc = parquet_beginscan(oldrel, SnapshotNow, oldTupDesc, proj);
			sdesc->splits = GetFileSplitsOfSegment(tab->scantable_splits,
			                oldrel->rd_id, GetQEIndex());
			parquet_getnext(sdesc, ForwardScanDirection, oldslot);


			while(!TupIsNull(oldslot))
			{
				oldCxt = MemoryContextSwitchTo(GetPerTupleMemoryContext(estate));
				econtext->ecxt_scantuple = oldslot;

				if(newrel)
				{
					Datum *slotvalues = slot_get_values(oldslot);
					bool  *slotnulls = slot_get_isnull(oldslot);
					Datum *newslotvalues = slot_get_values(newslot);
					bool *newslotnulls = slot_get_isnull(newslot);

					int nv = Min(oldslot->tts_tupleDescriptor->natts, newslot->tts_tupleDescriptor->natts);

					/* aocs does not do oid yet */
					Assert(!oldTupDesc->tdhasoid);
					Assert(!newTupDesc->tdhasoid);

					/* Dropped att should be set correctly by aocs_getnext */
					/* transfer values from old to new slot */

					memcpy(newslotvalues, slotvalues, sizeof(Datum) * nv);
					memcpy(newslotnulls, slotnulls, sizeof(bool) * nv);
					TupSetVirtualTupleNValid(newslot, nv);

					/* Process supplied expressions */
					foreach(l, tab->newvals)
					{
						NewColumnValue *ex = lfirst(l);

						newslotvalues[ex->attnum-1] =
							ExecEvalExpr(ex->exprstate,
										 econtext,
										 &newslotnulls[ex->attnum-1],
										 NULL
								);

						if (ex->attnum > nv)
							TupSetVirtualTupleNValid(newslot, ex->attnum);
					}

					/* Use the modified tuple to check constraints below */
					econtext->ecxt_scantuple = newslot;
				}

				/* Check constraints */
				foreach (l, tab->constraints)
				{
					NewConstraint *con = lfirst(l);
					switch(con->contype)
					{
						case CONSTR_CHECK:
							if(!ExecQual(con->qualstate, econtext, true))
								ereport(ERROR,
										(errcode(ERRCODE_CHECK_VIOLATION),
										 errmsg("check constraint \"%s\" is violated",
												con->name
											 ),
										 errOmitLocation(true)));
							break;
						case CONSTR_FOREIGN:
							/* Nothing to do */
							break;
						default:
							elog(ERROR, "Unrecognized constraint type: %d",
								 (int) con->contype);
					}
				}

				if(newrel)
				{
					MemoryContextSwitchTo(oldCxt);
					parquet_insert(idesc, newslot);
				}

				ResetExprContext(econtext);
				CHECK_FOR_INTERRUPTS();

				MemoryContextSwitchTo(oldCxt);
				parquet_getnext(sdesc, ForwardScanDirection, oldslot);
			}

			parquet_endscan(sdesc);

			if(newrel)
			{
				StringInfo buf = NULL;
				QueryContextDispatchingSendBack sendback = NULL;

				if (Gp_role == GP_ROLE_EXECUTE)
					buf = PreSendbackChangedCatalog(1);

				sendback = CreateQueryContextDispatchingSendBack(
						idesc->parquet_rel->rd_att->natts);

				idesc->sendback = sendback;
				sendback->relid = RelationGetRelid(idesc->parquet_rel);

				parquet_insert_finish(idesc);

				if (Gp_role == GP_ROLE_EXECUTE)
					AddSendbackChangedCatalogContent(buf, sendback);

				DropQueryContextDispatchingSendBack(sendback);

				if (Gp_role == GP_ROLE_EXECUTE)
					FinishSendbackChangedCatalog(buf);
			}
			pfree(proj);
		}
		else if(relstorage_is_ao(relstorage) && Gp_role == GP_ROLE_DISPATCH)
		{
			/*
			 * All we want to do on the QD during an AO table rewrite
			 * is to drop the shared memory hash table entry for this
			 * table if it exists. We must do so since before the
			 * rewrite we probably have few non-zero segfile entries
			 * for this table while after the rewrite only segno zero
			 * will be full and the others will be empty. By dropping
			 * the hash entry we force refreshing the entry from the
			 * catalog the next time a write into this AO table comes
			 * along.
			 *
			 * Note that ALTER already took an exclusive lock on the
			 * old relation so we are guaranteed to not drop the hash
			 * entry from under any concurrent operation.
			 */
			LWLockAcquire(AOSegFileLock, LW_EXCLUSIVE);
			AORelRemoveHashEntry(RelationGetRelid(oldrel), false);
			LWLockRelease(AOSegFileLock);
		}
		else
		{
			Assert(!"Invalid relstorage type");
		}

		ExecDropSingleTupleTableSlot(oldslot);
		ExecDropSingleTupleTableSlot(newslot);
	}

	FreeExecutorState(estate);

	/*
	 * In hawq, here we dispatch the process to segments as opposed to what
	 * we did in GPDB which is to dispatch the whole statement from the top-level.
	 * The reason is we need a new relation created, but not yet swapped, so
	 * the catalog status is somewhat transient.  This is the only timing we
	 * can construct metadata dispatch and delegate to segments.  We don't
	 * need to dispatch the process if ATRewriteTable has no work to do.
	 */
	if (Gp_role == GP_ROLE_DISPATCH && (newrel || needscan))
	{
		AlterRewriteTableInfo *ar_tab;
		QueryContextInfo *contextdisp;
		DispatchDataResult result;
		QueryResource *resource = NULL;
		int target_segment_num = -1;
		List *segment_segnos = NIL;
		QueryResource *savedResource = NULL;

		{
		  /*
		   * calculate the target segment number based on
		   * the target relation.
		   */
		  GpPolicy *targetPolicy = NULL;

		  targetPolicy = GpPolicyFetch(CurrentMemoryContext, tab->relid);
		  Assert(targetPolicy);
		  target_segment_num = targetPolicy->bucketnum;
		  pfree(targetPolicy);

      if (newrel)
      {
        targetPolicy = GpPolicyFetch(CurrentMemoryContext, newrel->rd_id);
        Assert(targetPolicy);
        if (target_segment_num != targetPolicy->bucketnum)
        {
          pfree(targetPolicy);
          elog(ERROR, "target segment num %d IS NOT equal to the bucket number of this relation %d", target_segment_num, targetPolicy->bucketnum);
        }
        pfree(targetPolicy);
      }
		}

	  resource = AllocateResource(QRL_ONCE, 1, 1, target_segment_num, target_segment_num,NULL,0);
	  savedResource = GetActiveQueryResource();
	  SetActiveQueryResource(resource);

	  segment_segnos = SetSegnoForWrite(NIL, 0, target_segment_num, true, true, false);

    /*
     * We create seg files for the new relation here.
     */
    if (newrel)
    {
      CreateAppendOnlyParquetSegFileForRelationOnMaster(newrel, segment_segnos);
    }

		/* prepare for the metadata dispatch */
		contextdisp = CreateQueryContextInfo();
		ar_tab = prepareAlteredTableInfo(tab);
		ar_tab->scantable_splits = NIL;
		ar_tab->ao_segnos = segment_segnos;

		/*
		 * For the original table, there could be a case to scan
		 * partition table, while the new rel is always a new single
		 * relation.
		 */
		prepareDispatchedCatalogRelation(contextdisp,
										 tab->relid,
										 false,
										 NULL);
		ar_tab->scantable_splits = AssignAOSegFileSplitToSegment(tab->relid, NIL,
		                    target_segment_num, ar_tab->scantable_splits);
		/*
		 * Specify the segno directly as we don't have segno mapping here.
		 */
		if (OidIsValid(OIDNewHeap))
			prepareDispatchedCatalogSingleRelation(contextdisp,
												   OIDNewHeap,
												   true,
												   segment_segnos);
		FinalizeQueryContextInfo(contextdisp);

		ar_tab->newheap_oid = OIDNewHeap;

    dispatch_statement_node((Node *) ar_tab, contextdisp, resource, &result);
    cdbdisp_iterate_results_sendback(result.result, result.numresults,
                UpdateCatalogModifiedOnSegments);
    dispatch_free_result(&result);
    DropQueryContextInfo(contextdisp);
    FreeResource(resource);
    SetActiveQueryResource(savedResource);
	}

	heap_close(oldrel, NoLock);
	if (newrel)
		heap_close(newrel, NoLock);

}

/*
 * ATGetQueueEntry: find or create an entry in the ALTER TABLE work queue
 */
static AlteredTableInfo *
ATGetQueueEntry(List **wqueue, Relation rel)
{
	Oid			relid = RelationGetRelid(rel);
	AlteredTableInfo *tab;
	ListCell   *ltab;

	foreach(ltab, *wqueue)
	{
		tab = (AlteredTableInfo *) lfirst(ltab);
		if (tab->relid == relid)
			return tab;
	}

	/*
	 * Not there, so add it.  Note that we make a copy of the relation's
	 * existing descriptor before anything interesting can happen to it.
	 */
	tab = (AlteredTableInfo *) palloc0(sizeof(AlteredTableInfo));
	tab->relid = relid;
	tab->relkind = rel->rd_rel->relkind;
	tab->oldDesc = CreateTupleDescCopy(RelationGetDescr(rel));

	*wqueue = lappend(*wqueue, tab);

	return tab;
}

/*
 * Issue an error, if this is a part of a partitioned table or, in case 
 * rejectroot is true, if this is a partitioned table itself.
 *
 * Usually called from ATPrepCmd to validate a subcommand of an ALTER
 * TABLE command.  Many commands may be invoked on an entire partitioned
 * table, but not on just a part.  These specify rejectroot as false.
 */
static void
ATPartitionCheck(AlterTableType subtype, Relation rel, bool rejectroot, bool recursing)
{
	if (recursing)
		return;

	if (rejectroot &&
		(rel_is_child_partition(RelationGetRelid(rel)) ||
		 rel_is_partitioned(RelationGetRelid(rel))))
	{
		ereport(ERROR,
				(errcode(ERRCODE_WRONG_OBJECT_TYPE),
				 errmsg("can't %s \"%s\"; it is a partitioned table or part thereof",
						alterTableCmdString(subtype),
						RelationGetRelationName(rel)),
				 errOmitLocation(true)));
	}
	else if (rel_is_child_partition(RelationGetRelid(rel)))
	{
		ereport(ERROR,
				(errcode(ERRCODE_WRONG_OBJECT_TYPE),
				 errmsg("can't %s \"%s\"; it is part of a partitioned table",
						alterTableCmdString(subtype),
						RelationGetRelationName(rel)),
				 errhint("You may be able to perform the operation on the partitioned table as a whole."),
				 errOmitLocation(true)));
	}
}

/*
 * ATSimplePermissions
 *
 * - Ensure that it is a relation (or possibly a view)
 * - Ensure this user is the owner
 * - Ensure that it is not a system table
 */
static void
ATSimplePermissions(Relation rel, bool allowView)
{
	if (rel->rd_rel->relkind != RELKIND_RELATION)
	{
		if (allowView)
		{
			if (rel->rd_rel->relkind != RELKIND_VIEW)
				ereport(ERROR,
						(errcode(ERRCODE_WRONG_OBJECT_TYPE),
						 errmsg("\"%s\" is not a table or view",
								RelationGetRelationName(rel)),
						 errOmitLocation(true)));
		}
		else if (!IsUnderPostmaster &&
				 (rel->rd_rel->relkind == RELKIND_AOSEGMENTS ||
				  rel->rd_rel->relkind == RELKIND_AOBLOCKDIR))
		{
			/*
			 * Allow ALTER TABLE operations in standard alone mode on
			 * AO segment tables.
			 */
		}
		else
			ereport(ERROR,
					(errcode(ERRCODE_WRONG_OBJECT_TYPE),
					 errmsg("\"%s\" is not a table",
							RelationGetRelationName(rel)),
					 errOmitLocation(true)));
	}

	/* Permissions checks */
	if (!pg_class_ownercheck(RelationGetRelid(rel), GetUserId()))
		aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_CLASS,
					   RelationGetRelationName(rel));

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

/*
 * ATSimplePermissionsRelationOrIndex
 *
 * - Ensure that it is a relation or an index
 * - Ensure this user is the owner
 * - Ensure that it is not a system table
 */
static void
ATSimplePermissionsRelationOrIndex(Relation rel)
{
	if (rel->rd_rel->relkind != RELKIND_RELATION &&
		rel->rd_rel->relkind != RELKIND_INDEX)
		ereport(ERROR,
				(errcode(ERRCODE_WRONG_OBJECT_TYPE),
				 errmsg("\"%s\" is not a table or index",
						RelationGetRelationName(rel)),
				 errOmitLocation(true)));

	/* Permissions checks */
	if (!pg_class_ownercheck(RelationGetRelid(rel), GetUserId()))
		aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_CLASS,
					   RelationGetRelationName(rel));

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

/*
 * ATSimpleRecursion
 *
 * Simple table recursion sufficient for most ALTER TABLE operations.
 * All direct and indirect children are processed in an unspecified order.
 * Note that if a child inherits from the original table via multiple
 * inheritance paths, it will be visited just once.
 */
static void
ATSimpleRecursion(List **wqueue, Relation rel,
				  AlterTableCmd *cmd, bool recurse)
{
	/*
	 * Propagate to children if desired.  Non-table relations never have
	 * children, so no need to search in that case.
	 */
	if (recurse && rel->rd_rel->relkind == RELKIND_RELATION)
	{
		Oid			relid = RelationGetRelid(rel);
		ListCell   *child;
		List	   *children;

		/* this routine is actually in the planner */
		children = find_all_inheritors(relid);

		/*
		 * find_all_inheritors does the recursive search of the inheritance
		 * hierarchy, so all we have to do is process all of the relids in the
		 * list that it returns.
		 */
		foreach(child, children)
		{
			Oid			childrelid = lfirst_oid(child);
			Relation	childrel;

			if (childrelid == relid)
				continue;
			childrel = relation_open(childrelid, AccessExclusiveLock);
			CheckTableNotInUse(childrel, "ALTER TABLE");
			ATPrepCmd(wqueue, childrel, cmd, false, true);
			relation_close(childrel, NoLock);
		}
	}
}

/*
 * ATOneLevelRecursion
 *
 * Here, we visit only direct inheritance children.  It is expected that
 * the command's prep routine will recurse again to find indirect children.
 * When using this technique, a multiply-inheriting child will be visited
 * multiple times.
 */
/*
static void
ATOneLevelRecursion(List **wqueue, Relation rel,
					AlterTableCmd *cmd)
{
	Oid			relid = RelationGetRelid(rel);
	ListCell   *child;
	List	   *children;

	* this routine is actually in the planner *
	children = find_inheritance_children(relid);

	foreach(child, children)
	{
		Oid			childrelid = lfirst_oid(child);
		Relation	childrel;

		childrel = relation_open(childrelid, AccessExclusiveLock);
		CheckTableNotInUse(childrel, "ALTER TABLE");
		ATPrepCmd(wqueue, childrel, cmd, true, true);
		relation_close(childrel, NoLock);
	}
}
*/

/*
 * find_composite_type_dependencies
 *
 * Check to see if a composite type is being used as a column in some
 * other table (possibly nested several levels deep in composite types!).
 * Eventually, we'd like to propagate the check or rewrite operation
 * into other such tables, but for now, just error out if we find any.
 *
 * Caller should provide either a table name or a type name (not both) to
 * report in the error message, if any.
 *
 * We assume that functions and views depending on the type are not reasons
 * to reject the ALTER.  (How safe is this really?)
 */
void
find_composite_type_dependencies(Oid typeOid,
								 const char *origTblName,
								 const char *origTypeName)
{
	cqContext  *pcqCtx;
	HeapTuple	depTup;

	/*
	 * We scan pg_depend to find those things that depend on the rowtype. (We
	 * assume we can ignore refobjsubid for a rowtype.)
	 */

	pcqCtx = caql_beginscan(
			NULL,
			cql("SELECT * FROM pg_depend "
				" WHERE refclassid = :1 "
				" AND refobjid = :2 ",
				ObjectIdGetDatum(TypeRelationId),
				ObjectIdGetDatum(typeOid)));

	while (HeapTupleIsValid(depTup = caql_getnext(pcqCtx)))
	{
		Form_pg_depend pg_depend = (Form_pg_depend) GETSTRUCT(depTup);
		Relation	rel;
		Form_pg_attribute att;

		/* Ignore dependees that aren't user columns of relations */
		/* (we assume system columns are never of rowtypes) */
		if (pg_depend->classid != RelationRelationId ||
			pg_depend->objsubid <= 0)
			continue;

		rel = relation_open(pg_depend->objid, AccessShareLock);
		att = rel->rd_att->attrs[pg_depend->objsubid - 1];

		if (rel->rd_rel->relkind == RELKIND_RELATION)
		{
			if (origTblName)
				ereport(ERROR,
						(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
						 errmsg("cannot alter table \"%s\" because column \"%s\".\"%s\" uses its rowtype",
								origTblName,
								RelationGetRelationName(rel),
								NameStr(att->attname)),
										   errOmitLocation(true)));
			else
				ereport(ERROR,
						(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
						 errmsg("cannot alter type \"%s\" because column \"%s\".\"%s\" uses it",
								origTypeName,
								RelationGetRelationName(rel),
								NameStr(att->attname)),
										   errOmitLocation(true)));
		}
		else if (OidIsValid(rel->rd_rel->reltype))
		{
			/*
			 * A view or composite type itself isn't a problem, but we must
			 * recursively check for indirect dependencies via its rowtype.
			 */
			find_composite_type_dependencies(rel->rd_rel->reltype,
											 origTblName, origTypeName);
		}

		relation_close(rel, AccessShareLock);
	}
	caql_endscan(pcqCtx);
}


/*
 * ALTER TABLE ADD COLUMN
 *
 * Adds an additional attribute to a relation making the assumption that
 * CHECK, NOT NULL, and FOREIGN KEY constraints will be removed from the
 * AT_AddColumn AlterTableCmd by analyze.c and added as independent
 * AlterTableCmd's.
 */
static void
ATPrepAddColumn(Relation rel, bool recurse, AlterTableCmd *cmd)
{
	/* 
	 * If there's an encoding clause, this better be an append only
	 * column oriented table.
	 */
	ColumnDef *def = (ColumnDef *)cmd->def;
	if (def->encoding)
		ereport(ERROR,
				(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
				 errmsg("ENCODING clause supplied for table that is not supported")));

	if (def->encoding)
		def->encoding = transformStorageEncodingClause(def->encoding);

	/*
	 * If we are told not to recurse, there had better not be any child
	 * tables; else the addition would put them out of step.
	 */
	if (!recurse && find_inheritance_children(RelationGetRelid(rel)) != NIL)
	{
		ereport(ERROR,
				(errcode(ERRCODE_INVALID_TABLE_DEFINITION),
				 errmsg("column must be added to child tables too")));
	}
	/*
	 * We are the master and the table has child(ren):
	 * 		internally create and execute new AlterTableStmt(s) on child(ren)
	 * 		before dispatching the original AlterTableStmt
	 * This is to ensure that pg_constraint oid is consistent across segments for
	 * 		ALTER TABLE ... ADD COLUMN ... CHECK ...
	 */
	else if (Gp_role == GP_ROLE_DISPATCH)
	{
		/*
		 * Recurse to add the column to child classes.
		 *
		 * We must recurse one level at a time, so that multiply-inheriting
		 * children are visited the right number of times and end up with the
		 * right attinhcount.
		 */
		List		*children;
		ListCell	*lchild;

		children = find_inheritance_children(RelationGetRelid(rel));
		DestReceiver *dest = None_Receiver;
		foreach(lchild, children)
		{
			Oid 			childrelid = lfirst_oid(lchild);
			Relation 		childrel;

			RangeVar 		*rv;
			AlterTableCmd 	*atc;
			AlterTableStmt 	*ats;

			if (childrelid == RelationGetRelid(rel))
				continue;

			childrel = heap_open(childrelid, AccessShareLock);
			CheckTableNotInUse(childrel, "ALTER TABLE");

			/* Recurse to child */
			atc = copyObject(cmd);
			atc->subtype = AT_AddColumnRecurse;

			/* Child should see column as singly inherited */
			((ColumnDef *) atc->def)->inhcount = 1;
			((ColumnDef *) atc->def)->is_local = false;

			rv = makeRangeVar(NULL /*catalogname*/, get_namespace_name(RelationGetNamespace(childrel)),
							  get_rel_name(childrelid), -1);

			ats = makeNode(AlterTableStmt);
			ats->relation = rv;
			ats->cmds = list_make1(atc);
			ats->relkind = OBJECT_TABLE;

			heap_close(childrel, AccessShareLock);

			ProcessUtility((Node *)ats,
							synthetic_sql,
							NULL,
							false, /* not top level */
							dest,
							NULL);
		}
	}
}

void
ATAddColumn(Relation rel, ColumnDef *colDef)
{
	ATExecAddColumn((AlteredTableInfo*)NULL, rel, colDef);
}

static void
ATExecAddColumn(AlteredTableInfo *tab, Relation rel,
				ColumnDef *colDef)
{
	Oid			myrelid = RelationGetRelid(rel);
	Relation	pgclass,
				attrdesc;
	HeapTuple	reltup;
	HeapTuple	attributeTuple;
	Form_pg_attribute attribute;
	FormData_pg_attribute attributeD;
	int			i;
	int			minattnum,
				maxatts;
	HeapTuple	typeTuple;
	Oid			typeOid;
	Form_pg_type tform;
	Expr	   *defval;
	cqContext	cqc;
	cqContext	cqc2;
	cqContext  *pclaCtx;
	cqContext  *patCtx;

	/*
	 * Append Only tables don't support ADD COLUMN when no default value is
	 * specified. This is because this scenario makes a schema change that
	 * memtuples can't deal with yet. If a default value is specified than it
	 * it ok because the whole table will get re-written in phase 3. Let's
	 * catch this now before doing any real work. 
	 *
	 * coldDef->raw_default is null in 2 cases - when there is no DEFAULT 
	 * specified and when DEFAULT NULL is specified. We only want to block
	 * the case when there is no DEFAULT specified. Hence we also check
	 * colDef->default_is_null as it records the fact that DEFAULT NULL was 
	 * specified. 
 	*/
	 
	if ((RelationIsAoRows(rel) || RelationIsParquet(rel)) &&
		(!colDef->default_is_null && !colDef->raw_default))
	{
		ereport(ERROR,
				(errcode(ERRCODE_GP_FEATURE_NOT_YET),
				 errmsg("ADD COLUMN with no default value in append-only tables"
						" is not yet supported."),
								   errOmitLocation(true)
                ));
	}

	attrdesc = heap_open(AttributeRelationId, RowExclusiveLock);

	patCtx = caql_beginscan( 
			caql_addrel(cqclr(&cqc2), attrdesc),
			cql("INSERT INTO pg_attribute ",
				NULL));

	/*
	 * Are we adding the column to a recursion child?  If so, check whether to
	 * merge with an existing definition for the column.
	 */
	if (colDef->inhcount > 0)
	{
		HeapTuple	tuple;
		cqContext	cqc3;
		cqContext  *patCtx2;

		patCtx2 = caql_addrel(cqclr(&cqc3), attrdesc);

		/* Does child already have a column by this name? */
		tuple = caql_getattname(patCtx2, myrelid, colDef->colname);
		if (HeapTupleIsValid(tuple))
		{
			Form_pg_attribute childatt = (Form_pg_attribute) GETSTRUCT(tuple);

			/* Okay if child matches by type */
			if (typenameTypeId(NULL, colDef->typname) != childatt->atttypid ||
				colDef->typname->typmod != childatt->atttypmod)
				ereport(ERROR,
						(errcode(ERRCODE_DATATYPE_MISMATCH),
						 errmsg("child table \"%s\" has different type for column \"%s\"",
							RelationGetRelationName(rel), colDef->colname),
									   errOmitLocation(true)));

			/* Bump the existing child att's inhcount */
			childatt->attinhcount++;
			caql_update_current(patCtx2, tuple);
			/* and Update indexes (implicit) */

			heap_freetuple(tuple);

			/* Inform the user about the merge */
			if (Gp_role == GP_ROLE_EXECUTE)
			{
				ereport(DEBUG1,
			  (errmsg("merging definition of column \"%s\" for child \"%s\"",
					  colDef->colname, RelationGetRelationName(rel)),
							   errOmitLocation(true)));

			}
			else
			ereport(NOTICE,
			  (errmsg("merging definition of column \"%s\" for child \"%s\"",
					  colDef->colname, RelationGetRelationName(rel)),
							   errOmitLocation(true)));

			heap_close(attrdesc, RowExclusiveLock);
			return;
		}
	}

	pgclass = heap_open(RelationRelationId, RowExclusiveLock);

	pclaCtx = caql_addrel(cqclr(&cqc), pgclass);

	reltup = caql_getfirst(
			pclaCtx,
			cql("SELECT * FROM pg_class "
				" WHERE oid = :1 "
				" FOR UPDATE ",
				ObjectIdGetDatum(myrelid)));

	if (!HeapTupleIsValid(reltup))
		elog(ERROR, "cache lookup failed for relation %u", myrelid);

	/*
	 * this test is deliberately not attisdropped-aware, since if one tries to
	 * add a column matching a dropped column name, it's gonna fail anyway.
	 *
	 * For GPDB upgrade, we know that some columns don't exist, so don't go to
	 * the waste of looking them up. This could be a major cost if we're adding
	 * 20,000 columns for AO, for example.
	 */
	if (!(!IsUnderPostmaster && (rel->rd_rel->relkind == RELKIND_AOSEGMENTS ||
								 rel->rd_rel->relkind == RELKIND_AOBLOCKDIR)))
	{
		cqContext	cqc3;

		if (caql_getcount(
					caql_addrel(cqclr(&cqc3), attrdesc),
					cql("SELECT COUNT(*) FROM pg_attribute "
						" WHERE attrelid = :1 "
						" AND attname = :2 ",
						ObjectIdGetDatum(myrelid),
						PointerGetDatum(colDef->colname))))
		{
			ereport(ERROR,
					(errcode(ERRCODE_DUPLICATE_COLUMN),
					 errmsg("column \"%s\" of relation \"%s\" already exists",
							colDef->colname, RelationGetRelationName(rel)),
					 errOmitLocation(true)));
		}
	}
	minattnum = ((Form_pg_class) GETSTRUCT(reltup))->relnatts;
	maxatts = minattnum + 1;
	if (maxatts > MaxHeapAttributeNumber)
		ereport(ERROR,
				(errcode(ERRCODE_TOO_MANY_COLUMNS),
				 errmsg("tables can have at most %d columns",
						MaxHeapAttributeNumber)));
	i = minattnum + 1;

	typeTuple = typenameType(NULL, colDef->typname);
	tform = (Form_pg_type) GETSTRUCT(typeTuple);
	typeOid = HeapTupleGetOid(typeTuple);

	/* make sure datatype is legal for a column */
	CheckAttributeType(colDef->colname, typeOid);

	attributeTuple = heap_addheader(Natts_pg_attribute,
									false,
									ATTRIBUTE_TUPLE_SIZE,
									(void *) &attributeD);

	attribute = (Form_pg_attribute) GETSTRUCT(attributeTuple);

	attribute->attrelid = myrelid;
	namestrcpy(&(attribute->attname), colDef->colname);
	attribute->atttypid = typeOid;
	attribute->attstattarget = -1;
	attribute->attlen = tform->typlen;
	attribute->attcacheoff = -1;
	attribute->atttypmod = colDef->typname->typmod;
	attribute->attnum = i;
	attribute->attbyval = tform->typbyval;
	attribute->attndims = list_length(colDef->typname->arrayBounds);
	attribute->attstorage = tform->typstorage;
	attribute->attalign = tform->typalign;
	attribute->attnotnull = colDef->is_not_null;
	attribute->atthasdef = false;
	attribute->attisdropped = false;
	attribute->attislocal = colDef->is_local;
	attribute->attinhcount = colDef->inhcount;

	ReleaseType(typeTuple);

	caql_insert(patCtx, attributeTuple); /* implicit update of index as well */

	caql_endscan(patCtx);
	heap_close(attrdesc, RowExclusiveLock);

	/*
	 * Update number of attributes in pg_class tuple
	 */
	((Form_pg_class) GETSTRUCT(reltup))->relnatts = maxatts;

	caql_update_current(pclaCtx, reltup);/* implicit update of index as well */

	heap_freetuple(reltup);

	heap_close(pgclass, RowExclusiveLock);

	/* Make the attribute's catalog entry visible */
	CommandCounterIncrement();

	/*
	 * Store the DEFAULT, if any, in the catalogs
	 */
	if (colDef->raw_default)
	{
		RawColumnDefault *rawEnt;

		rawEnt = (RawColumnDefault *) palloc(sizeof(RawColumnDefault));
		rawEnt->attnum = attribute->attnum;
		rawEnt->raw_default = copyObject(colDef->raw_default);

		/*
		 * This function is intended for CREATE TABLE, so it processes a
		 * _list_ of defaults, but we just do one.
		 */
		AddRelationConstraints(rel, list_make1(rawEnt), NIL);

		/* Make the additional catalog changes visible */
		CommandCounterIncrement();
	}

	/*
	 * Tell Phase 3 to fill in the default expression, if there is one.
	 *
	 * If there is no default, Phase 3 doesn't have to do anything, because
	 * that effectively means that the default is NULL.  The heap tuple access
	 * routines always check for attnum > # of attributes in tuple, and return
	 * NULL if so, so without any modification of the tuple data we will get
	 * the effect of NULL values in the new column.
	 *
	 * An exception occurs when the new column is of a domain type: the domain
	 * might have a NOT NULL constraint, or a check constraint that indirectly
	 * rejects nulls.  If there are any domain constraints then we construct
	 * an explicit NULL default value that will be passed through
	 * CoerceToDomain processing.  (This is a tad inefficient, since it causes
	 * rewriting the table which we really don't have to do, but the present
	 * design of domain processing doesn't offer any simple way of checking
	 * the constraints more directly.)
	 *
	 * Note: we use build_column_default, and not just the cooked default
	 * returned by AddRelationConstraints, so that the right thing happens
	 * when a datatype's default applies.
	 */
	defval = (Expr *) build_column_default(rel, attribute->attnum);

	if (!defval && GetDomainConstraints(typeOid) != NIL)
	{
		Oid			basetype = getBaseType(typeOid);

		defval = (Expr *) makeNullConst(basetype, -1);
		defval = (Expr *) coerce_to_target_type(NULL, 
												(Node *) defval,
												basetype,
												typeOid,
												colDef->typname->typmod,
												COERCION_ASSIGNMENT,
												COERCE_IMPLICIT_CAST,
												-1);
		if (defval == NULL)		/* should not happen */
			elog(ERROR, "failed to coerce base type to domain");
	}

	/*
	 * MPP-14367/MPP-19664 - Handling of default NULL for AO/CO tables. Currently
	 * memtuples cannot deal with the scenario where the number of
  	 * attributes in the tuple data don't match the attnum. We will generate
	 * an explicit NULL default value and force a rewrite of the table below.
	 * Note: This is inefficient and there is already another JIRA MPP-5419 open
	 * to track adding columns without default values to AO tables efficiently.
	 * When that JIRA is fixed, the following piece of code may be removed
	 */
	if (!defval && (RelationIsAoRows(rel))
			&& colDef->default_is_null)
	{
		defval = (Expr *) makeNullConst(typeOid, -1);
	}

	if (defval)
	{
		NewColumnValue *newval;

		newval = (NewColumnValue *) palloc0(sizeof(NewColumnValue));
		newval->attnum = attribute->attnum;
		newval->expr = defval;

		/* tab is null if this is called by "create or replace view"
		 * which can't have any default value.
		 */
		Assert(tab);
		tab->newvals = lappend(tab->newvals, newval);
	}

	/*
	 * If the new column is NOT NULL, tell Phase 3 it needs to test that.
	 * Also, "create or replace view" won't have constraint on the column.
	 */
	Assert(!colDef->is_not_null || tab);
	if (tab)
		tab->new_notnull |= colDef->is_not_null;

	/*
	 * Add needed dependency entries for the new column.
	 */
	add_column_datatype_dependency(myrelid, i, attribute->atttypid);

	if (colDef->encoding)
		ereport(ERROR,
				(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
				 errmsg("ENCODING clause not supported")));
						
	/* MPP-6929: metadata tracking */
	if ((Gp_role == GP_ROLE_DISPATCH)
		&& MetaTrackValidKindNsp(rel->rd_rel))
		MetaTrackUpdObject(RelationRelationId,
						   RelationGetRelid(rel),
						   GetUserId(),
						   "ALTER", "ADD COLUMN"
				);

}

/*
 * Install a column's dependency on its datatype.
 */
static void
add_column_datatype_dependency(Oid relid, int32 attnum, Oid typid)
{
	ObjectAddress myself,
				referenced;

	myself.classId = RelationRelationId;
	myself.objectId = relid;
	myself.objectSubId = attnum;
	referenced.classId = TypeRelationId;
	referenced.objectId = typid;
	referenced.objectSubId = 0;
	recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
}

/*
 * ALTER TABLE ALTER COLUMN DROP NOT NULL
 */
static void
ATExecDropNotNull(Relation rel, const char *colName)
{
	HeapTuple	tuple;
	AttrNumber	attnum;
	Relation	attr_rel;
	List	   *indexoidlist;
	ListCell   *indexoidscan;
	cqContext	cqc;
	cqContext  *pcqCtx;

	/*
	 * lookup the attribute
	 */
	attr_rel = heap_open(AttributeRelationId, RowExclusiveLock);

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

	tuple = caql_getattname(pcqCtx, RelationGetRelid(rel), colName);

	if (!HeapTupleIsValid(tuple))
		ereport(ERROR,
				(errcode(ERRCODE_UNDEFINED_COLUMN),
				 errmsg("column \"%s\" of relation \"%s\" does not exist",
						colName, RelationGetRelationName(rel)),
				 errOmitLocation(true)));

	attnum = ((Form_pg_attribute) GETSTRUCT(tuple))->attnum;

	/* Prevent them from altering a system attribute */
	if (attnum <= 0)
		ereport(ERROR,
				(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
				 errmsg("cannot alter system column \"%s\"",
						colName)));

	/*
	 * Check that the attribute is not in a primary key
	 */

	/* Loop over all indexes on the relation */
	indexoidlist = RelationGetIndexList(rel);

	foreach(indexoidscan, indexoidlist)
	{
		Oid			indexoid = lfirst_oid(indexoidscan);
		HeapTuple	indexTuple;
		Form_pg_index indexStruct;
		int			i;
		cqContext  *pidxCtx;

		pidxCtx = caql_beginscan(
				NULL,
				cql("SELECT * FROM pg_index "
					" WHERE indexrelid = :1 ",
					ObjectIdGetDatum(indexoid)));

		indexTuple = caql_getnext(pidxCtx);

		if (!HeapTupleIsValid(indexTuple))
			elog(ERROR, "cache lookup failed for index %u", indexoid);
		indexStruct = (Form_pg_index) GETSTRUCT(indexTuple);

		/* If the index is not a primary key, skip the check */
		if (indexStruct->indisprimary)
		{
			/*
			 * Loop over each attribute in the primary key and see if it
			 * matches the to-be-altered attribute
			 */
			for (i = 0; i < indexStruct->indnatts; i++)
			{
				if (indexStruct->indkey.values[i] == attnum)
					ereport(ERROR,
							(errcode(ERRCODE_INVALID_TABLE_DEFINITION),
							 errmsg("column \"%s\" is in a primary key",
									colName),
							 errOmitLocation(true)));
			}
		}

		caql_endscan(pidxCtx);
	}

	list_free(indexoidlist);

	/*
	 * Okay, actually perform the catalog change ... if needed
	 */
	if (((Form_pg_attribute) GETSTRUCT(tuple))->attnotnull)
	{
		((Form_pg_attribute) GETSTRUCT(tuple))->attnotnull = FALSE;

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

	heap_close(attr_rel, RowExclusiveLock);

	/* MPP-6929: metadata tracking */
	if ((Gp_role == GP_ROLE_DISPATCH)
		&& MetaTrackValidKindNsp(rel->rd_rel))
		MetaTrackUpdObject(RelationRelationId,
						   RelationGetRelid(rel),
						   GetUserId(),
						   "ALTER", "ALTER COLUMN DROP NOT NULL"
				);

}

/*
 * ALTER TABLE ALTER COLUMN SET NOT NULL
 */
static void
ATExecSetNotNull(AlteredTableInfo *tab, Relation rel,
				 const char *colName)
{
	HeapTuple	tuple;
	AttrNumber	attnum;
	Relation	attr_rel;
	cqContext	cqc;
	cqContext  *pcqCtx;

	/*
	 * lookup the attribute
	 */
	attr_rel = heap_open(AttributeRelationId, RowExclusiveLock);

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

	tuple = caql_getattname(pcqCtx, RelationGetRelid(rel), colName);

	if (!HeapTupleIsValid(tuple))
		ereport(ERROR,
				(errcode(ERRCODE_UNDEFINED_COLUMN),
				 errmsg("column \"%s\" of relation \"%s\" does not exist",
						colName, RelationGetRelationName(rel)),
			     errOmitLocation(true)));

	attnum = ((Form_pg_attribute) GETSTRUCT(tuple))->attnum;

	/* Prevent them from altering a system attribute */
	if (attnum <= 0)
		ereport(ERROR,
				(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
				 errmsg("cannot alter system column \"%s\"",
						colName)));

	/*
	 * Okay, actually perform the catalog change ... if needed
	 */
	if (!((Form_pg_attribute) GETSTRUCT(tuple))->attnotnull)
	{
		((Form_pg_attribute) GETSTRUCT(tuple))->attnotnull = TRUE;

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

		/* Tell Phase 3 it needs to test the constraint */
		tab->new_notnull = true;
	}

	heap_close(attr_rel, RowExclusiveLock);

	/* MPP-6929: metadata tracking */
	if ((Gp_role == GP_ROLE_DISPATCH)
		&& MetaTrackValidKindNsp(rel->rd_rel))
		MetaTrackUpdObject(RelationRelationId,
						   RelationGetRelid(rel),
						   GetUserId(),
						   "ALTER", "ALTER COLUMN SET NOT NULL"
				);

}

/*
 * ALTER TABLE ALTER COLUMN SET/DROP DEFAULT
 */
static void
ATExecColumnDefault(Relation rel, const char *colName,
					Node *newDefault)
{
	AttrNumber	attnum;

	/*
	 * get the number of the attribute
	 */
	attnum = get_attnum(RelationGetRelid(rel), colName);
	if (attnum == InvalidAttrNumber)
		ereport(ERROR,
				(errcode(ERRCODE_UNDEFINED_COLUMN),
				 errmsg("column \"%s\" of relation \"%s\" does not exist",
						colName, RelationGetRelationName(rel)),
				 errOmitLocation(true)));

	/* Prevent them from altering a system attribute */
	if (attnum <= 0)
		ereport(ERROR,
				(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
				 errmsg("cannot alter system column \"%s\"",
						colName)));

	/*
	 * Remove any old default for the column.  We use RESTRICT here for
	 * safety, but at present we do not expect anything to depend on the
	 * default.
	 */
	RemoveAttrDefault(RelationGetRelid(rel), attnum, DROP_RESTRICT, false);

	if (newDefault)
	{
		/* SET DEFAULT */
		RawColumnDefault *rawEnt;

		rawEnt = (RawColumnDefault *) palloc(sizeof(RawColumnDefault));
		rawEnt->attnum = attnum;
		rawEnt->raw_default = newDefault;

		/*
		 * This function is intended for CREATE TABLE, so it processes a
		 * _list_ of defaults, but we just do one.
		 */
		AddRelationConstraints(rel, list_make1(rawEnt), NIL);
	}

	/* MPP-6929: metadata tracking */
	if ((Gp_role == GP_ROLE_DISPATCH)
		&& MetaTrackValidKindNsp(rel->rd_rel))
		MetaTrackUpdObject(RelationRelationId,
						   RelationGetRelid(rel),
						   GetUserId(),
						   "ALTER", "ALTER COLUMN DEFAULT"
				);


}

/*
 * ALTER TABLE ALTER COLUMN SET STATISTICS
 */
static void
ATPrepSetStatistics(Relation rel, const char *colName, Node *flagValue)
{
	/*
	 * We do our own permission checking because (a) we want to allow SET
	 * STATISTICS on indexes (for expressional index columns), and (b) we want
	 * to allow SET STATISTICS on system catalogs without requiring
	 * allowSystemTableModsDDL to be turned on.
	 */
	if (rel->rd_rel->relkind != RELKIND_RELATION &&
		rel->rd_rel->relkind != RELKIND_INDEX)
		ereport(ERROR,
				(errcode(ERRCODE_WRONG_OBJECT_TYPE),
				 errmsg("\"%s\" is not a table or index",
						RelationGetRelationName(rel)),
				 errOmitLocation(true)));

	/* Permissions checks */
	if (!pg_class_ownercheck(RelationGetRelid(rel), GetUserId()))
		aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_CLASS,
					   RelationGetRelationName(rel));
}

static void
ATExecSetStatistics(Relation rel, const char *colName, Node *newValue)
{
	int			newtarget;
	Relation	attrelation;
	HeapTuple	tuple;
	Form_pg_attribute attrtuple;
	cqContext	cqc;
	cqContext  *pcqCtx;

	Assert(IsA(newValue, Integer));
	newtarget = intVal(newValue);

	/*
	 * Limit target to a sane range
	 */
	if (newtarget < -1)
	{
		ereport(ERROR,
				(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
				 errmsg("statistics target %d is too low",
						newtarget)));
	}
	else if (newtarget > 1000)
	{
		newtarget = 1000;
		ereport(WARNING,
				(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
				 errmsg("lowering statistics target to %d",
						newtarget)));
	}

	attrelation = heap_open(AttributeRelationId, RowExclusiveLock);

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

	tuple = caql_getattname(pcqCtx, RelationGetRelid(rel), colName);

	if (!HeapTupleIsValid(tuple))
		ereport(ERROR,
				(errcode(ERRCODE_UNDEFINED_COLUMN),
				 errmsg("column \"%s\" of relation \"%s\" does not exist",
						colName, RelationGetRelationName(rel))));
	attrtuple = (Form_pg_attribute) GETSTRUCT(tuple);

	if (attrtuple->attnum <= 0)
		ereport(ERROR,
				(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
				 errmsg("cannot alter system column \"%s\"",
						colName)));

	attrtuple->attstattarget = newtarget;

	caql_update_current(pcqCtx, tuple); /* implicit update of index as well */

	heap_freetuple(tuple);

	heap_close(attrelation, RowExclusiveLock);

	/* MPP-6929: metadata tracking */
	if ((Gp_role == GP_ROLE_DISPATCH)
		&& MetaTrackValidKindNsp(rel->rd_rel))
		MetaTrackUpdObject(RelationRelationId,
						   RelationGetRelid(rel),
						   GetUserId(),
						   "ALTER", "ALTER COLUMN SET STATISTICS"
				);


}

/*
 * ALTER TABLE ALTER COLUMN SET STORAGE
 */
static void
ATExecSetStorage(Relation rel, const char *colName, Node *newValue)
{
	char	   *storagemode;
	char		newstorage;
	Relation	attrelation;
	HeapTuple	tuple;
	Form_pg_attribute attrtuple;
	cqContext	cqc;
	cqContext  *pcqCtx;

	Assert(IsA(newValue, String));
	storagemode = strVal(newValue);

	if (pg_strcasecmp(storagemode, "plain") == 0)
		newstorage = 'p';
	else if (pg_strcasecmp(storagemode, "external") == 0)
		newstorage = 'e';
	else if (pg_strcasecmp(storagemode, "extended") == 0)
		newstorage = 'x';
	else if (pg_strcasecmp(storagemode, "main") == 0)
		newstorage = 'm';
	else
	{
		ereport(ERROR,
				(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
				 errmsg("invalid storage type \"%s\"",
						storagemode)));
		newstorage = 0;			/* keep compiler quiet */
	}

	attrelation = heap_open(AttributeRelationId, RowExclusiveLock);

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

	tuple = caql_getattname(pcqCtx, RelationGetRelid(rel), colName);

	if (!HeapTupleIsValid(tuple))
		ereport(ERROR,
				(errcode(ERRCODE_UNDEFINED_COLUMN),
				 errmsg("column \"%s\" of relation \"%s\" does not exist",
						colName, RelationGetRelationName(rel)),
				 errOmitLocation(true)));
	attrtuple = (Form_pg_attribute) GETSTRUCT(tuple);

	if (attrtuple->attnum <= 0)
		ereport(ERROR,
				(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
				 errmsg("cannot alter system column \"%s\"",
						colName)));

	/*
	 * safety check: do not allow toasted storage modes unless column datatype
	 * is TOAST-aware.
	 */
	if (newstorage == 'p' || TypeIsToastable(attrtuple->atttypid))
		attrtuple->attstorage = newstorage;
	else
		ereport(ERROR,
				(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
				 errmsg("column data type %s can only have storage PLAIN",
						format_type_be(attrtuple->atttypid))));

	caql_update_current(pcqCtx, tuple); /* implicit update of index as well */

	heap_freetuple(tuple);

	heap_close(attrelation, RowExclusiveLock);
	
	/* MPP-6929: metadata tracking */
	if ((Gp_role == GP_ROLE_DISPATCH)
		&& MetaTrackValidKindNsp(rel->rd_rel))
		MetaTrackUpdObject(RelationRelationId,
						   RelationGetRelid(rel),
						   GetUserId(),
						   "ALTER", "ALTER COLUMN SET STORAGE"
				);
	
}


/*
 * ALTER TABLE DROP COLUMN
 *
 * DROP COLUMN cannot use the normal ALTER TABLE recursion mechanism,
 * because we have to decide at runtime whether to recurse or not depending
 * on whether attinhcount goes to zero or not.	(We can't check this in a
 * static pre-pass because it won't handle multiple inheritance situations
 * correctly.)
 */
static void
ATExecDropColumn(List **wqueue, Relation rel, const char *colName,
				 DropBehavior behavior,
				 bool recurse, bool recursing)
{
	HeapTuple	tuple;
	Form_pg_attribute targetatt;
	AttrNumber	attnum;
	List	   *children;
	ObjectAddress object;
	GpPolicy  *policy;
	PartitionNode *pn;
	cqContext	*pcqCtx;

	/* At top level, permission check was done in ATPrepCmd, else do it */
	if (recursing)
		ATSimplePermissions(rel, false);

	/*
	 * get the number of the attribute
	 */
	pcqCtx = caql_getattname_scan(NULL, RelationGetRelid(rel), colName);

	tuple = caql_get_current(pcqCtx);

	if (!HeapTupleIsValid(tuple))
		ereport(ERROR,
				(errcode(ERRCODE_UNDEFINED_COLUMN),
				 errmsg("column \"%s\" of relation \"%s\" does not exist",
						colName, RelationGetRelationName(rel))));
	targetatt = (Form_pg_attribute) GETSTRUCT(tuple);

	attnum = targetatt->attnum;

	/* Can't drop a system attribute, except OID */
	if (attnum <= 0 && attnum != ObjectIdAttributeNumber)
		ereport(ERROR,
				(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
				 errmsg("cannot drop system column \"%s\"",
						colName),
								   errOmitLocation(true)));

	/* Don't drop inherited columns */
	if (targetatt->attinhcount > 0 && !recursing)
		ereport(ERROR,
				(errcode(ERRCODE_INVALID_TABLE_DEFINITION),
				 errmsg("cannot drop inherited column \"%s\"",
						colName),
								   errOmitLocation(true)));

	/* better not be a column we partition on */
	pn = RelationBuildPartitionDesc(rel, false);
	if (pn)
	{
		List *patts = get_partition_attrs(pn);

		if (list_member_int(patts, attnum))
			ereport(ERROR,
					(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
					 errmsg("cannot drop partitioning column \"%s\"",
							colName),
									   errOmitLocation(true)));

		/*
		 * Remove any partition encoding entry
		 */
		RemovePartitionEncodingByRelidAttribute(RelationGetRelid(rel), attnum);
	}

	caql_endscan(pcqCtx);

	policy = rel->rd_cdbpolicy;
	if (policy != NULL && policy->ptype == POLICYTYPE_PARTITIONED)
	{
		int			ia = 0;

		for (ia = 0; ia < policy->nattrs; ia++)
		{
			if (attnum == policy->attrs[ia])
			{
				policy->nattrs = 0;
				rel->rd_cdbpolicy = GpPolicyCopy(GetMemoryChunkContext(rel), policy);
				GpPolicyReplace(RelationGetRelid(rel), policy);
				if (Gp_role != GP_ROLE_EXECUTE)
				    ereport(NOTICE,
						(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
						 errmsg("Dropping a column that is part of the "
								"distribution policy forces a "
								"NULL distribution policy"),
										   errOmitLocation(true)));
			}
		}
	}

	/*
	 * Propagate to children as appropriate.  Unlike most other ALTER
	 * routines, we have to do this one level of recursion at a time; we can't
	 * use find_all_inheritors to do it in one pass.
	 */
	children = find_inheritance_children(RelationGetRelid(rel));

	if (children)
	{
		Relation	attr_rel;
		ListCell   *child;

		attr_rel = heap_open(AttributeRelationId, RowExclusiveLock);
		foreach(child, children)
		{
			Oid			childrelid = lfirst_oid(child);
			Relation	childrel;
			Form_pg_attribute childatt;
			cqContext	cqc;
			cqContext  *attcqCtx;

			childrel = heap_open(childrelid, AccessExclusiveLock);
			CheckTableNotInUse(childrel, "ALTER TABLE");

			attcqCtx = caql_addrel(cqclr(&cqc), attr_rel);

			tuple = caql_getattname(attcqCtx, childrelid, colName);

			if (!HeapTupleIsValid(tuple))		/* shouldn't happen */
				elog(ERROR, "cache lookup failed for attribute \"%s\" of relation %u",
					 colName, childrelid);
			childatt = (Form_pg_attribute) GETSTRUCT(tuple);

			if (childatt->attinhcount <= 0)		/* shouldn't happen */
				elog(ERROR, "relation %u has non-inherited attribute \"%s\"",
					 childrelid, colName);

			if (recurse)
			{
				/*
				 * If the child column has other definition sources,
				 * just decrement its inheritance count;
				 * if not or if this is part of a partition
				 * configuration, recurse to delete it.
				 */
				if ((childatt->attinhcount == 1 && !childatt->attislocal) ||
					pn)
				{
					/* Time to delete this child column, too */
					ATExecDropColumn(wqueue, childrel, colName, behavior, true, true);
				}
				else
				{
					/* Child column must survive my deletion */
					childatt->attinhcount--;

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

					/* Make update visible */
					CommandCounterIncrement();
				}
			}
			else
			{
				/*
				 * If we were told to drop ONLY in this table (no recursion),
				 * we need to mark the inheritors' attribute as locally
				 * defined rather than inherited.
				 */
				childatt->attinhcount--;
				childatt->attislocal = true;

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

				/* Make update visible */
				CommandCounterIncrement();
			}

			heap_freetuple(tuple);

			heap_close(childrel, NoLock);
		}
		heap_close(attr_rel, RowExclusiveLock);
	}

	/*
	 * Perform the actual column deletion
	 */
	object.classId = RelationRelationId;
	object.objectId = RelationGetRelid(rel);
	object.objectSubId = attnum;

	performDeletion(&object, behavior);

	/*
	 * If we dropped the OID column, must adjust pg_class.relhasoids and
	 * tell Phase 3 to physically get rid of the column.
	 */
	if (attnum == ObjectIdAttributeNumber)
	{
		Form_pg_class tuple_class;
		AlteredTableInfo *tab;
		cqContext  *relcqCtx;

		relcqCtx = caql_beginscan(
				NULL,
				cql("SELECT * FROM pg_class "
					" WHERE oid = :1 "
					" FOR UPDATE ",
					ObjectIdGetDatum(RelationGetRelid(rel))));

		tuple = caql_getnext(relcqCtx);

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

		/* make a copy to update */
		tuple = heap_copytuple(tuple);

		tuple_class = (Form_pg_class) GETSTRUCT(tuple);

		tuple_class->relhasoids = false;

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

		caql_endscan(relcqCtx);
		
		/* Find or create work queue entry for this table */
		tab = ATGetQueueEntry(wqueue, rel);
		
		/* Tell Phase 3 to physically remove the OID column */
		tab->new_dropoids = true;
	}

	/* MPP-6929: metadata tracking */
	if ((Gp_role == GP_ROLE_DISPATCH)
		&& MetaTrackValidKindNsp(rel->rd_rel))
		MetaTrackUpdObject(RelationRelationId,
						   RelationGetRelid(rel),
						   GetUserId(),
						   "ALTER", "DROP COLUMN"
				);

}

/*
 * ALTER TABLE ADD INDEX
 *
 * There is no such command in the grammar, but the parser converts UNIQUE
 * and PRIMARY KEY constraints into AT_AddIndex subcommands.  This lets us
 * schedule creation of the index at the appropriate time during ALTER.
 */
static void
ATExecAddIndex(AlteredTableInfo *tab, Relation rel,
			   IndexStmt *stmt, bool is_rebuild, bool part_expanded)
{
	bool		check_rights;
	bool		skip_build;
	bool		quiet;

	Assert(IsA(stmt, IndexStmt));

	/* The index should already be built if we are a QE */
	if (Gp_role == GP_ROLE_EXECUTE)
		return;

	/* suppress schema rights check when rebuilding existing index */
	check_rights = !is_rebuild;
	/* skip index build if phase 3 will have to rewrite table anyway */
	skip_build = (tab->newvals != NIL);
	/* suppress notices when rebuilding existing index */
	quiet = is_rebuild;

	DefineIndex(RelationGetRelid(rel), /* relation */
				stmt->idxname,	/* index name */
				InvalidOid,		/* no predefined OID */
				stmt->accessMethod,		/* am name */
				stmt->tableSpace,
				stmt->indexParams,		/* parameters */
				(Expr *) stmt->whereClause,
				stmt->rangetable,
				stmt->options,
				stmt->unique,
				stmt->primary,
				stmt->isconstraint,
				true,			/* is_alter_table */
				check_rights,
				skip_build,
				quiet,
				false,
				part_expanded,
				stmt);

	/* 
	 * If we're the master and this is a partitioned table, cascade index
	 * creation for all children.
	 */
	if (Gp_role == GP_ROLE_DISPATCH &&
		rel_is_partitioned(RelationGetRelid(rel)))
	{
		List *children = find_all_inheritors(RelationGetRelid(rel));
		ListCell *lc;
		bool prefix_match = false;
		char *pname = RelationGetRelationName(rel);
		char *iname = stmt->idxname ? stmt->idxname : "idx";
		DestReceiver *dest = None_Receiver;

		/* is the parent relation name a prefix of the index name? */
		if (strlen(iname) > strlen(pname) &&
			strncmp(pname, iname, strlen(pname)) == 0)
			prefix_match = true;

		foreach(lc, children)
		{
			Oid relid = lfirst_oid(lc);
			Relation crel;
			IndexStmt *istmt;
			AlterTableStmt *ats;
			AlterTableCmd *atc;
			RangeVar *rv;
			char *idxname;

			if (relid == RelationGetRelid(rel))
				continue;

 			crel = heap_open(relid, AccessShareLock);
			istmt = copyObject(stmt);
			istmt->idxOids = NIL;
			istmt->is_part_child = true;
			istmt->constrOid = InvalidOid;

			ats = makeNode(AlterTableStmt);
			atc = makeNode(AlterTableCmd);

			rv = makeRangeVar(NULL /*catalogname*/, get_namespace_name(RelationGetNamespace(rel)),
							  get_rel_name(relid), -1);
			istmt->relation = rv;
			if (prefix_match)
			{
				/* 
				 * If the next character in the index name is '_', absorb
				 * it, as ChooseRelationName() will add another.
				 */
				int off = 0;
				if (iname[strlen(pname)] == '_')
					off = 1;
				idxname = ChooseRelationName(RelationGetRelationName(crel),
											 NULL,
											 (iname + strlen(pname) + off),
											 RelationGetNamespace(crel),
											 NULL);
			}
			else
				idxname = ChooseRelationName(RelationGetRelationName(crel),
											 NULL,
											 iname,
											 RelationGetNamespace(crel),
											 NULL);
			istmt->idxname = idxname;
			atc->subtype = AT_AddIndex;
			atc->def = (Node *)istmt;
			atc->part_expanded = true;

			ats->relation = copyObject(istmt->relation);
			ats->cmds = list_make1(atc);
			ats->relkind = OBJECT_TABLE;

			heap_close(crel, AccessShareLock); /* already locked master */

			ProcessUtility((Node *)ats, 
						   synthetic_sql,
						   NULL, 
						   false, /* not top level */
						   dest, 
						   NULL);
		}
	}

	/* MPP-6929: metadata tracking */
	if ((Gp_role == GP_ROLE_DISPATCH)
		&& MetaTrackValidKindNsp(rel->rd_rel))
		MetaTrackUpdObject(RelationRelationId,
						   RelationGetRelid(rel),
						   GetUserId(),
						   "ALTER", "ADD INDEX"
				);

}


static void
ATExecAddConstraint(AlteredTableInfo *tab, Relation rel, Node *newConstraint, bool recurse)
{
	switch (nodeTag(newConstraint))
	{
		case T_Constraint:
			{
				Constraint *constr = (Constraint *) newConstraint;
				/*
				 * Currently, we only expect to see CONSTR_CHECK nodes
				 * arriving here (see the preprocessing done in
				 * parser/analyze.c).  Use a switch anyway to make it easier
				 * to add more code later.
				 */
				switch (constr->contype)
				{
					case CONSTR_CHECK:
						{
							ATAddCheckConstraint(tab, rel, constr, recurse);
							break;
						}
					default:
						elog(ERROR, "unrecognized constraint type: %d",
							 (int) constr->contype);
				}
				break;
			}
		case T_FkConstraint:
			{
				FkConstraint *fkconstraint = (FkConstraint *) newConstraint;
				/*
				 * Assign or validate constraint name
				 */
				if (fkconstraint->constr_name)
				{
					if (ConstraintNameIsUsed(CONSTRAINT_RELATION,
											 RelationGetRelid(rel),
											 RelationGetNamespace(rel),
											 fkconstraint->constr_name))
						ereport(ERROR,
								(errcode(ERRCODE_DUPLICATE_OBJECT),
								 errmsg("constraint \"%s\" for relation \"%s\" already exists",
										fkconstraint->constr_name,
										RelationGetRelationName(rel)),
												   errOmitLocation(true)));
				}
				else
					fkconstraint->constr_name =
						ChooseConstraintName(RelationGetRelationName(rel),
									strVal(linitial(fkconstraint->fk_attrs)),
											 "fkey",
											 RelationGetNamespace(rel),
											 NIL);

				ATAddForeignKeyConstraint(tab, rel, fkconstraint);

				break;
			}
		default:
			elog(ERROR, "unrecognized node type: %d",
				 (int) nodeTag(newConstraint));
	}

	/* MPP-6929: metadata tracking */
	if ((Gp_role == GP_ROLE_DISPATCH)
		&& MetaTrackValidKindNsp(rel->rd_rel))
		MetaTrackUpdObject(RelationRelationId,
						   RelationGetRelid(rel),
						   GetUserId(),
						   "ALTER", "ADD CONSTRAINT"
				);

}

static void
ATAddCheckConstraint(AlteredTableInfo *tab, Relation rel, Constraint *constr, bool recurse)
{
	List		*newcons;
	ListCell	*lcon;
	List 		*children;
	ListCell	*lchild;

	/*
	 * Call AddRelationNewConstraints to do the work.
	 * It returns a list of cooked constraints.
	 */
	newcons = AddRelationConstraints(rel, NIL, list_make1(constr));

	/* Add each constraint to Phase 3's queue */
	foreach(lcon, newcons)
	{
		CookedConstraint *ccon = (CookedConstraint *) lfirst(lcon);
		NewConstraint *newcon;

		newcon = (NewConstraint *) palloc0(sizeof(NewConstraint));
		newcon->name = ccon->name;
		newcon->contype = ccon->contype;
		/* ExecQual wants implicit-AND format */
		newcon->qual = (Node *) make_ands_implicit((Expr *) ccon->expr);

		tab->constraints = lappend(tab->constraints, newcon);

		/* Save the actually assigned name if it was defaulted on partitioned table */
		if (rel_is_partitioned(RelationGetRelid(rel)) && constr->name == NULL)
			constr->name = ccon->name;
	}

	/*
	 * If this constraint needs to be recursed, this is a base/parent table,
	 * and we are the master, then cascade check constraint creation for all children.
	 * We do it here to synchronize pg_constraint oid.
	 */
	if (Gp_role == GP_ROLE_DISPATCH && recurse)
	{
		/* Propagate to children as appropriate. */
		children = find_inheritance_children(RelationGetRelid(rel));
		if (children == NIL)
			return;

		DestReceiver *dest = None_Receiver;
		foreach(lchild, children)
		{
			Oid 			childrelid = lfirst_oid(lchild);
			Relation 		childrel;
			Constraint 		*childconstr;

			RangeVar 		*rv;
			AlterTableCmd 	*atc;
			AlterTableStmt 	*ats;

			if (childrelid == RelationGetRelid(rel))
				continue;

 			childrel = heap_open(childrelid, AccessShareLock);
 			CheckTableNotInUse(childrel, "ALTER TABLE");

 			/* Recurse to child */
 			childconstr = copyObject(constr);
 			childconstr->conoid = InvalidOid;
 			//Insist(childconstr->name != NULL);

			rv = makeRangeVar(NULL /*catalogname*/, get_namespace_name(RelationGetNamespace(childrel)),
							  get_rel_name(childrelid), -1);

			atc = makeNode(AlterTableCmd);
			atc->subtype = AT_AddConstraintRecurse;
			atc->def = (Node *) childconstr;

			ats = makeNode(AlterTableStmt);
			ats->relation = rv;
			ats->cmds = list_make1(atc);
			ats->relkind = OBJECT_TABLE;

			heap_close(childrel, AccessShareLock);

			ProcessUtility((Node *)ats,
						   synthetic_sql,
						   NULL,
						   false, /* not top level */
						   dest,
						   NULL);
		}
	}
}


/*
 * Add a foreign-key constraint to a single table
 *
 * Subroutine for ATExecAddConstraint.	Must already hold exclusive
 * lock on the rel, and have done appropriate validity/permissions checks
 * for it.
 */
static void
ATAddForeignKeyConstraint(AlteredTableInfo *tab, Relation rel,
						  FkConstraint *fkconstraint)
{
	Relation	pkrel;
	AclResult	aclresult;
	int16		pkattnum[INDEX_MAX_KEYS];
	int16		fkattnum[INDEX_MAX_KEYS];
	Oid			pktypoid[INDEX_MAX_KEYS];
	Oid			fktypoid[INDEX_MAX_KEYS];
	Oid			opclasses[INDEX_MAX_KEYS];
	int			i;
	int			numfks,
				numpks;
	Oid			indexOid;
	Oid			constrOid;

	/*
	 * Grab an exclusive lock on the pk table, so that someone doesn't delete
	 * rows out from under us. (Although a lesser lock would do for that
	 * purpose, we'll need exclusive lock anyway to add triggers to the pk
	 * table; trying to start with a lesser lock will just create a risk of
	 * deadlock.)
	 */
	if (OidIsValid(fkconstraint->old_pktable_oid))
	{
		pkrel = heap_open(fkconstraint->old_pktable_oid, AccessExclusiveLock);
	}
	else
	{
		pkrel = heap_openrv(fkconstraint->pktable, AccessExclusiveLock);
	}

	/*
	 * Validity and permissions checks
	 *
	 * Note: REFERENCES permissions checks are redundant with CREATE TRIGGER,
	 * but we may as well error out sooner instead of later.
	 */
	if (pkrel->rd_rel->relkind != RELKIND_RELATION)
		ereport(ERROR,
				(errcode(ERRCODE_WRONG_OBJECT_TYPE),
				 errmsg("referenced relation \"%s\" is not a table",
						RelationGetRelationName(pkrel)),
								   errOmitLocation(true)));

	aclresult = pg_class_aclcheck(RelationGetRelid(pkrel), GetUserId(),
								  ACL_REFERENCES);
	if (aclresult != ACLCHECK_OK)
		aclcheck_error(aclresult, ACL_KIND_CLASS,
					   RelationGetRelationName(pkrel));

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

	aclresult = pg_class_aclcheck(RelationGetRelid(rel), GetUserId(),
								  ACL_REFERENCES);
	if (aclresult != ACLCHECK_OK)
		aclcheck_error(aclresult, ACL_KIND_CLASS,
					   RelationGetRelationName(rel));

	/*
	 * Disallow reference from permanent table to temp table or vice versa.
	 * (The ban on perm->temp is for fairly obvious reasons.  The ban on
	 * temp->perm is because other backends might need to run the RI triggers
	 * on the perm table, but they can't reliably see tuples the owning
	 * backend has created in the temp table, because non-shared buffers are
	 * used for temp tables.)
	 */
	if (isTempNamespace(RelationGetNamespace(pkrel)))
	{
		if (!isTempNamespace(RelationGetNamespace(rel)))
			ereport(ERROR,
					(errcode(ERRCODE_INVALID_TABLE_DEFINITION),
					 errmsg("cannot reference temporary table from permanent table constraint"),
							   errOmitLocation(true)));
	}
	else
	{
		if (isTempNamespace(RelationGetNamespace(rel)))
			ereport(ERROR,
					(errcode(ERRCODE_INVALID_TABLE_DEFINITION),
					 errmsg("cannot reference permanent table from temporary table constraint"),
							   errOmitLocation(true)));
	}
	
	/*
	 * Disallow reference to a part of a partitioned table.  A foreign key 
	 * must reference the whole partitioned table or none of it.
	 */
	if ( rel_is_child_partition(RelationGetRelid(pkrel)) )
	{
		ereport(ERROR,
				(errcode(ERRCODE_INVALID_TABLE_DEFINITION),
				 errmsg("cannot reference just part of a partitioned table"),
				 errOmitLocation(true)));
	}

	/*
	 * Look up the referencing attributes to make sure they exist, and record
	 * their attnums and type OIDs.
	 */
	MemSet(pkattnum, 0, sizeof(pkattnum));
	MemSet(fkattnum, 0, sizeof(fkattnum));
	MemSet(pktypoid, 0, sizeof(pktypoid));
	MemSet(fktypoid, 0, sizeof(fktypoid));
	MemSet(opclasses, 0, sizeof(opclasses));

	numfks = transformColumnNameList(RelationGetRelid(rel),
									 fkconstraint->fk_attrs,
									 fkattnum, fktypoid);

	/*
	 * If the attribute list for the referenced table was omitted, lookup the
	 * definition of the primary key and use it.  Otherwise, validate the
	 * supplied attribute list.  In either case, discover the index OID and
	 * index opclasses, and the attnums and type OIDs of the attributes.
	 */
	if (fkconstraint->pk_attrs == NIL)
	{
		numpks = transformFkeyGetPrimaryKey(pkrel, &indexOid,
											&fkconstraint->pk_attrs,
											pkattnum, pktypoid,
											opclasses);
	}
	else
	{
		numpks = transformColumnNameList(RelationGetRelid(pkrel),
										 fkconstraint->pk_attrs,
										 pkattnum, pktypoid);
		/* Look for an index matching the column list */
		indexOid = transformFkeyCheckAttrs(pkrel, numpks, pkattnum,
										   opclasses);
	}

	/* Be sure referencing and referenced column types are comparable */
	if (numfks != numpks)
		ereport(ERROR,
				(errcode(ERRCODE_INVALID_FOREIGN_KEY),
				 errmsg("number of referencing and referenced columns for foreign key disagree"),
						   errOmitLocation(true)));

	for (i = 0; i < numpks; i++)
	{
		/*
		 * pktypoid[i] is the primary key table's i'th key's type fktypoid[i]
		 * is the foreign key table's i'th key's type
		 *
		 * Note that we look for an operator with the PK type on the left;
		 * when the types are different this is critical because the PK index
		 * will need operators with the indexkey on the left. (Ordinarily both
		 * commutator operators will exist if either does, but we won't get
		 * the right answer from the test below on opclass membership unless
		 * we select the proper operator.)
		 */
		Operator	o = oper(NULL, list_make1(makeString("=")),
							 pktypoid[i], fktypoid[i],
							 true, -1);

		if (o == NULL)
			ereport(ERROR,
					(errcode(ERRCODE_UNDEFINED_FUNCTION),
					 errmsg("foreign key constraint \"%s\" "
							"cannot be implemented",
							fkconstraint->constr_name),
					 errdetail("Key columns \"%s\" and \"%s\" "
							   "are of incompatible types: %s and %s.",
							   strVal(list_nth(fkconstraint->fk_attrs, i)),
							   strVal(list_nth(fkconstraint->pk_attrs, i)),
							   format_type_be(fktypoid[i]),
							   format_type_be(pktypoid[i])),
									   errOmitLocation(true)));

		/*
		 * Check that the found operator is compatible with the PK index, and
		 * generate a warning if not, since otherwise costly seqscans will be
		 * incurred to check FK validity.
		 */
		if (Gp_role != GP_ROLE_EXECUTE && !op_in_opclass(oprid(o), opclasses[i]))
			ereport(WARNING,
					(errmsg("foreign key constraint \"%s\" "
							"will require costly sequential scans",
							fkconstraint->constr_name),
					 errdetail("Key columns \"%s\" and \"%s\" "
							   "are of different types: %s and %s.",
							   strVal(list_nth(fkconstraint->fk_attrs, i)),
							   strVal(list_nth(fkconstraint->pk_attrs, i)),
							   format_type_be(fktypoid[i]),
							   format_type_be(pktypoid[i])),
									   errOmitLocation(true)));

		ReleaseOperator(o);
	}

	/*
	 * Tell Phase 3 to check that the constraint is satisfied by existing rows
	 * (we can skip this during table creation).
	 */
	if (!fkconstraint->skip_validation)
	{
		NewConstraint *newcon;

		newcon = (NewConstraint *) palloc0(sizeof(NewConstraint));
		newcon->name = fkconstraint->constr_name;
		newcon->contype = CONSTR_FOREIGN;
		newcon->refrelid = RelationGetRelid(pkrel);
		newcon->qual = (Node *) fkconstraint;

		tab->constraints = lappend(tab->constraints, newcon);
	}

	/*
	 * Record the FK constraint in pg_constraint.
	 */
	constrOid = CreateConstraintEntry(fkconstraint->constr_name,
									  fkconstraint->constrOid,
									  RelationGetNamespace(rel),
									  CONSTRAINT_FOREIGN,
									  fkconstraint->deferrable,
									  fkconstraint->initdeferred,
									  RelationGetRelid(rel),
									  fkattnum,
									  numfks,
									  InvalidOid,		/* not a domain
														 * constraint */
									  RelationGetRelid(pkrel),
									  pkattnum,
									  numpks,
									  fkconstraint->fk_upd_action,
									  fkconstraint->fk_del_action,
									  fkconstraint->fk_matchtype,
									  indexOid,
									  NULL,		/* no check constraint */
									  NULL,
									  NULL);
	fkconstraint->constrOid = constrOid;

	/*
	 * Create the triggers that will enforce the constraint.
	 */
	createForeignKeyTriggers(rel, RelationGetRelid(pkrel), fkconstraint,
	                         constrOid);

	/*
	 * Close pk table, but keep lock until we've committed.
	 */
	heap_close(pkrel, NoLock);
}


/*
 * transformColumnNameList - transform list of column names
 *
 * Lookup each name and return its attnum and type OID
 */
static int
transformColumnNameList(Oid relId, List *colList,
						int16 *attnums, Oid *atttypids)
{
	ListCell   *l;
	int			attnum;

	attnum = 0;
	foreach(l, colList)
	{
		char	   *attname = strVal(lfirst(l));
		HeapTuple	atttuple;
		cqContext  *pcqCtx;

		pcqCtx = caql_getattname_scan(NULL, relId, attname);

		atttuple = caql_get_current(pcqCtx);

		if (!HeapTupleIsValid(atttuple))
			ereport(ERROR,
					(errcode(ERRCODE_UNDEFINED_COLUMN),
					 errmsg("column \"%s\" referenced in foreign key constraint does not exist",
							attname),
									   errOmitLocation(true)));
		if (attnum >= INDEX_MAX_KEYS)
			ereport(ERROR,
					(errcode(ERRCODE_TOO_MANY_COLUMNS),
					 errmsg("cannot have more than %d keys in a foreign key",
							INDEX_MAX_KEYS)));
		attnums[attnum] = ((Form_pg_attribute) GETSTRUCT(atttuple))->attnum;
		atttypids[attnum] = ((Form_pg_attribute) GETSTRUCT(atttuple))->atttypid;

		caql_endscan(pcqCtx);

		attnum++;
	}

	return attnum;
}

/*
 * transformFkeyGetPrimaryKey -
 *
 *	Look up the names, attnums, and types of the primary key attributes
 *	for the pkrel.	Also return the index OID and index opclasses of the
 *	index supporting the primary key.
 *
 *	All parameters except pkrel are output parameters.	Also, the function
 *	return value is the number of attributes in the primary key.
 *
 *	Used when the column list in the REFERENCES specification is omitted.
 */
static int
transformFkeyGetPrimaryKey(Relation pkrel, Oid *indexOid,
						   List **attnamelist,
						   int16 *attnums, Oid *atttypids,
						   Oid *opclasses)
{
	List	   *indexoidlist;
	ListCell   *indexoidscan;
	HeapTuple	indexTuple = NULL;
	Form_pg_index indexStruct = NULL;
	Datum		indclassDatum;
	bool		isnull;
	oidvector  *indclass;
	int			i;
	cqContext  *pcqCtx;

	/*
	 * Get the list of index OIDs for the table from the relcache, and look up
	 * each one in the pg_index syscache until we find one marked primary key
	 * (hopefully there isn't more than one such).
	 */
	*indexOid = InvalidOid;

	indexoidlist = RelationGetIndexList(pkrel);

	foreach(indexoidscan, indexoidlist)
	{
		Oid			indexoid = lfirst_oid(indexoidscan);

		pcqCtx = caql_beginscan(
				NULL,
				cql("SELECT * FROM pg_index "
					" WHERE indexrelid = :1 ",
					ObjectIdGetDatum(indexoid)));

		indexTuple = caql_getnext(pcqCtx);

		if (!HeapTupleIsValid(indexTuple))
			elog(ERROR, "cache lookup failed for index %u", indexoid);
		indexStruct = (Form_pg_index) GETSTRUCT(indexTuple);
		if (indexStruct->indisprimary)
		{
			*indexOid = indexoid;
			break;
		}
		caql_endscan(pcqCtx);
	}

	list_free(indexoidlist);

	/*
	 * Check that we found it
	 */
	if (!OidIsValid(*indexOid))
		ereport(ERROR,
				(errcode(ERRCODE_UNDEFINED_OBJECT),
				 errmsg("there is no primary key for referenced table \"%s\"",
						RelationGetRelationName(pkrel)),
								   errOmitLocation(true)));

	/* Must get indclass the hard way */
	indclassDatum = caql_getattr(pcqCtx,
								 Anum_pg_index_indclass, &isnull);
	Assert(!isnull);
	indclass = (oidvector *) DatumGetPointer(indclassDatum);

	/*
	 * Now build the list of PK attributes from the indkey definition (we
	 * assume a primary key cannot have expressional elements)
	 */
	*attnamelist = NIL;
	for (i = 0; i < indexStruct->indnatts; i++)
	{
		int			pkattno = indexStruct->indkey.values[i];

		attnums[i] = pkattno;
		atttypids[i] = attnumTypeId(pkrel, pkattno);
		opclasses[i] = indclass->values[i];
		*attnamelist = lappend(*attnamelist,
			   makeString(pstrdup(NameStr(*attnumAttName(pkrel, pkattno)))));
	}

	caql_endscan(pcqCtx);

	return i;
}

/*
 * transformFkeyCheckAttrs -
 *
 *	Make sure that the attributes of a referenced table belong to a unique
 *	(or primary key) constraint.  Return the OID of the index supporting
 *	the constraint, as well as the opclasses associated with the index
 *	columns.
 */
Oid
transformFkeyCheckAttrs(Relation pkrel,
						int numattrs, int16 *attnums,
						Oid *opclasses) /* output parameter */
{
	Oid			indexoid = InvalidOid;
	bool		found = false;
	List	   *indexoidlist;
	ListCell   *indexoidscan;

	/*
	 * Get the list of index OIDs for the table from the relcache, and look up
	 * each one in the pg_index syscache, and match unique indexes to the list
	 * of attnums we are given.
	 */
	indexoidlist = RelationGetIndexList(pkrel);

	foreach(indexoidscan, indexoidlist)
	{
		HeapTuple	indexTuple;
		cqContext  *pcqCtx;
		Form_pg_index indexStruct;
		int			i,
					j;

		indexoid = lfirst_oid(indexoidscan);
		pcqCtx = caql_beginscan(
				NULL,
				cql("SELECT * FROM pg_index "
					" WHERE indexrelid = :1 ",
					ObjectIdGetDatum(indexoid)));

		indexTuple = caql_getnext(pcqCtx);

		if (!HeapTupleIsValid(indexTuple))
			elog(ERROR, "cache lookup failed for index %u", indexoid);
		indexStruct = (Form_pg_index) GETSTRUCT(indexTuple);

		/*
		 * Must have the right number of columns; must be unique and not a
		 * partial index; forget it if there are any expressions, too
		 */
		if (indexStruct->indnatts == numattrs &&
			indexStruct->indisunique &&
			heap_attisnull(indexTuple, Anum_pg_index_indpred) &&
			heap_attisnull(indexTuple, Anum_pg_index_indexprs))
		{
			/* Must get indclass the hard way */
			Datum		indclassDatum;
			bool		isnull;
			oidvector  *indclass;

			indclassDatum = caql_getattr(pcqCtx,
										 Anum_pg_index_indclass, &isnull);
			Assert(!isnull);
			indclass = (oidvector *) DatumGetPointer(indclassDatum);

			/*
			 * The given attnum list may match the index columns in any order.
			 * Check that each list is a subset of the other.
			 */
			for (i = 0; i < numattrs; i++)
			{
				found = false;
				for (j = 0; j < numattrs; j++)
				{
					if (attnums[i] == indexStruct->indkey.values[j])
					{
						found = true;
						break;
					}
				}
				if (!found)
					break;
			}
			if (found)
			{
				for (i = 0; i < numattrs; i++)
				{
					found = false;
					for (j = 0; j < numattrs; j++)
					{
						if (attnums[j] == indexStruct->indkey.values[i])
						{
							opclasses[j] = indclass->values[i];
							found = true;
							break;
						}
					}
					if (!found)
						break;
				}
			}
		}
		caql_endscan(pcqCtx);
		if (found)
			break;
	} /* end foreach(indexoidscan, indexoidlist) */

	if (!found)
		ereport(ERROR,
				(errcode(ERRCODE_INVALID_FOREIGN_KEY),
				 errmsg("there is no unique constraint matching given keys for referenced table \"%s\"",
						RelationGetRelationName(pkrel)),
								   errOmitLocation(true)));

	list_free(indexoidlist);

	return indexoid;
}

/*
 * Scan the existing rows in a table to verify they meet a proposed FK
 * constraint.
 *
 * Caller must have opened and locked both relations.
 */
static void
validateForeignKeyConstraint(FkConstraint *fkconstraint,
							 Relation rel,
							 Relation pkrel)
{
	HeapScanDesc scan;
	HeapTuple	tuple;
	Trigger		trig;
	ListCell   *list;
	int			count;

	/*
	 * See if we can do it with a single LEFT JOIN query.  A FALSE result
	 * indicates we must proceed with the fire-the-trigger method.
	 */
	if (RI_Initial_Check(fkconstraint, rel, pkrel))
		return;

	/*
	 * Scan through each tuple, calling RI_FKey_check_ins (insert trigger) as
	 * if that tuple had just been inserted.  If any of those fail, it should
	 * ereport(ERROR) and that's that.
	 */
	MemSet(&trig, 0, sizeof(trig));
	trig.tgoid = InvalidOid;
	trig.tgname = fkconstraint->constr_name;
	trig.tgenabled = TRUE;
	trig.tgisconstraint = TRUE;
	trig.tgconstrrelid = RelationGetRelid(pkrel);
	trig.tgdeferrable = FALSE;
	trig.tginitdeferred = FALSE;

	trig.tgargs = (char **) palloc(sizeof(char *) *
								   (4 + list_length(fkconstraint->fk_attrs)
									+ list_length(fkconstraint->pk_attrs)));

	trig.tgargs[0] = trig.tgname;
	trig.tgargs[1] = RelationGetRelationName(rel);
	trig.tgargs[2] = RelationGetRelationName(pkrel);
	trig.tgargs[3] = fkMatchTypeToString(fkconstraint->fk_matchtype);
	count = 4;
	foreach(list, fkconstraint->fk_attrs)
	{
		char	   *fk_at = strVal(lfirst(list));

		trig.tgargs[count] = fk_at;
		count += 2;
	}
	count = 5;
	foreach(list, fkconstraint->pk_attrs)
	{
		char	   *pk_at = strVal(lfirst(list));

		trig.tgargs[count] = pk_at;
		count += 2;
	}
	trig.tgnargs = count - 1;

	scan = heap_beginscan(rel, SnapshotNow, 0, NULL);

	while ((tuple = heap_getnext(scan, ForwardScanDirection)) != NULL)
	{
		FunctionCallInfoData fcinfo;
		TriggerData trigdata;

		/*
		 * Make a call to the trigger function
		 *
		 * No parameters are passed, but we do set a context
		 */
		MemSet(&fcinfo, 0, sizeof(fcinfo));

		/*
		 * We assume RI_FKey_check_ins won't look at flinfo...
		 */
		trigdata.type = T_TriggerData;
		trigdata.tg_event = TRIGGER_EVENT_INSERT | TRIGGER_EVENT_ROW;
		trigdata.tg_relation = rel;
		trigdata.tg_trigtuple = tuple;
		trigdata.tg_newtuple = NULL;
		trigdata.tg_trigger = &trig;
		trigdata.tg_trigtuplebuf = scan->rs_cbuf;
		trigdata.tg_newtuplebuf = InvalidBuffer;

		fcinfo.context = (Node *) &trigdata;

		RI_FKey_check_ins(&fcinfo);
	}

	heap_endscan(scan);

	pfree(trig.tgargs);
}

static void
CreateFKCheckTrigger(Oid myRelOid, Oid refRelOid,
					 FkConstraint *fkconstraint,
					 ObjectAddress *constrobj, ObjectAddress *trigobj,
					 bool on_insert)
{
	CreateTrigStmt *fk_trigger;
	ListCell   *fk_attr;
	ListCell   *pk_attr;

	fk_trigger = makeNode(CreateTrigStmt);
	fk_trigger->trigname = fkconstraint->constr_name;
	fk_trigger->relation = NULL;
	fk_trigger->before = false;
	fk_trigger->row = true;

	/* Either ON INSERT or ON UPDATE */
	if (on_insert)
	{
		fk_trigger->funcname = SystemFuncName("RI_FKey_check_ins");
		fk_trigger->actions[0] = 'i';
		fk_trigger->trigOid = fkconstraint->trig1Oid;
	}
	else
	{
		fk_trigger->funcname = SystemFuncName("RI_FKey_check_upd");
		fk_trigger->actions[0] = 'u';
		fk_trigger->trigOid = fkconstraint->trig2Oid;
	}
	fk_trigger->actions[1] = '\0';

	fk_trigger->isconstraint = true;
	fk_trigger->deferrable = fkconstraint->deferrable;
	fk_trigger->initdeferred = fkconstraint->initdeferred;
	fk_trigger->constrrel = NULL;

	fk_trigger->args = NIL;
	fk_trigger->args = lappend(fk_trigger->args,
							   makeString(fkconstraint->constr_name));
	fk_trigger->args = lappend(fk_trigger->args,
							   makeString(get_rel_name(myRelOid)));
	fk_trigger->args = lappend(fk_trigger->args,
							   makeString(fkconstraint->pktable->relname));
	fk_trigger->args = lappend(fk_trigger->args,
				makeString(fkMatchTypeToString(fkconstraint->fk_matchtype)));
	if (list_length(fkconstraint->fk_attrs) != list_length(fkconstraint->pk_attrs))
		ereport(ERROR,
				(errcode(ERRCODE_INVALID_FOREIGN_KEY),
				 errmsg("number of referencing and referenced columns for foreign key disagree"),
						   errOmitLocation(true)));

	forboth(fk_attr, fkconstraint->fk_attrs,
			pk_attr, fkconstraint->pk_attrs)
	{
		fk_trigger->args = lappend(fk_trigger->args, lfirst(fk_attr));
		fk_trigger->args = lappend(fk_trigger->args, lfirst(pk_attr));
	}

	trigobj->objectId = CreateTrigger(fk_trigger, myRelOid, refRelOid, true);

	if (on_insert)
		fkconstraint->trig1Oid = trigobj->objectId;
	else
		fkconstraint->trig2Oid = trigobj->objectId;

	/* Register dependency from trigger to constraint */
	recordDependencyOn(trigobj, constrobj, DEPENDENCY_INTERNAL);

	/* Make changes-so-far visible */
	CommandCounterIncrement();
}

/*
 * Create the triggers that implement an FK constraint.
 */
static void
createForeignKeyTriggers(Relation rel, Oid refRelOid,
						 FkConstraint *fkconstraint, Oid constrOid)
{
	Oid         myRelOid;
	CreateTrigStmt *fk_trigger;
	ListCell   *fk_attr;
	ListCell   *pk_attr;
	ObjectAddress trigobj,
				constrobj;

	/*
	 * Special for Greenplum Database: Ignore foreign keys for now, with warning
	 */
	if (Gp_role == GP_ROLE_DISPATCH || Gp_role == GP_ROLE_EXECUTE)
	{
		if (Gp_role == GP_ROLE_DISPATCH)
			ereport(WARNING,
				(errcode(ERRCODE_INVALID_TABLE_DEFINITION),
				 errmsg("Referential integrity (FOREIGN KEY) constraints are not supported in Greenplum Database, will not be enforced."),
						   errOmitLocation(true)));
	}

	myRelOid = RelationGetRelid(rel);

	/*
	 * Preset objectAddress fields
	 */
	constrobj.classId = ConstraintRelationId;
	constrobj.objectId = constrOid;
	constrobj.objectSubId = 0;
	trigobj.classId = TriggerRelationId;
	trigobj.objectSubId = 0;

	/* Make changes-so-far visible */
	CommandCounterIncrement();

	/*
	 * Build and execute a CREATE CONSTRAINT TRIGGER statement for the CHECK
	 * action for both INSERTs and UPDATEs on the referencing table.
	 */
	CreateFKCheckTrigger(myRelOid, refRelOid, fkconstraint,
						 &constrobj, &trigobj, true);
	CreateFKCheckTrigger(myRelOid, refRelOid, fkconstraint,
						 &constrobj, &trigobj, false);

	/*
	 * Build and execute a CREATE CONSTRAINT TRIGGER statement for the ON
	 * DELETE action on the referenced table.
	 */
	fk_trigger = makeNode(CreateTrigStmt);
	fk_trigger->trigname = fkconstraint->constr_name;
	fk_trigger->relation = NULL;
	fk_trigger->before = false;
	fk_trigger->row = true;
	fk_trigger->actions[0] = 'd';
	fk_trigger->actions[1] = '\0';

	fk_trigger->isconstraint = true;
	fk_trigger->constrrel = NULL;
	switch (fkconstraint->fk_del_action)
	{
		case FKCONSTR_ACTION_NOACTION:
			fk_trigger->deferrable = fkconstraint->deferrable;
			fk_trigger->initdeferred = fkconstraint->initdeferred;
			fk_trigger->funcname = SystemFuncName("RI_FKey_noaction_del");
			break;
		case FKCONSTR_ACTION_RESTRICT:
			fk_trigger->deferrable = false;
			fk_trigger->initdeferred = false;
			fk_trigger->funcname = SystemFuncName("RI_FKey_restrict_del");
			break;
		case FKCONSTR_ACTION_CASCADE:
			fk_trigger->deferrable = false;
			fk_trigger->initdeferred = false;
			fk_trigger->funcname = SystemFuncName("RI_FKey_cascade_del");
			break;
		case FKCONSTR_ACTION_SETNULL:
			fk_trigger->deferrable = false;
			fk_trigger->initdeferred = false;
			fk_trigger->funcname = SystemFuncName("RI_FKey_setnull_del");
			break;
		case FKCONSTR_ACTION_SETDEFAULT:
			fk_trigger->deferrable = false;
			fk_trigger->initdeferred = false;
			fk_trigger->funcname = SystemFuncName("RI_FKey_setdefault_del");
			break;
		default:
			elog(ERROR, "unrecognized FK action type: %d",
				 (int) fkconstraint->fk_del_action);
			break;
	}

	fk_trigger->args = NIL;
	fk_trigger->args = lappend(fk_trigger->args,
							   makeString(fkconstraint->constr_name));
	fk_trigger->args = lappend(fk_trigger->args,
							   makeString(get_rel_name(myRelOid)));
	fk_trigger->args = lappend(fk_trigger->args,
							   makeString(fkconstraint->pktable->relname));
	fk_trigger->args = lappend(fk_trigger->args,
				makeString(fkMatchTypeToString(fkconstraint->fk_matchtype)));
	forboth(fk_attr, fkconstraint->fk_attrs,
			pk_attr, fkconstraint->pk_attrs)
	{
		fk_trigger->args = lappend(fk_trigger->args, lfirst(fk_attr));
		fk_trigger->args = lappend(fk_trigger->args, lfirst(pk_attr));
	}

	fk_trigger->trigOid = fkconstraint->trig3Oid;

	trigobj.objectId = CreateTrigger(fk_trigger, refRelOid, myRelOid, true);

	fkconstraint->trig3Oid = trigobj.objectId;

	/* Register dependency from trigger to constraint */
	recordDependencyOn(&trigobj, &constrobj, DEPENDENCY_INTERNAL);

	/* Make changes-so-far visible */
	CommandCounterIncrement();

	/*
	 * Build and execute a CREATE CONSTRAINT TRIGGER statement for the ON
	 * UPDATE action on the referenced table.
	 */
	fk_trigger = makeNode(CreateTrigStmt);
	fk_trigger->trigname = fkconstraint->constr_name;
	fk_trigger->relation = NULL;
	fk_trigger->before = false;
	fk_trigger->row = true;
	fk_trigger->actions[0] = 'u';
	fk_trigger->actions[1] = '\0';
	fk_trigger->isconstraint = true;
	fk_trigger->constrrel = NULL;
	switch (fkconstraint->fk_upd_action)
	{
		case FKCONSTR_ACTION_NOACTION:
			fk_trigger->deferrable = fkconstraint->deferrable;
			fk_trigger->initdeferred = fkconstraint->initdeferred;
			fk_trigger->funcname = SystemFuncName("RI_FKey_noaction_upd");
			break;
		case FKCONSTR_ACTION_RESTRICT:
			fk_trigger->deferrable = false;
			fk_trigger->initdeferred = false;
			fk_trigger->funcname = SystemFuncName("RI_FKey_restrict_upd");
			break;
		case FKCONSTR_ACTION_CASCADE:
			fk_trigger->deferrable = false;
			fk_trigger->initdeferred = false;
			fk_trigger->funcname = SystemFuncName("RI_FKey_cascade_upd");
			break;
		case FKCONSTR_ACTION_SETNULL:
			fk_trigger->deferrable = false;
			fk_trigger->initdeferred = false;
			fk_trigger->funcname = SystemFuncName("RI_FKey_setnull_upd");
			break;
		case FKCONSTR_ACTION_SETDEFAULT:
			fk_trigger->deferrable = false;
			fk_trigger->initdeferred = false;
			fk_trigger->funcname = SystemFuncName("RI_FKey_setdefault_upd");
			break;
		default:
			elog(ERROR, "unrecognized FK action type: %d",
				 (int) fkconstraint->fk_upd_action);
			break;
	}

	fk_trigger->args = NIL;
	fk_trigger->args = lappend(fk_trigger->args,
							   makeString(fkconstraint->constr_name));
	fk_trigger->args = lappend(fk_trigger->args,
							   makeString(get_rel_name(myRelOid)));
	fk_trigger->args = lappend(fk_trigger->args,
							   makeString(fkconstraint->pktable->relname));
	fk_trigger->args = lappend(fk_trigger->args,
				makeString(fkMatchTypeToString(fkconstraint->fk_matchtype)));
	forboth(fk_attr, fkconstraint->fk_attrs,
			pk_attr, fkconstraint->pk_attrs)
	{
		fk_trigger->args = lappend(fk_trigger->args, lfirst(fk_attr));
		fk_trigger->args = lappend(fk_trigger->args, lfirst(pk_attr));
	}

	fk_trigger->trigOid = fkconstraint->trig4Oid;

	trigobj.objectId = CreateTrigger(fk_trigger, refRelOid, myRelOid, true);

	fkconstraint->trig4Oid = trigobj.objectId;

	/* Register dependency from trigger to constraint */
	recordDependencyOn(&trigobj, &constrobj, DEPENDENCY_INTERNAL);
}

/*
 * fkMatchTypeToString -
 *	  convert FKCONSTR_MATCH_xxx code to string to use in trigger args
 */
static char *
fkMatchTypeToString(char match_type)
{
	switch (match_type)
	{
		case FKCONSTR_MATCH_FULL:
			return pstrdup("FULL");
		case FKCONSTR_MATCH_PARTIAL:
			return pstrdup("PARTIAL");
		case FKCONSTR_MATCH_UNSPECIFIED:
			return pstrdup("UNSPECIFIED");
		default:
			elog(ERROR, "unrecognized match type: %d",
				 (int) match_type);
	}
	return NULL;				/* can't get here */
}

/*
 * ALTER TABLE DROP CONSTRAINT
 */
static void
ATPrepDropConstraint(List **wqueue, Relation rel,
					 bool recurse, AlterTableCmd *cmd)
{
	/*
	 * We don't want errors or noise from child tables, so we have to pass
	 * down a modified command.
	 *
	 * This can't result in dropping the partitioning rule because the
	 * partitioning rule exists only on the part, and ATPrepCmd guards
	 * against dropping directly from parts.
	 */
	if (recurse)
	{
		AlterTableCmd *childCmd = copyObject(cmd);

		childCmd->subtype = AT_DropConstraintQuietly;
		ATSimpleRecursion(wqueue, rel, childCmd, recurse);
	}
}

static void
ATExecDropConstraint(Relation rel, const char *constrName,
					 DropBehavior behavior, bool quiet)
{
	int			deleted;

	deleted = RemoveRelConstraints(rel, constrName, behavior);

	if (!quiet)
	{
		/* If zero constraints deleted, complain */
		if (deleted == 0)
			ereport(ERROR,
					(errcode(ERRCODE_UNDEFINED_OBJECT),
					 errmsg("constraint \"%s\" does not exist",
							constrName),
									   errOmitLocation(true)));
		/* Otherwise if more than one constraint deleted, notify */
		else if (deleted > 1 && Gp_role != GP_ROLE_EXECUTE)
			ereport(NOTICE,
					(errmsg("multiple constraints named \"%s\" were dropped",
							constrName),
									   errOmitLocation(true)));
	}

	/* MPP-6929: metadata tracking */
	if ((Gp_role == GP_ROLE_DISPATCH)
		&& MetaTrackValidKindNsp(rel->rd_rel))
		MetaTrackUpdObject(RelationRelationId,
						   RelationGetRelid(rel),
						   GetUserId(),
						   "ALTER", "DROP CONSTRAINT"
				);

}

/*
 * ALTER COLUMN TYPE
 */
static void
ATPrepAlterColumnType(List **wqueue,
					  AlteredTableInfo *tab, Relation rel,
					  bool recurse, bool recursing,
					  AlterTableCmd *cmd)
{
	char	   *colName = cmd->name;
	TypeName   *typname = (TypeName *) cmd->def;
	HeapTuple	tuple;
	Form_pg_attribute attTup;
	AttrNumber	attnum;
	Oid			targettype;
	Node	   *transform;
	NewColumnValue *newval;
	ParseState *pstate = make_parsestate(NULL);
	cqContext  *pcqCtx;

	/* lookup the attribute so we can check inheritance status */
	pcqCtx = caql_getattname_scan(NULL, RelationGetRelid(rel), colName);
	
	tuple = caql_get_current(pcqCtx);
	
	if (!HeapTupleIsValid(tuple))
		ereport(ERROR,
				(errcode(ERRCODE_UNDEFINED_COLUMN),
				 errmsg("column \"%s\" of relation \"%s\" does not exist",
						colName, RelationGetRelationName(rel)),
								   errOmitLocation(true)));
	attTup = (Form_pg_attribute) GETSTRUCT(tuple);
	attnum = attTup->attnum;

	/* Can't alter a system attribute */
	if (attnum <= 0)
		ereport(ERROR,
				(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
				 errmsg("cannot alter system column \"%s\"",
						colName),
								   errOmitLocation(true)));

	/* Don't alter inherited columns */
	if (attTup->attinhcount > 0 && !recursing)
		ereport(ERROR,
				(errcode(ERRCODE_INVALID_TABLE_DEFINITION),
				 errmsg("cannot alter inherited column \"%s\"",
						colName),
								   errOmitLocation(true)));

	/* Look up the target type */
	targettype = typenameTypeId(NULL, typname);

	/* make sure datatype is legal for a column */
	CheckAttributeType(colName, targettype);

	/*
	 * Set up an expression to transform the old data value to the new type.
	 * If a USING option was given, transform and use that expression, else
	 * just take the old value and try to coerce it.  We do this first so that
	 * type incompatibility can be detected before we waste effort, and
	 * because we need the expression to be parsed against the original table
	 * rowtype.
	 */

	/* GPDB: we always need the RTE */
	{
		RangeTblEntry *rte;

		/* Expression must be able to access vars of old table */
		rte = addRangeTableEntryForRelation(pstate,
											rel,
											NULL,
											false,
											true);
		addRTEtoQuery(pstate, rte, false, true, true);
	}

	if (cmd->transform)
	{
		transform = transformExpr(pstate, cmd->transform);
		/* It can't return a set */
		if (expression_returns_set(transform))
			ereport(ERROR,
					(errcode(ERRCODE_DATATYPE_MISMATCH),
					 errmsg("transform expression must not return a set"),
							   errOmitLocation(true)));

		/* No subplans or aggregates, either... */
		if (pstate->p_hasSubLinks)
			ereport(ERROR,
					(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
					 errmsg("cannot use subquery in transform expression"),
							   errOmitLocation(true)));
		if (pstate->p_hasAggs)
			ereport(ERROR,
					(errcode(ERRCODE_GROUPING_ERROR),
			errmsg("cannot use aggregate function in transform expression"),
					   errOmitLocation(true)));
		if (pstate->p_hasWindFuncs)
			ereport(ERROR,
					(errcode(ERRCODE_SYNTAX_ERROR),
			errmsg("cannot use window function in transform expression"),
					   errOmitLocation(true)));

	}
	else
	{
		transform = (Node *) makeVar(1, attnum,
									 attTup->atttypid, attTup->atttypmod,
									 0);
	}

	transform = coerce_to_target_type(pstate,
									  transform, exprType(transform),
									  targettype, typname->typmod,
									  COERCION_ASSIGNMENT,
									  COERCE_IMPLICIT_CAST,
									  -1);
	if (transform == NULL)
		ereport(ERROR,
				(errcode(ERRCODE_DATATYPE_MISMATCH),
				 errmsg("column \"%s\" cannot be cast to type \"%s\"",
						colName, TypeNameToString(typname)),
								   errOmitLocation(true)));

	free_parsestate(&pstate);

	/*
	 * Add a work queue item to make ATRewriteTable update the column
	 * contents.
	 */
	newval = (NewColumnValue *) palloc0(sizeof(NewColumnValue));
	newval->attnum = attnum;
	newval->expr = (Expr *) transform;

	tab->newvals = lappend(tab->newvals, newval);

	caql_endscan(pcqCtx);

	/*
	 * The recursion case is handled by ATSimpleRecursion.	However, if we are
	 * told not to recurse, there had better not be any child tables; else the
	 * alter would put them out of step.
	 */
	if (recurse)
		ATSimpleRecursion(wqueue, rel, cmd, recurse);
	else if (!recursing &&
			 find_inheritance_children(RelationGetRelid(rel)) != NIL)
		ereport(ERROR,
				(errcode(ERRCODE_INVALID_TABLE_DEFINITION),
				 errmsg("type of inherited column \"%s\" must be changed in child tables too",
						colName),
								   errOmitLocation(true)));
}

static void
ATExecAlterColumnType(AlteredTableInfo *tab, Relation rel,
					  const char *colName, TypeName *typname)
{
	HeapTuple	heapTup;
	Form_pg_attribute attTup;
	AttrNumber	attnum;
	HeapTuple	typeTuple;
	Form_pg_type tform;
	Oid			targettype;
	Node	   *defaultexpr;
	Relation	attrelation;
	Relation	depRel;
	HeapTuple	depTup;
	GpPolicy * policy = NULL;
	bool		sourceIsInt = false;
	bool		targetIsInt = false;
	bool		sourceIsVarlenA = false;
	bool		targetIsVarlenA = false;
	bool		hashCompatible = false;
	cqContext	cqc;
	cqContext	cqc2;
	cqContext  *pcqCtx;
	cqContext  *patCtx;

	attrelation = heap_open(AttributeRelationId, RowExclusiveLock);

	patCtx = caql_addrel(cqclr(&cqc2), attrelation);

	/* Look up the target column */
	heapTup = caql_getattname(patCtx, RelationGetRelid(rel), colName);

	if (!HeapTupleIsValid(heapTup))		/* shouldn't happen */
		ereport(ERROR,
				(errcode(ERRCODE_UNDEFINED_COLUMN),
				 errmsg("column \"%s\" of relation \"%s\" does not exist",
						colName, RelationGetRelationName(rel)),
								   errOmitLocation(true)));
	attTup = (Form_pg_attribute) GETSTRUCT(heapTup);
	attnum = attTup->attnum;

	/* Check for multiple ALTER TYPE on same column --- can't cope */
	if (attTup->atttypid != tab->oldDesc->attrs[attnum - 1]->atttypid ||
		attTup->atttypmod != tab->oldDesc->attrs[attnum - 1]->atttypmod)
		ereport(ERROR,
				(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
				 errmsg("cannot alter type of column \"%s\" twice",
						colName),
								   errOmitLocation(true)));

	/* Look up the target type (should not fail, since prep found it) */
	typeTuple = typenameType(NULL, typname);
	tform = (Form_pg_type) GETSTRUCT(typeTuple);
	targettype = HeapTupleGetOid(typeTuple);

	if (targettype == INT4OID ||
		targettype == INT2OID ||
		targettype == INT8OID)
		sourceIsInt = true;

	if (attTup->atttypid == INT4OID ||
		attTup->atttypid == INT2OID ||
		attTup->atttypid == INT8OID)
		targetIsInt = true;

	if (targettype == VARCHAROID ||
		targettype == CHAROID ||
		targettype == TEXTOID)
		targetIsVarlenA = true;

	if (attTup->atttypid == VARCHAROID ||
		attTup->atttypid == CHAROID ||
		attTup->atttypid == TEXTOID)
		sourceIsVarlenA = true;

	if (sourceIsInt && targetIsInt)
		hashCompatible = true;
	else if (sourceIsVarlenA && targetIsVarlenA)
		hashCompatible = true;

	/*
	 * If there is a default expression for the column, get it and ensure we
	 * can coerce it to the new datatype.  (We must do this before changing
	 * the column type, because build_column_default itself will try to
	 * coerce, and will not issue the error message we want if it fails.)
	 *
	 * We remove any implicit coercion steps at the top level of the old
	 * default expression; this has been agreed to satisfy the principle of
	 * least surprise.	(The conversion to the new column type should act like
	 * it started from what the user sees as the stored expression, and the
	 * implicit coercions aren't going to be shown.)
	 */
	if (attTup->atthasdef)
	{
		defaultexpr = build_column_default(rel, attnum);
		Assert(defaultexpr);
		defaultexpr = strip_implicit_coercions(defaultexpr);
		defaultexpr = coerce_to_target_type(NULL,		/* no UNKNOWN params */
										  defaultexpr, exprType(defaultexpr),
											targettype, typname->typmod,
											COERCION_ASSIGNMENT,
											COERCE_IMPLICIT_CAST,
											-1);
		if (defaultexpr == NULL)
			ereport(ERROR,
					(errcode(ERRCODE_DATATYPE_MISMATCH),
			errmsg("default for column \"%s\" cannot be cast to type \"%s\"",
				   colName, TypeNameToString(typname)),
						   errOmitLocation(true)));
	}
	else
		defaultexpr = NULL;

	/*
	 * Find everything that depends on the column (constraints, indexes, etc),
	 * and record enough information to let us recreate the objects.
	 *
	 * The actual recreation does not happen here, but only after we have
	 * performed all the individual ALTER TYPE operations.	We have to save
	 * the info before executing ALTER TYPE, though, else the deparser will
	 * get confused.
	 *
	 * There could be multiple entries for the same object, so we must check
	 * to ensure we process each one only once.  Note: we assume that an index
	 * that implements a constraint will not show a direct dependency on the
	 * column.
	 */
	depRel = heap_open(DependRelationId, RowExclusiveLock);

	/* FOR UPDATE due to DELETE later... */
	pcqCtx = caql_beginscan(
			caql_addrel(cqclr(&cqc), depRel),
			cql("SELECT * FROM pg_depend "
				" WHERE refclassid = :1 "
				" AND refobjid = :2 "
				" AND refobjsubid = :3 "
				" FOR UPDATE ",
				ObjectIdGetDatum(RelationRelationId),
				ObjectIdGetDatum(RelationGetRelid(rel)),
				Int32GetDatum((int32) attnum)));

	while (HeapTupleIsValid(depTup = caql_getnext(pcqCtx)))
	{
		Form_pg_depend foundDep = (Form_pg_depend) GETSTRUCT(depTup);
		ObjectAddress foundObject;

		/* We don't expect any PIN dependencies on columns */
		if (foundDep->deptype == DEPENDENCY_PIN)
			elog(ERROR, "cannot alter type of a pinned column");

		foundObject.classId = foundDep->classid;
		foundObject.objectId = foundDep->objid;
		foundObject.objectSubId = foundDep->objsubid;

		switch (getObjectClass(&foundObject))
		{
			case OCLASS_CLASS:
				{
					char		relKind = get_rel_relkind(foundObject.objectId);

					if (relKind == RELKIND_INDEX)
					{
						Assert(foundObject.objectSubId == 0);
						if (!list_member_oid(tab->changedIndexOids, foundObject.objectId))
						{
							char * indexdefstring = pg_get_indexdef_string(foundObject.objectId);
							tab->changedIndexOids = lappend_oid(tab->changedIndexOids,
													   foundObject.objectId);
							tab->changedIndexDefs = lappend(tab->changedIndexDefs,indexdefstring);

							if (Gp_role == GP_ROLE_DISPATCH && indexdefstring &&strstr(indexdefstring," UNIQUE ")!=0 && !hashCompatible)
							{
								policy = rel->rd_cdbpolicy;
								if (policy != NULL && policy->ptype == POLICYTYPE_PARTITIONED)
								{
									int			ia = 0;

									if (cdbRelSize(rel) != 0)

									for (ia = 0; ia < policy->nattrs; ia++)
									{
										if (attnum == policy->attrs[ia])
										{
											ereport(ERROR,
													(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
													 errmsg("Changing the type of a column that is part of the distribution policy and used in a unique index is not allowed"),
															   errOmitLocation(true)));
										}
									}
								}
							}
						}
					}
					else if (relKind == RELKIND_SEQUENCE)
					{
						/*
						 * This must be a SERIAL column's sequence.  We need
						 * not do anything to it.
						 */
						Assert(foundObject.objectSubId == 0);
					}
					else
					{
						/* Not expecting any other direct dependencies... */
						elog(ERROR, "unexpected object depending on column: %s",
							 getObjectDescription(&foundObject));
					}
					break;
				}

			case OCLASS_CONSTRAINT:
				Assert(foundObject.objectSubId == 0);
				if (!list_member_oid(tab->changedConstraintOids,
									 foundObject.objectId))
				{
					char	   *defstring = pg_get_constraintdef_string(foundObject.objectId);

					if (Gp_role == GP_ROLE_DISPATCH && !hashCompatible)
					if (strstr(defstring," UNIQUE")!=0 ||
						strstr(defstring,"PRIMARY KEY")!=0 )
					{
						policy = rel->rd_cdbpolicy;
						if (policy != NULL && policy->ptype == POLICYTYPE_PARTITIONED)
						{
							int			ia = 0;

							if (cdbRelSize(rel) != 0)

							for (ia = 0; ia < policy->nattrs; ia++)
							{
								if (attnum == policy->attrs[ia])
								{
									ereport(ERROR,
											(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
											 errmsg("Changing the type of a column that is used in a UNIQUE or PRIMARY KEY constraint is not allowed"),
													   errOmitLocation(true)));
								}
							}
						}
					}

					/*
					 * Put NORMAL dependencies at the front of the list and
					 * AUTO dependencies at the back.  This makes sure that
					 * foreign-key constraints depending on this column will
					 * be dropped before unique or primary-key constraints of
					 * the column; which we must have because the FK
					 * constraints depend on the indexes belonging to the
					 * unique constraints.
					 */
					if (foundDep->deptype == DEPENDENCY_NORMAL)
					{
						tab->changedConstraintOids =
							lcons_oid(foundObject.objectId,
									  tab->changedConstraintOids);
						tab->changedConstraintDefs =
							lcons(defstring,
								  tab->changedConstraintDefs);
					}
					else
					{
						tab->changedConstraintOids =
							lappend_oid(tab->changedConstraintOids,
													   foundObject.objectId);
						tab->changedConstraintDefs =
							lappend(tab->changedConstraintDefs,
									defstring);
				}
				}
				break;

			case OCLASS_REWRITE:
				/* XXX someday see if we can cope with revising views */
				ereport(ERROR,
						(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
						 errmsg("cannot alter type of a column used by a view or rule"),
						 errdetail("%s depends on column \"%s\"",
								   getObjectDescription(&foundObject),
								   colName),
										   errOmitLocation(true)));
				break;

			case OCLASS_DEFAULT:

				/*
				 * Ignore the column's default expression, since we will fix
				 * it below.
				 */
				Assert(defaultexpr);
				break;

			case OCLASS_PROC:
			case OCLASS_TYPE:
			case OCLASS_CAST:
			case OCLASS_CONVERSION:
			case OCLASS_LANGUAGE:
			case OCLASS_OPERATOR:
			case OCLASS_OPCLASS:
			case OCLASS_TRIGGER:
			case OCLASS_SCHEMA:

				/*
				 * We don't expect any of these sorts of objects to depend on
				 * a column.
				 */
				elog(ERROR, "unexpected object depending on column: %s",
					 getObjectDescription(&foundObject));
				break;

			default:
				elog(ERROR, "unrecognized object class: %u",
					 foundObject.classId);
		}
	}

	caql_endscan(pcqCtx);

	/*
	 * Now scan for dependencies of this column on other things.  The only
	 * thing we should find is the dependency on the column datatype, which we
	 * want to remove.
	 */

	pcqCtx = caql_beginscan(
			caql_addrel(cqclr(&cqc), depRel),
			cql("SELECT * FROM pg_depend "
				" WHERE classid = :1 "
				" AND objid = :2 "
				" AND objsubid = :3 "
				" FOR UPDATE ",
				ObjectIdGetDatum(RelationRelationId),
				ObjectIdGetDatum(RelationGetRelid(rel)),
				Int32GetDatum((int32) attnum)));

	while (HeapTupleIsValid(depTup = caql_getnext(pcqCtx)))
	{
		Form_pg_depend foundDep = (Form_pg_depend) GETSTRUCT(depTup);

		if (foundDep->deptype != DEPENDENCY_NORMAL)
			elog(ERROR, "found unexpected dependency type '%c'",
				 foundDep->deptype);
		if (foundDep->refclassid != TypeRelationId ||
			foundDep->refobjid != attTup->atttypid)
			elog(ERROR, "found unexpected dependency for column");

		caql_delete_current(pcqCtx);
	}

	caql_endscan(pcqCtx);
	heap_close(depRel, RowExclusiveLock);

	policy = rel->rd_cdbpolicy;
	if (policy != NULL && policy->ptype == POLICYTYPE_PARTITIONED &&
		!hashCompatible)
	{
		if (Gp_role != GP_ROLE_EXECUTE)
		{
			int			ia = 0;
			ListCell   *lc;
			List	   *partkeys;
			
			partkeys = rel_partition_key_attrs(rel->rd_id);
			foreach (lc, partkeys)
			{
				if ( attnum == lfirst_int(lc) )
					ereport(ERROR,
							(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
							 errmsg("cannot alter type of a column used in "
									"a partitioning key"),
							 errOmitLocation(true)));
			}

			if (cdbRelSize(rel) != 0)
			{
				for (ia = 0; ia < policy->nattrs; ia++)
				{
					if (attnum == policy->attrs[ia])
						ereport(ERROR,
								(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
								 errmsg("cannot alter type of a column used in "
										"a distribution policy"),
								 errOmitLocation(true)));
				}
			}
		}
	}

	/*
	 * Here we go --- change the recorded column type.	(Note heapTup is a
	 * copy of the syscache entry, so okay to scribble on.)
	 */
	attTup->atttypid = targettype;
	attTup->atttypmod = typname->typmod;
	attTup->attndims = list_length(typname->arrayBounds);
	attTup->attlen = tform->typlen;
	attTup->attbyval = tform->typbyval;
	attTup->attalign = tform->typalign;
	attTup->attstorage = tform->typstorage;

	ReleaseType(typeTuple);

	caql_update_current(patCtx, heapTup);/* implicit update of index as well */

	heap_close(attrelation, RowExclusiveLock);

	/* Install dependency on new datatype */
	add_column_datatype_dependency(RelationGetRelid(rel), attnum, targettype);

	/*
	 * Drop any pg_statistic entry for the column, since it's now wrong type
	 */
	RemoveStatistics(RelationGetRelid(rel), attnum);

	/*
	 * Update the default, if present, by brute force --- remove and re-add
	 * the default.  Probably unsafe to take shortcuts, since the new version
	 * may well have additional dependencies.  (It's okay to do this now,
	 * rather than after other ALTER TYPE commands, since the default won't
	 * depend on other column types.)
	 */
	if (defaultexpr)
	{
		/* Must make new row visible since it will be updated again */
		CommandCounterIncrement();

		/*
		 * We use RESTRICT here for safety, but at present we do not expect
		 * anything to depend on the default.
		 */
		RemoveAttrDefault(RelationGetRelid(rel), attnum, DROP_RESTRICT, true);

		StoreAttrDefault(rel, attnum, nodeToString(defaultexpr));
	}

	/* Cleanup */
	heap_freetuple(heapTup);

	/* MPP-6929: metadata tracking */
	if ((Gp_role == GP_ROLE_DISPATCH)
		&& MetaTrackValidKindNsp(rel->rd_rel))
		MetaTrackUpdObject(RelationRelationId,
						   RelationGetRelid(rel),
						   GetUserId(),
						   "ALTER", "ALTER COLUMN TYPE"
				);


}

/*
 * Cleanup after we've finished all the ALTER TYPE operations for a
 * particular relation.  We have to drop and recreate all the indexes
 * and constraints that depend on the altered columns.
 */
static void
ATPostAlterTypeCleanup(List **wqueue, AlteredTableInfo *tab)
{
	ObjectAddress obj;
	ListCell   *def_item;
	ListCell   *oid_item;

	/*
	 * Re-parse the index and constraint definitions, and attach them to the
	 * appropriate work queue entries.	We do this before dropping because in
	 * the case of a FOREIGN KEY constraint, we might not yet have exclusive
	 * lock on the table the constraint is attached to, and we need to get
	 * that before dropping.  It's safe because the parser won't actually look
	 * at the catalogs to detect the existing entry.
	 *
	 * We can't rely on the output of deparsing to tell us which relation
	 * to operate on, because concurrent activity might have made the name
	 * resolve differently.  Instead, we've got to use the OID of the
	 * constraint or index we're processing to figure out which relation
	 * to operate on.
	 */
	forboth(oid_item, tab->changedIndexOids,
			def_item, tab->changedIndexDefs)
	{
		/*
		 * Temporary workaround for MPP-1318. INDEX CREATE is dispatched
		 * immediately, which unfortunately breaks the ALTER work queue.
		 */
		ereport(ERROR,
				(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
						errmsg("cannot alter indexed column"),
						errhint("DROP the index first, and recreate it after the ALTER"),
						errOmitLocation(true)));
		/*Oid     oldId = lfirst_oid(oid_item);
		Oid     relid;

		relid = IndexGetRelation(oldId);
		ATPostAlterTypeParse(relid, InvalidOid,
				(char *) lfirst(def_item),
				wqueue, oldOid);*/
	}

	/* Reuse old constraint OID for new constraint */
	forboth(oid_item, tab->changedConstraintOids,
			def_item, tab->changedConstraintDefs)
	{
		Oid     oldId = lfirst_oid(oid_item);
		Oid     relid;
		Oid     confrelid;

		get_constraint_relation_oids(oldId, &relid, &confrelid);
		ATPostAlterTypeParse(relid, confrelid,
							 (char *) lfirst(def_item),
							 wqueue, oldId);
	}

	/*
	 * Now we can drop the existing constraints and indexes --- constraints
	 * first, since some of them might depend on the indexes.  In fact, we
	 * have to delete FOREIGN KEY constraints before UNIQUE constraints, but
	 * we already ordered the constraint list to ensure that would happen. It
	 * should be okay to use DROP_RESTRICT here, since nothing else should be
	 * depending on these objects.
	 */
	foreach(oid_item, tab->changedConstraintOids)
	{
		obj.classId = ConstraintRelationId;
		obj.objectId = lfirst_oid(oid_item);
		obj.objectSubId = 0;
		performDeletion(&obj, DROP_RESTRICT);
	}

	foreach(oid_item, tab->changedIndexOids)
	{
		obj.classId = RelationRelationId;
		obj.objectId = lfirst_oid(oid_item);
		obj.objectSubId = 0;
		performDeletion(&obj, DROP_RESTRICT);
	}

	/*
	 * The objects will get recreated during subsequent passes over the work
	 * queue.
	 */
}

static void
ATPostAlterTypeParse(Oid oldRelId, Oid refRelId, char *cmd, List **wqueue, Oid constrOid)
{
	List	   *raw_parsetree_list;
	List	   *querytree_list;
	ListCell   *list_item;
	Relation    rel;

	/*
	 * We expect that we only have to do raw parsing and parse analysis, not
	 * any rule rewriting, since these will all be utility statements.
	 */
	raw_parsetree_list = raw_parser(cmd);
	querytree_list = NIL;
	foreach(list_item, raw_parsetree_list)
	{
		Node	   *parsetree = (Node *) lfirst(list_item);

		querytree_list = list_concat(querytree_list,
									 parse_analyze(parsetree, cmd, NULL, 0));
	}

	/* Caller should already have acquired whatever lock we need. */
	rel = relation_open(oldRelId, NoLock);

	/*
	 * Attach each generated command to the proper place in the work queue.
	 * Note this could result in creation of entirely new work-queue entries.
	 */
	foreach(list_item, querytree_list)
	{
		Query	   *query = (Query *) lfirst(list_item);
		AlteredTableInfo *tab;

		Assert(IsA(query, Query));
		Assert(query->commandType == CMD_UTILITY);
		switch (nodeTag(query->utilityStmt))
		{
			case T_IndexStmt:
				{
					IndexStmt  *stmt = (IndexStmt *) query->utilityStmt;
					AlterTableCmd *newcmd;

					tab = ATGetQueueEntry(wqueue, rel);
					newcmd = makeNode(AlterTableCmd);
					newcmd->subtype = AT_ReAddIndex;
					newcmd->def = (Node *) stmt;
					tab->subcmds[AT_PASS_OLD_INDEX] =
						lappend(tab->subcmds[AT_PASS_OLD_INDEX], newcmd);
					break;
				}
			case T_AlterTableStmt:
				{
					AlterTableStmt *stmt = (AlterTableStmt *) query->utilityStmt;
					ListCell   *lcmd;

					tab = ATGetQueueEntry(wqueue, rel);
					foreach(lcmd, stmt->cmds)
					{
						AlterTableCmd *cmd = (AlterTableCmd *) lfirst(lcmd);

						switch (cmd->subtype)
						{
							case AT_AddIndex:
								cmd->subtype = AT_ReAddIndex;
								tab->subcmds[AT_PASS_OLD_INDEX] =
									lappend(tab->subcmds[AT_PASS_OLD_INDEX], cmd);
								break;
							case AT_AddConstraint:
								/* Reuse old constraint OID for new constraint */
								if (nodeTag(cmd->def) == T_Constraint)
									((Constraint *)cmd->def)->conoid = constrOid;
								else if (nodeTag(cmd->def) == T_FkConstraint)
									((FkConstraint *)cmd->def)->constrOid = constrOid;
								tab->subcmds[AT_PASS_OLD_CONSTR] =
									lappend(tab->subcmds[AT_PASS_OLD_CONSTR], cmd);
								break;
							default:
								elog(ERROR, "unexpected statement type: %d",
									 (int) cmd->subtype);
						}
					}
					break;
				}
			default:
				elog(ERROR, "unexpected statement type: %d",
					 (int) nodeTag(query->utilityStmt));
		}
	}

	relation_close(rel, NoLock);
}

/*
 * ALTER TABLE OWNER
 *
 * recursing is true if we are recursing from a table to its indexes,
 * sequences, or toast table.  We don't allow the ownership of those things to
 * be changed separately from the parent table.  Also, we can skip permission
 * checks (this is necessary not just an optimization, else we'd fail to
 * handle toast tables properly).
 *
 * recursing is also true if ALTER TYPE OWNER is calling us to fix up a
 * free-standing composite type.
 */
void
ATExecChangeOwner(Oid relationOid, Oid newOwnerId, bool recursing)
{
	Relation	target_rel;
	HeapTuple	tuple;
	Form_pg_class tuple_class;
	cqContext  *pcqCtx;

	/*
	 * Get exclusive lock till end of transaction on the target table. Use
	 * relation_open so that we can work on indexes and sequences.
	 */
	target_rel = relation_open(relationOid, AccessExclusiveLock);

	/* Get its pg_class tuple, too */
	pcqCtx = caql_beginscan(
			NULL,
			cql("SELECT * FROM pg_class "
				" WHERE oid = :1 "
				" FOR UPDATE ",
				ObjectIdGetDatum(relationOid)));

	tuple = caql_getnext(pcqCtx);

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

	/* Can we change the ownership of this tuple? */
	switch (tuple_class->relkind)
	{
		case RELKIND_RELATION:
		case RELKIND_VIEW:
			/* ok to change owner */
			break;
		case RELKIND_INDEX:
			if (!recursing)
			{
				/*
				 * Because ALTER INDEX OWNER used to be allowed, and in fact
				 * is generated by old versions of pg_dump, we give a warning
				 * and do nothing rather than erroring out.  Also, to avoid
				 * unnecessary chatter while restoring those old dumps, say
				 * nothing at all if the command would be a no-op anyway.
				 */
				if (tuple_class->relowner != newOwnerId)
					ereport(WARNING,
							(errcode(ERRCODE_WRONG_OBJECT_TYPE),
							 errmsg("cannot change owner of index \"%s\"",
									NameStr(tuple_class->relname)),
							 errhint("Change the ownership of the index's table, instead."),
									   errOmitLocation(true)));
				/* quick hack to exit via the no-op path */
				newOwnerId = tuple_class->relowner;
			}
			break;
		case RELKIND_SEQUENCE:
			if (!recursing &&
				tuple_class->relowner != newOwnerId)
			{
				/* if it's an owned sequence, disallow changing it by itself */
				Oid			tableId;
				int32		colId;

				if (sequenceIsOwned(relationOid, &tableId, &colId))
					ereport(ERROR,
							(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
							 errmsg("cannot change owner of sequence \"%s\"",
									NameStr(tuple_class->relname)),
					  errdetail("Sequence \"%s\" is linked to table \"%s\".",
								NameStr(tuple_class->relname),
								get_rel_name(tableId)),
										   errOmitLocation(true)));
			}
			break;
		case RELKIND_TOASTVALUE:
		case RELKIND_AOSEGMENTS:
		case RELKIND_AOBLOCKDIR:
		case RELKIND_COMPOSITE_TYPE:
			if (recursing)
				break;
			/* FALL THRU */
		default:
			ereport(ERROR,
					(errcode(ERRCODE_WRONG_OBJECT_TYPE),
					 errmsg("\"%s\" is not a table, view, or sequence",
							NameStr(tuple_class->relname)),
									   errOmitLocation(true)));
	}

	/*
	 * If the new owner is the same as the existing owner, consider the
	 * command to have succeeded.  This is for dump restoration purposes.
	 */
	if (tuple_class->relowner != newOwnerId)
	{
		Datum		repl_val[Natts_pg_class];
		bool		repl_null[Natts_pg_class];
		bool		repl_repl[Natts_pg_class];
		Acl		   *newAcl;
		Datum		aclDatum;
		bool		isNull;
		HeapTuple	newtuple;

		/* skip permission checks when recursing to index or toast table */
		if (!recursing)
		{
			/* Superusers can always do it */
			if (!superuser())
			{
				Oid			namespaceOid = tuple_class->relnamespace;
				AclResult	aclresult;

				/* Otherwise, must be owner of the existing object */
				if (!pg_class_ownercheck(relationOid, GetUserId()))
					aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_CLASS,
								   RelationGetRelationName(target_rel));

				/* Must be able to become new owner */
				check_is_member_of_role(GetUserId(), newOwnerId);

				/* New owner must have CREATE privilege on namespace */
				aclresult = pg_namespace_aclcheck(namespaceOid, newOwnerId,
												  ACL_CREATE);
				if (aclresult != ACLCHECK_OK)
					aclcheck_error(aclresult, ACL_KIND_NAMESPACE,
								   get_namespace_name(namespaceOid));
			}
		}

		memset(repl_null, false, sizeof(repl_null));
		memset(repl_repl, false, sizeof(repl_repl));

		repl_repl[Anum_pg_class_relowner - 1] = true;
		repl_val[Anum_pg_class_relowner - 1] = ObjectIdGetDatum(newOwnerId);

		/*
		 * Determine the modified ACL for the new owner.  This is only
		 * necessary when the ACL is non-null.
		 */
		aclDatum = caql_getattr(pcqCtx,
								Anum_pg_class_relacl,
								&isNull);
		if (!isNull)
		{
			newAcl = aclnewowner(DatumGetAclP(aclDatum),
								 tuple_class->relowner, newOwnerId);
			repl_repl[Anum_pg_class_relacl - 1] = true;
			repl_val[Anum_pg_class_relacl - 1] = PointerGetDatum(newAcl);
		}

		newtuple = caql_modify_current(pcqCtx, repl_val, repl_null, repl_repl);

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

		heap_freetuple(newtuple);

		/*
		 * Update owner dependency reference, if any.  A composite type has
		 * none, because it's tracked for the pg_type entry instead of here;
		 * indexes don't have their own entries either.
		 */
		if (tuple_class->relkind != RELKIND_COMPOSITE_TYPE &&
			tuple_class->relkind != RELKIND_INDEX &&
			tuple_class->relkind != RELKIND_TOASTVALUE)
			changeDependencyOnOwner(RelationRelationId, relationOid,
									newOwnerId);

		/*
		 * Also change the ownership of the table's rowtype, if it has one
		 */
		if (tuple_class->relkind != RELKIND_INDEX)
			AlterTypeOwnerInternal(tuple_class->reltype, newOwnerId,
							tuple_class->relkind == RELKIND_COMPOSITE_TYPE);

		/*
		 * If we are operating on a table, also change the ownership of any
		 * indexes and sequences that belong to the table, as well as the
		 * table's toast table (if it has one)
		 */
		if (tuple_class->relkind == RELKIND_RELATION ||
			tuple_class->relkind == RELKIND_TOASTVALUE ||
			tuple_class->relkind == RELKIND_AOSEGMENTS ||
			tuple_class->relkind == RELKIND_AOBLOCKDIR)
		{
			List	   *index_oid_list;
			ListCell   *i;

			/* Find all the indexes belonging to this relation */
			index_oid_list = RelationGetIndexList(target_rel);

			/* For each index, recursively change its ownership */
			foreach(i, index_oid_list)
				ATExecChangeOwner(lfirst_oid(i), newOwnerId, true);

			list_free(index_oid_list);
		}

		if (tuple_class->relkind == RELKIND_RELATION)
		{
			/* If it has a toast table, recurse to change its ownership */
			if (tuple_class->reltoastrelid != InvalidOid)
				ATExecChangeOwner(tuple_class->reltoastrelid, newOwnerId,
								  true);

			if(RelationIsAoRows(target_rel) || RelationIsParquet(target_rel))
			{
				Oid segrelid, blkdirrelid;
				GetAppendOnlyEntryAuxOids(relationOid, SnapshotNow,
									  &segrelid, NULL,
									  &blkdirrelid, NULL);
				
				/* If it has an AO segment table, recurse to change its
				 * ownership */
				if (segrelid != InvalidOid)
					ATExecChangeOwner(segrelid, newOwnerId, true);

				/* If it has an AO block directory table, recurse to change its
				 * ownership */
				if (blkdirrelid != InvalidOid)
					ATExecChangeOwner(blkdirrelid, newOwnerId, true);
			}
			
			/* If it has dependent sequences, recurse to change them too */
			change_owner_recurse_to_sequences(relationOid, newOwnerId);
		}
	}

	caql_endscan(pcqCtx);

	relation_close(target_rel, NoLock);

	/* MPP-6929: metadata tracking */
	if ((Gp_role == GP_ROLE_DISPATCH)
		&& MetaTrackValidKindNsp(tuple_class)
			)
		MetaTrackUpdObject(RelationRelationId,
						   relationOid,
						   GetUserId(),
						   "ALTER", "OWNER"
				);

}

/*
 * change_owner_recurse_to_sequences
 *
 * Helper function for ATExecChangeOwner.  Examines pg_depend searching
 * for sequences that are dependent on serial columns, and changes their
 * ownership.
 */
static void
change_owner_recurse_to_sequences(Oid relationOid, Oid newOwnerId)
{
	cqContext  *pcqCtx;
	HeapTuple	tup;

	/*
	 * SERIAL sequences are those having an auto dependency on one of the
	 * table's columns (we don't care *which* column, exactly).
	 */
	pcqCtx = caql_beginscan(
			NULL,
			cql("SELECT * FROM pg_depend "
				" WHERE refclassid = :1 "
				" AND refobjid = :2 ",
				ObjectIdGetDatum(RelationRelationId),
				ObjectIdGetDatum(relationOid)));
	/* we leave refobjsubid unspecified */

	while (HeapTupleIsValid(tup = caql_getnext(pcqCtx)))
	{
		Form_pg_depend depForm = (Form_pg_depend) GETSTRUCT(tup);
		Relation	seqRel;

		/* skip dependencies other than auto dependencies on columns */
		if (depForm->refobjsubid == 0 ||
			depForm->classid != RelationRelationId ||
			depForm->objsubid != 0 ||
			depForm->deptype != DEPENDENCY_AUTO)
			continue;

		/* Use relation_open just in case it's an index */
		seqRel = relation_open(depForm->objid, AccessExclusiveLock);

		/* skip non-sequence relations */
		if (RelationGetForm(seqRel)->relkind != RELKIND_SEQUENCE)
		{
			/* No need to keep the lock */
			relation_close(seqRel, AccessExclusiveLock);
			continue;
		}

		/* We don't need to close the sequence while we alter it. */
		ATExecChangeOwner(depForm->objid, newOwnerId, true);

		/* Now we can close it.  Keep the lock till end of transaction. */
		relation_close(seqRel, NoLock);
	}

	caql_endscan(pcqCtx);

}

/*
 * ALTER TABLE CLUSTER ON
 *
 * The only thing we have to do is to change the indisclustered bits.
 */
static void
ATExecClusterOn(Relation rel, const char *indexName)
{
	Oid			indexOid;

	indexOid = get_relname_relid(indexName, rel->rd_rel->relnamespace);

	if (!OidIsValid(indexOid))
		ereport(ERROR,
				(errcode(ERRCODE_UNDEFINED_OBJECT),
				 errmsg("index \"%s\" for table \"%s\" does not exist",
						indexName, RelationGetRelationName(rel)),
								   errOmitLocation(true)));

	/* Check index is valid to cluster on */
	check_index_is_clusterable(rel, indexOid, false);

	/* And do the work */
	mark_index_clustered(rel, indexOid);

	/* MPP-6929: metadata tracking */
	if ((Gp_role == GP_ROLE_DISPATCH)
		&& MetaTrackValidKindNsp(rel->rd_rel))
		MetaTrackUpdObject(RelationRelationId,
						   RelationGetRelid(rel),
						   GetUserId(),
						   "ALTER", "CLUSTER ON"
				);
}

/*
 * ALTER TABLE SET WITHOUT CLUSTER
 *
 * We have to find any indexes on the table that have indisclustered bit
 * set and turn it off.
 */
static void
ATExecDropCluster(Relation rel)
{
	mark_index_clustered(rel, InvalidOid);

	/* MPP-6929: metadata tracking */
	if ((Gp_role == GP_ROLE_DISPATCH)
		&& MetaTrackValidKindNsp(rel->rd_rel))
		MetaTrackUpdObject(RelationRelationId,
						   RelationGetRelid(rel),
						   GetUserId(),
						   "ALTER", "SET WITHOUT CLUSTER"
				);

}

/*
 * ALTER TABLE SET TABLESPACE
 */

/* 
 * Convert tablespace name to pg_tablespace Oid.  Error out if not valid and
 * settable by the current user.
 */
Oid
get_settable_tablespace_oid(char *tablespacename)
{
	Oid			tablespaceId;
	AclResult	aclresult;
	
	/* Check that the tablespace exists */
	tablespaceId = get_tablespace_oid(tablespacename);
	if (!OidIsValid(tablespaceId))
		ereport(ERROR,
				(errcode(ERRCODE_UNDEFINED_OBJECT),
				 errmsg("tablespace \"%s\" does not exist", tablespacename)));
	
	/* Check its permissions */
	aclresult = pg_tablespace_aclcheck(tablespaceId, GetUserId(), ACL_CREATE);
	if (aclresult != ACLCHECK_OK)
		aclcheck_error(aclresult, ACL_KIND_TABLESPACE, tablespacename);
	
	return tablespaceId;
}

static void
ATPrepSetTableSpace(AlteredTableInfo *tab, Relation rel, char *tablespacename)
{
	Oid			tablespaceId;

	tablespaceId = get_settable_tablespace_oid(tablespacename);

	/* Save info for Phase 3 to do the real work */
	if (OidIsValid(tab->newTableSpace))
		ereport(ERROR,
				(errcode(ERRCODE_SYNTAX_ERROR),
				 errmsg("cannot have multiple SET TABLESPACE subcommands"),
						   errOmitLocation(true)));
	tab->newTableSpace = tablespaceId;
}

/* 
 * ATPartsPrepSetTableSpace is like ATPrepSetTableSpace except that it generates work queue
 * entries for the command (an ALTER TABLE ... SET TABLESPACE ...)  for each part within the 
 * sub-hierarchy indicated by the oid list. 
 *
 * Designed to be called from the AT_PartAlter case of ATPrepCmd.
 */
static void
ATPartsPrepSetTableSpace(List **wqueue, Relation rel, AlterTableCmd *cmd, List *oids)
{
	ListCell *lc;
	Oid tablespaceId;
	int pass = AT_PASS_MISC;
	
	Assert( cmd && cmd->subtype == AT_SetTableSpace );
	Assert( oids );
	
	tablespaceId = get_settable_tablespace_oid(cmd->name);
	Assert(tablespaceId);
	
	ereport(DEBUG1,
			(errmsg("Expanding ALTER TABLE %s SET TABLESPACE...", 
					RelationGetRelationName(rel))
			 ));
	
	foreach(lc, oids)
	{
		Oid partrelid = lfirst_oid(lc);
		Relation partrel = relation_open(partrelid, NoLock); 
		/* NoLock because we should be holding AccessExclusiveLock on parent */
		AlterTableCmd *partcmd = copyObject(cmd);
		AlteredTableInfo *parttab = ATGetQueueEntry(wqueue, partrel);
		if( OidIsValid(parttab->newTableSpace) )
			ereport(ERROR,
					(errcode(ERRCODE_SYNTAX_ERROR),
					 errmsg("conflicting SET TABLESPACE subcommands for \"%s\"",
							RelationGetRelationName(partrel)),
					 errOmitLocation(true)));
		
		parttab->newTableSpace = tablespaceId;
		parttab->subcmds[pass] = lappend(parttab->subcmds[pass], partcmd);
		
		ereport(DEBUG1,
				(errmsg("Will SET TABLESPACE on \"%s\"", 
						RelationGetRelationName(partrel))));
		
		relation_close(partrel, NoLock);
	}
}

/*
 * ALTER TABLE/INDEX SET (...) or RESET (...)
 */
static void
ATExecSetRelOptions(Relation rel, List *defList, bool isReset)
{
	Oid			relid;
	HeapTuple	tuple;
	HeapTuple	newtuple;
	Datum		datum;
	bool		isnull;
	Datum		newOptions;
	Datum		repl_val[Natts_pg_class];
	bool		repl_null[Natts_pg_class];
	bool		repl_repl[Natts_pg_class];
	cqContext  *pcqCtx;

	if (defList == NIL)
		return;					/* nothing to do */

	/* Get the old reloptions */
	relid = RelationGetRelid(rel);

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

	tuple = caql_getnext(pcqCtx);

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

	datum = caql_getattr(pcqCtx, Anum_pg_class_reloptions, &isnull);

	/* MPP-5777: disallow all options except fillfactor.
	 * Future work: could convert from SET to SET WITH codepath which
	 * can support additional reloption types
	 */
	if ((defList != NIL)
/*		&& ((rel->rd_rel->relkind == RELKIND_RELATION)
		|| (rel->rd_rel->relkind == RELKIND_TOASTVALUE)) */
			)
	{
		ListCell   *cell;

		foreach(cell, defList)
		{
			DefElem    *def = lfirst(cell);
			int			kw_len = strlen(def->defname);
			char	   *text_str = "fillfactor";
			int			text_len = strlen(text_str);

			if ((text_len != kw_len) ||
				(pg_strncasecmp(text_str, def->defname, kw_len) != 0))
				ereport(ERROR,
						(errcode(ERRCODE_WRONG_OBJECT_TYPE),
						 errmsg("cannot SET reloption \"%s\"",
								def->defname)));

		}
	}


	/* Generate new proposed reloptions (text array) */
	newOptions = transformRelOptions(isnull ? (Datum) 0 : datum,
									 defList, false, isReset);

	/* Validate */
	switch (rel->rd_rel->relkind)
	{
		case RELKIND_RELATION:
		case RELKIND_TOASTVALUE:
		case RELKIND_AOSEGMENTS:
		case RELKIND_AOBLOCKDIR:
			if(RelationIsAoRows(rel) || RelationIsParquet(rel))
				ereport(ERROR,
						(errcode(ERRCODE_WRONG_OBJECT_TYPE),
						 errmsg("altering reloptions for append only tables"
								" is not permitted"),
										   errOmitLocation(true)));

			(void) heap_reloptions(rel->rd_rel->relkind, newOptions, true);
			break;
		case RELKIND_INDEX:
			(void) index_reloptions(rel->rd_am->amoptions, newOptions, true);
			break;
		default:
			ereport(ERROR,
					(errcode(ERRCODE_WRONG_OBJECT_TYPE),
					 errmsg("\"%s\" is not a table, index, or TOAST table",
							RelationGetRelationName(rel)),
									   errOmitLocation(true)));
			break;
	}

	/*
	 * All we need do here is update the pg_class row; the new options will be
	 * propagated into relcaches during post-commit cache inval.
	 */
	memset(repl_val, 0, sizeof(repl_val));
	memset(repl_null, false, sizeof(repl_null));
	memset(repl_repl, false, sizeof(repl_repl));

	if (newOptions != (Datum) 0)
		repl_val[Anum_pg_class_reloptions - 1] = newOptions;
	else
		repl_null[Anum_pg_class_reloptions - 1] = true;

	repl_repl[Anum_pg_class_reloptions - 1] = true;

	newtuple = caql_modify_current(pcqCtx,
								   repl_val, repl_null, repl_repl);

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

	heap_freetuple(newtuple);

	caql_endscan(pcqCtx);

	/* MPP-6929: metadata tracking */
	if ((Gp_role == GP_ROLE_DISPATCH)
		&& MetaTrackValidKindNsp(rel->rd_rel))
		MetaTrackUpdObject(RelationRelationId,
						   RelationGetRelid(rel),
						   GetUserId(),
						   "ALTER", isReset ? "RESET" : "SET" 
				);


}

static void 
copy_append_only_data(
	RelFileNode		*oldRelFileNode,
	
	RelFileNode		*newRelFileNode,
	
	int32			segmentFileNum,

	char			*relationName,

	int64			eof,

	ItemPointer		persistentTid,
	
	int64			persistentSerialNum,
	
	char			*buffer)
{
	char srcFileName[MAXPGPATH];
	char dstFileName[MAXPGPATH];
	char extension[12];

	File		srcFile;

	MirroredAppendOnlyOpen mirroredDstOpen;

	int64	endOffset;
	int64	readOffset;
	int32	bufferLen;
	int 	retval;

	int 		primaryError;

	/*bool mirrorDataLossOccurred;*/

	/*bool mirrorCatchupRequired;

	MirrorDataLossTrackingState 	originalMirrorDataLossTrackingState;
	int64 							originalMirrorDataLossTrackingSessionNum;*/

	if (segmentFileNum > 0)
	{
		sprintf(extension, ".%u", segmentFileNum);
	}
	else
		extension[0] = '\0';

	CopyRelPath(srcFileName, MAXPGPATH, *oldRelFileNode);
	if (segmentFileNum > 0)
	{
		strcat(srcFileName, extension);
	}

	/*
	 * Open the files
	 */
	srcFile = PathNameOpenFile(srcFileName, O_RDONLY | PG_BINARY, 0);
	if (srcFile < 0)
		ereport(ERROR,
				(errcode_for_file_access(),
				 errmsg("could not open file \"%s\": %m", srcFileName),
				 errdetail("%s", HdfsGetLastError())));


	CopyRelPath(dstFileName, MAXPGPATH, *newRelFileNode);
	if (segmentFileNum > 0)
	{
		strcat(dstFileName, extension);
	}

	MirroredAppendOnly_OpenReadWrite(
								&mirroredDstOpen,
								newRelFileNode,
								segmentFileNum,
								relationName,
								/* logicalEof */ 0, // NOTE: This is the START EOF.  Since we are copying, we start at 0.
								true,
								&primaryError);
	if (primaryError != 0)
		ereport(ERROR,
				(errcode_for_file_access(),
				 errmsg("could not open file \"%s\" for relation '%s': %s", dstFileName, relationName, strerror(primaryError)),
				 errdetail("%s", HdfsGetLastError())));
	
	/*
	 * Do the data copying.
	 */
	endOffset = eof;
	readOffset = 0;
	bufferLen = (Size) Min(2*BLCKSZ, endOffset);
	while (readOffset < endOffset)
	{
		CHECK_FOR_INTERRUPTS();
		
		retval = FileRead(srcFile, buffer, bufferLen);
		if (retval != bufferLen) 
		{
			ereport(ERROR,
					(errcode_for_file_access(),
					 errmsg("could not read from position: " INT64_FORMAT " in file '%s' : %m", readOffset, srcFileName),
					 errdetail("%s", HdfsGetLastError())));
			
			break;
		}						
		
		MirroredAppendOnly_Append(
							  &mirroredDstOpen,
							  buffer,
							  bufferLen,
							  &primaryError/*,
							  &mirrorDataLossOccurred*/);
		if (primaryError != 0)
			ereport(ERROR,
					(errcode_for_file_access(),
					 errmsg("could not write file \"%s\": %s", dstFileName, strerror(primaryError)),
					 errdetail("%s", HdfsGetLastError())));
		
		readOffset += bufferLen;
		
		bufferLen = (Size) Min(2*BLCKSZ, endOffset - readOffset); 					
	}
	
	MirroredAppendOnly_FlushAndClose(
							&mirroredDstOpen,
							&primaryError
							/*&mirrorDataLossOccurred,
							&mirrorCatchupRequired,
							&originalMirrorDataLossTrackingState,
							&originalMirrorDataLossTrackingSessionNum*/);
	if (primaryError != 0)
		ereport(ERROR,
				(errcode_for_file_access(),
				 errmsg("could not flush (fsync) file \"%s\" for relation '%s': %s"
						 , dstFileName, relationName, strerror(primaryError)),
				 errdetail("%s", HdfsGetLastError())));

	FileClose(srcFile);

	if (Debug_persistent_print)
		elog(Persistent_DebugPrintLevel(), 
			 "ALTER TABLE SET TABLESPACE: Copied Append-Only segment file #%d EOF " INT64_FORMAT,
			 segmentFileNum,
			 eof);
}

static void
ATExecSetTableSpace_AppendOnly(
	Oid				tableOid,
	Relation		rel,
	Relation		gp_relfile_node,
	RelFileNode		*newRelFileNode)
{
	char *buffer;

	GpRelfileNodeScan 	gpRelfileNodeScan;

	HeapTuple tuple;

	int32 segmentFileNum = 0;

	ItemPointerData oldPersistentTid;
	int64 oldPersistentSerialNum = 0;

	ItemPointerData newPersistentTid;
	int64 newPersistentSerialNum;

	HeapTuple tupleCopy;

	AppendOnlyEntry *aoEntry;

	Snapshot	appendOnlyMetaDataSnapshot = SnapshotNow;
				/*
				 * We can use SnapshotNow since we have an exclusive lock on the source.
				 */
					
	int segmentCount;

	if (Debug_persistent_print)
		elog(Persistent_DebugPrintLevel(), 
			 "ALTER TABLE SET TABLESPACE: Append-Only "
			 "relation id %u, old path %u/%u/%u, new path %u/%u/%u",
			 RelationGetRelid(rel),
			 rel->rd_node.spcNode,
			 rel->rd_node.dbNode,
			 rel->rd_node.relNode,
			 newRelFileNode->spcNode,
			 newRelFileNode->dbNode,
			 newRelFileNode->relNode);

	/* Use palloc to ensure we get a maxaligned buffer */		
	buffer = palloc(2*BLCKSZ);

	aoEntry = GetAppendOnlyEntry(RelationGetRelid(rel), appendOnlyMetaDataSnapshot);

	if (Debug_persistent_print)
		elog(Persistent_DebugPrintLevel(), 
			 "ALTER TABLE SET TABLESPACE: pg_appendonly entry for Append-Only %u/%u/%u, segment file #%d "
			 "segrelid %u, segidxid %u, "
			 "persistent TID %s and serial number " INT64_FORMAT,
			 rel->rd_node.spcNode,
			 rel->rd_node.dbNode,
			 rel->rd_node.relNode,
			 segmentFileNum,
			 aoEntry->segrelid,
			 aoEntry->segidxid,
			 ItemPointerToString(&oldPersistentTid),
			 oldPersistentSerialNum);	

	/*
	 * Loop through segment files
	 *    Create segment file in new tablespace under transaction,
	 *    Copy Append-Only segment file data and fsync,
	 *    Update old gp_relation_node with new relfilenode and persistent information,
	 *    Schedule old segment file for drop under transaction,
	 */
	GpRelfileNodeBeginScan(
					gp_relfile_node,
					tableOid,
					rel->rd_rel->relfilenode,
					&gpRelfileNodeScan);
	segmentCount = 0;
	while ((tuple = GpRelfileNodeGetNext(
							&gpRelfileNodeScan,
							&segmentFileNum,
							&oldPersistentTid,
							&oldPersistentSerialNum)))
	{
		int64 eof = 0;
		/*
		 * Create segment file in new tablespace under transaction.
		 */

		MirroredFileSysObj_TransactionCreateAppendOnlyFile(
											newRelFileNode,
											segmentFileNum,
											rel->rd_rel->relname.data,
											/* doJustInTimeDirCreate */ true,
											&newPersistentTid,
											&newPersistentSerialNum);

		if (Debug_persistent_print)
			elog(Persistent_DebugPrintLevel(), 
				 "ALTER TABLE SET TABLESPACE: Create for Append-Only %u/%u/%u, segment file #%d "
				 "persistent TID %s and serial number " INT64_FORMAT,
				 newRelFileNode->spcNode,
				 newRelFileNode->dbNode,
				 newRelFileNode->relNode,
				 segmentFileNum,
				 ItemPointerToString(&newPersistentTid),
				 newPersistentSerialNum);


		/*
		 * Update gp_relation_node with new persistent information.
		 */
		tupleCopy = heap_copytuple(tuple);

		UpdateGpRelfileNodeTuple(
							gp_relfile_node,
							tupleCopy,
							newRelFileNode->relNode,
							segmentFileNum,
							&newPersistentTid,
							newPersistentSerialNum);

		/*
		 * Schedule old segment file for drop under transaction.
		 */
		MirroredFileSysObj_ScheduleDropAppendOnlyFile(
											&rel->rd_node,
											segmentFileNum,
											rel->rd_rel->relname.data,
											&oldPersistentTid,
											oldPersistentSerialNum);

		if (Debug_persistent_print)
			elog(Persistent_DebugPrintLevel(), 
				 "ALTER TABLE SET TABLESPACE: Drop for Append-Only %u/%u/%u, segment file #%d "
				 "persistent TID %s and serial number " INT64_FORMAT,
				 rel->rd_node.spcNode,
				 rel->rd_node.dbNode,
				 rel->rd_node.relNode,
				 segmentFileNum,
				 ItemPointerToString(&oldPersistentTid),
				 oldPersistentSerialNum);

		/*
		 * Copy Append-Only segment file data and fsync.
		 */
		if (RelationIsAoRows(rel))
		{
			FileSegInfo *fileSegInfo;

			fileSegInfo = GetFileSegInfo(rel, aoEntry, appendOnlyMetaDataSnapshot, segmentFileNum);
			if (fileSegInfo == NULL)
			{
				/*
				 * Segment file #0 is special and can exist without an entry.
				 */
				if (segmentFileNum == 0)
					eof = 0;
				else
					ereport(ERROR,
							(errmsg("Append-only %u/%u/%u row segment file #%d information missing",
									rel->rd_node.spcNode,
									rel->rd_node.dbNode,
									rel->rd_node.relNode,
									segmentFileNum)));

			}
			else
			{
				eof = fileSegInfo->eof;

				pfree(fileSegInfo);
			}
		}

		if (Debug_persistent_print)
			elog(Persistent_DebugPrintLevel(), 
				 "ALTER TABLE SET TABLESPACE: Going to copy Append-Only %u/%u/%u to %u/%u/%u, segment file #%d, EOF " INT64_FORMAT ", "
				 "persistent TID %s and serial number " INT64_FORMAT,
				 rel->rd_node.spcNode,
				 rel->rd_node.dbNode,
				 rel->rd_node.relNode,
				 newRelFileNode->spcNode,
				 newRelFileNode->dbNode,
				 newRelFileNode->relNode,
				 segmentFileNum,
				 eof,
				 ItemPointerToString(&newPersistentTid),
				 newPersistentSerialNum);
		
		copy_append_only_data(
						&rel->rd_node,
						newRelFileNode,
						segmentFileNum,
						rel->rd_rel->relname.data,
						eof,
						&newPersistentTid,
						newPersistentSerialNum,
						buffer);

		segmentCount++;
	}

	GpRelfileNodeEndScan(&gpRelfileNodeScan);

	if (Debug_persistent_print)
		elog(Persistent_DebugPrintLevel(), 
			 "ALTER TABLE SET TABLESPACE: Copied %d Append-Only segments from %u/%u/%u to %u/%u/%u, "
			 "persistent TID %s and serial number " INT64_FORMAT,
			 segmentCount,
			 rel->rd_node.spcNode,
			 rel->rd_node.dbNode,
			 rel->rd_node.relNode,
			 newRelFileNode->spcNode,
			 newRelFileNode->dbNode,
			 newRelFileNode->relNode,
			 ItemPointerToString(&newPersistentTid),
			 newPersistentSerialNum);

	pfree(aoEntry);

	pfree(buffer);
}

static void
ATExecSetTableSpace_BufferPool(
	Oid				tableOid,
	Relation		rel,
	Relation		gp_relfile_node,
	RelFileNode		*newRelFileNode)
{
	Oid			oldTablespace;
	HeapTuple	nodeTuple;
	ItemPointerData newPersistentTid;
	int64 newPersistentSerialNum;
	SMgrRelation dstrel;
	bool useWal;
	
	PersistentFileSysRelStorageMgr localRelStorageMgr;
	PersistentFileSysRelBufpoolKind relBufpoolKind;
	
	oldTablespace = rel->rd_rel->reltablespace ? rel->rd_rel->reltablespace : MyDatabaseTableSpace;

	/*
	 * We need to log the copied data in WAL enabled AND
	 * it's not a temp rel.
	 */
	useWal = !XLog_CanBypassWal() && !rel->rd_istemp;

	if (Debug_persistent_print)
		elog(Persistent_DebugPrintLevel(), 
			 "ALTER TABLE SET TABLESPACE: Buffer Pool managed "
			 "relation id %u, old path '%s', old relfilenode %u, old reltablespace %u, "
			 "new path '%s', new relfilenode %u, new reltablespace %u, "
			 "bulk load %s",
			 RelationGetRelid(rel),
			 relpath(rel->rd_node),
			 rel->rd_rel->relfilenode,
			 oldTablespace,
			 relpath(*newRelFileNode),
			 newRelFileNode->relNode,
			 newRelFileNode->spcNode,
			 (!useWal ? "true" : "false"));
	
	/* Fetch relation's gp_relfile_node row */
	/* TODO in hawq */
	Assert(!"need contentid");
	nodeTuple = ScanGpRelfileNodeTuple(
							gp_relfile_node,
							rel->rd_rel->relfilenode,
							/* segmentFileNum */ 0);
	if (!HeapTupleIsValid(nodeTuple))
		elog(ERROR, "cache lookup failed for relation %u, tablespace %u, relation file node %u", 
		     tableOid,
		     oldTablespace,
		     rel->rd_rel->relfilenode);

	GpPersistentRelfileNode_GetRelfileInfo(
										rel->rd_rel->relkind,
										rel->rd_rel->relstorage,
										rel->rd_rel->relam,
										&localRelStorageMgr,
										&relBufpoolKind);
	Assert(localRelStorageMgr == PersistentFileSysRelStorageMgr_BufferPool);
	
	dstrel = smgropen(*newRelFileNode);
	MirroredFileSysObj_TransactionCreateBufferPoolFile(
											dstrel,
											relBufpoolKind,
											rel->rd_isLocalBuf,
											rel->rd_rel->relname.data,
											/* doJustInTimeDirCreate */ true,
											/* bufferPoolBulkLoad */ !useWal,
											&newPersistentTid,
											&newPersistentSerialNum);

	if (Debug_persistent_print)
		elog(Persistent_DebugPrintLevel(), 
		     "ALTER TABLE SET TABLESPACE: Create for Buffer Pool managed '%s' "
			 "persistent TID %s and serial number " INT64_FORMAT,
			 relpath(*newRelFileNode),
			 ItemPointerToString(&newPersistentTid),
			 newPersistentSerialNum);

	/* copy relation data to the new physical file */
	copy_buffer_pool_data(
					rel, 
					dstrel,
					&newPersistentTid,
					newPersistentSerialNum,
					useWal);

	if (Debug_persistent_print)
		elog(Persistent_DebugPrintLevel(), 
			 "ALTER TABLE SET TABLESPACE: Scheduling drop for '%s' "
			 "persistent TID %s and serial number " INT64_FORMAT,
			 relpath(*newRelFileNode),
			 ItemPointerToString(&rel->rd_relationnodeinfo.persistentTid),
			 rel->rd_relationnodeinfo.persistentSerialNum);


	/* schedule unlinking old physical file */
	MirroredFileSysObj_ScheduleDropBufferPoolRel(rel);

	/*
	 * Now drop smgr references.  The source was already dropped by
	 * smgrscheduleunlink.
	 */
	smgrclose(dstrel);

	/* Update gp_relfile_node row. */
	UpdateGpRelfileNodeTuple(
						gp_relfile_node,
						nodeTuple,
						newRelFileNode->relNode,
						/* segmentFileNum */ 0,
						&newPersistentTid,
						newPersistentSerialNum);

}

static bool
ATExecSetTableSpace_Relation(Oid tableOid, Oid newTableSpace, Oid newrelfilenode)
{
	Relation    rel;
	Relation	pg_class;
	Oid			oldTableSpace;
	HeapTuple	tuple;
	Form_pg_class rd_rel;
	Relation	gp_relfile_node;
	RelFileNode newrnode;
	cqContext	cqc;
	cqContext  *pcqCtx;

	rel = relation_open(tableOid, AccessExclusiveLock);

	/*
	 * We can never allow moving of shared or nailed-in-cache relations,
	 * because we can't support changing their reltablespace values.
	 */
	if (rel->rd_rel->relisshared || rel->rd_isnailed)
		ereport(ERROR,
				(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
				 errmsg("cannot move system relation \"%s\"",
						RelationGetRelationName(rel)),
								   errOmitLocation(true)));

	/*
	 * Don't allow moving temp tables of other backends ... their local buffer
	 * manager is not going to cope.
	 */
	if (isOtherTempNamespace(RelationGetNamespace(rel)))
		ereport(ERROR,
				(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
				 errmsg("cannot move temporary tables of other sessions"),
						   errOmitLocation(true)));

	/*
	 * No work if no change in tablespace.
	 */
	oldTableSpace = rel->rd_rel->reltablespace;
	if (newTableSpace == oldTableSpace ||
		(newTableSpace == MyDatabaseTableSpace && oldTableSpace == 0))
	{
		/* XXX - Why do we hold the lock if we aren't changing anything? */
		relation_close(rel, NoLock);
		return false;
	}

	/* Fetch relation's pg_class row */
	pg_class = heap_open(RelationRelationId, RowExclusiveLock);

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

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

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

	gp_relfile_node = heap_open(GpRelfileNodeRelationId, RowExclusiveLock);

	/* create another storage file. Is it a little ugly ? */
	/* NOTE: any conflict in relfilenode value will be caught here */
	newrnode = rel->rd_node;
	newrnode.relNode = newrelfilenode;
	newrnode.spcNode = newTableSpace;

	/* update the pg_class row */
	rd_rel->reltablespace = (newTableSpace == MyDatabaseTableSpace) ? InvalidOid : newTableSpace;
	rd_rel->relfilenode = newrelfilenode;
	
	if (Debug_persistent_print)
		elog(Persistent_DebugPrintLevel(), 
			 "ALTER TABLE SET TABLESPACE: Update pg_class for relation id %u --> relfilenode to %u, reltablespace to %u",
			 tableOid,
			 rd_rel->relfilenode,
			 rd_rel->reltablespace);

	caql_update_current(pcqCtx, tuple); /* implicit update of index as well */

	heap_freetuple(tuple);

	if (RelationIsAoRows(rel) || RelationIsParquet(rel))
		ATExecSetTableSpace_AppendOnly(
								tableOid,
								rel, 
								gp_relfile_node,
								&newrnode);
	else
		ATExecSetTableSpace_BufferPool(
								tableOid,
								rel, 
								gp_relfile_node,
								&newrnode);


	heap_close(pg_class, RowExclusiveLock);

	heap_close(gp_relfile_node, RowExclusiveLock);

	/* Make sure the reltablespace change is visible */
	CommandCounterIncrement();

	/* Hold the lock until commit */
	relation_close(rel, NoLock);

	return true;
}

/*
 * Execute ALTER TABLE SET TABLESPACE for cases where there is no tuple
 * rewriting to be done, so we just want to copy the data as fast as possible.
 */
static void
ATExecSetTableSpace(Oid tableOid, Oid newTableSpace, TableOidInfo *oidInfo)
{
	Relation	rel;
	Oid         newrelfilenode;
	Oid			reltoastrelid = InvalidOid;
	Oid			reltoastidxid = InvalidOid;
	Oid			relaosegrelid = InvalidOid;
	Oid			relaosegidxid = InvalidOid;
	Oid			relaoblkdirrelid = InvalidOid;
	Oid			relaoblkdiridxid = InvalidOid;
	Oid			relbmrelid = InvalidOid;
	Oid			relbmidxid = InvalidOid;


	/* Ensure valid input */
	Assert(OidIsValid(tableOid));
	Assert(OidIsValid(newTableSpace));
	Assert(oidInfo);

	newrelfilenode = oidInfo->relOid;

	/*
	 * Need lock here in case we are recursing to toast table or index
	 */
	rel = relation_open(tableOid, AccessExclusiveLock);

	reltoastrelid = rel->rd_rel->reltoastrelid;

	/* Find the toast relation index */
	if (reltoastrelid)
	{
		Relation toastrel;

		toastrel = relation_open(reltoastrelid, NoLock);
		reltoastidxid = toastrel->rd_rel->reltoastidxid;
		relation_close(toastrel, NoLock);
	}

	/* Get the ao sub objects */
	if (RelationIsAoRows(rel))
		GetAppendOnlyEntryAuxOids(tableOid, SnapshotNow,
								  &relaosegrelid, &relaosegidxid,
								  &relaoblkdirrelid, &relaoblkdiridxid);

	/* Get the bitmap sub objects */
	if (RelationIsBitmapIndex(rel))
		GetBitmapIndexAuxOids(rel, &relbmrelid, &relbmidxid);

	/* Move the main table */
	if (!ATExecSetTableSpace_Relation(tableOid, newTableSpace, newrelfilenode))
	{
		/* XXX - Why do we hold the lock if we aren't changing anything? */
		relation_close(rel, NoLock);
		return;
	}

	/* Move associated toast/toast_index/ao subobjects */
	if (OidIsValid(reltoastrelid))
		ATExecSetTableSpace_Relation(reltoastrelid, newTableSpace, 
									 oidInfo->toastOid);
	if (OidIsValid(reltoastidxid))
		ATExecSetTableSpace_Relation(reltoastidxid, newTableSpace,
									 oidInfo->toastIndexOid);
	if (OidIsValid(relaosegrelid))
		ATExecSetTableSpace_Relation(relaosegrelid, newTableSpace,
									 oidInfo->aosegOid);
	if (OidIsValid(relaosegidxid))
		ATExecSetTableSpace_Relation(relaosegidxid, newTableSpace,
									 oidInfo->aosegIndexOid);
	if (OidIsValid(relaoblkdirrelid))
		ATExecSetTableSpace_Relation(relaoblkdirrelid, newTableSpace,
									 oidInfo->aoblkdirOid);
	if (OidIsValid(relaoblkdiridxid))
		ATExecSetTableSpace_Relation(relaoblkdiridxid, newTableSpace,
									 oidInfo->aoblkdirIndexOid);

	/* 
	 * MPP-7996 - bitmap index subobjects w/Alter Table Set tablespace
	 *
	 * Minor hack: Bitmap indexes are never AO tables.  Rather than extending
	 * OidInfo with yet more oids we simply overload aosegOid/aosegIndexOid
	 * to serve double purpose as oids for the bitmap subobjects.
	 */
	if (OidIsValid(relbmrelid))
	{
		Assert(!relaosegrelid);
		ATExecSetTableSpace_Relation(relbmrelid, newTableSpace,
									 oidInfo->aosegOid);
	}
	if (OidIsValid(relbmidxid))
	{
		Assert(!relaosegidxid);
		ATExecSetTableSpace_Relation(relbmidxid, newTableSpace,
									 oidInfo->aosegIndexOid);
	}

	/* MPP-6929: metadata tracking */
	if ((Gp_role == GP_ROLE_DISPATCH) && MetaTrackValidKindNsp(rel->rd_rel))
		MetaTrackUpdObject(RelationRelationId,
						   RelationGetRelid(rel),
						   GetUserId(),
						   "ALTER", "SET TABLESPACE"
			);

	/* Hold the lock until commit */
	relation_close(rel, NoLock);
}

/*
 * Copy data, block by block
 */
static void
copy_buffer_pool_data(
	Relation 	rel,

	SMgrRelation dst,

	ItemPointer persistentTid,

	int64 		persistentSerialNum,

	bool		useWal)
{
	SMgrRelation src;
	BlockNumber nblocks;
	BlockNumber blkno;
	char		buf[BLCKSZ];
	Page		page = (Page) buf;


	/*
	 * Since we copy the file directly without looking at the shared buffers,
	 * we'd better first flush out any pages of the source relation that are
	 * in shared buffers.  We assume no new changes will be made while we are
	 * holding exclusive lock on the rel.
	 */
	FlushRelationBuffers(rel);

	nblocks = RelationGetNumberOfBlocks(rel);

	/* RelationGetNumberOfBlocks will certainly have opened rd_smgr */
	src = rel->rd_smgr;

	if (useWal)
	{
		if (Debug_persistent_print)
		{
			elog(Persistent_DebugPrintLevel(),
				 "copy_buffer_pool_data %u/%u/%u: not bypassing the WAL -- not using bulk load, persistent serial num " INT64_FORMAT ", TID %s",
				 rel->rd_node.spcNode,
				 rel->rd_node.dbNode,
				 rel->rd_node.relNode,
				 persistentSerialNum,
				 ItemPointerToString(persistentTid));
		}
	}
	
	for (blkno = 0; blkno < nblocks; blkno++)
	{
		smgrread(src, blkno, buf);

		/* XLOG stuff */
		if (useWal)
		{
			xl_heap_newpage xlrec;
			XLogRecPtr	recptr;
			XLogRecData rdata[2];

			/* NO ELOG(ERROR) from here till newpage op is logged */
			START_CRIT_SECTION();

			xlrec.heapnode.node = dst->smgr_rnode;
			xlrec.heapnode.persistentTid = *persistentTid;
			xlrec.heapnode.persistentSerialNum = persistentSerialNum;
			xlrec.blkno = blkno;

			rdata[0].data = (char *) &xlrec;
			rdata[0].len = SizeOfHeapNewpage;
			rdata[0].buffer = InvalidBuffer;
			rdata[0].next = &(rdata[1]);

			rdata[1].data = (char *) page;
			rdata[1].len = BLCKSZ;
			rdata[1].buffer = InvalidBuffer;
			rdata[1].next = NULL;

			recptr = XLogInsert(RM_HEAP_ID, XLOG_HEAP_NEWPAGE, rdata);

			PageSetLSN(page, recptr);
			PageSetTLI(page, ThisTimeLineID);

			END_CRIT_SECTION();
		}

		
		// -------- MirroredLock ----------
		LWLockAcquire(MirroredLock, LW_SHARED);
		
		/*
		 * Now write the page.	We say isTemp = true even if it's not a temp
		 * rel, because there's no need for smgr to schedule an fsync for this
		 * write; we'll do it ourselves below.
		 */
		smgrwrite(dst, blkno, buf, true);
		
		LWLockRelease(MirroredLock);
		// -------- MirroredLock ----------
	}

	/*
	 * If the rel isn't temp, we must fsync it down to disk before it's safe
	 * to commit the transaction.  (For a temp rel we don't care since the rel
	 * will be uninteresting after a crash anyway.)
	 *
	 * It's obvious that we must do this when not WAL-logging the copy. It's
	 * less obvious that we have to do it even if we did WAL-log the copied
	 * pages. The reason is that since we're copying outside shared buffers, a
	 * CHECKPOINT occurring during the copy has no way to flush the previously
	 * written data to disk (indeed it won't know the new rel even exists).  A
	 * crash later on would replay WAL from the checkpoint, therefore it
	 * wouldn't replay our earlier WAL entries. If we do not fsync those pages
	 * here, they might still not be on disk when the crash occurs.
	 */
	
	// -------- MirroredLock ----------
	LWLockAcquire(MirroredLock, LW_SHARED);
	
	if (!rel->rd_istemp)
		smgrimmedsync(dst);
	
	LWLockRelease(MirroredLock);
	// -------- MirroredLock ----------

	if (useWal)
	{
		if (Debug_persistent_print)
		{
			elog(Persistent_DebugPrintLevel(),
				 "copy_buffer_pool_data %u/%u/%u: did not bypass the WAL -- did not use bulk load, persistent serial num " INT64_FORMAT ", TID %s",
				 rel->rd_node.spcNode,
				 rel->rd_node.dbNode,
				 rel->rd_node.relNode,
				 persistentSerialNum,
				 ItemPointerToString(persistentTid));
		}
	}
}

/*
 * ALTER TABLE ENABLE/DISABLE TRIGGER
 *
 * We just pass this off to trigger.c.
 */
static void
ATExecEnableDisableTrigger(Relation rel, char *trigname,
						   bool enable, bool skip_system)
{
	EnableDisableTrigger(rel, trigname, enable, skip_system);

	/* MPP-6929: metadata tracking */
	if ((Gp_role == GP_ROLE_DISPATCH)
		&& MetaTrackValidKindNsp(rel->rd_rel))
		MetaTrackUpdObject(RelationRelationId,
						   RelationGetRelid(rel),
						   GetUserId(),
						   "ALTER", 
						   enable ? "ENABLE TRIGGER" : 
						   "DISABLE TRIGGER"
				);

}

static void
inherit_parent(Relation parent_rel, Relation child_rel, bool is_partition, List *inhAttrNameList)
{
	cqContext  *pcqCtx;
	cqContext	cqc;
	HeapTuple	inheritsTuple;
	int32		inhseqno;
	List	   *children;
	Relation	catalogRelation;

	/*
	 * Check for duplicates in the list of parents, and determine the highest
	 * inhseqno already present; we'll use the next one for the new parent.
	 * (Note: get RowExclusiveLock because we will write pg_inherits below.)
	 *
	 * Note: we do not reject the case where the child already inherits from
	 * the parent indirectly; CREATE TABLE doesn't reject comparable cases.
	 */
	catalogRelation = heap_open(InheritsRelationId, RowExclusiveLock);
	pcqCtx = caql_beginscan(
			caql_addrel(cqclr(&cqc), catalogRelation),
			cql("SELECT * FROM pg_inherits "
				" WHERE inhrelid = :1 "
				" FOR UPDATE ",
				ObjectIdGetDatum(RelationGetRelid(child_rel))));

	/* inhseqno sequences start at 1 */
	inhseqno = 0;
	while (HeapTupleIsValid(inheritsTuple = caql_getnext(pcqCtx)))
	{
		Form_pg_inherits inh = (Form_pg_inherits) GETSTRUCT(inheritsTuple);

		if (inh->inhparent == RelationGetRelid(parent_rel))
			ereport(ERROR,
					(errcode(ERRCODE_DUPLICATE_TABLE),
					 errmsg("inherited relation \"%s\" duplicated",
							RelationGetRelationName(parent_rel)),
									   errOmitLocation(true)));
		if (inh->inhseqno > inhseqno)
			inhseqno = inh->inhseqno;
	}
	caql_endscan(pcqCtx);

	/*
	 * Prevent circularity by seeing if proposed parent inherits from child.
	 * (In particular, this disallows making a rel inherit from itself.)
	 *
	 * This is not completely bulletproof because of race conditions: in
	 * multi-level inheritance trees, someone else could concurrently
	 * be making another inheritance link that closes the loop but does
	 * not join either of the rels we have locked.  Preventing that seems
	 * to require exclusive locks on the entire inheritance tree, which is
	 * a cure worse than the disease.  find_all_inheritors() will cope with
	 * circularity anyway, so don't sweat it too much.
	 */
	children = find_all_inheritors(RelationGetRelid(child_rel));

	if (list_member_oid(children, RelationGetRelid(parent_rel)))
		ereport(ERROR,
				(errcode(ERRCODE_DUPLICATE_TABLE),
				 errmsg("circular inheritance not allowed"),
				 errdetail("\"%s\" is already a child of \"%s\".",
						   RelationGetRelationName(parent_rel),
						   RelationGetRelationName(child_rel)),
								   errOmitLocation(true)));

	/* If parent has OIDs then child must have OIDs */
	if (parent_rel->rd_rel->relhasoids && !child_rel->rd_rel->relhasoids)
		ereport(ERROR,
				(errcode(ERRCODE_WRONG_OBJECT_TYPE),
				 errmsg("table \"%s\" without OIDs cannot inherit from table \"%s\" with OIDs",
						RelationGetRelationName(child_rel),
						RelationGetRelationName(parent_rel)),
								   errOmitLocation(true)));

	/* Match up the columns and bump attinhcount and attislocal */
	MergeAttributesIntoExisting(child_rel, parent_rel, inhAttrNameList, is_partition);

	/* Match up the constraints and make sure they're present in child */
	MergeConstraintsIntoExisting(child_rel, parent_rel);

	/*
	 * OK, it looks valid.  Make the catalog entries that show inheritance.
	 */
	StoreCatalogInheritance1(RelationGetRelid(child_rel),
							 RelationGetRelid(parent_rel),
							 inhseqno + 1,
							 catalogRelation, is_partition);

	/* Now we're done with pg_inherits */
	heap_close(catalogRelation, RowExclusiveLock);

}

/*
 * ALTER TABLE INHERIT
 *
 * Add a parent to the child's parents. This verifies that all the columns and
 * check constraints of the parent appear in the child and that they have the
 * same data types and expressions.
 */
static void
ATExecAddInherit(Relation child_rel, Node *node)
{
	Relation	parent_rel;
	bool		is_partition;
	RangeVar   *parent;
	List	   *inhAttrNameList = NIL;

	Assert(PointerIsValid(node));

	if (IsA(node, InheritPartitionCmd))
	{
		parent = ((InheritPartitionCmd *)node)->parent;
		is_partition = true;
	}
	else
	{
		List *inhParms;
		Assert(IsA(node, List));
		inhParms = (List *)node;

		Insist(list_length(inhParms) == 2);
		Assert(IsA(linitial(inhParms), RangeVar));
		Assert(lsecond(inhParms) == NIL || IsA(lsecond(inhParms), List));

		parent = (RangeVar *)linitial(inhParms);
		inhAttrNameList = (List *)lsecond(inhParms);
		is_partition = false;
	}

	/*
	 * AccessShareLock on the parent is what's obtained during normal CREATE
	 * TABLE ... INHERITS ..., so should be enough here.
	 */
	parent_rel = heap_openrv(parent, AccessShareLock);

	/*
	 * Must be owner of both parent and child -- child was checked by
	 * ATSimplePermissions call in ATPrepCmd
	 */
	ATSimplePermissions(parent_rel, false);

	/* Permanent rels cannot inherit from temporary ones */
	if (!isTempNamespace(RelationGetNamespace(child_rel)) &&
		isTempNamespace(RelationGetNamespace(parent_rel)))
		ereport(ERROR,
				(errcode(ERRCODE_WRONG_OBJECT_TYPE),
				 errmsg("cannot inherit from temporary relation \"%s\"",
						RelationGetRelationName(parent_rel)),
								   errOmitLocation(true)));

	if (is_partition)
	{
		/* lookup all attrs */
		int attno;

		for (attno = 0; attno < parent_rel->rd_att->natts; attno++)
		{
			Form_pg_attribute	 attribute = parent_rel->rd_att->attrs[attno];
			char				*attributeName = NameStr(attribute->attname);

			/* MPP-5397: ignore dropped cols */
			if (!attribute->attisdropped)
				inhAttrNameList =
						lappend(inhAttrNameList,
								makeString(attributeName));
		}

	}
	inherit_parent(parent_rel, child_rel, is_partition, inhAttrNameList);

	/*
	 * Keep our lock on the parent relation until commit, unless we're
	 * doing partitioning, in which case the parent is sufficiently locked.
	 * We want to unlock here in case we're doing deep sub partitioning. We do
	 * not want to acquire too many locks since we're overflow the lock buffer.
	 * An exclusive lock on the parent table is sufficient to guard against
	 * concurrency issues.
	 */
	if (is_partition)
		heap_close(parent_rel, AccessShareLock);
	else
		heap_close(parent_rel, NoLock);

	/* MPP-6929: metadata tracking */
	if ((Gp_role == GP_ROLE_DISPATCH)
		&& MetaTrackValidKindNsp(child_rel->rd_rel))
		MetaTrackUpdObject(RelationRelationId,
						   RelationGetRelid(child_rel),
						   GetUserId(),
						   "ALTER", "INHERIT"
				);
}

/*
 * Obtain the source-text form of the constraint expression for a check
 * constraint, given its pg_constraint tuple
 */
static char *
decompile_conbin(HeapTuple contup, TupleDesc tupdesc)
{
	Form_pg_constraint con;
	bool		isnull;
	Datum		attr;
	Datum		expr;

	con = (Form_pg_constraint) GETSTRUCT(contup);
	attr = heap_getattr(contup, Anum_pg_constraint_conbin, tupdesc, &isnull);
	if (isnull)
		elog(ERROR, "null conbin for constraint %u", HeapTupleGetOid(contup));

	expr = DirectFunctionCall2(pg_get_expr, attr,
							   ObjectIdGetDatum(con->conrelid));
	return DatumGetCString(DirectFunctionCall1(textout, expr));
}
/*
	toast_idxid = index_create(toast_relid, toast_idxname, newIndexOid,
							   indexInfo,
							   BTREE_AM_OID,
							   rel->rd_rel->reltablespace,
							   classObjectId,
							   true, false, true, false);*/

/*
 * Check columns in child table match up with columns in parent, and increment
 * their attinhcount.
 *
 * Called by ATExecAddInherit
 *
 * Currently all parent columns must be found in child. Missing columns are an
 * error.  One day we might consider creating new columns like CREATE TABLE
 * does.  However, that is widely unpopular --- in the common use case of
 * partitioned tables it's a foot-gun.
 *
 * The data type must match exactly. If the parent column is NOT NULL then
 * the child must be as well. Defaults are not compared, however.
 */
static void
MergeAttributesIntoExisting(Relation child_rel, Relation parent_rel, List *inhAttrNameList,
							bool is_partition)
{
	Relation	attrrel;
	AttrNumber	parent_attno;
	int			parent_natts;
	TupleDesc	tupleDesc;
	HeapTuple	tuple;
	ListCell	*attNameCell;
	cqContext	cqc;
	cqContext  *pcqCtx;

	attrrel = heap_open(AttributeRelationId, RowExclusiveLock);

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

	tupleDesc = RelationGetDescr(parent_rel);
	parent_natts = tupleDesc->natts;

	/*
	 * If we have an inherited column list, ensure all named columns exist in parent
	 * and that the list excludes system columns.
	 */
	foreach( attNameCell, inhAttrNameList )
	{
		bool columnDefined = false;
		char *inhAttrName = strVal((Value *)lfirst(attNameCell));

		for (parent_attno = 1; parent_attno <= parent_natts && !columnDefined; parent_attno++)
		{
			char *attributeName;
			Form_pg_attribute attribute = tupleDesc->attrs[parent_attno - 1];
			if (attribute->attisdropped)
				continue;
			attributeName = NameStr(attribute->attname);
			columnDefined = (strcmp(inhAttrName, attributeName) == 0);
		}

		if (!columnDefined)
			ereport(ERROR,
					(errcode(ERRCODE_UNDEFINED_COLUMN),
					errmsg("column \"%s\" does not exist in parent table \"%s\"",
							inhAttrName,
							RelationGetRelationName(parent_rel)),
									   errOmitLocation(true)));
	}

	for (parent_attno = 1; parent_attno <= parent_natts; parent_attno++)
	{
		Form_pg_attribute attribute = tupleDesc->attrs[parent_attno - 1];
		char	   *attributeName = NameStr(attribute->attname);

		/* Ignore dropped columns in the parent. */
		if (attribute->attisdropped)
			continue;

		/* Find same column in child (matching on column name). */
		tuple = caql_getattname(pcqCtx, RelationGetRelid(child_rel),
								attributeName);

		if (HeapTupleIsValid(tuple))
		{
			/* Check they are same type and typmod */
			Form_pg_attribute childatt = (Form_pg_attribute) GETSTRUCT(tuple);

			if (attribute->atttypid != childatt->atttypid ||
				attribute->atttypmod != childatt->atttypmod)
				ereport(ERROR,
						(errcode(ERRCODE_DATATYPE_MISMATCH),
						 errmsg("child table \"%s\" has different type for column \"%s\"",
								RelationGetRelationName(child_rel),
								attributeName),
										   errOmitLocation(true)));

			if (attribute->attnotnull && !childatt->attnotnull)
				ereport(ERROR,
						(errcode(ERRCODE_DATATYPE_MISMATCH),
					  errmsg("column \"%s\" in child table must be marked NOT NULL",
							 attributeName),
									   errOmitLocation(true)));

			/*
			 * OK, bump the child column's inheritance count.  (If we fail
			 * later on, this change will just roll back.)
			 */
			childatt->attinhcount++;

			/*
			 * For locally-defined attributes, check to see if the attribute is named
			 * in the "fully-inherited" list.  If so, mark the child attribute as
			 * not locally defined.  (Default/standard behaviour is to leave the
			 * attribute locally defined.)
			 */
			if (childatt->attislocal)
			{
				/* never local when we're doing partitioning */
				if (is_partition)
					childatt->attislocal = false;
				else
				{
					foreach( attNameCell, inhAttrNameList )
					{
						char *inhAttrName = strVal((Value *)lfirst(attNameCell));
						if (strcmp(attributeName, inhAttrName) == 0)
						{
							childatt->attislocal = false;
							break;
						}
					}
				}
			}

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

			heap_freetuple(tuple);
		}
		else
		{
			ereport(ERROR,
					(errcode(ERRCODE_DATATYPE_MISMATCH),
					 errmsg("child table is missing column \"%s\"",
							attributeName),
									   errOmitLocation(true)));
		}
	}

	heap_close(attrrel, RowExclusiveLock);
}

/*
 * Check constraints in child table match up with constraints in parent
 *
 * Called by ATExecAddInherit and exchange_part_inheritance
 *
 * Currently all constraints in parent must be present in the child. One day we
 * may consider adding new constraints like CREATE TABLE does. We may also want
 * to allow an optional flag on parent table constraints indicating they are
 * intended to ONLY apply to the master table, not to the children. That would
 * make it possible to ensure no records are mistakenly inserted into the
 * master in partitioned tables rather than the appropriate child.
 *
 * XXX This is O(N^2) which may be an issue with tables with hundreds of
 * constraints. As long as tables have more like 10 constraints it shouldn't be
 * a problem though. Even 100 constraints ought not be the end of the world.
 */
static void
MergeConstraintsIntoExisting(Relation child_rel, Relation parent_rel)
{
	Relation	catalogRelation;
	TupleDesc	tupleDesc;
	cqContext  *pcqCtx;
	cqContext	cqc;
	HeapTuple	constraintTuple;
	ListCell   *elem;
	List	   *constraints;

	/* First gather up the child's constraint definitions */
	catalogRelation = heap_open(ConstraintRelationId, AccessShareLock);
	tupleDesc = RelationGetDescr(catalogRelation);

	pcqCtx = caql_beginscan(
			caql_addrel(cqclr(&cqc), catalogRelation),
			cql("SELECT * FROM pg_constraint "
				" WHERE conrelid = :1 ",
				ObjectIdGetDatum(RelationGetRelid(child_rel))));

	constraints = NIL;
	while (HeapTupleIsValid(constraintTuple = caql_getnext(pcqCtx)))
	{
		Form_pg_constraint con = (Form_pg_constraint) GETSTRUCT(constraintTuple);

		if (con->contype != CONSTRAINT_CHECK)
			continue;

		constraints = lappend(constraints, heap_copytuple(constraintTuple));
	}

	caql_endscan(pcqCtx);

	/* Then scan through the parent's constraints looking for matches */

	pcqCtx = caql_beginscan(
			caql_addrel(cqclr(&cqc), catalogRelation),
			cql("SELECT * FROM pg_constraint "
				" WHERE conrelid = :1 ",
				ObjectIdGetDatum(RelationGetRelid(parent_rel))));

	while (HeapTupleIsValid(constraintTuple = caql_getnext(pcqCtx)))
	{
		Form_pg_constraint parent_con = (Form_pg_constraint) GETSTRUCT(constraintTuple);
		bool		found = false;
		Form_pg_constraint child_con = NULL;
		HeapTuple	child_contuple = NULL;

		if (parent_con->contype != CONSTRAINT_CHECK)
			continue;

		foreach(elem, constraints)
		{
			child_contuple = (HeapTuple) lfirst(elem);
			child_con = (Form_pg_constraint) GETSTRUCT(child_contuple);
			if (strcmp(NameStr(parent_con->conname),
					   NameStr(child_con->conname)) == 0)
			{
				found = true;
				break;
			}
		}

		if (!found)
			ereport(ERROR,
					(errcode(ERRCODE_DATATYPE_MISMATCH),
					 errmsg("child table is missing constraint \"%s\"",
							NameStr(parent_con->conname)),
									   errOmitLocation(true)));

		if (parent_con->condeferrable != child_con->condeferrable ||
			parent_con->condeferred != child_con->condeferred ||
			strcmp(decompile_conbin(constraintTuple, tupleDesc),
				   decompile_conbin(child_contuple, tupleDesc)) != 0)
			ereport(ERROR,
					(errcode(ERRCODE_DATATYPE_MISMATCH),
					 errmsg("constraint definition for check constraint \"%s\" does not match",
							NameStr(parent_con->conname)),
									   errOmitLocation(true)));

		/*
		 * TODO: add conislocal,coninhcount to constraints. This is where we
		 * would have to bump them just like attributes
		 */
	}

	caql_endscan(pcqCtx);
	heap_close(catalogRelation, AccessShareLock);
}

/*
 * ALTER TABLE NO INHERIT
 *
 * Drop a parent from the child's parents. This just adjusts the attinhcount
 * and attislocal of the columns and removes the pg_inherit and pg_depend
 * entries.
 *
 * If attinhcount goes to 0 then attislocal gets set to true. If it goes back
 * up attislocal stays true, which means if a child is ever removed from a
 * parent then its columns will never be automatically dropped which may
 * surprise. But at least we'll never surprise by dropping columns someone
 * isn't expecting to be dropped which would actually mean data loss.
 */
static void
ATExecDropInherit(Relation rel, RangeVar *parent, bool is_partition)
{
	Relation	parent_rel;
	Relation	catalogRelation;
	cqContext  *pcqCtx;
	cqContext	cqc;
	HeapTuple	inheritsTuple,
				attributeTuple,
				depTuple;
	bool		found = false;

	/*
	 * AccessShareLock on the parent is probably enough, seeing that DROP TABLE
	 * doesn't lock parent tables at all.  We need some lock since we'll be
	 * inspecting the parent's schema.
	 */
	parent_rel = heap_openrv(parent, AccessShareLock);

	/*
	 * We don't bother to check ownership of the parent table --- ownership
	 * of the child is presumed enough rights.
	 */

	/*
	 * Find and destroy the pg_inherits entry linking the two, or error out
	 * if there is none.
	 */

	/* XXX XXX: could do DELETE FROM ... WHERE ... AND inhparent = :2,
	   ObjectIdGetDatum(RelationGetRelid(parent_rel)) 
	*/
	pcqCtx = caql_beginscan(
			NULL,
			cql("SELECT * FROM pg_inherits "
				" WHERE inhrelid = :1 "
				" FOR UPDATE ",
				ObjectIdGetDatum(RelationGetRelid(rel))));

	while (HeapTupleIsValid(inheritsTuple = caql_getnext(pcqCtx)))
	{
		Oid			inhparent;

		inhparent = ((Form_pg_inherits) GETSTRUCT(inheritsTuple))->inhparent;
		if (inhparent == RelationGetRelid(parent_rel))
		{
			caql_delete_current(pcqCtx);
			found = true;
			break;
		}
	}
	caql_endscan(pcqCtx);

	if (!found)
		ereport(ERROR,
				(errcode(ERRCODE_UNDEFINED_TABLE),
				 errmsg("relation \"%s\" is not a parent of relation \"%s\"",
						RelationGetRelationName(parent_rel),
						RelationGetRelationName(rel)),
								   errOmitLocation(true)));

	/*
	 * Search through child columns looking for ones matching parent rel
	 */
	catalogRelation = heap_open(AttributeRelationId, RowExclusiveLock);

	/* XXX XXX: AND attisdrop = FALSE, etc */
	pcqCtx = caql_beginscan(
			caql_addrel(cqclr(&cqc), catalogRelation),
			cql("SELECT * FROM pg_attribute "
				" WHERE attrelid = :1 "
				" FOR UPDATE ",
				ObjectIdGetDatum(RelationGetRelid(rel))));

	while (HeapTupleIsValid(attributeTuple = caql_getnext(pcqCtx)))
	{
		Form_pg_attribute att = (Form_pg_attribute) GETSTRUCT(attributeTuple);
		HeapTuple	attnameTuple;

		/* Ignore if dropped or not inherited */
		if (att->attisdropped)
			continue;
		if (att->attinhcount <= 0)
			continue;

		/* XXX: would have been attname_exists() */
		attnameTuple = caql_getattname(NULL, RelationGetRelid(parent_rel),
									   NameStr(att->attname));

		if (HeapTupleIsValid(attnameTuple))
		{
			/* Decrement inhcount and possibly set islocal to true */
			HeapTuple	copyTuple = heap_copytuple(attributeTuple);
			Form_pg_attribute copy_att = (Form_pg_attribute) GETSTRUCT(copyTuple);

			copy_att->attinhcount--;
			if (copy_att->attinhcount == 0)
				copy_att->attislocal = true;

			caql_update_current(pcqCtx, copyTuple);
			heap_freetuple(copyTuple);
			heap_freetuple(attnameTuple);
		}
	}
	caql_endscan(pcqCtx);
	heap_close(catalogRelation, RowExclusiveLock);

	/*
	 * Drop the dependency
	 *
	 * There's no convenient way to do this, so go trawling through pg_depend
	 */

	/* XXX XXX: AND refclassid, refobjid, etc */
	pcqCtx = caql_beginscan(
			NULL,
			cql("SELECT * FROM pg_depend "
				" WHERE classid = :1 "
				" AND objid = :2 "
				" AND objsubid = :3 "
				" FOR UPDATE ",
				ObjectIdGetDatum(RelationRelationId),
				ObjectIdGetDatum(RelationGetRelid(rel)),
				Int32GetDatum(0)));

	while (HeapTupleIsValid(depTuple = caql_getnext(pcqCtx)))
	{
		Form_pg_depend dep = (Form_pg_depend) GETSTRUCT(depTuple);

		if (dep->refclassid == RelationRelationId &&
			dep->refobjid == RelationGetRelid(parent_rel) &&
			dep->refobjsubid == 0 &&
			((dep->deptype == DEPENDENCY_NORMAL && !is_partition) ||
			 (dep->deptype == DEPENDENCY_AUTO && is_partition)))
				caql_delete_current(pcqCtx);
	}

	caql_endscan(pcqCtx);

	/* keep our lock on the parent relation until commit */
	heap_close(parent_rel, NoLock);

	/* MPP-6929: metadata tracking */
	if ((Gp_role == GP_ROLE_DISPATCH)
		&& MetaTrackValidKindNsp(rel->rd_rel))
		MetaTrackUpdObject(RelationRelationId,
						   RelationGetRelid(rel),
						   GetUserId(),
						   "ALTER", "NO INHERIT"
				);


}

/*
 * deparse pg_class.reloptions into a list.
 */
static List *
reloptions_list(Oid relid)
{
	Datum reloptions;
    HeapTuple tuple;
	bool isNull = true;
	List *opts = NIL;
	cqContext	*pcqCtx;

	pcqCtx = caql_beginscan(
			NULL,
			cql("SELECT * FROM pg_class "
				" WHERE oid = :1 ",
				ObjectIdGetDatum(relid)));

	tuple = caql_getnext(pcqCtx);

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

    reloptions = caql_getattr(pcqCtx,
							  Anum_pg_class_reloptions,
							  &isNull);
    if (!isNull)
		opts = untransformRelOptions(reloptions);

	caql_endscan(pcqCtx);

	return opts;
}

/*
 * Build:
 *
 * CREATE TABLE pg_temp_<NNNN> AS SELECT * FROM rel
 *   DISTRIBUTED BY dist_clause
 */
static QueryDesc *
build_ctas_with_dist(Relation rel, List *dist_clause,
					 List *storage_opts, RangeVar **tmprv, List **hidden_types)
{
	Query *q;
	SelectStmt *s = makeNode(SelectStmt);
	Node *n;
	List	*parsetrees;
	RangeVar *from_tbl;
	List *rewritten;
	PlannedStmt *stmt;
	DestReceiver *dest;
	QueryDesc *queryDesc;
	RangeVar *tmprel = make_temp_table_name(rel, MyBackendId);
	bool pre_built;

	{
		ResTarget *t = makeNode(ResTarget);
	    ColumnRef *c = makeNode(ColumnRef);
        c->fields = list_make1(makeString("*"));
        c->location = -1;
        t->val = (Node *)c;
        t->location = -1;
		s->targetList = list_make1(t);
	}

	from_tbl = makeRangeVar(NULL /*catalogname*/, get_namespace_name(RelationGetNamespace(rel)),
							pstrdup(RelationGetRelationName(rel)), -1);
	from_tbl->inhOpt = INH_NO; /* MPP-5300: turn off inheritance -
								* Otherwise, the data from the child
								* tables is added to the parent!
								*/
	s->fromClause = list_make1(from_tbl);

	/* Handle tables with OIDS */
	if (rel->rd_rel->relhasoids)
		storage_opts = lappend(storage_opts, defWithOids(true));

	pre_built = prebuild_temp_table(rel, tmprel, dist_clause,
									storage_opts, hidden_types,
									(RelationIsAoRows(rel) ||
									 RelationIsParquet(rel)));
	if (pre_built)
	{
		InsertStmt *i = makeNode(InsertStmt);

		i->relation = tmprel;
		i->selectStmt = (Node *)s;
		n = (Node *)i;
	}
	else
	{
		Oid tblspc = rel->rd_rel->reltablespace;

		s->intoClause = makeNode(IntoClause);
		s->intoClause->rel = tmprel;
		s->intoClause->options = storage_opts;
		s->intoClause->tableSpaceName = get_tablespace_name(tblspc);
		s->distributedBy = dist_clause;
		n = (Node *)s;
	}
	*tmprv = tmprel;

	parsetrees = parse_analyze((Node *)n, NULL, NULL, 0);
	Assert(list_length(parsetrees) == 1);
	q = (Query *)linitial(parsetrees);

	AcquireRewriteLocks(q);

	/* Rewrite through rule system */
	rewritten = QueryRewrite(q);

	/* We don't expect more or less than one result query */
	Assert(list_length(rewritten) == 1);

	q = (Query *) linitial(rewritten);
	Assert(q->commandType == CMD_SELECT || q->commandType == CMD_INSERT);

	/* plan the query */
	stmt = planner(q, 0, NULL, QRL_ONCE);

	/*
	 * Update snapshot command ID to ensure this query sees results of any
	 * previously executed queries.
	 */
	//ActiveSnapshot->curcid = GetCurrentCommandId();

	/* Create dest receiver for COPY OUT */
	dest = CreateDestReceiver(DestIntoRel, NULL);

	/* Create a QueryDesc requesting no output */
	queryDesc = CreateQueryDesc(stmt,  pstrdup("(internal SELECT INTO query)"),
								ActiveSnapshot, InvalidSnapshot,
								dest, NULL, false);
	return queryDesc;
}

static Datum
new_rel_opts(Relation rel, List *lwith)
{
	Datum newOptions = PointerGetDatum(NULL);
	bool make_heap = false;
	bool need_free_value = false;
	if (lwith && list_length(lwith))
	{
		ListCell *lc;

		/*
		 * See if user has specified appendonly = false. If so, we
		 * have no use for the existing reloptions
		 */
		foreach(lc, lwith)
		{
			DefElem *e = lfirst(lc);
			if (pg_strcasecmp(e->defname, "appendonly") == 0 &&
				pg_strcasecmp(defGetString(e, &need_free_value), "false") == 0)
			{
				make_heap = true;
				break;
			}
		}
	}

	if (!make_heap)
	{
		/* Get the old reloptions */
		bool isnull;
		Oid relid = RelationGetRelid(rel);
		cqContext	*pcqCtx;
		HeapTuple optsTuple;

		pcqCtx = caql_beginscan(
				NULL,
				cql("SELECT * FROM pg_class "
					" WHERE oid = :1 ",
					ObjectIdGetDatum(relid)));

		optsTuple  = caql_getnext(pcqCtx);

		if (!HeapTupleIsValid(optsTuple))
				elog(ERROR, "cache lookup failed for relation %u", relid);

		newOptions = caql_getattr(pcqCtx,
								  Anum_pg_class_reloptions, &isnull);

		/* take a copy since we're using it after ReleaseSysCache() */
		if (!isnull)
			newOptions = datumCopy(newOptions, false, -1);

		caql_endscan(pcqCtx);
	}

	/* Generate new proposed reloptions (text array) */
	newOptions = transformRelOptions(newOptions, lwith, false, false);

	return newOptions;
}

static RangeVar *
make_temp_table_name(Relation rel, BackendId id)
{
	char *nspname,
		 tmpname[NAMEDATALEN];
	/* temporary enough */
	snprintf(tmpname, NAMEDATALEN, "pg_temp_%u_%i", RelationGetRelid(rel), id);
	nspname = get_namespace_name(RelationGetNamespace(rel));

	return makeRangeVar(NULL /*catalogname*/, nspname, pstrdup(tmpname), -1);
}

/* Fill-in the names field of the given TypeName node with the name
 * of an existing type that matches the given internal length, and alignment.
 *
 * If none can be found, return NULL, else return the given TypeName
 * pointer.
 *
 * It may seem as if we should include by-value in the test, but built-in
 * types cover the allowable internal lengths for these and we don't want
 * to second guess.
 *
 * Specifically for use by make_typename.
 */
static TypeName *
pick_name_of_similar_type(TypeName *tname, int2 typlen, char typalign)
{
	HeapTuple	tuple;

	/* XXX XXX: not sure why this is RowExclusiveLock */
	tuple = caql_getfirst(
			NULL,
			cql("SELECT * FROM pg_type "
				" WHERE typlen = :1 "
				" AND typalign = :2 "
				" FOR UPDATE ",
				Int16GetDatum(typlen),
				CharGetDatum(typalign)));

	if (HeapTupleIsValid(tuple))
	{
		Form_pg_type typtuple = (Form_pg_type)GETSTRUCT(tuple);
		tname->names =
			list_make2(makeString(get_namespace_name(typtuple->typnamespace)),
					   makeString(pstrdup(NameStr(typtuple->typname))));
	}
	else
		tname = NULL;


	return tname;
}

/*
 * Build the basic CreateFunctionStmt statement for dispatch as part of
 * build_hidden_type().
 */
static CreateFunctionStmt *
build_iofunc(char *newname, char *iotype, char *baseio, char *returns)
{
	CreateFunctionStmt *iofunc;
	char ioname[NAMEDATALEN];
	FunctionParameter *param;
	List *args;

	if (strcmp("in", iotype) == 0)
	   args = list_make2(makeString("pg_catalog"), makeString("cstring"));
	else
		args = list_make1(makeString(newname));

	/*
	 * CREATE FUNCTION F(cstring) RETURNS shelltype AS 'int4(cstring)' language
	 * internal;
	 */
	iofunc = makeNode(CreateFunctionStmt);
	snprintf(ioname, NAMEDATALEN, "%s_%s", newname, iotype);
	iofunc->funcname = list_make1(makeString(pstrdup(ioname)));
	param = makeNode(FunctionParameter);
	param->argType = makeTypeNameFromNameList(args);
	param->mode = FUNC_PARAM_IN;
	iofunc->parameters = list_make1(param);
	iofunc->returnType = makeTypeName(returns);
	iofunc->options = list_make2(makeDefElem("as", (Node *)list_make1(makeString(baseio))),
								 makeDefElem("language", (Node *)makeString("internal")));

	return iofunc;
}

/*
 * Build a temporary hidden type for dropped columns for which there is no
 * suitable pg_type entry. We find these "ghost types" when a user has created a
 * type, dropped a column using it and THEN dropped the type. There is a kind of
 * "homeopathic echo" here, where we have the structural details of the type in
 * pg_attribute but no way of pin pointing the type configuration by name.
 *
 * Procedure:
 * a) Build a shell type
 * b) Create IO functions
 * c) Fill out the shell type with IO functions and correct length and alignment
 * data
 *
 * The IO functions do not have to do anything because all values in the column
 * will be NULL, the functions will never be called.
 */
static TypeName *
build_hidden_type(Form_pg_attribute att)
{
	DefineStmt *newtype;
	CreateFunctionStmt *iofunc;
	Value *inputname;
	Value *outputname;
	List *parsetrees;
	DestReceiver *dest = None_Receiver;
	Query *q;
	char *alignname = NULL;
	TypeName *typname;
	char newname[NAMEDATALEN];

	Assert(Gp_role == GP_ROLE_DISPATCH);

	snprintf(newname, NAMEDATALEN, "pg_atsdb_%u_%i_%u", att->attrelid,
			 att->attnum, MyBackendId);

	/* shell type */
	newtype = makeNode(DefineStmt);
	newtype->kind = OBJECT_TYPE;
	newtype->defnames = list_make1(makeString(newname));

	/* that's all that's needed for the shell! */
	parsetrees = parse_analyze((Node *)newtype, NULL, NULL, 0);
	Assert(list_length(parsetrees) == 1);
	q = (Query *)linitial(parsetrees);
	ProcessUtility((Node *)q->utilityStmt, 
				   synthetic_sql,
				   NULL, 
				   false, /* not top level */
				   dest, 
				   NULL);
	CommandCounterIncrement();

	/*
	 * Now for the input function.
	 */
	iofunc = build_iofunc(newname, "in", "int4in", newname);
	inputname = copyObject(linitial(iofunc->funcname));
	parsetrees = parse_analyze((Node *)iofunc, NULL, NULL, 0);
	q = (Query *)linitial(parsetrees);
	ProcessUtility((Node *)q->utilityStmt, 
				   synthetic_sql,
				   NULL, 
				   false, /* not top level */
				   dest, 
				   NULL);
	CommandCounterIncrement();

	/* and then output */
	/* output function accepts shellname as its argument */
	iofunc = build_iofunc(newname, "out", "int4out", "cstring");
	outputname = copyObject(linitial(iofunc->funcname));
	parsetrees = parse_analyze((Node *)iofunc, NULL, NULL, 0);
	q = (Query *)linitial(parsetrees);
	ProcessUtility((Node *)q->utilityStmt,
				   synthetic_sql,
				   NULL, 
				   false, /* not top level */
				   dest, 
				   NULL);
	CommandCounterIncrement();

	/* now build full type */
	newtype = makeNode(DefineStmt);
	newtype->kind = OBJECT_TYPE;
	newtype->defnames = list_make1(makeString(newname));

	newtype->definition = lappend(newtype->definition, makeDefElem("input", (Node *)inputname));
	newtype->definition = lappend(newtype->definition, makeDefElem("output", (Node *)outputname));

	if (att->attbyval)
		newtype->definition = lappend(newtype->definition, makeDefElem("passedbyvalue",
																	   (Node *)makeInteger(1)));

	if (att->attlen == -1)
		newtype->definition = lappend(newtype->definition, makeDefElem("internallength",
																	   (Node *)makeString("variable")));
	else
		newtype->definition = lappend(newtype->definition, makeDefElem("internallength",
																	   (Node *)makeInteger(att->attlen)));

	if (att->attalign == 'd')
		alignname = "double";
	else if (att->attalign == 'i')
		alignname = "int4";
	else if (att->attalign == 's')
		alignname = "int2";
	else if (att->attalign == 'c')
		alignname = "char";
	else
		Assert(false); /* shouldn't get here */

	newtype->definition = lappend(newtype->definition, makeDefElem("alignment",
																   (Node *)makeString(alignname)));

	parsetrees = parse_analyze((Node *)newtype, NULL, NULL, 0);
	q = (Query *)linitial(parsetrees);
	ProcessUtility((Node *)q->utilityStmt,
				   synthetic_sql,
				   NULL, 
				   false, /* not top level */
				   dest, 
				   NULL);
	CommandCounterIncrement();

	typname = makeNode(TypeName);
	typname->names = list_make1(makeString(pstrdup(newname)));

	return typname;
}

/* Allocate and return a pointer to a TypeName node specifying the
 * qualified name of an existing type that matches the internal length
 * and alignment of the given pg_attribute tuple.
 *
 * First we try a few hard-coded builtin types. Internal types exist for
 *    select distinct typlen, typalign
 *    from pg_type where typlen > 0;
 * on a new catalog.  Names are not unique.
 *
 * MPP-5483: If that fails, we look in pg_type for a match.  If even that
 * fails, we issue an error.
 *
 * Specifically for use by prebuilt_temp_table.
 */
static TypeName *
make_typname(Form_pg_attribute att, bool *built)
{
	TypeName *tname = makeNode(TypeName);
	int2 attlen = att->attlen;
	Value *typname = NULL;
	bool dig_in_catalog = false;

	Assert(att->attisdropped); /* better not be here unless */

	tname->typmod = att->atttypmod;

	if (attlen == -1)
	{
		if (att->attalign == 'i')
		{
			if (att->atttypmod < MaxAttrSize)
				typname = makeString(pstrdup("varchar"));
			else
				typname = makeString(pstrdup("numeric"));

			/* 
			 * We're building dropped columns. Dropped columns should never
			 * create a TOAST table because they only ever contain NULL. So,
			 * even if the original typmod was -1 (variable length), set it to a
			 * real value so that we avoid TOAST creation. To do this, we must
			 * be one byte longer than the maximum variable length header size.
			 * See needs_toast_table().
			 *
			 * XXX: there may be occassions where tables with dropped TOASTable
			 * columns do still have TOAST tables. Need to explore those.
			 */
			tname->typmod = 1 + Max(NUMERIC_HDRSZ, VARHDRSZ);
		}
		else if (att->attalign == 'd')
			typname = makeString(pstrdup("path"));
		else
			dig_in_catalog = true;
	}
	else if (attlen == 1 && att->attalign == 'c')
    {
		typname = makeString(pstrdup("char"));
    }
	else if (attlen == 2 && att->attalign == 's')
    {
		typname = makeString(pstrdup("int2"));
    }
	else if (attlen == 4 && att->attalign == 'i')
    {
		typname = makeString(pstrdup("int4"));
    }
	else if (attlen == 6 && att->attalign == 's')
    {
            typname = makeString(pstrdup("tid"));
	}
    else if (attlen == 6 && att->attalign == 'i')
	{
            typname = makeString(pstrdup("macaddr"));
    }
	else if (attlen == 8 && att->attalign == 'd')
    {
		typname = makeString(pstrdup("int8"));
    }
	else if (attlen == 12 && att->attalign == 'd')
    {
			typname = makeString(pstrdup("timetz"));
	}
	else if (attlen == 12 && att->attalign == 'i')
	{
		typname = makeString(pstrdup("tinterval"));
    }
	else if (attlen == 16 && att->attalign == 'd')
    {
		typname = makeString(pstrdup("interval"));
    }
	else if (attlen == 24 && att->attalign == 'd')
    {
		typname = makeString(pstrdup("circle"));
    }
	else if (attlen == 32 && att->attalign == 'd')
    {
		typname = makeString(pstrdup("box"));
    }
	else if (attlen == 64 && att->attalign == 'i')
    {
		typname = makeString(pstrdup("name"));
    }
	else
	{
		dig_in_catalog = true;
    }

	*built = false; /* assume we found an existing type */
	if ( dig_in_catalog )
	{
		tname = pick_name_of_similar_type(tname, attlen, att->attalign);
		if (!tname)
		{
			*built = true;
			tname = build_hidden_type(att);
		}
	}
	else
	{
		tname->names = list_make2(makeString(pstrdup("pg_catalog")), typname);
	}

	tname->location = -1;
	return tname;
}

/*
 * If the table has dropped columns, we must create the table and
 * drop the columns before we can dispatch the select statement.
 * Return true if we do it, false if we do not. If we return false,
 * there are no dropped columns and we can do a SELECT INTO later.
 * If we need to do it, but fail, issue an error. (See make_type.)
 *
 * Specifically for build_ctas_with_dist.
 *
 * Note that the caller should guarantee that isTmpTableAo has
 * a value that matches 'opts'.
 */
static bool
prebuild_temp_table(Relation rel, RangeVar *tmpname, List *distro, List *opts,
					List **hidden_types, bool isTmpTableAo)
{
	bool need_rebuild = false;
	int attno = 0;
	TupleDesc tupdesc = RelationGetDescr(rel);
	List *drop_atts = NIL; /* attnums where we want an attribute to drop */

	if (!need_rebuild)
	{
		for (attno = 0; attno < tupdesc->natts; attno++)
		{
			if (tupdesc->attrs[attno]->attisdropped)
			{
				need_rebuild = true;
				break;
			}
		}
	}

	/*
	 * If the new table is an AO table with indexes, always use
	 * Create Table + Insert Into. During Create Table phase,
	 * we determine whether to create the block directory
	 * depending on whether the original table has indexes. It is
	 * important to create the block directory to support the reindex
	 * later. See MPP-9545 for more info.
	 */
	if (isTmpTableAo &&
		rel->rd_rel->relhasindex)
		need_rebuild = true;

	if (need_rebuild)
	{
		CreateStmt *cs = makeNode(CreateStmt);
		List *parsetrees;
		Query *q;
		char *dstr = "__gp_atsdb_droppedcol";
		DestReceiver *dest = None_Receiver;

		cs->relKind = RELKIND_RELATION;
		cs->distributedBy = distro;
		cs->relation = tmpname;
		cs->ownerid = rel->rd_rel->relowner;
		cs->tablespacename = get_tablespace_name(rel->rd_rel->reltablespace);
		cs->buildAoBlkdir = false;

		if (isTmpTableAo &&
			rel->rd_rel->relhasindex)
			cs->buildAoBlkdir = true;

		cs->options = opts;

		for (attno = 0; attno < tupdesc->natts; attno++)
		{
			ColumnDef *cd = makeNode(ColumnDef);
			TypeName *tname = NULL;
			Form_pg_attribute att = tupdesc->attrs[attno];

			cd->is_local = true;

			if (att->attisdropped)
			{
				NameData alias;
				bool built;

				tname = make_typname(att, &built);
				snprintf(NameStr(alias), sizeof(alias), "%s%d", dstr, attno);
				cd->colname = pstrdup(NameStr(alias));
				drop_atts = lappend_int(drop_atts, attno);

				if (built)
					*hidden_types = lappend(*hidden_types, tname->names);
			}
			else
			{
				Type typ = typeidType(att->atttypid);
				Oid typnamespace = ((Form_pg_type) GETSTRUCT(typ))->typnamespace;
				char *nspname = get_namespace_name(typnamespace);
				int arno;
				char *typstr;
				int4 ndims = att->attndims;

				tname = makeNode(TypeName);

				if (!PointerIsValid(nspname))
					elog(ERROR, "could not lookup namespace %d", typnamespace);
				cd->colname = pstrdup(NameStr(att->attname));
				typstr = typeTypeName(typ);
				tname->names = list_make2(makeString(nspname),
										  makeString(typstr));
				ReleaseType(typ);
				tname->typmod = att->atttypmod;

				/*
				 * If this is a built in array type, like _int4, then reduce
				 * the array dimensions by 1. This is an annoying postgres
				 * hack which I wish would go away.
				 */
				if (typstr && typstr[0] == '_' && ndims > 0)
					ndims--;

				for (arno = 0; arno < ndims; arno++)
					/* bound of -1 are fine because this has no effect on data */
					tname->arrayBounds = lappend(tname->arrayBounds,
												 makeInteger(-1));

			}

			tname->location = -1;
			cd->typname = tname;
			cs->tableElts = lappend(cs->tableElts, cd);
		}
		parsetrees = parse_analyze((Node *)cs, NULL, NULL, 0);
		Assert(list_length(parsetrees) == 1);
		q = (Query *)linitial(parsetrees);
		ProcessUtility((Node *)q->utilityStmt, 
					   synthetic_sql,
					   NULL, 
					   false, /* not top level */
					   dest, 
					   NULL);
		CommandCounterIncrement();

		/* should always be true */
		if (drop_atts)
		{
			/* Build an ALTER TABLE DROP COLUMN statement */
			AlterTableStmt *ats = makeNode(AlterTableStmt);
			ListCell *lc;

			ats->relkind = OBJECT_TABLE;
			ats->relation = tmpname;

			foreach(lc, drop_atts)
			{
				AlterTableCmd *atc = makeNode(AlterTableCmd);
				NameData colname;

				attno = lfirst_int(lc);
				atc->subtype = AT_DropColumn;
				snprintf(NameStr(colname), NAMEDATALEN, "%s%d", dstr, attno);
				atc->name = pstrdup(NameStr(colname));
				ats->cmds = lappend(ats->cmds, atc);
			}
#ifdef NOT_USED
			elog_node_display(NOTICE, "DROP STATEMENT", ats, true);
#endif

			parsetrees = parse_analyze((Node *)ats, NULL, NULL, 0);
			Assert(list_length(parsetrees) == 1);
			q = (Query *)linitial(parsetrees);
			ProcessUtility((Node *)q->utilityStmt, 
						   synthetic_sql,
						   NULL, 
						   false, /* not top level */
						   dest, 
						   NULL);
			CommandCounterIncrement();
		}
	}
	return need_rebuild;
}

/* Build a human readable tag for what we're doing */
static char *
make_distro_str(List *lwith, List *ldistro)
{
    char       *distro_str = "SET WITH DISTRIBUTED BY";

	if (lwith && ldistro)
		distro_str = "SET WITH DISTRIBUTED BY";
	else
	{
		if (lwith)
			distro_str = "SET WITH";
		else if (ldistro)
			distro_str = "SET DISTRIBUTED BY";
	}
	return pstrdup(distro_str); /* don't return a stack address */
}

/*
 * ALTER TABLE SET DISTRIBUTED BY
 *
 * set distribution policy for rel
 *
 * GPSQL: Despite the GP_ROLE_DISPATCH references, note that this entire
 * function executes only on the master.
 */
static void
ATExecSetDistributedBy(Relation rel, Node *node, AlterTableCmd *cmd)
{
	Assert(Gp_role != GP_ROLE_EXECUTE);		/* GPSQL */

	List 	   *lprime;
	List 	   *lwith, *ldistro;
	List	   *cols = NIL;
	ListCell   *lc;
	GpPolicy   *policy = NULL;
	QueryDesc  *queryDesc;
	RangeVar   *tmprv = NULL;
	Oid			tmprelid;
	Oid			tarrelid = RelationGetRelid(rel);
	List	   *oid_map = NIL;
	List	   *qe_data = NIL; /* data to pass to QEs */
	bool        rand_pol = false;
	bool        force_reorg = false;
	Datum		newOptions = PointerGetDatum(NULL);
	bool		change_policy = false;
	bool		is_ao = false;
    bool        is_aocs = false;
	List	   *hidden_types = NIL; /* types we need to build for dropped columns */

	/* Permissions checks */
	if (!pg_class_ownercheck(RelationGetRelid(rel), GetUserId()))
		aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_CLASS,
					   RelationGetRelationName(rel));

	/* Can't ALTER TABLE SET system catalogs */
	if (IsSystemRelation(rel))
		ereport(ERROR,
				(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
				 errmsg("permission denied: \"%s\" is a system catalog",
						RelationGetRelationName(rel)),
								   errOmitLocation(true)));

	Assert(PointerIsValid(node));
	Assert(IsA(node, List));

	lprime = (List *)node;

	/* 
	 * First element is the WITH clause, second element is the actual
	 * distribution clause.
	 */
	lwith   = (List *)linitial(lprime);
	ldistro = (List *)lsecond(lprime);

	if (Gp_role == GP_ROLE_UTILITY)
		ereport(ERROR,
				(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
				 errmsg("SET DISTRIBUTED BY not supported in utility mode")));

	/* we only support fully distributed tables */
	if (Gp_role == GP_ROLE_DISPATCH)
	{
		if (rel->rd_cdbpolicy->ptype != POLICYTYPE_PARTITIONED)
			ereport(ERROR,
					(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
					 errmsg("%s not supported on non-distributed tables",
							ldistro ? "SET DISTRIBUTED BY" : "SET WITH"),
									   errOmitLocation(true)));
	}

	if (Gp_role == GP_ROLE_DISPATCH)
	{
		if (lwith)
		{
			bool		 seen_reorg = false;
			ListCell	*lc;
			char		*reorg_str = "reorganize";
			List		*nlist = NIL;

			/* remove the "REORGANIZE=true/false" from the WITH clause */
			foreach(lc, lwith)
			{
        DefElem *def = lfirst(lc);

        if (pg_strcasecmp(reorg_str, def->defname) != 0)
        {
          /* MPP-7770: disable changing storage options for now */
          if (!gp_setwith_alter_storage)
            ereport(ERROR,
                (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
                    errmsg("option \"%s\" not supported", def->defname),
                    errOmitLocation(true)));

          if (pg_strcasecmp(def->defname, "appendonly") == 0)
          {
            if (IsA(def->arg, String)
                && pg_strcasecmp(strVal(def->arg), "true") == 0)
            {
              is_ao = true;
            }
            else
            {
              is_ao = false;
            }
          }

          if (pg_strcasecmp(def->defname, "orientation") == 0)
          {
            if (IsA(def->arg, String)
                && pg_strcasecmp(strVal(def->arg), "column") == 0)
            {
              ereport(ERROR,
                  (errcode(ERRCODE_GP_FEATURE_NOT_SUPPORTED),
                      errmsg("orientation option \"column\" is deprecated. Not support it any more."),
                      errhint("valid orientation option is \"row\" or \"parquet\""),
                      errOmitLocation(true)));
            }
            else if (IsA(def->arg, String)
                && pg_strcasecmp(strVal(def->arg), "parquet") == 0)
            {
              is_aocs = true;
            }
            else
            {
              if (!IsA(def->arg, String)
                  || pg_strcasecmp(strVal(def->arg), "row") != 0)
                ereport(ERROR,
                    (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                        errmsg("invalid orientation option"),
                        errhint("valid orientation option is \"row\" or \"parquet\""),
                        errOmitLocation(true)));
            }
          }

          nlist = lappend(nlist, def);
				}
				else
				{
          /* have we been here before ? */
          if (seen_reorg)
            ereport(ERROR,
                (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                    errmsg("\"%s\" specified more than once", reorg_str),
                    errOmitLocation(true)));

          seen_reorg = true;
          if (!def->arg)
          {
            force_reorg = true;
          }
          else
          {
            if (IsA(def->arg, String)
                && pg_strcasecmp("TRUE", strVal(def->arg)) == 0)
            {
              force_reorg = true;
            }
            else if (IsA(def->arg, String)
                && pg_strcasecmp("FALSE", strVal(def->arg)) == 0)
            {
              force_reorg = false;
            }
            else
            {
              ereport(ERROR,
                  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                      errmsg("Invalid REORGANIZE option"),
                      errhint("valid REORGANIZE option is \"true\" or \"false\""),
                      errOmitLocation(true)));
            }
          }
				}
			}

      if (is_aocs && !is_ao)
      {
          ereport(ERROR,
                  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                   errmsg("specify orientation requires appendonly"),
                     errOmitLocation(true)));
      }

			lwith = nlist;

			/*
			 * If there are other storage options, but REORGANIZE is not
			 * specified, then the storage must be re-org'd.  But if
			 * REORGANIZE was specified use that setting.
			 *
			 * If the user specified we not force a reorg but there are other
			 * WITH clause items, then we cannot honour what the user has
			 * requested.
			 */
			if (!seen_reorg && list_length(lwith))
				force_reorg = true;
			else if (seen_reorg && force_reorg == false && list_length(lwith))
				ereport(ERROR,
						(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
						 errmsg("%s must be set to true when changing storage "
								 "type", reorg_str),
										   errOmitLocation(true)));

			newOptions = new_rel_opts(rel, lwith);
			
			/* ensure that the options parse */
			if (newOptions)
				(void)heap_reloptions(rel->rd_rel->relkind, newOptions, true);
		}
		else
			newOptions = new_rel_opts(rel, NIL);

		if (ldistro)
			change_policy = true;

		if (ldistro && linitial(ldistro) == NULL)
		{
			Insist(list_length(ldistro) == 1);

			rand_pol = true;

			if (!force_reorg)
			{
				if (rel->rd_cdbpolicy->nattrs == 0)
					ereport(WARNING,
							(errcode(ERRCODE_DUPLICATE_OBJECT),
							 errmsg("distribution policy of relation \"%s\" "
									"already set to DISTRIBUTED RANDOMLY",
									RelationGetRelationName(rel)),
							 errhint("Use ALTER TABLE \"%s\" "
									 "SET WITH (REORGANIZE=TRUE) "
									 "DISTRIBUTED RANDOMLY "
									 "to force a random redistribution",
									 RelationGetRelationName(rel)),
											   errOmitLocation(true)));
			}

			policy = (GpPolicy *) palloc(sizeof(GpPolicy));
			policy->ptype = POLICYTYPE_PARTITIONED;
			policy->nattrs = 0;

			rel->rd_cdbpolicy = GpPolicyCopy(GetMemoryChunkContext(rel),
										 policy);
			GpPolicyReplace(RelationGetRelid(rel), policy);

			/* only need to rebuild if have new storage options */
			if (!(DatumGetPointer(newOptions) || force_reorg))
			{
				/*
				 * caller expects ATExecSetDistributedBy() to close rel
				 * (see the non-random distribution case below for why.
				 */
				heap_close(rel, NoLock);
				goto l_distro_fini;
			}
		}
	}

	/*
	 * Changing a table from random distribution to a specific distribution
	 * policy is the hard bit. For that, we must do the following:
	 *
	 * a) Ensure that the proposed policy is sensible
	 * b) Create a temporary table and reorganise data according to
	 * our desired distribution policy. To do this, we build a Query
	 * node which expresses the query CREATE TABLE tmp_table_name AS
	 * SELECT * FROM cur_table DISTRIBUTED BY (policy)
	 * c) Execute the query across all nodes
	 * d) Update our parse tree to include the details of the newly created
	 * table
	 * e) Update the ownership of the temporary table
	 * f) Swap the relfilenodes of the existing table and the temporary table
	 * g) Update the policy on the QD to reflect the underlying data
	 * h) Drop the temporary table -- and with it, the old copy of the data
	 */
	if (Gp_role == GP_ROLE_DISPATCH)
	{
		volatile Snapshot saveSnapshot = NULL;
		if (change_policy)
		{
			policy = palloc(sizeof(GpPolicy) +
							sizeof(policy->attrs[0]) * list_length(ldistro));
			policy->ptype = POLICYTYPE_PARTITIONED;
			policy->nattrs = 0;

			/* Step (a) */
			if (!rand_pol)
			{
				foreach(lc, ldistro)
				{
					char *colName = strVal((Value *)lfirst(lc));
					cqContext	*attcqCtx;
					HeapTuple tuple;

					attcqCtx = caql_getattname_scan(NULL, 
													RelationGetRelid(rel), 
													colName);
	
					tuple = caql_get_current(attcqCtx);

					AttrNumber	attnum;

					if (list_member(cols, lfirst(lc)))
							ereport(ERROR,
									(errcode(ERRCODE_DUPLICATE_OBJECT),
									 errmsg("distribution policy must be a "
											"unique set of columns"),
									 errhint("Column \"%s\" appears "
											 "more than once", colName),
													   errOmitLocation(true)));
					if (!HeapTupleIsValid(tuple))
							ereport(ERROR,
									(errcode(ERRCODE_UNDEFINED_COLUMN),
									 errmsg("column \"%s\" of "
											"relation \"%s\" does not exist",
											colName,
											RelationGetRelationName(rel)),
													   errOmitLocation(true)));

					attnum = ((Form_pg_attribute) GETSTRUCT(tuple))->attnum;

					/* Prevent them from altering a system attribute */
					if (attnum <= 0)
					ereport(ERROR,
							(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
						    errmsg("cannot distribute by system column \"%s\"",
									colName),
											   errOmitLocation(true)));

					policy->attrs[policy->nattrs++] = attnum;

					caql_endscan(attcqCtx);
					cols = lappend(cols, lfirst(lc));
				} /* end foreach */

				Assert(policy->nattrs > 0);

				/*
				 * See if the the old policy is the same as the new one but
				 * remember, we still might have to rebuild if there are new
				 * storage options.
				 */
				if (!DatumGetPointer(newOptions) && !force_reorg &&
					(policy->nattrs == rel->rd_cdbpolicy->nattrs))
				{
					int i;
					bool diff = false;

					for (i = 0; i < policy->nattrs; i++)
					{
						if (policy->attrs[i] != rel->rd_cdbpolicy->attrs[i])
						{
							diff = true;
							break;
						}
					}
					if (!diff)
					{
						char *dist =
							palloc(list_length(ldistro) * (NAMEDATALEN + 1));

						dist[0] = '\0';

						foreach(lc, ldistro)
						{
							if (lc != list_head(ldistro))
								strcat(dist, ",");
							strcat(dist, strVal(lfirst(lc)));
						}
						ereport(WARNING,
							(errcode(ERRCODE_DUPLICATE_OBJECT),
							 errmsg("distribution policy of relation \"%s\" "
									"already set to (%s)",
									RelationGetRelationName(rel),
									dist),
							 errhint("Use ALTER TABLE \"%s\" "
									 "SET WITH (REORGANIZE=TRUE) "
									 "DISTRIBUTED BY (%s) "
									 "to force redistribution",
									 RelationGetRelationName(rel),
									 dist),
											   errOmitLocation(true)));
						heap_close(rel, NoLock);
						/* Tell QEs to do nothing */
						linitial(lprime) = NULL;
						lsecond(lprime) = list_make1(NULL);

						return;
						/* don't goto l_distro_fini -- didn't do anything! */
					}
				}
			}
		}

		if (!ldistro)
			ldistro = make_dist_clause(rel);

		/* force the use of legacy query optimizer, since PQO will not redistribute the tuples if the current and required
		   distributions are both RANDOM even when reorganize is set to "true"*/
		bool saveOptimizerGucValue = optimizer;
		optimizer = false;

		if (saveOptimizerGucValue)
		{
			elog(LOG, "ALTER SET DISTRIBUTED BY: falling back to legacy query optimizer to ensure re-distribution of tuples.");
		}

		PG_TRY();
		{
			/* 
			 * We need to update our snapshot here to make sure we see all
			 * committed work. We have an exclusive lock on the table so no one
			 * will be able to access the table now.
			 */
			saveSnapshot = ActiveSnapshot;
			ActiveSnapshot = CopySnapshot(GetLatestSnapshot());

	    /* Step (b) - build CTAS */
	    queryDesc = build_ctas_with_dist(rel, ldistro,
	                     untransformRelOptions(newOptions),
	                     &tmprv,
	                     &hidden_types);

			/* Step (c) - run on all nodes */
			ExecutorStart(queryDesc, 0);
			ExecutorRun(queryDesc, ForwardScanDirection, 0L);
			ExecutorEnd(queryDesc);
			FreeQueryDesc(queryDesc);

			/* Restore the old snapshot */
			ActiveSnapshot = saveSnapshot;
			optimizer = saveOptimizerGucValue;

		}
		PG_CATCH();
		{
			ActiveSnapshot = saveSnapshot;
			optimizer = saveOptimizerGucValue;

			PG_RE_THROW();
		}
		PG_END_TRY();

		CommandCounterIncrement(); /* see the effects of the command */

		/*
		 * Step (d) - tell the seg nodes about the temporary relation. This
		 * involves stomping on the node we've been given
		 */
		qe_data = lappend(qe_data, makeInteger(MyBackendId));
	}
	/*
	GPSQL: ALTER SET DISTRIBUTED BY doesn't need to propagate the tmprv and relopts to
	the QEs, because the QEs won't be needing to revise their own catalogs.

	else
	{
		int backend_id;
		bool reorg = true;

		Assert(list_length(lprime) >= 2);

		lwith = linitial(lprime);
		qe_data = lsecond(lprime);

		if (lwith)
		{
			if (list_length(lwith))
			{
				DefElem *e = linitial(lwith);
				if (pg_strcasecmp(e->defname, "reorganize") == 0 &&
					pg_strcasecmp(strVal(e->arg), "false") == 0)
					reorg = false;
			}
		}
		else if (!lwith)
			reorg = false;

		if (!reorg && list_length(qe_data) == 1 && linitial(qe_data) == NULL)
		{
			heap_close(rel, NoLock);
			goto l_distro_fini;			
		}

		backend_id = intVal(linitial(qe_data));
		tmprv = make_temp_table_name(rel, backend_id);
		oid_map = lsecond(qe_data);
		if (list_length(qe_data) == 3)
			hidden_types = lthird(qe_data);

		if (list_length(lprime) == 3)
		{
			Value *v = lthird(lprime);
			if (intVal(v) == 1)
      {
			  is_ao = true;
        relstorage = RELSTORAGE_AOROWS;
      }
			else
      {
				is_ao = false;
        relstorage = RELSTORAGE_HEAP;
      }
		}

		newOptions = new_rel_opts(rel, lwith);
	}
	*/

	/*
	 * Step (e) - Correct ownership on temporary table:
	 *   necessary so that the toast tables/indices have the correct
	 *   owner after we swap them.
	 *
	 * Note: ATExecChangeOwner does NOT dispatch, so this does not
	 * belong in the dispatch block above (MPP-9663).
	 */
	ATExecChangeOwner(RangeVarGetRelid(tmprv, false, false /*allowHcatalog*/),
					  rel->rd_rel->relowner, true);
	CommandCounterIncrement(); /* see the effects of the command */

	/*
	 * Step (f) - swap relfilenodes and MORE !!!
	 *
	 * Just lookup the Oid and pass it to swap_relation_files(). To do
	 * this we must close the rel, since it needs to be forgotten by
	 * the cache, we keep the lock though. ATRewriteCatalogs() knows
	 * that we've closed the relation here.
	 */
	heap_close(rel, NoLock);
   	tmprelid = RangeVarGetRelid(tmprv, false, false /*allowHcatalog*/);
	swap_relation_files(tarrelid, tmprelid, false);

	if (DatumGetPointer(newOptions))
	{
		Datum		repl_val[Natts_pg_class];
		bool		repl_null[Natts_pg_class];
		bool		repl_repl[Natts_pg_class];
		HeapTuple	newOptsTuple;
		HeapTuple	tuple;
		cqContext	*relcqCtx;

		/*
		 * All we need do here is update the pg_class row; the new
		 * options will be propagated into relcaches during
		 * post-commit cache inval.
		 */
		MemSet(repl_val, 0, sizeof(repl_val));
		MemSet(repl_null, false, sizeof(repl_null));
		MemSet(repl_repl, false, sizeof(repl_repl));

		if (newOptions != (Datum) 0)
			repl_val[Anum_pg_class_reloptions - 1] = newOptions;
		else
			repl_null[Anum_pg_class_reloptions - 1] = true;

		repl_repl[Anum_pg_class_reloptions - 1] = true;

		relcqCtx = caql_beginscan(
				NULL,
				cql("SELECT * FROM pg_class "
					" WHERE oid = :1 "
					" FOR UPDATE ",
					ObjectIdGetDatum(tarrelid)));

		tuple = caql_getnext(relcqCtx);

		Insist(HeapTupleIsValid(tuple));
		newOptsTuple = caql_modify_current(relcqCtx,
										   repl_val, repl_null, repl_repl);

		caql_update_current(relcqCtx, newOptsTuple);
		/* and Update indexes (implicit) */

		heap_freetuple(newOptsTuple);

		caql_endscan(relcqCtx);

		/*
		 * Increment cmd counter to make updates visible; this is
		 * needed because the same tuple has to be updated again
		 */
		CommandCounterIncrement();
	}

	/* now, reindex */
	/* GPSQL: This will run only on the master, and that's ok. At this
	 * stage of GPSQL, the only indexes we're concerned with are those
	 * that reside on the master, which index master metadata. */
	reindex_relation(tarrelid, false, false /* ao_segs ? */, false,
					 &oid_map, Gp_role == GP_ROLE_DISPATCH);

	/* Step (g) */
	if (Gp_role == GP_ROLE_DISPATCH)
	{
		if (change_policy)
			GpPolicyReplace(tarrelid, policy);

		qe_data = lappend(qe_data, oid_map);

		if (hidden_types)
			qe_data = lappend(qe_data, hidden_types);
		linitial(lprime) = lwith;
		lsecond(lprime) = qe_data;
		lprime = lappend(lprime, makeInteger(is_ao ? (is_aocs ? 2 : 1) : 0));
	}

	/* Step (h) Drop the table */
	{
		ObjectAddress object;
		object.classId = RelationRelationId;
		object.objectId = tmprelid;
		object.objectSubId = 0;

		performDeletion(&object, DROP_RESTRICT);

		if (hidden_types)
		{
			object.classId = TypeRelationId;

			foreach(lc, hidden_types)
			{
				TypeName *tname = makeTypeNameFromNameList(lfirst(lc));
				Oid typid = typenameTypeId(NULL, tname);

				object.objectId = typid;

				/* cascade to get rid of functions */
				performDeletion(&object, DROP_CASCADE);
			}
		}
	}

	AORelRemoveHashEntryOnCommit(tarrelid);

l_distro_fini:

	/* MPP-6929: metadata tracking */
	if (Gp_role == GP_ROLE_DISPATCH)
	{
		char *distro_str = make_distro_str(lwith, ldistro);
		/* don't check relkind - must be a table */
		MetaTrackUpdObject(RelationRelationId,
						   tarrelid,
						   GetUserId(),
						   "ALTER", distro_str
				);
	}

}


/*
 * rel could be a toast table, toast table index or index on a
 * table. Get that table's OID.
 */
static Oid
rel_get_table_oid(Relation rel)
{
	Oid toid = RelationGetRelid(rel);
	Relation thisrel = NULL;

	if (rel->rd_rel->relkind == RELKIND_INDEX)
	{
		Oid indrelid;
		int fetchCount;

		indrelid = caql_getoid_plus(
				NULL,
				&fetchCount,
				NULL,
				cql("SELECT indrelid FROM pg_index "
					" WHERE indexrelid = :1 ",
					ObjectIdGetDatum(toid)));

		if (!fetchCount)
			elog(ERROR, "cache lookup failure: cannot find pg_index entry for OID %u",
				 toid);
		toid = indrelid;

		thisrel = relation_open(toid, NoLock);
		toid = rel_get_table_oid(thisrel); /* **RECURSIVE** */
		relation_close(thisrel, NoLock);
		return toid;
	}
	else if (rel->rd_rel->relkind == RELKIND_AOSEGMENTS ||
			 rel->rd_rel->relkind == RELKIND_AOBLOCKDIR ||
			 rel->rd_rel->relkind == RELKIND_TOASTVALUE)
	{
		/* use pg_depend to find parent */
		cqContext  *pcqCtx;
		cqContext	cqc;
		HeapTuple tup;

		/* XXX XXX: SnapShotAny */
		pcqCtx = caql_beginscan(
				caql_snapshot(cqclr(&cqc), SnapshotAny),
				cql("SELECT * FROM pg_depend "
					" WHERE classid = :1 "
					" AND objid = :2 ",
					ObjectIdGetDatum(RelationRelationId),
					ObjectIdGetDatum(toid)));
		/*
		 * We use SnapshotAny because the ordering of the dependency code means
		 * that some times we've already deleted the pg_depend tuple. So, we do
		 * an extra test below to see that, if this tuple is deleted, it was
		 * done so by our xid, otherwise we overlook it.
		 */

		while (HeapTupleIsValid(tup = caql_getnext(pcqCtx)))
		{
			Form_pg_depend foundDep = (Form_pg_depend) GETSTRUCT(tup);
			HeapTupleHeader htup = tup->t_data;

			if (!TransactionIdIsNormal(HeapTupleHeaderGetXmax(htup)) ||
				TransactionIdIsCurrentTransactionId(HeapTupleHeaderGetXmax(htup)))
			{
				if (foundDep->deptype == DEPENDENCY_INTERNAL)
				{
					toid = foundDep->refobjid;
					break;
				}
			}
		}
		caql_endscan(pcqCtx);
	}
	return toid;
}

/*
 * partition children, toast tables and indexes, and indexes on partition
 * children do not long lived locks because the lock on the partition master
 * protects us.
 */
bool
rel_needs_long_lock(Oid relid)
{
	bool needs_lock = true;
	Relation rel = relation_open(relid, NoLock);

	relid = rel_get_table_oid(rel);

	relation_close(rel, NoLock);

	if (Gp_role == GP_ROLE_DISPATCH)
		needs_lock = !rel_is_child_partition(relid);
	else
	{
		int fetchCount;

		fetchCount  = caql_getcount(
				NULL,
				cql("SELECT COUNT(*) FROM pg_inherits "
					" WHERE inhrelid = :1 "
					" AND inhseqno = :2 ",
					 ObjectIdGetDatum(relid),
					Int32GetDatum(1)));

		if (fetchCount)
			needs_lock = false;
	}
	return needs_lock;
}


/*
 * ALTER TABLE ... ADD PARTITION
 *
 */

static 	AlterPartitionId *
wack_pid_relname(AlterPartitionId 		 *pid,
				 PartitionNode  		**ppNode,
				 Relation 				  rel,
				 PgPartRule 			**ppar_prule,
				 char 					**plrelname,
				 char 					 *lRelNameBuf)
{
	AlterPartitionId 	*locPid = pid;	/* local pid if IDRule */

	if (!pid)
		return NULL;

	if (AT_AP_IDRule == locPid->idtype)
	{
		List 		*l1		   = (List *)pid->partiddef;
		ListCell 	*lc;
		PgPartRule 	*par_prule = NULL;

		lc = list_head(l1);
		*ppar_prule = (PgPartRule*) lfirst(lc);

		par_prule = *ppar_prule;

		*plrelname = par_prule->relname;

		if (par_prule && par_prule->topRule && par_prule->topRule->children)
			*ppNode = par_prule->topRule->children;

		lc = lnext(lc);

		locPid = (AlterPartitionId *)lfirst(lc);

		Assert(locPid);
	}
	else
	{
		*ppNode = RelationBuildPartitionDesc(rel, false);

		snprintf(lRelNameBuf, (NAMEDATALEN*2),
					 "relation \"%s\"",
					 RelationGetRelationName(rel));
		*plrelname = lRelNameBuf;
	}

	return locPid;
}

static void
ATPExecPartAdd(AlteredTableInfo *tab,
			   Relation rel,
               AlterPartitionCmd *pc,
			   AlterTableType att)
{
	AlterPartitionId 	*pid 		= (AlterPartitionId *)pc->partid;
	PgPartRule   		*prule 		= NULL;
	PartitionNode  		*pNode 		= NULL;
	char           		*parTypName = NULL;
	char			 	 namBuf[NAMEDATALEN];
	AlterPartitionId 	*locPid 	= NULL;	/* local pid if IDRule */
	PgPartRule* 		 par_prule 	= NULL;	/* prule for parent if IDRule */
	char 		 		 lRelNameBuf[(NAMEDATALEN*2)];
	char 				*lrelname   = NULL;
	AlterPartitionCmd   *pc2		= NULL;
	bool				 is_split = false;
	bool				 bSetTemplate = (att == AT_PartSetTemplate);

	/* This whole function is QD only. */
	if (Gp_role != GP_ROLE_DISPATCH)
		return;

	pc2 = (AlterPartitionCmd *)pc->arg2;

	if (pc2->partid)
		is_split = true;

	locPid =
			wack_pid_relname(pid,
							 &pNode,
							 rel,
							 &par_prule,
							 &lrelname,
							 lRelNameBuf);

	if (!pNode)
		ereport(ERROR,
				(errcode(ERRCODE_UNDEFINED_OBJECT),
				 errmsg("%s is not partitioned", lrelname),
				 errOmitLocation(true)));

	switch (pNode->part->parkind)
	{
		case 'h': /* hash */
			parTypName = "HASH";
			break;
		case 'r': /* range */
			parTypName = "RANGE";
			break;
		case 'l': /* list */
			parTypName = "LIST";
			break;
		default:
			elog(ERROR, "unrecognized partitioning kind '%c'",
				 pNode->part->parkind);
			Assert(false);
			break;
	} /* end switch */


	if (locPid->idtype == AT_AP_IDName)
			snprintf(namBuf, sizeof(namBuf), " \"%s\"",
					 strVal(locPid->partiddef));
	else
			namBuf[0] = '\0';

	if ('h' == pNode->part->parkind)
		ereport(ERROR,
				(errcode(ERRCODE_INVALID_TABLE_DEFINITION),
				 errmsg("cannot add HASH partition%s to %s",
						namBuf,
						lrelname),
				 errhint("recreate the table to increase the "
						 "number of partitions"),
								   errOmitLocation(true)));


	/* partition must have a valid name */
	if ((locPid->idtype != AT_AP_IDName)
		&& (locPid->idtype != AT_AP_IDNone))
		ereport(ERROR,
				(errcode(ERRCODE_INVALID_TABLE_DEFINITION),
				 errmsg("cannot ADD partition%s to %s by rank or value",
						namBuf,
						lrelname),
					 errhint("use a named partition"),
							   errOmitLocation(true)));

	PartitionElem *pElem = (PartitionElem *) pc2->arg1;
	Node *pStoreAttr = pElem->storeAttr;
	if (pStoreAttr && ((AlterPartitionCmd *)pStoreAttr)->arg1)
	{
		List *pWithList = (List *)(((AlterPartitionCmd *)pStoreAttr)->arg1);
		GpPolicy *parentPolicy = GpPolicyFetch(CurrentMemoryContext, RelationGetRelid(rel));
		int bucketnum = parentPolicy->bucketnum;
		int child_bucketnum = GetRelOpt_bucket_num_fromOptions(pWithList, bucketnum);

		if (child_bucketnum != bucketnum)
			ereport(ERROR,
					(errcode(ERRCODE_GP_FEATURE_NOT_SUPPORTED),
							errmsg("distribution policy for partition%s "
									"must be the same as that for %s",
									namBuf,
									lrelname)));
	}

	/* don't check if splitting or setting a subpartition template */
	if (!is_split && !bSetTemplate)
		/* We complain if partition already exists, so prule should be NULL */
		prule = get_part_rule(rel, pid, true, false,
							  CurrentMemoryContext, NULL,
							  false);

	if (!prule)
	{
		bool isDefault = intVal(pc->arg1);

		/* DEFAULT checks */
		if (!isDefault && (pNode->default_part) &&
			!is_split && !bSetTemplate) /* MPP-6093: ok to reset template */
			ereport(ERROR,
				(errcode(ERRCODE_INVALID_TABLE_DEFINITION),
				 errmsg("cannot add %s partition%s to "
						"%s with DEFAULT partition \"%s\"",
						parTypName,
						namBuf,
						lrelname,
						pNode->default_part->parname),
				 errhint("need to SPLIT partition \"%s\"",
						 pNode->default_part->parname),
								   errOmitLocation(true)));

		if (isDefault && !is_split)
		{
			if ('h' == pNode->part->parkind)
				ereport(ERROR,
						(errcode(ERRCODE_INVALID_TABLE_DEFINITION),
						 errmsg("cannot add a DEFAULT partition%s "
								"to %s of type HASH",
								namBuf,
								lrelname),
										   errOmitLocation(true)));

			/* MPP-6093: ok to reset template */
			if (pNode->default_part && !bSetTemplate)
				ereport(ERROR,
						(errcode(ERRCODE_DUPLICATE_OBJECT),
						 errmsg("DEFAULT partition \"%s\" for "
								"%s already exists",
								pNode->default_part->parname,
								lrelname),
										   errOmitLocation(true)));

			/* XXX XXX: move this check to gram.y ? */
            if (pElem->boundSpec)
                ereport(ERROR,
                        (errcode(ERRCODE_INVALID_TABLE_DEFINITION),
                         errmsg("invalid use of boundary specification "
                                "for DEFAULT partition%s of %s",
                                namBuf,
                                lrelname),
                                           errOmitLocation(true)));
		}

		/* Do the real work for add ... */
		

		if ('r' == pNode->part->parkind)
		{
			atpxPartAddList(rel, pc, pNode,
							pc2->arg2, /* utl statement */
							(locPid->idtype == AT_AP_IDName) ?
							locPid->partiddef : NULL, /* partition name */
							isDefault, (PartitionElem *) pc2->arg1,
							PARTTYP_RANGE,
							par_prule,
							lrelname,
							bSetTemplate,
							rel->rd_rel->relowner);

		}
		else if ('l' == pNode->part->parkind)
		{
			atpxPartAddList(rel, pc, pNode,
							pc2->arg2, /* utl statement */
							(locPid->idtype == AT_AP_IDName) ?
							locPid->partiddef : NULL, /* partition name */
							isDefault, (PartitionElem *) pc2->arg1,
							PARTTYP_LIST,
							par_prule,
							lrelname,
							bSetTemplate,
							rel->rd_rel->relowner);
		}

	}

	/* MPP-6929: metadata tracking */
	if (!is_split && !bSetTemplate)
		MetaTrackUpdObject(RelationRelationId,
						   RelationGetRelid(rel),
						   GetUserId(),
						   "PARTITION", "ADD"
				);

} /* end ATPExecPartAdd */


/*
 * Add partition hierarchy to catalogs.
 *
 * parts is a list, with a partitioning rule and potentially sub-partitions.
 */
static void
ATExecPartAddInternal(Relation rel, Node *def)
{
	PartitionBy *part = (PartitionBy *)def;
	add_part_to_catalog(RelationGetRelid(rel), part, false);
}


/* ALTER TABLE ... ALTER PARTITION */
static void
ATPExecPartAlter(List **wqueue, AlteredTableInfo *tab, Relation rel,
                 AlterPartitionCmd *pc)
{
	AlterPartitionId 	*pid		   = (AlterPartitionId *)pc->partid;
	AlterTableCmd 		*atc		   = (AlterTableCmd *)pc->arg1;
	PgPartRule   		*prule		   = NULL;
	List 				*pidlst		   = NIL;
	AlterPartitionId 	*pid2		   = makeNode(AlterPartitionId);
	AlterPartitionCmd 	*pc2		   = NULL;
	bool				 bPartitionCmd = true;	/* true if a "partition" cmd */
	Relation			 rel2		   = rel;

	while (1)
	{
		pidlst = lappend(pidlst, pid);

		if (atc->subtype != AT_PartAlter)
			break;
		pc2 = (AlterPartitionCmd *)atc->def;
		pid = (AlterPartitionId *)pc2->partid;
		atc = (AlterTableCmd *)pc2->arg1;
	}

	/* let split, exchange through */
	if (!(atc->subtype == AT_PartExchange ||
		  atc->subtype == AT_PartSplit ||
		  atc->subtype == AT_SetDistributedBy) &&
		Gp_role != GP_ROLE_DISPATCH)
		return;

	switch (atc->subtype)
	{
		case AT_PartAdd:				/* Add */
		case AT_PartCoalesce:			/* Coalesce */
		case AT_PartDrop:				/* Drop */
		case AT_PartSplit:				/* Split */
		case AT_PartMerge:				/* Merge */
		case AT_PartModify:				/* Modify */
		case AT_PartSetTemplate:		/* Set Subpartition Template */
				if (!gp_allow_non_uniform_partitioning_ddl)
				{
					ereport(ERROR,
						   (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
							errmsg("Cannot modify multi-level partitioned table to have non-uniform partitioning hierarchy.")));
				}
				break;
				/* XXX XXX: treat set subpartition template special:

				need to pass the pNode to ATPExecPartSetTemplate and bypass
				ATExecCmd ...

				*/
		case AT_PartRename:	 			/* Rename */
		case AT_PartExchange:			/* Exchange */
		case AT_PartTruncate:			/* Truncate */
				break;

		/* Next, list of ALTER TABLE commands applicable to a child table */
		case AT_SetTableSpace:			/* Set Tablespace */
		case AT_SetDistributedBy:	/* SET DISTRIBUTED BY */
				bPartitionCmd = false;
				break;
		default:
			ereport(ERROR,
					(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
					 errmsg("cannot ALTER PARTITION for relation \"%s\"",
							RelationGetRelationName(rel)),
									   errOmitLocation(true)));
	}

	if (Gp_role == GP_ROLE_DISPATCH)
	{
		pid2->idtype = AT_AP_IDList;
		pid2->partiddef = (Node *)pidlst;
		pid2->location  = -1;

		prule = get_part_rule(rel, pid2, true, true,
							  CurrentMemoryContext, NULL,
							  false);

		if (!prule)
			ereport(ERROR,
					(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
					 errmsg("cannot ALTER PARTITION for relation \"%s\"",
							RelationGetRelationName(rel)),
									   errOmitLocation(true)));
		if (bPartitionCmd)
		{
			/* build the IDRule for the nested ALTER PARTITION cmd ... */
			Assert(IsA(atc->def, AlterPartitionCmd));

			pc2 = (AlterPartitionCmd *)atc->def;
			pid = (AlterPartitionId *)pc2->partid;

			pid2->idtype = AT_AP_IDRule;
			pid2->partiddef = (Node *)list_make2((Node *)prule, pid);
			pid2->location  = -1;

			pc2->partid = (Node *)pid2;
		}
		else /* treat as a table */
		{
			/* Update PID for use on QEs */
			pid2->idtype = AT_AP_IDRule;
			pid2->partiddef = (Node *)list_make2((Node *)prule, pid);
			pid2->location  = -1;
			pc->partid = (Node *)pid2;

			/* get the child table relid */
			rel2 = heap_open(prule->topRule->parchildrelid,
							 AccessExclusiveLock);

			/* MPP-5524: check if can change distribution policy */
			if (atc->subtype == AT_SetDistributedBy)
			{
				List *dist_cnames = NIL;
				Assert(IsA(atc->def, List));

				dist_cnames = lsecond((List*)atc->def);

				/*	might be null if no policy set, e.g. just a change
				 *	of storage options...
				 */
				if (dist_cnames)
				{
					Assert(IsA(dist_cnames, List));

					if (! can_implement_dist_on_part(rel, dist_cnames) )
						ereport(ERROR,
								(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
								 errmsg("cannot ALTER PARTITION ... SET "
										"DISTRIBUTED BY for %s",
										prule->relname),
										errhint("distribution policy of "
												"partition must match parent"),
														   errOmitLocation(true)
										));
				}

			}

			/*
			 * Give the notice first, because it looks weird if it
			 * comes after a failure message
			 */
			ereport(NOTICE,
					(errmsg("altering table \"%s\" "
							"(%s)",
							RelationGetRelationName(rel2),
							prule->relname)));
		}
	}
	else if (Gp_role == GP_ROLE_EXECUTE && atc->subtype == AT_SetDistributedBy)
	{
		pid = (AlterPartitionId *)pc->partid;
		Assert(IsA(pid->partiddef, List));
		prule = (PgPartRule *)linitial((List *)pid->partiddef);
		/* get the child table relid */
		rel2 = heap_open(prule->topRule->parchildrelid,
						 AccessExclusiveLock);
		bPartitionCmd = false;
	}
	/* execute the command */
	ATExecCmd(wqueue, tab, rel2, atc);

	if (!bPartitionCmd)
	{
		/* NOTE: for the case of Set Distro,
		 * ATExecSetDistributedBy rebuilds the relation, so rel2
		 * is already gone!
		 */
		if (atc->subtype != AT_SetDistributedBy)
			heap_close(rel2, NoLock);
	}

	/* MPP-6929: metadata tracking - don't track this! */

} /* end ATPExecPartAlter */


/* ALTER TABLE ... COALESCE PARTITION */
static void
ATPExecPartCoalesce(Relation rel,
                    AlterPartitionCmd *pc)
{
	AlterPartitionId *pid = (AlterPartitionId *)pc->partid;
	PgPartRule   *prule = NULL;

	if (Gp_role != GP_ROLE_DISPATCH)
		return;

	prule = get_part_rule(rel, pid, true, true, CurrentMemoryContext, NULL,
						  false);

	if (0)
	{

		parruleord_open_gap(
				prule->pNode->part->partid,
				prule->pNode->part->parlevel,
				prule->topRule->parparentoid,
				prule->topRule->parruleord,
				0,
				CurrentMemoryContext);

	}

    ereport(ERROR,
            (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
             errmsg("cannot COALESCE PARTITION for relation \"%s\"",
                    RelationGetRelationName(rel)),
             			   errOmitLocation(true)));

}

/* ALTER TABLE ... DROP PARTITION */

static void
ATPExecPartDrop(Relation rel,
                AlterPartitionCmd *pc)
{
	AlterPartitionId 	*pid 		 = (AlterPartitionId *)pc->partid;
	PgPartRule   		*prule 		 = NULL;
	PartitionNode  		*pNode  	 = NULL;
	DropStmt 			*ds 		 = (DropStmt *)pc->arg1;
	bool 				 bCheckMaybe = !(ds->missing_ok);
	AlterPartitionId 	*locPid 	 = pid;  /* local pid if IDRule */
	PgPartRule* 		 par_prule 	 = NULL; /* prule for parent if IDRule */
	char 		 		 lRelNameBuf[(NAMEDATALEN*2)];
	char 				*lrelname	= NULL;
	bool 				 bForceDrop	= false;

	if (Gp_role != GP_ROLE_DISPATCH)
		return;

	if (pc->arg2 &&
		IsA(pc->arg2, AlterPartitionCmd))
	{
		/* NOTE: Ugh, I hate this hack.  Normally, PartDrop has a null
		 * pc->arg2 (the DropStmt is on arg1).  However, for SPLIT, we
		 * have the case where we may need to DROP that last partition
		 * of a table, which in only ok because we will re-ADD two
		 * partitions to replace it.  So allow bForceDrop only for
		 * this case.  We need a better way to decorate the ALTER cmd
		 * structs to annotate these special cases.
		 */
		bForceDrop = true;
	}

	/* missing partition id only ok for range partitions -- just get
	 * first one */

	locPid =
			wack_pid_relname(pid,
							 &pNode,
							 rel,
							 &par_prule,
							 &lrelname,
							 lRelNameBuf);

	if (AT_AP_IDNone == locPid->idtype)
	{
		if (pNode && pNode->part && (pNode->part->parkind != 'r'))
		{
			if (strlen(lrelname))
				ereport(ERROR,
						(errcode(ERRCODE_SYNTAX_ERROR),
						 errmsg("missing name or value for DROP for %s",
								lrelname),
										   errOmitLocation(true)));
			else
				ereport(ERROR,
						(errcode(ERRCODE_SYNTAX_ERROR),
						 errmsg("missing name or value for DROP"),
								   errOmitLocation(true)));
		}

		/* if a range partition, and not specified, just get the first one */
		locPid->idtype = AT_AP_IDRank;
		locPid->partiddef = (Node *)makeInteger(1);
	}

	prule = get_part_rule(rel, pid, bCheckMaybe, true,
						  CurrentMemoryContext, NULL, false);

	/* MPP-3722: complain if for(value) matches the default partition */
	if ((locPid->idtype == AT_AP_IDValue)
		&& prule &&
		(prule->topRule == prule->pNode->default_part))
			ereport(ERROR,
					(errcode(ERRCODE_WRONG_OBJECT_TYPE),
					 errmsg("FOR expression matches "
							"DEFAULT partition%s of %s",
							prule->partIdStr,
							prule->relname),
					 errhint("FOR expression may only specify "
							 "a non-default partition in this context."),
									   errOmitLocation(true)));

	if (!prule)
	{
		Assert(ds->missing_ok);
		switch (locPid->idtype)
		{
			case AT_AP_IDNone:				/* no ID */
				/* should never happen */
				Assert(false);
				break;
			case AT_AP_IDName:				/* IDentify by Name */
				ereport(NOTICE,
					(errcode(ERRCODE_UNDEFINED_OBJECT),
					 errmsg("partition \"%s\" of %s does not "
							"exist, skipping",
							strVal(locPid->partiddef),
							lrelname
							),
									   errOmitLocation(true)));

				break;
			case AT_AP_IDValue:				/* IDentifier FOR Value */
				ereport(NOTICE,
					(errcode(ERRCODE_UNDEFINED_OBJECT),
					 errmsg("partition for specified value of "
							"%s does not exist, skipping",
							lrelname
							 ),
									   errOmitLocation(true)));

				break;
			case AT_AP_IDRank:				/* IDentifier FOR Rank */
				ereport(NOTICE,
					(errcode(ERRCODE_UNDEFINED_OBJECT),
					 errmsg("partition for specified rank of "
							"%s does not exist, skipping",
							lrelname
							 ),
									   errOmitLocation(true)));

				break;
			case AT_AP_ID_oid:				/* IDentifier by oid */
				ereport(NOTICE,
					(errcode(ERRCODE_UNDEFINED_OBJECT),
					 errmsg("partition for specified oid of "
							"%s does not exist, skipping",
							lrelname
							 ),
									   errOmitLocation(true)));
				break;
			case AT_AP_IDDefault:			/* IDentify DEFAULT partition */
				ereport(NOTICE,
					(errcode(ERRCODE_UNDEFINED_OBJECT),
					 errmsg("DEFAULT partition for "
							"%s does not exist, skipping",
							lrelname
							 ),
									   errOmitLocation(true)));
				break;
			default: /* XXX XXX */
				Assert(false);
		}
		return;
	}
	else
	{
		char* prelname;
		int   numParts = list_length(prule->pNode->rules);
		DestReceiver 	*dest = None_Receiver;
		Relation rel2;
		RangeVar *relation;
		char *namespace_name;

		/* add the default partition to the count of partitions */
		if (prule->pNode->default_part)
			numParts++;

		/* maybe ERRCODE_INVALID_TABLE_DEFINITION ? */

		/* cannot drop a hash partition */
		if ('h' == prule->pNode->part->parkind)
			ereport(ERROR,
					(errcode(ERRCODE_DEPENDENT_OBJECTS_STILL_EXIST),
					 errmsg("cannot drop HASH partition%s of %s",
							prule->partIdStr,
							prule->relname),
					 errhint("recreate the table to reduce the "
							 "number of partitions"),
									   errOmitLocation(true)));

		/* cannot drop last partition of table */
		if (!bForceDrop && (numParts <= 1))
		{
			if (AT_AP_IDRule != pid->idtype)
				ereport(ERROR,
						(errcode(ERRCODE_DEPENDENT_OBJECTS_STILL_EXIST),
						 errmsg("cannot drop partition%s of "
								"%s -- only one remains",
								prule->partIdStr,
								prule->relname),
						 errhint("Use DROP TABLE \"%s\" to remove the "
								 "table and the final partition ",
								 RelationGetRelationName(rel)),
										   errOmitLocation(true)));
			else
				ereport(ERROR,
						(errcode(ERRCODE_DEPENDENT_OBJECTS_STILL_EXIST),
						 errmsg("cannot drop partition%s of "
								"%s -- only one remains",
								prule->partIdStr,
								prule->relname),
						 errhint("DROP the parent partition to remove the "
								 "final partition "),
										   errOmitLocation(true)));

		}
		rel2 = heap_open(prule->topRule->parchildrelid, NoLock);

		elog(DEBUG5, "dropping partition oid %u", prule->topRule->parchildrelid);
		prelname = pstrdup(RelationGetRelationName(rel2));
		namespace_name = get_namespace_name(rel2->rd_rel->relnamespace);

		/* XXX XXX : don't need "relation" unless fix to use removerelation */
		relation = makeRangeVar(NULL /*catalogname*/, namespace_name, prelname, -1);
		relation->location = pc->location;

		heap_close(rel2, NoLock);

		ds->removeType = OBJECT_TABLE;
		ds->bAllowPartn = true; /* allow drop of partitions */

		if (prule->topRule->children)
		{
			List *l1 = atpxDropList(rel2, prule->topRule->children);

			ds->objects = lappend(l1,
								  list_make2(makeString(namespace_name),
											 makeString(prelname)));
		}
		else
			ds->objects = list_make1(list_make2(makeString(namespace_name),
												makeString(prelname)));

		ProcessUtility((Node *) ds,
					   synthetic_sql,
					   NULL, 
					   false, /* not top level */
					   dest, 
					   NULL);

		/* Notify of name if did not use name for partition id spec */
		if (prule && prule->topRule && prule->topRule->children
			&& (ds->behavior != DROP_CASCADE ))
		{
			ereport(NOTICE,
					(errmsg("dropped partition%s for %s and its children",
							prule->partIdStr,
							prule->relname)));
		}
		else if ((pid->idtype != AT_AP_IDName)
				 && prule->isName)
				ereport(NOTICE,
						(errmsg("dropped partition%s for %s",
								prule->partIdStr,
								prule->relname)));


		/* MPP-6929: metadata tracking */
		MetaTrackUpdObject(RelationRelationId,
						   RelationGetRelid(rel),
						   GetUserId(),
						   "PARTITION", "DROP"
				);
	}

} /* end ATPExecPartDrop */

static void
exchange_part_inheritance(Oid oldrelid, Oid newrelid)
{
	int fetchCount;
	Oid parentid;
	Relation oldrel;
	Relation newrel;
	Relation parent;

	oldrel = heap_open(oldrelid, AccessExclusiveLock);
	newrel = heap_open(newrelid, AccessExclusiveLock);

	parentid = caql_getoid_plus(
			NULL,
			&fetchCount,
			NULL,
			cql("SELECT inhparent FROM pg_inherits "
				" WHERE inhrelid = :1 ",
				ObjectIdGetDatum(oldrelid)));

	/* should be one and only one parent when it comes to inheritance */
	Assert(1 == fetchCount); 

	parent = heap_open(parentid, AccessShareLock); /* should be enough */
	ATExecDropInherit(oldrel,
			makeRangeVar(NULL /*catalogname*/, get_namespace_name(parent->rd_rel->relnamespace),
					     RelationGetRelationName(parent), -1),
			true);

	inherit_parent(parent, newrel, true /* it's a partition */, NIL);
	heap_close(parent, NoLock);
	heap_close(oldrel, NoLock);
	heap_close(newrel, NoLock);
}

/* ALTER TABLE ... EXCHANGE PARTITION 
 * 
 * Do the exchange that was validated earlier (in ATPrepExchange).
 */
static void
ATPExecPartExchange(AlteredTableInfo *tab, Relation rel, AlterPartitionCmd *pc)
{
	Oid					 oldrelid 	= InvalidOid;
	Oid					 newrelid 	= InvalidOid;
	PgPartRule   	    *orig_prule = NULL;
	AlterPartitionCmd	*pc2 = NULL;
	bool is_split = false;
	List				*pcols = NIL; /* partitioned attributes of rel */
	AlterPartitionIdType orig_pid_type = AT_AP_IDNone;	/* save for NOTICE msg at end... */

	if (Gp_role == GP_ROLE_UTILITY)
		return;
	
	/* Exchange for SPLIT is different from user-requested EXCHANGE.  The special
	 * coding to indicate SPLIT is obscure. */
	is_split = ((AlterPartitionCmd *)pc->arg2)->arg2 != NULL;

	if (Gp_role == GP_ROLE_DISPATCH)
	{
		AlterPartitionId   *pid   = (AlterPartitionId *)pc->partid;
		PgPartRule   	   *prule = NULL;
		RangeVar       	   *newrelrv  = (RangeVar *)pc->arg1;
		RangeVar		   *oldrelrv;
		PartitionNode 	   *pn;
		Relation			oldrel;

		pn = RelationBuildPartitionDesc(rel, false);
		pcols = get_partition_attrs(pn);

		prule = get_part_rule(rel, pid, true, true,
							  CurrentMemoryContext, NULL, false);

		if (!prule)
			return;

		if (prule && prule->topRule && prule->topRule->children)
			ereport(ERROR,
					(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
					 errmsg("cannot EXCHANGE PARTITION for "
							"%s -- partition has children",
							prule->relname
							 ),
									   errOmitLocation(true)));

		orig_pid_type = pid->idtype;
		orig_prule = prule;

		oldrelid = prule->topRule->parchildrelid;
		newrelid = RangeVarGetRelid(newrelrv, false, false /*allowHcatalog*/);

		pfree(pc->partid);

		oldrel = heap_open(oldrelid, NoLock);
		oldrelrv =
			makeRangeVar(NULL /*catalogname*/, get_namespace_name(RelationGetNamespace(oldrel)),
						 get_rel_name(oldrelid), -1);
		heap_close(oldrel, NoLock);

		pc->partid = (Node *)oldrelrv;
		pc2 = (AlterPartitionCmd *)pc->arg2;
		pc2->arg2 = (Node *)pcols; /* for execute nodes */

		/* MPP-6929: metadata tracking */
		MetaTrackUpdObject(RelationRelationId,
						   RelationGetRelid(rel),
						   GetUserId(),
						   "PARTITION", "EXCHANGE"
				);
	}
	else if (Gp_role == GP_ROLE_EXECUTE)
	{
		RangeVar *oldrelrv;
		RangeVar *newrelrv;

		Assert(IsA(pc->partid, RangeVar));
		Assert(IsA(pc->arg1, RangeVar));
		oldrelrv = (RangeVar *)pc->partid;
		newrelrv = (RangeVar *)pc->arg1;
		oldrelid = RangeVarGetRelid(oldrelrv, false, false /*allowHcatalog*/);
		newrelid = RangeVarGetRelid(newrelrv, false, false /*allowHcatalog*/);
		pc2 = (AlterPartitionCmd *)pc->arg2;
		pcols = (List *)pc2->arg2;
	}

	Assert(OidIsValid(oldrelid));
	Assert(OidIsValid(newrelid));

#if IF_ONLY_IT_WAS_THAT_SIMPLE
	swap_relation_files(oldrelid, newrelid, false);
	CommandCounterIncrement();
#else
	/*
	 * It would be nice to just swap the relfilenodes. In fact, we could
	 * do that in most cases, the exceptions being tables with dropped 
	 * columns and append only tables.
	 *
	 * So instead, we swap the names of the tables, the type names, the 
	 * constraints, inheritance. We do not swap indexes, ao information
	 * or statistics.
	 *
	 * Note that the state, whether QD or QE, at this point is
	 * - rel -- relid of partitioned table
	 * - oldrelid -- relid of part currently in place
	 * - newrelid -- relid of candidate part to exchange in
	 * - orig_pid_type -- what kind of AlterTablePartitionId id'd the part
	 * - orig_prule -- Used in issuing notice in occasional case.
	 * - pc2->arg1 -- integer Value node: 1 validate, else 0.
	 * - pcols -- integer list of master partitioning columns
	 */
	{
		char			 tmpname1[NAMEDATALEN];
		char			 tmpname2[NAMEDATALEN];
		char			*newname;
		char			*oldname;
		Relation		 newrel;
		Relation		 oldrel;
		AttrMap			*newmap;
		AttrMap			*oldmap;
		List			*newcons;
		bool __MAYBE_UNUSED	 ok;
		bool			 validate	= intVal(pc2->arg1) ? true : false;
		Oid				 oldnspid	= InvalidOid;
		Oid				 newnspid	= InvalidOid;
		char			*newNspName = NULL;
		char			*oldNspName = NULL;

		newrel = heap_open(newrelid, AccessExclusiveLock);
		oldrel = heap_open(oldrelid, AccessExclusiveLock);

		oldnspid = RelationGetNamespace(oldrel);
		newnspid = RelationGetNamespace(newrel);

		if (oldnspid != newnspid)
		{
			newNspName = pstrdup(get_namespace_name(newnspid));
			oldNspName = pstrdup(get_namespace_name(oldnspid));
		}

		newname = pstrdup(RelationGetRelationName(newrel));
		oldname = pstrdup(RelationGetRelationName(oldrel));
		
		ok = map_part_attrs(rel, newrel, &newmap, FALSE);
		Assert(ok);
		ok = map_part_attrs(rel, oldrel, &oldmap, FALSE);
		Assert(ok);

		newcons = cdb_exchange_part_constraints(rel, oldrel, newrel, validate, is_split);
		tab->constraints = list_concat(tab->constraints, newcons);
		CommandCounterIncrement();

		exchange_part_inheritance(RelationGetRelid(oldrel), RelationGetRelid(newrel));
		CommandCounterIncrement();

		snprintf(tmpname1, sizeof(tmpname1), "pg_temp_%u", oldrelid);
		snprintf(tmpname2, sizeof(tmpname2), "pg_temp_%u", newrelid);

		exchange_permissions(RelationGetRelid(oldrel),
							 RelationGetRelid(newrel));
		CommandCounterIncrement();

		heap_close(newrel, NoLock);
		heap_close(oldrel, NoLock);

		/* rename rel renames the type too */
		renamerel(oldrelid, tmpname1, NULL);
		CommandCounterIncrement();
		RelationForgetRelation(oldrelid);

		/* MPP-6979: if the namespaces are different, switch them */
		if (newNspName)
		{
			/* move the old partition (which has a temporary name) to
			 * the new namespace 
			 */
			oldrel = heap_open(oldrelid, AccessExclusiveLock);
			AlterRelationNamespaceInternalTwo(oldrel,
											  oldrelid,
											  oldnspid, newnspid,
											  true,
											  newNspName);
			heap_close(oldrel, NoLock);
			CommandCounterIncrement();
			RelationForgetRelation(oldrelid);

			/* before we move the new table to the old namespace,
			 * rename it to a temporary name to avoid a name
			 * collision.  It would be nice to have an atomic
			 * operation to rename and renamespace a relation... 
			 */
			renamerel(newrelid, tmpname2, NULL);
			CommandCounterIncrement();
			RelationForgetRelation(newrelid);

			newrel = heap_open(newrelid, AccessExclusiveLock);
			AlterRelationNamespaceInternalTwo(newrel,
											  newrelid,
											  newnspid, oldnspid,
											  true,
											  oldNspName);
			heap_close(newrel, NoLock);
			CommandCounterIncrement();
			RelationForgetRelation(newrelid);
		}

		renamerel(newrelid, oldname, NULL);
		CommandCounterIncrement();
		RelationForgetRelation(newrelid);

		renamerel(oldrelid, newname, NULL);
		CommandCounterIncrement();
		RelationForgetRelation(oldrelid);

		CommandCounterIncrement();

		/* fix up partitioning rule if we're on the QD*/
		if (Gp_role == GP_ROLE_DISPATCH)
		{
			exchange_part_rule(oldrelid, newrelid);
			CommandCounterIncrement();

			/* Notify of name if did not use name for partition id spec */
			if ( orig_pid_type != AT_AP_IDName && orig_prule->isName )
				ereport(NOTICE,
						(errmsg("exchanged partition%s of "
								"%s with relation \"%s\"",
								orig_prule->partIdStr,
								orig_prule->relname,
								newname),
						 errOmitLocation(true)));
		}
	}
	tab->exchange_relid = newrelid;
#endif
}

/* ALTER TABLE ... MERGE PARTITION */
static void
ATPExecPartMerge(Relation rel,
                 AlterPartitionCmd *pc)
{
	Relation source = NULL;
	Relation target = NULL;

	if (Gp_role == GP_ROLE_UTILITY)
		return;
	else if (Gp_role == GP_ROLE_DISPATCH)
	{
		AlterPartitionId   *pid   = (AlterPartitionId *)pc->partid;
		PgPartRule   	   *prule1 = NULL;
		PgPartRule   	   *prule2 = NULL;
		PgPartRule   	   *prule3 = NULL;
		RangeVar		   *relrv1, *relrv2;
		Relation			r1, r2;

		prule1 = get_part_rule(rel, pid, true, true,
							   CurrentMemoryContext, NULL, false);

		/*
		 * XXX: get_namespace_name(prule1->topRule->parchildrelid) is wrong
		 * need the relnamespace not relid
		 */
		relrv1 = makeRangeVar(
					NULL /*catalogname*/, 
					get_namespace_name(prule1->topRule->parchildrelid),
					get_rel_name(prule1->topRule->parchildrelid), -1);

		r1 = heap_openrv(relrv1, AccessExclusiveLock);

		prule2 = get_part_rule(rel, (AlterPartitionId *)pc->arg1,
							   true, true,
							   CurrentMemoryContext, NULL, false);

		relrv2 = makeRangeVar(
					NULL /*catalogname*/, 	
					get_namespace_name(prule2->topRule->parchildrelid),
					get_rel_name(prule2->topRule->parchildrelid), -1);

		r2 = heap_openrv(relrv2, AccessExclusiveLock);

		if (pc->arg2)
		{
			AlterPartitionCmd *pc2 = (AlterPartitionCmd *)pc->arg2;

			prule3 = get_part_rule(rel, (AlterPartitionId *)pc2->partid,
								   true, true, CurrentMemoryContext,
								   NULL, false);

			Assert(PointerIsValid(prule3));

			if (prule3->topRule->parchildrelid == prule1->topRule->parchildrelid)
			{
				source = r1;
				pc->partid = (Node *)relrv1;
				target = r2;
				pc->arg1 = (Node *)relrv2;
			}
			else if (prule3->topRule->parchildrelid == prule2->topRule->parchildrelid)
			{
				source = r2;
				pc->partid = (Node *)relrv2;
				target = r1;
				pc->arg1 = (Node *)relrv1;
			}
			else
			{
				ereport(ERROR,
						(errcode(ERRCODE_INVALID_TABLE_DEFINITION),
						 errmsg("target of MERGE must be either \"%s\" or "
								"\"%s\"",
								get_rel_name(prule1->topRule->parchildrelid),
								get_rel_name(prule2->topRule->parchildrelid)),
										   errOmitLocation(true)));

			}
		}
		else
		{
			source = r1;
			target = r2;
			pc->partid = (Node *)relrv1;
			pc->arg1 = (Node *)relrv2;
		}

		/* MPP-6929: metadata tracking */
		MetaTrackUpdObject(RelationRelationId,
						   RelationGetRelid(rel),
						   GetUserId(),
						   "PARTITION", "MERGE"
				);
	}
	else if (Gp_role == GP_ROLE_EXECUTE)
	{
		RangeVar *relrv;

		Assert(IsA(pc->partid, RangeVar));
		Assert(IsA(pc->arg1, RangeVar));

		relrv = (RangeVar *)pc->partid;
		source = heap_openrv(relrv, AccessExclusiveLock);

		relrv = (RangeVar *)pc->arg1;
		target = heap_openrv(relrv, AccessExclusiveLock);
	}

	elog(NOTICE, "merging");
	elog(NOTICE, "%s", RelationGetRelationName(source));

	elog(NOTICE, "with %s", RelationGetRelationName(target));

    ereport(ERROR,
            (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
             errmsg("cannot MERGE PARTITION for relation \"%s\"",
                    RelationGetRelationName(rel)),
             			   errOmitLocation(true)));

}


/* ALTER TABLE ... MODIFY PARTITION */
static void
ATPExecPartModify(Relation rel,
                  AlterPartitionCmd *pc)
{
	AlterPartitionId *pid = (AlterPartitionId *)pc->partid;
	PgPartRule   *prule = NULL;

	if (Gp_role != GP_ROLE_DISPATCH)
		return;

	prule = get_part_rule(rel, pid, true, true, CurrentMemoryContext, NULL,
						  false);

	if (prule)
	{
		AlterPartitionCmd 		*pc2 	= (AlterPartitionCmd *)pc->arg1;
		AlterPartitionCmd 		*pc3 	= (AlterPartitionCmd *)pc2;
		DefElem    				*def 	= (DefElem *)pc3->arg1;
		bool 					 bStart = false;
		bool 					 bEnd 	= false;
		bool 					 bAdd 	= false;
		bool 					 bDrop 	= false;
		char           *parTypName = NULL;

		if (0 == strcmp(def->defname, "START"))
			bStart = true;
		else if (0 == strcmp(def->defname, "END"))
			bEnd = true;
		else if (0 == strcmp(def->defname, "ADD"))
			bAdd = true;
		else if (0 == strcmp(def->defname, "DROP"))
			bDrop = true;
		else Assert(false);

		switch (prule->pNode->part->parkind)
		{
			case 'h': /* hash */
				parTypName = "HASH";
				break;
			case 'r': /* range */
				parTypName = "RANGE";
				break;
			case 'l': /* list */
				parTypName = "LIST";
				break;
			default:
				elog(ERROR, "unrecognized partitioning kind '%c'",
					 prule->pNode->part->parkind);
				Assert(false);
				break;
		} /* end switch */

		/* cannot modify default partitions */
		if (prule->pNode->default_part == prule->topRule)
			ereport(ERROR,
					(errcode(ERRCODE_INVALID_TABLE_DEFINITION),
					 errmsg("cannot MODIFY DEFAULT %s partition%s "
							"for relation \"%s\"",
							parTypName,
							((prule && prule->isName) ? prule->partIdStr : ""),
							RelationGetRelationName(rel)),
									   errOmitLocation(true)));

		if ((bStart || bEnd) && ('r' != prule->pNode->part->parkind))
			ereport(ERROR,
					(errcode(ERRCODE_INVALID_TABLE_DEFINITION),
					 errmsg("invalid use of %s boundary specification "
							"in partition%s of type %s",
							"RANGE",
							((prule && prule->isName) ? prule->partIdStr : ""),
							parTypName
							 ),
									   errOmitLocation(true)));

		if ((bAdd || bDrop) && ('l' != prule->pNode->part->parkind))
			ereport(ERROR,
					(errcode(ERRCODE_INVALID_TABLE_DEFINITION),
					 errmsg("invalid use of %s boundary specification "
							"in partition%s of type %s",
							"LIST",
							((prule && prule->isName) ? prule->partIdStr : ""),
							parTypName
							 ),
									   errOmitLocation(true)));

		if (bAdd || bDrop)
		{
			atpxModifyListOverlap(rel, pid, prule,
								  (PartitionElem *)pc3->arg2,
								  bAdd);
		}
		if (bStart || bEnd)
		{
			atpxModifyRangeOverlap(rel, pid, prule,
								   (PartitionElem *)pc3->arg2);
		}


		if (0)
		parruleord_reset_rank(
				prule->pNode->part->partid,
				prule->pNode->part->parlevel,
				prule->topRule->parparentoid,
				prule->topRule->parruleord,
				CurrentMemoryContext);

		/* MPP-6929: metadata tracking */
		MetaTrackUpdObject(RelationRelationId,
						   RelationGetRelid(rel),
						   GetUserId(),
						   "PARTITION", "MODIFY"
				);
	}

	if (0)
    ereport(ERROR,
            (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
             errmsg("cannot MODIFY PARTITION for relation \"%s\"",
                    RelationGetRelationName(rel)),
             			   errOmitLocation(true)));

}

/* ALTER TABLE ... RENAME PARTITION */

static void
ATPExecPartRename(Relation rel,
                  AlterPartitionCmd *pc)
{
	AlterPartitionId 	*pid 	   = (AlterPartitionId *)pc->partid;
	PgPartRule   		*prule 	   = NULL;
	PartitionNode  		*pNode     = NULL;
	PgPartRule* 		 par_prule = NULL;	/* prule for parent if IDRule */
	char 		 		 lRelNameBuf[(NAMEDATALEN*2)];
	char 				*lrelname=NULL;

	if (Gp_role != GP_ROLE_DISPATCH)
		return;

	wack_pid_relname(pid, &pNode, rel, &par_prule,
					 &lrelname, lRelNameBuf);

	prule = get_part_rule(rel, pid, true, true, CurrentMemoryContext, NULL,
						  false);

	if (prule)
	{
		AlterPartitionId		 newpid;
		Relation			 	 targetrelation;
		char        		 	 targetrelname[NAMEDATALEN];
		Relation			 	 parentrelation;
		Oid						 namespaceId;
		char	   			   	*newpartname = strVal(pc->arg1);
		char	   			   	*relname;
		char	  			 	 parentname[NAMEDATALEN];
		int 				 	 partDepth 	 = prule->pNode->part->parlevel;
		RenameStmt 			   	*renStmt 	 = makeNode(RenameStmt);
		DestReceiver 		   	*dest  		 = None_Receiver;
		Relation				 part_rel;
		HeapTuple				 tuple;
		Form_pg_partition_rule	 pgrule;
		List 					*renList 	 = NIL;
		int 					 skipped 	 = 0;
		int 					 renamed 	 = 0;
		cqContext				 cqc;
		cqContext				*pcqCtx;

		newpid.idtype = AT_AP_IDName;
		newpid.partiddef = pc->arg1;
		newpid.location = -1;

		/* ERROR if exists */
		get_part_rule1(rel, &newpid, true, false,
						CurrentMemoryContext, NULL,
						pNode,
						lrelname,
						NULL);

		targetrelation = relation_open(prule->topRule->parchildrelid,
									   AccessExclusiveLock);

		StrNCpy(targetrelname, RelationGetRelationName(targetrelation),
				NAMEDATALEN);

		namespaceId = RelationGetNamespace(targetrelation);

		relation_close(targetrelation, AccessExclusiveLock);

		if (0 == prule->topRule->parparentoid)
		{
			StrNCpy(parentname,
					RelationGetRelationName(rel), NAMEDATALEN);
		}
		else
		{
			Assert(par_prule);
			if (par_prule)
			{
				/* look in the parent prule */
				parentrelation =
					RelationIdGetRelation(par_prule->topRule->parchildrelid);
				StrNCpy(parentname,
						RelationGetRelationName(parentrelation), NAMEDATALEN);
				RelationClose(parentrelation);
			}
		}

		/* MPP-3523: the "label" portion of the new relation is
		 * prt_`newpartname', and makeObjectName won't truncate this
		 * portion of the partition name -- it will assert instead.
		 */
		if (strlen(newpartname) > (NAMEDATALEN - 8))
			ereport(ERROR,
					(errcode(ERRCODE_INVALID_TABLE_DEFINITION),
					 errmsg("name \"%s\" for child partition "
							"is too long",
							newpartname)));

		relname = ChoosePartitionName(parentname,
									  partDepth,
									  newpartname,
									  namespaceId);
		/* does CommandCounterIncrement */

		renStmt->renameType = OBJECT_TABLE;
		renStmt->relation = makeRangeVar(NULL /*catalogname*/, get_namespace_name(namespaceId),
										 pstrdup(targetrelname), -1);

		renStmt->subname = NULL;
		renStmt->newname = relname;
		renStmt->bAllowPartn = true; /* allow rename of partitions */

		if (prule && prule->topRule && prule->topRule->children)
				pNode = prule->topRule->children;
		else
				pNode = NULL;

		/* rename the children as well */
		renList = atpxRenameList(pNode, targetrelname, relname, &skipped);

		part_rel = heap_open(PartitionRuleRelationId, RowExclusiveLock);

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

		tuple = caql_getfirst(
				pcqCtx,
				cql("SELECT * FROM pg_partition_rule "
					" WHERE oid = :1 "
					" FOR UPDATE ",
					ObjectIdGetDatum(prule->topRule->parruleid)));
		Insist(HeapTupleIsValid(tuple));

		pgrule = (Form_pg_partition_rule)GETSTRUCT(tuple);
		namestrcpy(&(pgrule->parname), newpartname);

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

		heap_freetuple(tuple);
		heap_close(part_rel, NoLock);

		CommandCounterIncrement();

		ProcessUtility((Node *) renStmt,
					   synthetic_sql,
					   NULL,
					   false, /* not top level */
					   dest, 
					   NULL);

		/* process children if there are any */
		if (renList)
		{
			ListCell 		*lc;

			foreach(lc, renList)
			{
				ListCell 		*lc2;
				List  			*lpair = lfirst(lc);

				lc2 = list_head(lpair);

				renStmt->relation = (RangeVar *)lfirst(lc2);
				lc2 = lnext(lc2);
				renStmt->newname = (char *)lfirst(lc2);

				ProcessUtility((Node *) renStmt,
							   synthetic_sql,
							   NULL, 
							   false, /* not top level */
							   dest, 
							   NULL);
				renamed++;
			}
		}

		/* MPP-6929: metadata tracking */
		MetaTrackUpdObject(RelationRelationId,
						   RelationGetRelid(rel),
						   GetUserId(),
						   "PARTITION", "RENAME"
				);

		/* Notify of name if did not use name for partition id spec */
		if ((pid->idtype != AT_AP_IDName)
			&& prule->isName)
			ereport(NOTICE,
					(errmsg("renamed partition%s to \"%s\" for %s",
							prule->partIdStr,
							newpartname,
							prule->relname)));

		/* MPP-3542: warn when skip child partitions */
		if (skipped)
		{
			ereport(WARNING,
					(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
					 errmsg("renamed %d partitions, skipped %d child partitions due to name truncation",
							renamed, skipped),
									   errOmitLocation(true)));
		}

	}

} /* end ATPExecPartRename */


/* ALTER TABLE ... SET SUBPARTITION TEMPLATE  */
static void
ATPExecPartSetTemplate(AlteredTableInfo *tab,
					   Relation rel,
                       AlterPartitionCmd *pc)
{
	AlterPartitionId	*pid   = (AlterPartitionId *)pc->partid;
	PgPartRule			*prule = NULL;
	int					 lvl   = 1;

	if (Gp_role != GP_ROLE_DISPATCH)
		return;

	/* set template for top level table */
    if (pid && (pid->idtype != AT_AP_IDName))
    {
		Assert((pid->idtype == AT_AP_IDRule) && IsA(pid->partiddef, List));

		/* MPP-5941: work correctly with many levels of templates */
		/* wah! the idrule is invalid, so can't use get_part_rule.
		 * So pull the pgpartrule directly from the idrule (yuck!)
		 */
		prule = (PgPartRule *)linitial((List*)pid->partiddef);

		Assert(prule);

		/* current pnode level is one below current (our parent), and
		 * we want the one above us (our subpartition), so add 2
		 */
		lvl = prule->pNode->part->parlevel + 2;

		Assert (lvl > 1);
	}

	{
		/* relid, level, no parent */
		switch (del_part_template(RelationGetRelid(rel), lvl, 0))
		{
			case 0:
				if (pc->arg1)
				{
					/* no prior template - just add new one */
					ereport(NOTICE,
							(errmsg("%s level %d "
									"subpartition template specification "
									"for relation \"%s\"",
									"adding",
									lvl,
									RelationGetRelationName(rel))));
				}
				else
				{
					/* tried to drop non-existent template */
					ereport(ERROR,
							(errcode(ERRCODE_UNDEFINED_OBJECT),
							 errmsg("relation \"%s\" does not have a "
									"level %d "
									"subpartition template specification",
									RelationGetRelationName(rel),
									lvl),
											   errOmitLocation(true)));
				}
				break;
			case 1:
					/* if have new spec,
					 * note old spec is being replaced,
					 * else just note it is dropped
					 */
					ereport(NOTICE,
							(errmsg("%s level %d "
									"subpartition template specification "
									"for relation \"%s\"",
									(pc->arg1) ? "replacing" : "dropped",
									lvl,
									RelationGetRelationName(rel))));
				break;
			default:
					elog(ERROR,
						 "could not drop "
						 "level %d "
						 "subpartition template specification "
						 "for relation \"%s\"",
						 lvl,
						 RelationGetRelationName(rel));
					break;
		}

	}

	if (pc->arg1)
		ATPExecPartAdd(tab, rel, pc, AT_PartSetTemplate);

	/* MPP-6929: metadata tracking */
	MetaTrackUpdObject(RelationRelationId,
					   RelationGetRelid(rel),
					   GetUserId(),
					   "ALTER", "SET SUBPARTITION TEMPLATE"
			);


} /* end ATPExecPartSetTemplate */


static bool
partrule_walker(Node *node, void *context)
{
	part_rule_cxt *p = (part_rule_cxt *)context;

	if (node == NULL)
		return false;
	if (IsA(node, PgPartRule))
	{
		PgPartRule *pg = (PgPartRule *)node;

		partrule_walker((Node *)pg->topRule, p);
		partrule_walker((Node *)pg->pNode, p);
		return false;
	}
	else if (IsA(node, Partition))
	{
		return false;
	}
	else if (IsA(node, PartitionRule))
	{
		PartitionRule *pr = (PartitionRule *)node;

		if (pr->parchildrelid == p->old_oid)
			pr->parchildrelid = p->new_oid;

		return partrule_walker((Node *)pr->children, p);

	}
	else if (IsA(node, PartitionNode))
	{
		PartitionNode *pn = (PartitionNode *)node;
		ListCell *lc;

		partrule_walker((Node *)pn->default_part, p);
		foreach(lc, pn->rules)
		{
			PartitionRule *r = lfirst(lc);
			partrule_walker((Node *)r, p);
		}
		return false;
	}

	return expression_tree_walker(node, partrule_walker, p);
}

/* 
 * Build a basic ResultRelInfo for executing split. We only need
 * the relation descriptor and index information.
 */
static ResultRelInfo *
make_split_resultrel(Relation rel)
{
	ResultRelInfo *rri;

	rri = palloc0(sizeof(ResultRelInfo));
	rri->type = T_ResultRelInfo;
	rri->ri_RelationDesc = rel;
	rri->ri_NumIndices = 0;

	ExecOpenIndices(rri);
	return rri;
}

/*
 * Close indexes and free memory
 */
static void
destroy_split_resultrel(ResultRelInfo *rri)
{
	ExecCloseIndices(rri);

	/* 
	 * Don't do anything with the relation descriptor, that's our caller's job
	 */
	pfree(rri);

}

/*
 * Scan tuples from the temprel (origin, T) and route them to split parts (A, B)
 * based on the constraints.  It is important that the origin may have dropped
 * columns while the new relations will not.
 *
 * This also covers index tuple population.  Note this doesn't handle row OID
 * as it's not allowed in partition.
 */
static void
split_rows(Relation intoa, Relation intob, Relation temprel, List *splits, int segno)
{
	ResultRelInfo *rria = make_split_resultrel(intoa);
	ResultRelInfo *rrib = make_split_resultrel(intob);
	EState *estate = CreateExecutorState();
	TupleDesc		tupdescT = temprel->rd_att;
	TupleTableSlot *slotT = MakeSingleTupleTableSlot(tupdescT);
	HeapScanDesc heapscan = NULL;
	AppendOnlyScanDesc aoscan = NULL;
  ParquetScanDesc parquetscan = NULL;
  bool *aocsproj = NULL;
	MemoryContext oldCxt;
	AppendOnlyInsertDesc aoinsertdesc_a = NULL;
	AppendOnlyInsertDesc aoinsertdesc_b = NULL;
  ParquetInsertDesc parquetinsertdesc_a = NULL;
  ParquetInsertDesc parquetinsertdesc_b = NULL;
	ExprState *achk = NULL;
	ExprState *bchk = NULL;

	/*
	 * Set up for reconstructMatchingTupleSlot.  In split operation,
	 * slot/tupdesc should look same between A and B, but here we don't
	 * assume so just in case, to be safe.
	 */
	rria->ri_partSlot = MakeSingleTupleTableSlot(RelationGetDescr(intoa));
	rrib->ri_partSlot = MakeSingleTupleTableSlot(RelationGetDescr(intob));
	map_part_attrs(temprel, intoa, &rria->ri_partInsertMap, true);
	map_part_attrs(temprel, intob, &rrib->ri_partInsertMap, true);
	Assert(NULL != rria->ri_RelationDesc);
	rria->ri_resultSlot = MakeSingleTupleTableSlot(rria->ri_RelationDesc->rd_att);
	Assert(NULL != rrib->ri_RelationDesc);
	rrib->ri_resultSlot = MakeSingleTupleTableSlot(rrib->ri_RelationDesc->rd_att);

	/* constr might not be defined if this is a default partition */
	if (intoa->rd_att->constr && intoa->rd_att->constr->num_check)
	{
		List * all_part_constraints = NIL;
		for (int i = 0; i < intoa->rd_att->constr->num_check; i++) 
			all_part_constraints = lappend(all_part_constraints, 
											stringToNode(intoa->rd_att->constr->check[i].ccbin));
		achk = ExecPrepareExpr((Expr *)all_part_constraints, estate);
	}

	if (intob->rd_att->constr && intob->rd_att->constr->num_check)
	{
		List * all_part_constraints = NIL;
		for (int i = 0; i < intob->rd_att->constr->num_check; i++) 
			all_part_constraints = lappend(all_part_constraints, 
											stringToNode(intob->rd_att->constr->check[i].ccbin));
		bchk = ExecPrepareExpr((Expr *)all_part_constraints, estate);
	}

	/* be careful about AO vs. normal heap tables */
	if (RelationIsHeap(temprel))
		heapscan = heap_beginscan(temprel, SnapshotNow, 0, NULL);
	else if (RelationIsAoRows(temprel))
	{
		aoscan = appendonly_beginscan(temprel, SnapshotNow, 0, NULL);
		aoscan->splits = splits;
	}
	else if (RelationIsParquet(temprel))
	{
		int nvp = temprel->rd_att->natts;
		int i;

		aocsproj = (bool *) palloc(sizeof(bool) * nvp);
		for(i=0; i<nvp; ++i)
			aocsproj[i] = true;


		parquetscan = parquet_beginscan(temprel, SnapshotNow, NULL /* relationTupleDesc */, aocsproj);
		parquetscan->splits = splits;
	}
	else
	{
		Assert(false);
	}

	oldCxt = MemoryContextSwitchTo(GetPerTupleMemoryContext(estate));

	while (true)
	{
		ExprContext *econtext = GetPerTupleExprContext(estate);
		bool targetIsA;
		Relation targetRelation;
		AppendOnlyInsertDesc *targetAODescPtr;
		ParquetInsertDesc *targetParquetDescPtr;
		TupleTableSlot	   *targetSlot;
		ItemPointer			tid;
		ResultRelInfo	   *targetRelInfo = NULL;
		AOTupleId			aoTupleId;

		/* read next tuple from temprel */
		if (RelationIsHeap(temprel))
		{
			HeapTuple tuple;

			tuple = heap_getnext(heapscan, ForwardScanDirection);
			if (!HeapTupleIsValid(tuple))
				break;

			tuple = heap_copytuple(tuple);
			ExecStoreHeapTuple(tuple, slotT, InvalidBuffer, false);
		}
		else if (RelationIsAoRows(temprel))
		{
			MemTuple mtuple;

			mtuple = appendonly_getnext(aoscan, ForwardScanDirection, slotT);
			if (!PointerIsValid(mtuple))
				break;

			TupClearShouldFree(slotT);
		}
		else if (RelationIsParquet(temprel)){
			parquet_getnext(parquetscan, ForwardScanDirection, slotT);
			if (TupIsNull(slotT))
				break;
		}

		/* prepare for ExecQual */
		econtext->ecxt_scantuple = slotT;

		/* determine if we are inserting into a or b */
		if (achk)
		{
			targetIsA = ExecQual((List *)achk, econtext, false);
		}
		else
		{
			Assert(PointerIsValid(bchk));

			targetIsA = !ExecQual((List *)bchk, econtext, false);
		}

		/* load variables for the specific target */
		if (targetIsA)
		{
			targetRelation = intoa;
			targetAODescPtr = &aoinsertdesc_a;
			targetParquetDescPtr = &parquetinsertdesc_a;
			targetRelInfo = rria;
		}
		else
		{
			targetRelation = intob;
			targetAODescPtr = &aoinsertdesc_b;
			targetParquetDescPtr = &parquetinsertdesc_b;
			targetRelInfo = rrib;
		}

		/*
		 * Map attributes from origin to target.  We should consider dropped
		 * columns in the origin.
		 */
		targetSlot = reconstructMatchingTupleSlot(slotT, targetRelInfo);

		/* insert into the target table */
		if (RelationIsHeap(targetRelation))
		{
			HeapTuple tuple;

			tuple = ExecFetchSlotHeapTuple(targetSlot);
			simple_heap_insert(targetRelation, tuple);

			/* cache TID for later updating of indexes */
			tid = &(((HeapTuple) tuple)->t_self);
		}
		else if (RelationIsAoRows(targetRelation))
		{
			MemTuple	mtuple;
			Oid			tupleOid;

			if (!(*targetAODescPtr))
			{
			  ResultRelSegFileInfo *segfileinfo = NULL;
				MemoryContextSwitchTo(oldCxt);
			  segfileinfo = InitResultRelSegFileInfo(segno, RELSTORAGE_AOROWS, 1);
				*targetAODescPtr = appendonly_insert_init(targetRelation,
														  segfileinfo);
				MemoryContextSwitchTo(GetPerTupleMemoryContext(estate));
			}

			mtuple = ExecFetchSlotMemTuple(targetSlot, false);
			appendonly_insert(*targetAODescPtr, mtuple, &tupleOid, &aoTupleId);

			/* cache TID for later updating of indexes */
			tid = (ItemPointer) &aoTupleId;
		}
		else if (RelationIsParquet(targetRelation)){
			if (!*targetParquetDescPtr)
			{
			  ResultRelSegFileInfo *segfileinfo = NULL;
				MemoryContextSwitchTo(oldCxt);
				segfileinfo = InitResultRelSegFileInfo(segno, RELSTORAGE_PARQUET, 1);
				*targetParquetDescPtr = parquet_insert_init(targetRelation,
													  segfileinfo);
				MemoryContextSwitchTo(GetPerTupleMemoryContext(estate));
			}

			parquet_insert(*targetParquetDescPtr, targetSlot);

			/* cache TID for later updating of indexes */
			tid = slot_get_ctid(targetSlot);
		}
		else
		{
			Assert(false);
		}

		/*
		 * Insert index for this tuple.
		 * TODO: for performance reason, should we call index_build() instead?
		 */
		if (targetRelInfo->ri_NumIndices > 0)
		{
			estate->es_result_relation_info = targetRelInfo;
			ExecInsertIndexTuples(targetSlot, tid, estate, false);
			estate->es_result_relation_info = NULL;
		}

		/* done, clean up context for this pass */
		ResetExprContext(econtext);
	}

	StringInfo buf = NULL;
	QueryContextDispatchingSendBack sendback = NULL;

	int aocount = 0;
	if (aoinsertdesc_a)
		++aocount;
	if (aoinsertdesc_b)
		++aocount;
	if (parquetinsertdesc_a)
		++aocount;
	if (parquetinsertdesc_b)
		++aocount;

	if (Gp_role == GP_ROLE_EXECUTE && aocount > 0)
		buf = PreSendbackChangedCatalog(aocount);

	if (aoinsertdesc_a)
	{
		sendback = CreateQueryContextDispatchingSendBack(1);
		aoinsertdesc_a->sendback = sendback;
		sendback->relid = RelationGetRelid(aoinsertdesc_a->aoi_rel);

		appendonly_insert_finish(aoinsertdesc_a);

		if (Gp_role == GP_ROLE_EXECUTE)
			AddSendbackChangedCatalogContent(buf, sendback);

		DropQueryContextDispatchingSendBack(sendback);
	}
	if (aoinsertdesc_b)
	{
		sendback = CreateQueryContextDispatchingSendBack(1);
		aoinsertdesc_b->sendback = sendback;
		sendback->relid = RelationGetRelid(aoinsertdesc_b->aoi_rel);

		appendonly_insert_finish(aoinsertdesc_b);

		if (Gp_role == GP_ROLE_EXECUTE)
			AddSendbackChangedCatalogContent(buf, sendback);

		DropQueryContextDispatchingSendBack(sendback);
	}
	if (parquetinsertdesc_a)
	{
		sendback = CreateQueryContextDispatchingSendBack(1);
		parquetinsertdesc_a->sendback = sendback;
		sendback->relid = RelationGetRelid(parquetinsertdesc_a->parquet_rel);

		parquet_insert_finish(parquetinsertdesc_a);

		if (Gp_role == GP_ROLE_EXECUTE)
			AddSendbackChangedCatalogContent(buf, sendback);

		DropQueryContextDispatchingSendBack(sendback);
	}
	if (parquetinsertdesc_b)
	{
		sendback = CreateQueryContextDispatchingSendBack(1);
		parquetinsertdesc_b->sendback = sendback;
		sendback->relid = RelationGetRelid(parquetinsertdesc_b->parquet_rel);

		parquet_insert_finish(parquetinsertdesc_b);

		if (Gp_role == GP_ROLE_EXECUTE)
			AddSendbackChangedCatalogContent(buf, sendback);

		DropQueryContextDispatchingSendBack(sendback);
	}

	if (Gp_role == GP_ROLE_EXECUTE && aocount > 0)
		FinishSendbackChangedCatalog(buf);

	MemoryContextSwitchTo(oldCxt);
	ExecDropSingleTupleTableSlot(slotT);
	ExecDropSingleTupleTableSlot(rria->ri_partSlot);
	ExecDropSingleTupleTableSlot(rrib->ri_partSlot);

	/*
	 * We created our target result tuple table slots upfront.
	 * We can drop them now.
	 */
	Assert(NULL != rria->ri_resultSlot);
	Assert(NULL != rria->ri_resultSlot->tts_tupleDescriptor);
	ExecDropSingleTupleTableSlot(rria->ri_resultSlot);
	rria->ri_resultSlot = NULL;

	Assert(NULL != rrib->ri_resultSlot);
	Assert(NULL != rrib->ri_resultSlot->tts_tupleDescriptor);
	ExecDropSingleTupleTableSlot(rrib->ri_resultSlot);
	rrib->ri_resultSlot = NULL;

	if (rria->ri_partInsertMap)
		pfree(rria->ri_partInsertMap);
	if (rrib->ri_partInsertMap)
		pfree(rrib->ri_partInsertMap);

	if (RelationIsHeap(temprel))
		heap_endscan(heapscan);
	else if (RelationIsAoRows(temprel))
		appendonly_endscan(aoscan);
	else if(RelationIsParquet(temprel)){
		pfree(aocsproj);
		parquet_endscan(parquetscan);
	}

	destroy_split_resultrel(rria);
	destroy_split_resultrel(rrib);
}

/* ALTER TABLE ... SPLIT PARTITION */

/* 
   atpxSplitDropRule: walk the partition rules, eliminating rules that
   match parruleid and paroid.  If topRule is supplied, walk his
   subtree as well (it may differ from pnode if the PgPartRule was
   copied).
*/
static void
atpxSplitDropRule(PartitionNode *pNode, PartitionRule *topRule,
				  Oid parruleid, Oid paroid)
{
	ListCell *lc;
	ListCell *lcprev = NULL, *lcdel = NULL;

	if (!pNode)
		return;

	foreach(lc, pNode->rules)
	{
		PartitionRule *rule = lfirst(lc);

		if (rule->children)
			atpxSplitDropRule(rule->children, NULL, 
							  parruleid, paroid);

		if ((parruleid == rule->parruleid) &&
			(paroid == rule->paroid))
		{
			lcdel = lc; /* should only be one match */
			break;
		}
		lcprev = lc;
	}
	if (lcdel)
		pNode->rules = list_delete_cell(pNode->rules, lcdel, lcprev);

	/* and the default partition */
	if (pNode->default_part)
	{
		PartitionRule *rule = pNode->default_part;

		if (rule->children)
				atpxSplitDropRule(rule->children, NULL,
								  parruleid, paroid);

		if ((parruleid == rule->parruleid) &&
			(paroid == rule->paroid))
			pNode->default_part = NULL;
	}

	/* check optional topRule */
	if (topRule && topRule->children)
		atpxSplitDropRule(topRule->children, NULL,
						  parruleid, paroid);

} /* end atpxSplitDropRule */

/* Given a Relation, make a distributed by () clause for parser consumption. */
List *
make_dist_clause(Relation rel)
{
	int i;
	List *distro = NIL;

	for (i = 0; i < rel->rd_cdbpolicy->nattrs; i++)
	{
		AttrNumber attno = rel->rd_cdbpolicy->attrs[i];
		TupleDesc tupdesc = RelationGetDescr(rel);
		Value *attstr;
		NameData attname;

		attname = tupdesc->attrs[attno - 1]->attname;
		attstr = makeString(pstrdup(NameStr(attname)));

		distro = lappend(distro, attstr);
	}

	if (!distro)
	{
		/* must be random distribution */
		distro = list_make1(NULL);
	}
	return distro;
}

/*
 * Given a relation, get all column encodings for that relation as a list of
 * ColumnReferenceStorageDirective structures.
 */
static List *
rel_get_column_encodings(Relation rel)
{
	List **colencs = RelationGetUntransformedAttributeOptions(rel);
	List *out = NIL;

	if (colencs)
	{
		AttrNumber attno;

		for (attno = 0; attno < RelationGetNumberOfAttributes(rel); attno++)
		{
			if (colencs[attno] && !rel->rd_att->attrs[attno]->attisdropped)
			{
				ColumnReferenceStorageDirective *d =
					makeNode(ColumnReferenceStorageDirective);
				char *colname = pstrdup(NameStr(rel->rd_att->attrs[attno]->attname));
				d->column = makeString(colname);
				d->encoding = colencs[attno];
		
				out = lappend(out, d);
			}
		}
	}
	return out;
}

/*
 * Depending on whether a table is heap, append only or append only column
 * oriented, return NIL, (appendonly=true) or (appendonly=true,
 * orientation=parquet) respectively.
 */
static List *
make_orientation_options(Relation rel)
{
	List *l = NIL;

	if (RelationIsAoRows(rel) ||
		RelationIsParquet(rel) )
	{
		l = lappend(l, makeDefElem("appendonly", (Node *)makeString("true")));

		if (RelationIsParquet(rel))
		{
			l = lappend(l, makeDefElem("orientation",
									   (Node *)makeString("parquet")));
		}
	}
	return l;
}

void
ATPExecPartSplit(Relation rel,
                 AlterPartitionCmd *pc)
{
	Relation temprel = NULL;
	Relation intoa = NULL;
	Relation intob = NULL;
	Oid temprelid;

	if (Gp_role == GP_ROLE_DISPATCH)
	{
		CreateStmt *ct = makeNode(CreateStmt);
		char tmpname[NAMEDATALEN];
		InhRelation *inh = makeNode(InhRelation);
		DestReceiver *dest = None_Receiver;
		Node *at = lsecond((List *)pc->arg1);
		AlterPartitionCmd *pc2 = (AlterPartitionCmd *)pc->arg2;
		AlterPartitionId *pid = (AlterPartitionId *)pc->partid;
		AlterTableStmt *ats = makeNode(AlterTableStmt);
		RangeVar *rv;
		AlterTableCmd *cmd = makeNode(AlterTableCmd);
		AlterPartitionCmd *mypc = makeNode(AlterPartitionCmd);
		AlterPartitionCmd *mypc2 = makeNode(AlterPartitionCmd);
		AlterPartitionId *idpid;
		RangeVar *tmprv;
		PgPartRule *prule;
		DropStmt *ds = makeNode(DropStmt);
		List *parsetrees;
		Query *q;
		char *nspname = get_namespace_name(RelationGetNamespace(rel));
		char *relname = get_rel_name(RelationGetRelid(rel));
		Oid relid = RelationGetRelid(rel);
		RangeVar *rva = NULL;
		RangeVar *rvb = NULL;
		int into_exists = 0; /* which into partition exists? */
		int i;
		AlterPartitionId *intopid1 = NULL;
		AlterPartitionId *intopid2 = NULL;
		Oid rel_to_drop = InvalidOid;
		AlterPartitionId *aapid = NULL; /* just for alter partition pids */
		Relation existrel;
		List *existstorage_opts;
		ListCell *lc;
		char *defparname = NULL; /* name of default partition (if specified) */
		List *distro = NIL;
		List *colencs = NIL;
		List *orient = NIL;

		/* Get target meta data */
		prule = get_part_rule(rel, pid, true, true,
							  CurrentMemoryContext, NULL, false);
		/*
		 * In order to implement SPLIT, we do the following:
		 *
		 * 1) Build a temporary table T on all nodes.
		 * 2) Exchange that table with the target partition P
		 *    Now, T has all the data or P
		 * 3) Drop partition P
		 * 4) Create two new partitions in the place of the old one
		 */

		/* look up INTO clause info, if the user supplied it */
		if (!pc2) /* no INTO */
		{
			if (prule->topRule->parisdefault)
			{
				defparname = pstrdup(prule->topRule->parname);
				into_exists = 2;
			}
		}
		else /* has INTO clause */
		{
			bool isdef = false;
			bool exists = false;
			char *parname = NULL;

			/*
			 * If we're working on a subpartition, the INTO partition is
			 * actually a child partition of the parent identified by
			 * prule. So, we cannot just use get_part_rule() to determine
			 * if one of them is a default.
			 */

			/* first item */
			if (pid->idtype == AT_AP_IDRule)
			{
				if (prule->pNode->default_part &&
					((AlterPartitionId *)pc2->partid)->idtype == AT_AP_IDDefault)
				{
					isdef = true;
					exists = true;
					parname = prule->pNode->default_part->parname;
					if (!defparname && isdef) 
						defparname = pstrdup(parname);
				}
				else
				{
					ListCell *rc;
					AlterPartitionId *id = (AlterPartitionId *)pc2->partid;

					if (id->idtype == AT_AP_IDDefault)
						ereport(ERROR,
								(errcode(ERRCODE_UNDEFINED_OBJECT),
								 errmsg("relation \"%s\" does not have a "
										"default partition",
										RelationGetRelationName(rel)),
												   errOmitLocation(true)));

					foreach(rc, prule->pNode->rules)
					{
						PartitionRule *r = lfirst(rc);

						if (strcmp(r->parname, strVal((Value *)id->partiddef)) == 0)
						{
							isdef = false;
							exists = true;
							parname = r->parname;
						}
					}

					if (prule->pNode->default_part &&
						strcmp(prule->pNode->default_part->parname,
							   strVal((Value *)id->partiddef)) == 0)
					{
						isdef = true;
						exists = true;
						parname = prule->pNode->default_part->parname;
						if (!defparname && isdef) 
							defparname = pstrdup(parname);
					}
				}
			}
			else /* not a AT_AP_IDRule */
			{
				PgPartRule *tmprule;
				tmprule = get_part_rule(rel, (AlterPartitionId *)pc2->partid,
										false, false, CurrentMemoryContext,
										NULL, false);
				if (tmprule)
				{
					isdef = tmprule->topRule->parisdefault;
					exists = true;
					parname = tmprule->topRule->parname;
					if (!defparname && isdef) 
						defparname = pstrdup(parname);
				}
			}

			if (exists && isdef)
			{
				intopid2 = (AlterPartitionId *)pc2->partid;
				intopid1 = (AlterPartitionId *)pc2->arg1;
				into_exists = 2;

				if (intopid2->idtype == AT_AP_IDDefault)
					 intopid2->partiddef = (Node *)makeString(pstrdup(parname));
			}
			else
			{
				if (exists)
					into_exists = 1;

				intopid1 = (AlterPartitionId *)pc2->partid;
				intopid2 = (AlterPartitionId *)pc2->arg1;
			}

			/* second item */
			exists = false;
			isdef = false;
			parname = NULL;
			if (pid->idtype == AT_AP_IDRule)
			{
				if (prule->pNode->default_part &&
					((AlterPartitionId *)pc2->arg1)->idtype == AT_AP_IDDefault)
				{
					isdef = true;
					exists = true;
					parname = prule->pNode->default_part->parname;
					if (!defparname && isdef) 
						defparname = pstrdup(parname);
				}
				else
				{
					ListCell *rc;
					AlterPartitionId *id = (AlterPartitionId *)pc2->arg1;

					if (id->idtype == AT_AP_IDDefault)
						ereport(ERROR,
								(errcode(ERRCODE_UNDEFINED_OBJECT),
								 errmsg("relation \"%s\" does not have a "
										"default partition",
										RelationGetRelationName(rel)),
												   errOmitLocation(true)));

					foreach(rc, prule->pNode->rules)
					{
						PartitionRule *r = lfirst(rc);

						if (strcmp(r->parname, strVal((Value *)id->partiddef)) == 0)
						{
							isdef = false;
							exists = true;
							parname = r->parname;
						}
					}

					if (prule->pNode->default_part &&
						strcmp(prule->pNode->default_part->parname,
							   strVal((Value *)id->partiddef)) == 0)
					{
						isdef = true;
						exists = true;
						parname = prule->pNode->default_part->parname;
						if (!defparname && isdef) 
							defparname = pstrdup(parname);
					}

				}
			}
			else
			{
				PgPartRule *tmprule;
				tmprule = get_part_rule(rel, (AlterPartitionId *)pc2->arg1,
										false, false, CurrentMemoryContext,
										NULL, false);
				if (tmprule)
				{
					isdef = tmprule->topRule->parisdefault;
					exists = true;
					parname = tmprule->topRule->parname;
					if (!defparname && isdef) 
						defparname = pstrdup(parname);
				}
			}

			if (exists)
			{
				if (into_exists != 0)
					ereport(ERROR,
							(errcode(ERRCODE_DUPLICATE_OBJECT),
							 errmsg("both INTO partitions "
									"already exist"),
							 errOmitLocation(true)));

				into_exists = 2;
				intopid1 = (AlterPartitionId *)pc2->partid;
				intopid2 = (AlterPartitionId *)pc2->arg1;

				if (isdef)
				{
					if (intopid2->idtype == AT_AP_IDDefault)
						 intopid2->partiddef = (Node *)makeString(parname);
				}
			}
		}

		existrel = heap_open(prule->topRule->parchildrelid, NoLock);
		existstorage_opts = reloptions_list(RelationGetRelid(existrel));
		distro = make_dist_clause(existrel);
		colencs = rel_get_column_encodings(existrel);
		orient = make_orientation_options(existrel);

		heap_close(existrel, NoLock);

		/* 1) Create temp table */
		rv = makeRangeVar(NULL /*catalogname*/, nspname, relname, -1);
		inh->relation = copyObject(rv);
        inh->options = list_make3_int(CREATE_TABLE_LIKE_INCLUDING_DEFAULTS,
									  CREATE_TABLE_LIKE_INCLUDING_CONSTRAINTS,
									  CREATE_TABLE_LIKE_INCLUDING_INDEXES);
		ct->tableElts = list_make1(inh);
		ct->distributedBy = list_copy(distro); /* must preserve the list for later */

		/* should be unique enough */
		snprintf(tmpname, NAMEDATALEN, "pg_temp_%u", relid);
		tmprv = makeRangeVar(NULL /*catalogname*/, nspname, tmpname, -1);
		ct->relation = tmprv;
		ct->relKind = RELKIND_RELATION;
		ct->ownerid = rel->rd_rel->relowner;
		ct->is_split_part = true;
		parsetrees = parse_analyze((Node *)ct, NULL, NULL, 0);

		q = (Query *)linitial(parsetrees);
		ProcessUtility((Node *)q->utilityStmt,
					   synthetic_sql,
					   NULL,
					   false, /* not top level */
					   dest, 
					   NULL);
		CommandCounterIncrement();

		/* get the oid of the temporary table */
		temprelid = get_relname_relid(tmpname,
									  RelationGetNamespace(rel));

		if (pid->idtype == AT_AP_IDRule)
		{
			idpid = copyObject(pid);
		}
		else
		{
			idpid = makeNode(AlterPartitionId);
			idpid->idtype = AT_AP_IDRule;
			idpid->partiddef = (Node *)list_make2((Node *)prule, pid);
			idpid->location  = -1;
		}

		/* 2) EXCHANGE temp with target */
		rel_to_drop = prule->topRule->parchildrelid;

		ats->relation = copyObject(rv);
		ats->relkind = OBJECT_TABLE;

		cmd->subtype = AT_PartExchange;

		mypc->partid = (Node *)idpid;
		mypc->arg1 = (Node *)tmprv;
		mypc->arg2 = (Node *)mypc2;

		mypc2->arg1 = (Node *)makeInteger(0);
		mypc2->arg2 = (Node *)makeInteger(1); /* tell them we're SPLIT */
		cmd->def = (Node *)mypc;
		ats->cmds = list_make1(cmd);
		parsetrees = parse_analyze((Node *)ats, NULL, NULL, 0);
		Assert(list_length(parsetrees) == 1);
		q = (Query *)linitial(parsetrees);

		heap_close(rel, NoLock);
		ProcessUtility((Node *)q->utilityStmt,
					   synthetic_sql,
					   NULL, 
					   false, /* not top level */
					   dest, 
					   NULL);
		rel = heap_open(relid, AccessExclusiveLock);
		CommandCounterIncrement();

		/* 3) drop the old partition */
		if (pid->idtype == AT_AP_IDRule)
		{
			PgPartRule *pr;
			part_rule_cxt cxt;

			idpid = copyObject(pid);


			/* need to update the OID reference */
			pr = linitial((List *)idpid->partiddef);
			cxt.old_oid = rel_to_drop;
			cxt.new_oid = temprelid;
			partrule_walker((Node *)pr, (void *)&cxt);
			elog(DEBUG5, "dropping OID %u", temprelid);
		}
		else
		{
			/* refresh prule, out of date due to EXCHANGE */
			prule = get_part_rule(rel, pid, true, true,
								  CurrentMemoryContext, NULL, false);
			idpid = makeNode(AlterPartitionId);
			idpid->idtype = AT_AP_IDRule;
			idpid->partiddef = (Node *)list_make2((Node *)prule, pid);
			idpid->location  = -1;
		}

		cmd->subtype = AT_PartDrop;

		ds->missing_ok = false;
		ds->behavior = DROP_RESTRICT;
		ds->removeType = OBJECT_TABLE;

		mypc->partid = (Node *)idpid;
		mypc->arg1 = (Node *)ds;
		/* MPP-6589: make DROP work, even if last one
		 * NOTE: hateful hackery.  Normally, the arg2 for the PartDrop
		 * cmd is null.  But since SPLIT may need to DROP the last
		 * partition before it re-ADDs two new ones, we pass a non-null
		 * arg2 as a flag to enable ForceDrop in ATPExecPartDrop().  
		*/
		mypc->arg2 = (Node *)makeNode(AlterPartitionCmd);

		cmd->def = (Node *)mypc;
		parsetrees = parse_analyze((Node *)ats, NULL, NULL, 0);
		heap_close(rel, NoLock);

		/* 
		 * Might have expanded to multiple statements if, for example, the
		 * master table has indexes on it.
		 */
		foreach(lc, parsetrees)
		{
			q = (Query *)lfirst(lc);

			ProcessUtility((Node *)q->utilityStmt, 
						   synthetic_sql,
						   NULL, 
						   false, /* not top level */
						   dest, 
						   NULL);
		}

		rel = heap_open(relid, AccessExclusiveLock);
		CommandCounterIncrement();

		/*
		 * Now that we've dropped the partition, we need to handle updating
		 * the PgPartRule pid for the case where it is a pid representing
		 * ALTER PARTITION ... ALTER PARTITION ...
		 *
		 * For the normal case, we'll just run get_part_rule() again deeper
		 * in the code.
		 */
		if (pid->idtype == AT_AP_IDRule)
		{
			AlterPartitionId *tmppid = copyObject(pid);

			/* MPP-10223: pid contains a "stale" pNode with a
			 * partition rule for the partition we just dropped.
			 * Delve deep into pNode to eliminate the topRule.
			 */
			if (1)
			{
				AlterPartitionId		*newpid	 = tmppid;
				PgPartRule				*tmprule = NULL;

				while (tmppid->idtype == AT_AP_IDRule)
				{
					List *l = (List *)tmppid->partiddef;

					/* wipe out the topRule because the partition was
					 * dropped, or PartAdd will find it and complain!!
					 * Note that because the pid was copied,
					 * tmprule->topRule has a separate copy of the
					 * prule subtree, so we need to fix this one, too.
					 */
					tmprule = (PgPartRule *)linitial(l);

					atpxSplitDropRule(tmprule->pNode, 
									  tmprule->topRule,
									  prule->topRule->parruleid, 
									  prule->topRule->paroid);
					tmppid = lsecond(l);
				}
				
				tmppid = newpid;
			}

			aapid = tmppid;
		}

		/* Add two new partitions */
		elog(DEBUG5, "Split partition: adding two new partitions");

		/* 4) add two new partitions, via a loop to reduce code duplication */
		for (i = 1; i <= 2; i++)
		{
			/* build up commands for adding two. */
			AlterPartitionId *mypid = makeNode(AlterPartitionId);
			CreateStmt *mycs = makeNode(CreateStmt);
			char *parname = NULL;
			AlterPartitionId *intopid = NULL;
			PartitionElem *pelem = makeNode(PartitionElem);
			Oid newchildrelid = InvalidOid;
			AlterPartitionCmd *storenode = NULL;

			/* use storage options for existing rel */
			if (existstorage_opts)
			{
				storenode = makeNode(AlterPartitionCmd);
				storenode->arg1 = (Node *)existstorage_opts;
				storenode->location = -1;
			}
			pelem->storeAttr = (Node *)storenode;

			if (pc2)
			{
				if (i == 1)
					intopid = intopid1;
				else
					intopid = intopid2;
			}
			else
			{
				if (into_exists == i && prule->topRule->parname)
					parname = pstrdup(prule->topRule->parname);
			}

			mycs->relation = makeRangeVar(NULL /*catalogname*/, NULL, "fake_partition_name", -1);
			mycs->relKind = RELKIND_RELATION;

			/*
			 * If the new partition is column oriented, initialize the column
			 * entity list to the set of column encodings. Latter in parse
			 * analysis of this statement, we will append to this list a LIKE
			 * clause to clone the other column attributes.
			 *
			 * Be careful to copy the list since it is modified by parse
			 * analysis.
			 */
			if (colencs)
				mycs->tableElts = list_copy(colencs);

			mycs->options = orient;

			mypid->idtype = AT_AP_IDNone;
			mypid->location = -1;
			mypid->partiddef = NULL;

			mypc->partid = (Node *)mypid;

			if (intopid)
				parname = strVal(intopid->partiddef);

			if (prule->topRule->parisdefault && i == into_exists)
			{
				/* nothing to do */
			}
			else
			{
				if (prule->pNode->part->parkind == 'r')
				{
					PartitionBoundSpec *a = makeNode(PartitionBoundSpec);

					if (prule->topRule->parisdefault)
					{
						a->partStart = linitial((List *)pc->arg1);
						a->partEnd = lsecond((List *)pc->arg1);
					}
					else if (i == 1)
					{
						PartitionRangeItem *ri;

						/* MPP-6589: if the partition has an "open"
						 * START, pass a NULL partStart 
						 */
						if (prule->topRule &&
							prule->topRule->parrangestart)
						{
							ri = makeNode(PartitionRangeItem);
							ri->location = -1;
							ri->everycount = 0;
							ri->partRangeVal = 
									copyObject(prule->topRule->parrangestart);
							ri->partedge =
									prule->topRule->parrangestartincl ? 
									PART_EDGE_INCLUSIVE : PART_EDGE_EXCLUSIVE;

							a->partStart = (Node *)ri;
						}
						else
							a->partStart = NULL;

						ri = makeNode(PartitionRangeItem);
						ri->location = -1;
						ri->everycount = 0;
						ri->partRangeVal = copyObject(at);
						ri->partedge = PART_EDGE_EXCLUSIVE;

						a->partEnd = (Node *)ri;
					}
					else if (i == 2)
					{
						PartitionRangeItem *ri;
						ri = makeNode(PartitionRangeItem);
						ri->location = -1;
						ri->everycount = 0;
						ri->partRangeVal = copyObject(at);
						ri->partedge = PART_EDGE_INCLUSIVE;

						a->partStart = (Node *)ri;

						/* MPP-6589: if the partition has an "open"
						 * END, pass a NULL partEnd 
						 */
						if (prule->topRule &&
							prule->topRule->parrangeend)
						{
							ri = makeNode(PartitionRangeItem);
							ri->location = -1;
							ri->everycount = 0;
							ri->partRangeVal =
									copyObject(prule->topRule->parrangeend);
							ri->partedge = prule->topRule->parrangeendincl ? 
									PART_EDGE_INCLUSIVE : PART_EDGE_EXCLUSIVE;

							a->partEnd = (Node *)ri;
						}
						else
							a->partEnd = NULL;

					}
					pelem->boundSpec = (Node *)a;
				}
				else
				{
					if ((into_exists && into_exists != i &&
						 prule->topRule->parisdefault) ||
						(i == 2 && !prule->topRule->parisdefault))
					{
						PartitionValuesSpec *valuesspec =
							makeNode(PartitionValuesSpec);

						valuesspec->partValues = copyObject(at);
						valuesspec->location = -1;
						pelem->boundSpec = (Node *)valuesspec;
					}
					else
					{
						PartitionValuesSpec *valuesspec =
							makeNode(PartitionValuesSpec);
						List *lv = prule->topRule->parlistvalues;
						List *newvals = NIL;
						ListCell *lc;
						List *atlist = (List *)at;

						/* must be LIST */
						Assert(prule->pNode->part->parkind == 'l');

						/*
						 * Iterate through list of existing constraints and
						 * pick out those not in AT() clause
						 */
						foreach(lc, lv)
						{
							List *cols = lfirst(lc);
							ListCell *parvals = list_head(atlist);
							int16 nkeys = prule->pNode->part->parnatts;
							bool found = false;

							while (parvals)
							{
								List *vals = lfirst(parvals);
								ListCell *lcv = list_head(vals);
								ListCell *lcc = list_head(cols);
								int parcol;
								bool matched = true;

								for (parcol = 0; parcol < nkeys; parcol++)
								{
									Oid opclass =
										prule->pNode->part->parclass[parcol];
									Oid funcid = get_opclass_proc(opclass, 0,
																  BTORDER_PROC);
									Const *v = lfirst(lcv);
									Const *c = lfirst(lcc);
									Datum d;

									if (v->constisnull && c->constisnull)
										continue;
									else if (v->constisnull || c->constisnull)
									{
										matched = false;
										break;
									}

									d = OidFunctionCall2(funcid, c->constvalue,
														 v->constvalue);

									if (DatumGetInt32(d) != 0)
									{
										matched = false;
										break;
									}

									lcv = lnext(lcv);
									lcc = lnext(lcc);
								}

								if (matched)
								{
									found = true;
									break;
								}

								parvals = lnext(parvals);
							}
							if (!found)
							{
								/* Not in AT() clause, so keep it */
								newvals = lappend(newvals,
										copyObject((Node *)cols));
							}
						}
						valuesspec->partValues = newvals;
						valuesspec->location = -1;
						pelem->boundSpec = (Node *)valuesspec;
					}
				}
			}

			/*
			 * We always want to create a partition name because we
			 * need to recall the partition details below.
			 */
			if (!parname)
			{
				char n[NAMEDATALEN];

				snprintf(n, NAMEDATALEN, "r%lu", random());
				parname = pstrdup(n);

			}

			pelem->partName = (Node *)makeString(parname);
			mypid->partiddef = pelem->partName;
			mypid->idtype = AT_AP_IDName;

			pelem->location  = -1;
			/* MPP-10421: determine if new partition, re-use of old
			 * partition, and/or is default partition 
			 */
			pelem->isDefault = (defparname && 
								parname &&
								(0 == strcmp(parname, defparname)));

			/* tell ADD PARTITION we're doing a SPLIT */
			mypc2->partid = (Node *)makeInteger(1);

			mypc2->arg1 = (Node *)pelem;
			mypc2->arg2 = (Node *)list_make1(mycs);
			mypc2->location = -1;

			mypc->arg1 = (Node *)makeInteger(pelem->isDefault ? 1 : 0);
			mypc->arg2 = (Node *)mypc2;
			mypc->location = -1;

			cmd->subtype = AT_PartAdd;
			cmd->def = (Node *)mypc;

			/* turn this into ALTER PARTITION if need be */
			if (pid->idtype == AT_AP_IDRule)
			{
				AlterTableCmd *ac = makeNode(AlterTableCmd);
				AlterPartitionCmd *ap = makeNode(AlterPartitionCmd);

				ac->subtype = AT_PartAlter;
				ac->def = (Node *)ap;
				ap->partid = (Node *)aapid;
				ap->arg1 = (Node *)cmd; /* embed the real command */
				ap->location = -1;

				cmd = ac;
			}

			ats->cmds = list_make1(cmd);
			parsetrees = parse_analyze((Node *)ats, NULL, NULL, 0);
			Assert(list_length(parsetrees) == 1);
			q = (Query *)linitial(parsetrees);

			heap_close(rel, NoLock);
			ProcessUtility((Node *)q->utilityStmt, 
						   synthetic_sql,
						   NULL, 
						   false, /* not top level */
						   dest, 
						   NULL);
			rel = heap_open(relid, AccessExclusiveLock);

			/* make our change visible */
			CommandCounterIncrement();

			/* get the rule back which ADD PARTITION just created */
			if (pid->idtype == AT_AP_IDRule)
			{
				cqContext cqc;
				int fetchCount;
				Relation rulerel = heap_open(PartitionRuleRelationId,
											 AccessShareLock);

				Datum d = DirectFunctionCall1(namein,
							CStringGetDatum(strVal(pelem->partName)));

				/* XXX XXX: SnapshotSelf - but we just did a
				 * CommandCounterIncrement()
				 */
				newchildrelid = caql_getoid_plus(
						caql_snapshot(caql_addrel(cqclr(&cqc), rulerel), 
								  SnapshotSelf), 
						&fetchCount,
						NULL,
						cql("SELECT parchildrelid FROM pg_partition_rule "
							" WHERE paroid = :1 "
							" AND parparentrule = :2 "
							" AND parname = :3 ",
							ObjectIdGetDatum(prule->topRule->paroid),
							ObjectIdGetDatum(prule->topRule->parparentoid),
							d));

				Insist(fetchCount);

				heap_close(rulerel, NoLock);
			}
			else
			{
				PgPartRule *tmprule;
				tmprule = get_part_rule(rel, mypid, true, true,
									    CurrentMemoryContext, NULL, false);
				newchildrelid = tmprule->topRule->parchildrelid;
			}

			Assert(OidIsValid(newchildrelid));

			if (i == 1)
			{
				intoa = heap_open(newchildrelid,
								  AccessExclusiveLock);

				rva = makeRangeVar(
							NULL /*catalogname*/, 
							get_namespace_name(RelationGetNamespace(intoa)),
						    get_rel_name(RelationGetRelid(intoa)), -1);
			}
			else
			{
				intob = heap_open(newchildrelid,
								  AccessExclusiveLock);

				rvb = makeRangeVar(
							NULL /*catalogname*/, 	
							get_namespace_name(RelationGetNamespace(intob)),
						    get_rel_name(RelationGetRelid(intob)), -1);

			}
		}

		temprel = heap_open(rel_to_drop, AccessExclusiveLock);

		/* update parse tree with info for the QEs */
		Assert(PointerIsValid(rva));
		Assert(PointerIsValid(rvb));

		/* update for consumption by QEs */
		pc->partid = (Node *)makeInteger(RelationGetRelid(temprel));
		pc->arg1 = (Node *)copyObject(rva);
		pc->arg2 = (Node *)copyObject(rvb);

		/* MPP-6929: metadata tracking */
		MetaTrackUpdObject(RelationRelationId,
						   RelationGetRelid(rel),
						   GetUserId(),
						   "PARTITION", "SPLIT"
				);

	} /* end if dispatch */
	else if (Gp_role == GP_ROLE_EXECUTE)
	{
		Oid temprelid;
		RangeVar *rva;
		RangeVar *rvb;

		temprelid = (Oid)intVal((Value *)pc->partid);
		temprel = heap_open(temprelid, AccessExclusiveLock);
		rva = (RangeVar *)pc->arg1;
		intoa = heap_openrv(rva, AccessExclusiveLock);
		rvb = (RangeVar *)pc->arg2;
		intob = heap_openrv(rvb, AccessExclusiveLock);
	}
	else
		return;

	/*
	 * Now, on every node, scan the exchanged out table, splitting data
	 * between two new partitions.
	 *
	 * To do this, we use the CHECK constraints we just created on the
	 * tables via ADD PARTITION.
	 */
	if (Gp_role == GP_ROLE_EXECUTE)
	{
    List *split = NIL;
    int segno = 0;
    if (RelationIsAoRows(temprel) || RelationIsParquet(temprel))
    {
      split = GetFileSplitsOfSegment(pc->scantable_splits,
            temprel->rd_id, GetQEIndex());
      segno = list_nth_int(pc->newpart_aosegnos, GetQEIndex());
    }
	  split_rows(intoa, intob, temprel, split, segno);
	}

	/* 
	 * In HAWQ, we need to dispatch the splitting of rows to segments. Most other
	 * ALTER operations, dispatch the ALTER phase 3 work to segments. ALTER .. SPLIT PARTITION
	 * is different as the actual working of splitting happens in phase 2. Hence we dispatch
	 * at this point 
	 */
	if (Gp_role == GP_ROLE_DISPATCH)
	{
		
		QueryContextInfo *contextdisp;
    QueryResource *resource = NULL;
    DispatchDataResult    result;
    List *segment_segnos;
    List *scantable_splits;
    QueryResource *savedResource = NULL;

    int target_segment_num = -1;

    /*
     * make sure all three relations have the same
     * bucket number.
     */
    {
      GpPolicy *targetPolicy = NULL;

      targetPolicy = GpPolicyFetch(CurrentMemoryContext, (Oid)intVal((Value *)pc->partid));
      Assert(targetPolicy);
      target_segment_num = targetPolicy->bucketnum;
      pfree(targetPolicy);

      targetPolicy = GpPolicyFetch(CurrentMemoryContext, intoa->rd_id);
      Assert(targetPolicy);
      if (target_segment_num != targetPolicy->bucketnum)
      {
        pfree(targetPolicy);
        elog(ERROR, "target segment num %d IS NOT equal to the bucket number of this relation %d", target_segment_num, targetPolicy->bucketnum);
      }
      pfree(targetPolicy);

      targetPolicy = GpPolicyFetch(CurrentMemoryContext, intob->rd_id);
      Assert(targetPolicy);
      if (target_segment_num != targetPolicy->bucketnum)
      {
        pfree(targetPolicy);
        elog(ERROR, "target segment num %d IS NOT equal to the bucket number of this relation %d", target_segment_num, targetPolicy->bucketnum);
      }
      pfree(targetPolicy);

    }

    resource = AllocateResource(QRL_ONCE, 1, 1, target_segment_num, target_segment_num, NULL, 0);
    savedResource = GetActiveQueryResource();
    SetActiveQueryResource(resource);
    segment_segnos = SetSegnoForWrite(NIL, 0, target_segment_num, true, true, false);
    scantable_splits = NIL;

		/* create the segfiles for the new relations here */
		CreateAppendOnlyParquetSegFileForRelationOnMaster(intoa, segment_segnos);

		CreateAppendOnlyParquetSegFileForRelationOnMaster(intob, segment_segnos);

		/* prepare for the metadata dispatch */	
		contextdisp = CreateQueryContextInfo();
		
		prepareDispatchedCatalogSingleRelation(contextdisp, 
							intoa->rd_id,
							true, 
							segment_segnos);

		prepareDispatchedCatalogSingleRelation(contextdisp, 
							intob->rd_id,
							true, 
							segment_segnos);

		prepareDispatchedCatalogRelation(contextdisp,
							(Oid)intVal((Value *)pc->partid), 
							false,
							NULL);

    /*
     * Dispatch split-related metadata.
     */
    scantable_splits = AssignAOSegFileSplitToSegment((Oid)intVal((Value *)pc->partid),
              NIL, target_segment_num, scantable_splits);

    pc->scantable_splits = scantable_splits;
    pc->newpart_aosegnos = segment_segnos;

    FinalizeQueryContextInfo(contextdisp);
    dispatch_statement_node((Node *) pc, contextdisp, resource, &result);
    cdbdisp_iterate_results_sendback(result.result, result.numresults,
                UpdateCatalogModifiedOnSegments);
    dispatch_free_result(&result);
    DropQueryContextInfo(contextdisp);
    FreeResource(resource);
    SetActiveQueryResource(savedResource);
	}

	elog(DEBUG5, "dropping temp rel %s", RelationGetRelationName(temprel));
	temprelid = RelationGetRelid(temprel);
	heap_close(temprel, NoLock);

	/* 
	 * In HAWQ, we only need to drop the temp relation on the master which will ensure
	 * the relation is dropped on segments as well. 
 	 */
	if (Gp_role != GP_ROLE_EXECUTE)
	{
		ObjectAddress addr;
		addr.classId = RelationRelationId;
		addr.objectId = temprelid;
		addr.objectSubId = 0;

		performDeletion(&addr, DROP_RESTRICT);
	}

	heap_close(intoa, NoLock);
	heap_close(intob, NoLock);
}

/* ALTER TABLE ... TRUNCATE PARTITION */
static List *
atpxTruncateList(Relation rel, PartitionNode *pNode)
{
	List *l1 = NIL;
	ListCell *lc;

	if (!pNode)
		return l1;

	/* add the child lists first */
	foreach(lc, pNode->rules)
	{
		PartitionRule *rule = lfirst(lc);
		List *l2 = NIL;

		if (rule->children)
			l2 = atpxTruncateList(rel, rule->children);
		else
			l2 = NIL;

		if (l2)
		{
			if (l1)
				l1 = list_concat(l1, l2);
			else
				l1 = l2;
		}
	}

	/* and the default partition */
	if (pNode->default_part)
	{
		PartitionRule *rule = pNode->default_part;
		List *l2 = NIL;

		if (rule->children)
			l2 = atpxTruncateList(rel, rule->children);
		else
			l2 = NIL;

		if (l2)
		{
			if (l1)
				l1 = list_concat(l1, l2);
			else
				l1 = l2;
		}
	}

	/* add entries for rules at current level */
	foreach(lc, pNode->rules)
	{
		PartitionRule 	*rule = lfirst(lc);
		RangeVar 		*rv;
		Relation		 rel;

		rel = heap_open(rule->parchildrelid, AccessShareLock);

		rv = makeRangeVar(NULL /*catalogname*/, get_namespace_name(RelationGetNamespace(rel)),
						  pstrdup(RelationGetRelationName(rel)), -1);

		heap_close(rel, NoLock);

		if (l1)
			l1 = lappend(l1, rv);
		else
			l1 = list_make1(rv);
	}

	/* and the default partition */
	if (pNode->default_part)
	{
		PartitionRule 	*rule = pNode->default_part;
		RangeVar 		*rv;
		Relation		 rel;

		rel = heap_open(rule->parchildrelid, AccessShareLock);
		rv = makeRangeVar(NULL /*catalogname*/, get_namespace_name(RelationGetNamespace(rel)),
						  pstrdup(RelationGetRelationName(rel)), -1);

		heap_close(rel, NoLock);

		if (l1)
			l1 = lappend(l1, rv);
		else
			l1 = list_make1(rv);
	}

	return l1;
} /* end atpxTruncateList */

static void
ATPExecPartTruncate(Relation rel,
                    AlterPartitionCmd *pc)
{
	AlterPartitionId *pid = (AlterPartitionId *)pc->partid;
	PgPartRule   *prule = NULL;

	if (Gp_role != GP_ROLE_DISPATCH)
		return;

	prule = get_part_rule(rel, pid, true, true, CurrentMemoryContext, NULL,
						  false);

	if (prule)
	{
		RangeVar 		*rv;
		TruncateStmt 	*ts   = (TruncateStmt *)pc->arg1;
		DestReceiver 	*dest = None_Receiver;
		Relation	  	 rel2;

		rel2 = heap_open(prule->topRule->parchildrelid, AccessShareLock);
		rv = makeRangeVar(NULL /*catalogname*/, get_namespace_name(RelationGetNamespace(rel2)),
						  pstrdup(RelationGetRelationName(rel2)), -1);

		rv->location = pc->location;

		if (prule->topRule->children)
		{
			List *l1 = atpxTruncateList(rel2, prule->topRule->children);

			ts->relations = lappend(l1, rv);
		}
		else
			ts->relations = list_make1(rv);

		heap_close(rel2, NoLock);

		ProcessUtility( (Node *) ts,
					   synthetic_sql,
					   NULL, 
					   false, /* not top level */
					   dest, 
					   NULL);

		/* Notify of name if did not use name for partition id spec */
		if (prule && prule->topRule && prule->topRule->children
			&& (ts->behavior != DROP_CASCADE ))
		{
			ereport(NOTICE,
					(errmsg("truncated partition%s for %s and its children",
							prule->partIdStr,
							prule->relname),
									   errOmitLocation(true)));
		}
		else if ((pid->idtype != AT_AP_IDName)
				 && prule->isName)
				ereport(NOTICE,
						(errmsg("truncated partition%s for %s",
								prule->partIdStr,
								prule->relname),
										   errOmitLocation(true)));
	}

} /* end ATPExecPartTruncate */

/*
 * Execute ALTER TABLE SET SCHEMA
 *
 * WARNING WARNING WARNING: In previous *minor* releases the caller was
 * responsible for checking ownership of the relation, but now we do it here.
 */
void
AlterTableNamespace(RangeVar *relation, const char *newschema)
{
	Relation	rel;
	Oid			relid;
	Oid			oldNspOid;
	Oid			nspOid;

	/* make sure this is not an hcatalog table */
	relid = RangeVarGetRelid(relation, false /*failOk*/, false /*allowHcatalog*/);
	rel = heap_openrv(relation, AccessExclusiveLock);
	CheckRelationOwnership(relid, true);

	oldNspOid = RelationGetNamespace(rel);

	/* heap_openrv allows TOAST, but we don't want to */
	if (rel->rd_rel->relkind == RELKIND_TOASTVALUE)
		ereport(ERROR,
				(errcode(ERRCODE_WRONG_OBJECT_TYPE),
				 errmsg("\"%s\" is a TOAST relation",
						RelationGetRelationName(rel)),
								   errOmitLocation(true)));

	if (rel->rd_rel->relkind == RELKIND_AOSEGMENTS)
		ereport(ERROR,
				(errcode(ERRCODE_WRONG_OBJECT_TYPE),
				 errmsg("\"%s\" is an Append Only segment listing relation",
						RelationGetRelationName(rel)),
								   errOmitLocation(true)));

	if (rel->rd_rel->relkind == RELKIND_AOBLOCKDIR)
		ereport(ERROR,
				(errcode(ERRCODE_WRONG_OBJECT_TYPE),
				 errmsg("\"%s\" is an Append Only block directory relation",
						RelationGetRelationName(rel)),
								   errOmitLocation(true)));

	/* if it's an owned sequence, disallow moving it by itself */
	if (rel->rd_rel->relkind == RELKIND_SEQUENCE)
	{
		Oid			tableId;
		int32		colId;

		if (sequenceIsOwned(relid, &tableId, &colId))
			ereport(ERROR,
					(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
				 errmsg("cannot move an owned sequence into another schema"),
					 errdetail("Sequence \"%s\" is linked to table \"%s\".",
							   RelationGetRelationName(rel),
							   get_rel_name(tableId)),
									   errOmitLocation(true)));
	}

	/* get schema OID and check its permissions */
	nspOid = LookupCreationNamespace(newschema);

	if (oldNspOid == nspOid)
		ereport(ERROR,
				(errcode(ERRCODE_DUPLICATE_TABLE),
				 errmsg("relation \"%s\" is already in schema \"%s\"",
						RelationGetRelationName(rel),
						newschema),
								   errOmitLocation(true)));

	/* disallow renaming into or out of temp schemas */
	if (isAnyTempNamespace(nspOid) || isAnyTempNamespace(oldNspOid))
		ereport(ERROR,
				(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
			errmsg("cannot move objects into or out of temporary schemas"),
					   errOmitLocation(true)));

	/* same for TOAST schema */
	if (nspOid == PG_TOAST_NAMESPACE || oldNspOid == PG_TOAST_NAMESPACE)
		ereport(ERROR,
				(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
				 errmsg("cannot move objects into or out of TOAST schema"),
						   errOmitLocation(true)));

	/* same for AO SEGMENT schema */
	if (nspOid == PG_AOSEGMENT_NAMESPACE || oldNspOid == PG_AOSEGMENT_NAMESPACE)
		ereport(ERROR,
				(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
				 errmsg("cannot move objects into or out of AO SEGMENT schema"),
						   errOmitLocation(true)));


	/* OK, modify the pg_class row and pg_depend entry */
	AlterRelationNamespaceInternalTwo(rel, relid,
									  oldNspOid, nspOid,
									  true, newschema);
	
	/* MPP-7825, MPP-6929, MPP-7600: metadata tracking */
	if ((Gp_role == GP_ROLE_DISPATCH)
		&& MetaTrackValidKindNsp(rel->rd_rel))
		MetaTrackUpdObject(RelationRelationId,
						   RelationGetRelid(rel),
						   GetUserId(),
						   "ALTER", "SET SCHEMA"
				);

	/* close rel, but keep lock until commit */
	relation_close(rel, NoLock);
}

static void
AlterRelationNamespaceInternalTwo(Relation rel,
								  Oid relid,
								  Oid oldNspOid, Oid newNspOid,
								  bool hasDependEntry,
								  const char *newschema)
{
	Relation classRel;

	/* OK, modify the pg_class row and pg_depend entry */
	classRel = heap_open(RelationRelationId, RowExclusiveLock);

	AlterRelationNamespaceInternal(classRel, relid, oldNspOid, newNspOid, 
								   hasDependEntry);

	/* Fix the table's rowtype too */
	AlterTypeNamespaceInternal(rel->rd_rel->reltype, newNspOid, false);

	/* Fix other dependent stuff */
	if (rel->rd_rel->relkind == RELKIND_RELATION)
	{
		AlterIndexNamespaces(classRel, rel, oldNspOid, newNspOid);
		AlterSeqNamespaces(classRel, rel, oldNspOid, newNspOid, newschema);
		AlterConstraintNamespaces(relid, oldNspOid, newNspOid, false);
	}
	heap_close(classRel, RowExclusiveLock);
}

/*
 * The guts of relocating a relation to another namespace: fix the pg_class
 * entry, and the pg_depend entry if any.  Caller must already have
 * opened and write-locked pg_class.
 */
void
AlterRelationNamespaceInternal(Relation classRel, Oid relOid,
							   Oid oldNspOid, Oid newNspOid,
							   bool hasDependEntry)
{
	HeapTuple	classTup;
	Form_pg_class classForm;
	cqContext	cqc;
	cqContext  *pcqCtx;

	Assert(RelationGetRelid(classRel) == RelationRelationId);

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

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

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

	Assert(classForm->relnamespace == oldNspOid);

	/* check for duplicate name (more friendly than unique-index failure) */
	if (get_relname_relid(NameStr(classForm->relname),
						  newNspOid) != InvalidOid)
		ereport(ERROR,
				(errcode(ERRCODE_DUPLICATE_TABLE),
				 errmsg("relation \"%s\" already exists in schema \"%s\"",
						NameStr(classForm->relname),
						get_namespace_name(newNspOid)),
								   errOmitLocation(true)));

	/* classTup is a copy, so OK to scribble on */
	classForm->relnamespace = newNspOid;

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

	/* Update dependency on schema if caller said so */
	if (hasDependEntry &&
		changeDependencyFor(RelationRelationId, relOid,
							NamespaceRelationId, oldNspOid, newNspOid) != 1)
		elog(ERROR, "failed to change schema dependency for relation \"%s\"",
			 NameStr(classForm->relname));

	heap_freetuple(classTup);
}

/*
 * Move all indexes for the specified relation to another namespace.
 *
 * Note: we assume adequate permission checking was done by the caller,
 * and that the caller has a suitable lock on the owning relation.
 */
static void
AlterIndexNamespaces(Relation classRel, Relation rel,
					 Oid oldNspOid, Oid newNspOid)
{
	List	   *indexList;
	ListCell   *l;

	indexList = RelationGetIndexList(rel);

	foreach(l, indexList)
	{
		Oid			indexOid = lfirst_oid(l);

		/*
		 * Note: currently, the index will not have its own dependency on the
		 * namespace, so we don't need to do changeDependencyFor(). There's no
		 * rowtype in pg_type, either.
		 */
		AlterRelationNamespaceInternal(classRel, indexOid,
									   oldNspOid, newNspOid,
									   false);
	}

	list_free(indexList);
}

/*
 * Move all SERIAL-column sequences of the specified relation to another
 * namespace.
 *
 * Note: we assume adequate permission checking was done by the caller,
 * and that the caller has a suitable lock on the owning relation.
 */
static void
AlterSeqNamespaces(Relation classRel, Relation rel,
				   Oid oldNspOid, Oid newNspOid, const char *newNspName)
{
	cqContext  *pcqCtx;
	HeapTuple	tup;

	/*
	 * SERIAL sequences are those having an auto dependency on one of the
	 * table's columns (we don't care *which* column, exactly).
	 */

	pcqCtx = caql_beginscan(
			NULL,
			cql("SELECT * FROM pg_depend "
				" WHERE refclassid = :1 "
				" AND refobjid = :2 ",
				ObjectIdGetDatum(RelationRelationId),
				ObjectIdGetDatum(RelationGetRelid(rel))));

	while (HeapTupleIsValid(tup = caql_getnext(pcqCtx)))
	{
		Form_pg_depend depForm = (Form_pg_depend) GETSTRUCT(tup);
		Relation	seqRel;

		/* skip dependencies other than auto dependencies on columns */
		if (depForm->refobjsubid == 0 ||
			depForm->classid != RelationRelationId ||
			depForm->objsubid != 0 ||
			depForm->deptype != DEPENDENCY_AUTO)
			continue;

		/* Use relation_open just in case it's an index */
		seqRel = relation_open(depForm->objid, AccessExclusiveLock);

		/* skip non-sequence relations */
		if (RelationGetForm(seqRel)->relkind != RELKIND_SEQUENCE)
		{
			/* No need to keep the lock */
			relation_close(seqRel, AccessExclusiveLock);
			continue;
		}

		/* Fix the pg_class and pg_depend entries */
		AlterRelationNamespaceInternal(classRel, depForm->objid,
									   oldNspOid, newNspOid,
									   true);

		/*
		 * Sequences have entries in pg_type. We need to be careful to move
		 * them to the new namespace, too.
		 */
		AlterTypeNamespaceInternal(RelationGetForm(seqRel)->reltype,
								   newNspOid, false);

		/* Now we can close it.  Keep the lock till end of transaction. */
		relation_close(seqRel, NoLock);
	}

	caql_endscan(pcqCtx);

}


/*
 * This code supports
 *	CREATE TEMP TABLE ... ON COMMIT { DROP | PRESERVE ROWS | DELETE ROWS }
 *
 * Because we only support this for TEMP tables, it's sufficient to remember
 * the state in a backend-local data structure.
 */

/*
 * Register a newly-created relation's ON COMMIT action.
 */
void
register_on_commit_action(Oid relid, OnCommitAction action)
{
	OnCommitItem *oc;
	MemoryContext oldcxt;

	/*
	 * We needn't bother registering the relation unless there is an ON COMMIT
	 * action we need to take.
	 */
	if (action == ONCOMMIT_NOOP || action == ONCOMMIT_PRESERVE_ROWS)
		return;

	oldcxt = MemoryContextSwitchTo(CacheMemoryContext);

	oc = (OnCommitItem *) palloc(sizeof(OnCommitItem));
	oc->relid = relid;
	oc->oncommit = action;
	oc->creating_subid = GetCurrentSubTransactionId();
	oc->deleting_subid = InvalidSubTransactionId;

	on_commits = lcons(oc, on_commits);

	MemoryContextSwitchTo(oldcxt);
}

/*
 * Unregister any ON COMMIT action when a relation is deleted.
 *
 * Actually, we only mark the OnCommitItem entry as to be deleted after commit.
 */
void
remove_on_commit_action(Oid relid)
{
	ListCell   *l;

	foreach(l, on_commits)
	{
		OnCommitItem *oc = (OnCommitItem *) lfirst(l);

		if (oc->relid == relid)
		{
			oc->deleting_subid = GetCurrentSubTransactionId();
			break;
		}
	}
}

/*
 * Perform ON COMMIT actions.
 *
 * This is invoked just before actually committing, since it's possible
 * to encounter errors.
 */
void
PreCommit_on_commit_actions(void)
{
	ListCell   *l;
	List	   *oids_to_truncate = NIL;

	foreach(l, on_commits)
	{
		OnCommitItem *oc = (OnCommitItem *) lfirst(l);

		/* Ignore entry if already dropped in this xact */
		if (oc->deleting_subid != InvalidSubTransactionId)
			continue;

		switch (oc->oncommit)
		{
			case ONCOMMIT_NOOP:
			case ONCOMMIT_PRESERVE_ROWS:
				/* Do nothing (there shouldn't be such entries, actually) */
				break;
			case ONCOMMIT_DELETE_ROWS:
				oids_to_truncate = lappend_oid(oids_to_truncate, oc->relid);
				break;
			case ONCOMMIT_DROP:
				{
					ObjectAddress object;

					object.classId = RelationRelationId;
					object.objectId = oc->relid;
					object.objectSubId = 0;
					performDeletion(&object, DROP_CASCADE);

					/*
					 * Note that table deletion will call
					 * remove_on_commit_action, so the entry should get marked
					 * as deleted.
					 */
					Assert(oc->deleting_subid != InvalidSubTransactionId);
					break;
				}
		}
	}
	if (oids_to_truncate != NIL)
	{
		heap_truncate(oids_to_truncate);
		CommandCounterIncrement();		/* XXX needed? */
	}
}

/*
 * Post-commit or post-abort cleanup for ON COMMIT management.
 *
 * All we do here is remove no-longer-needed OnCommitItem entries.
 *
 * During commit, remove entries that were deleted during this transaction;
 * during abort, remove those created during this transaction.
 */
void
AtEOXact_on_commit_actions(bool isCommit)
{
	ListCell   *cur_item;
	ListCell   *prev_item;

	prev_item = NULL;
	cur_item = list_head(on_commits);

	while (cur_item != NULL)
	{
		OnCommitItem *oc = (OnCommitItem *) lfirst(cur_item);

		if (isCommit ? oc->deleting_subid != InvalidSubTransactionId :
			oc->creating_subid != InvalidSubTransactionId)
		{
			/* cur_item must be removed */
			on_commits = list_delete_cell(on_commits, cur_item, prev_item);
			pfree(oc);
			if (prev_item)
				cur_item = lnext(prev_item);
			else
				cur_item = list_head(on_commits);
		}
		else
		{
			/* cur_item must be preserved */
			oc->creating_subid = InvalidSubTransactionId;
			oc->deleting_subid = InvalidSubTransactionId;
			prev_item = cur_item;
			cur_item = lnext(prev_item);
		}
	}
}

/*
 * Post-subcommit or post-subabort cleanup for ON COMMIT management.
 *
 * During subabort, we can immediately remove entries created during this
 * subtransaction.	During subcommit, just relabel entries marked during
 * this subtransaction as being the parent's responsibility.
 */
void
AtEOSubXact_on_commit_actions(bool isCommit, SubTransactionId mySubid,
							  SubTransactionId parentSubid)
{
	ListCell   *cur_item;
	ListCell   *prev_item;

	prev_item = NULL;
	cur_item = list_head(on_commits);

	while (cur_item != NULL)
	{
		OnCommitItem *oc = (OnCommitItem *) lfirst(cur_item);

		if (!isCommit && oc->creating_subid == mySubid)
		{
			/* cur_item must be removed */
			on_commits = list_delete_cell(on_commits, cur_item, prev_item);
			pfree(oc);
			if (prev_item)
				cur_item = lnext(prev_item);
			else
				cur_item = list_head(on_commits);
		}
		else
		{
			/* cur_item must be preserved */
			if (oc->creating_subid == mySubid)
				oc->creating_subid = parentSubid;
			if (oc->deleting_subid == mySubid)
				oc->deleting_subid = isCommit ? parentSubid : InvalidSubTransactionId;
			prev_item = cur_item;
			cur_item = lnext(prev_item);
		}
	}
}


/*
 * Transform the URI string list into a text array (the form that is
 * used in the catalog table pg_exttable). While at it we validate
 * the URI strings.
 *
 * The result is a text array but we declare it as Datum to avoid
 * including array.h in analyze.h.
 */
static Datum transformLocationUris(List *locs, List* fmtopts, bool isweb, bool iswritable, bool* isCustom)
{
	ListCell   *cell;
	ArrayBuildState *astate;
	Datum		result;
	UriProtocol first_protocol = URI_FILE; /* initialize to keep gcc quiet */
	bool		first_uri = true;
	
#define FDIST_DEF_PORT 8080

	/* Parser should not let this happen */
	Assert(locs != NIL);

	/* We build new array using accumArrayResult */
	astate = NULL;

	/*
	 * first, check for duplicate URI entries
	 */
	foreach(cell, locs)
	{
		Value		*v1 = lfirst(cell);
		const char	*uri1 = v1->val.str;
		ListCell   *rest;

		for_each_cell(rest, lnext(cell))
		{
			Value		*v2 = lfirst(rest);
			const char	*uri2 = v2->val.str;

			if (strcmp(uri1, uri2) == 0)
				ereport(ERROR,
						(errcode(ERRCODE_INVALID_TABLE_DEFINITION),
						 errmsg("location uri \"%s\" appears more than once",
								uri1),
										   errOmitLocation(true)));
		}
	}

	/*
	 * iterate through the user supplied URI list from LOCATION clause.
	 */
	foreach(cell, locs)
	{
		Uri			*uri;
		text		*t;
		char		*uri_str_orig;
		char		*uri_str_final;
		Size		len;
		Value		*v = lfirst(cell);
		
		/* get the current URI string from the command */
		uri_str_orig = pstrdup(v->val.str);

		/* parse it to its components */
		uri = ParseExternalTableUri(uri_str_orig);

		/* allocate memory for a modified URI string (if needs modification) */
		uri_str_final = (char *) palloc(strlen(uri_str_orig) *
						  sizeof(char) +
						  1 + 4 + 1 /* default port if added */);

		/*
		 * in here edit the uri string if needed
		 */

		/* in HAWQ 2.0, the file protocol is not supported any more. */
		if (uri->protocol == URI_FILE)
		{
	    ereport(ERROR,
	        (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
	        errmsg("the file protocol for external tables is deprecated"),
	        errhint("use the gpfdist protocol or COPY FROM instead"),
	        errOmitLocation(true)));
		}

		/* no port was specified for gpfdist, gpfdists or hdfs. add the default */
		if ((uri->protocol == URI_GPFDIST || uri->protocol == URI_GPFDISTS) && uri->port == -1)
		{
			char *at_hostname = (char *) uri_str_orig
					+ strlen(uri->protocol == URI_GPFDIST ? "gpfdist://" : "gpfdists://");
			char *after_hostname = strchr(at_hostname, '/');
			int  len = after_hostname - at_hostname;
			char *hostname = pstrdup(at_hostname);

			hostname[len] = '\0';

			/* add the default port number to the uri string */
			sprintf(uri_str_final, "%s%s:%d%s",
					(uri->protocol == URI_GPFDIST ? PROTOCOL_GPFDIST : PROTOCOL_GPFDISTS),
					hostname,
					FDIST_DEF_PORT, after_hostname);

			pfree(hostname);
		}
		else
		{
			/* no changes to original uri string */
			uri_str_final = (char *) uri_str_orig;
		}

		/* 
		 * If a custom protocol is used, validate its existence.
		 * If it exists, and a custom protocol url validator exists
		 * as well, invoke it now.
		 */
		if (first_uri && uri->protocol == URI_CUSTOM)
		{
			Oid		procOid = InvalidOid;
			
			procOid = LookupExtProtocolFunction(uri->customprotocol, 
												EXTPTC_FUNC_VALIDATOR, 
												false);

			if (OidIsValid(procOid) && Gp_role == GP_ROLE_DISPATCH)
				InvokeProtocolValidation(procOid, 
										 uri->customprotocol, 
										 iswritable, 
										 locs, fmtopts);
		}
		
		if(first_uri)
		{
		    first_protocol = uri->protocol;
		    first_uri = false;
		    if(uri->protocol == URI_CUSTOM){
		    		*isCustom = true;
		    }
		} 
		    	

		if(uri->protocol != first_protocol)
		{
			ereport(ERROR,
					(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
					 errmsg("URI protocols must be the same for all data sources"),
					 errhint("Available protocols are 'http', 'file', 'pxf', 'gpfdist' and 'gpfdists'"),
							   errOmitLocation(true)));

		}
		
		if(uri->protocol != URI_HTTP && isweb)
			ereport(ERROR,
					(errcode(ERRCODE_SYNTAX_ERROR),
					 errmsg("an EXTERNAL WEB TABLE may only use http URI\'s, problem in: \'%s\'", uri_str_final),
					 errhint("Use CREATE EXTERNAL TABLE instead."),
							   errOmitLocation(true)));

		if(uri->protocol == URI_HTTP && !isweb)
			ereport(ERROR,
					(errcode(ERRCODE_SYNTAX_ERROR),
					errmsg("http URI\'s can only be used in an external web table"),
					errhint("Use CREATE EXTERNAL WEB TABLE instead."),
							   errOmitLocation(true)));

		if(iswritable && (uri->protocol == URI_HTTP || uri->protocol == URI_FILE))
			ereport(ERROR,
					(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
					 errmsg("unsupported URI protocol \'%s\' for writable external table", 
							(uri->protocol == URI_HTTP ? "http" : "file")),
					 errhint("Writable external tables may use \'gpfdist(s)\' URIs only."),
							   errOmitLocation(true)));

		if(uri->protocol != URI_CUSTOM && iswritable && strchr(uri->path, '*'))
			ereport(ERROR,
					(errcode(ERRCODE_SYNTAX_ERROR),
					errmsg("Unsupported use of wildcard in a writable external web table definition: "
							"\'%s\'", uri_str_final),
					errhint("Specify the explicit path and file name to write into.")));
		
		if ((uri->protocol == URI_GPFDIST || uri->protocol == URI_GPFDISTS) && iswritable && uri->path[strlen(uri->path) - 1] == '/')
			ereport(ERROR,
					(errcode(ERRCODE_SYNTAX_ERROR),
					errmsg("Unsupported use of a directory name in a writable gpfdist(s) external table : "
							"\'%s\'", uri_str_final),
					errhint("Specify the explicit path and file name to write into."),
							   errOmitLocation(true)));

		len = VARHDRSZ + strlen(uri_str_final);

		/* +1 leaves room for sprintf's trailing null */
		t = (text *) palloc(len + 1);
		SET_VARSIZE(t, len);
		sprintf((char *) VARDATA(t), "%s", uri_str_final);


		astate = accumArrayResult(astate, PointerGetDatum(t),
								  false, TEXTOID,
								  CurrentMemoryContext);

		FreeExternalTableUri(uri);
		pfree(uri_str_final);
	}

	if (astate)
		result = makeArrayResult(astate, CurrentMemoryContext);
	else
		result = (Datum) 0;

	return result;

}

static Datum transformExecOnClause(List	*on_clause, int *preferred_segment_num, bool iswritable)
{
	ArrayBuildState *astate;
	Datum		result;

	ListCell   *exec_location_opt;
	char	   *exec_location_str = NULL;
	int			value_int;
	Size		len;
	text		*t;

	/*
	 * Extract options from the statement node tree
	 * NOTE: as of now we only support one option in the ON clause
	 * and therefore more than one is an error (check here in case
	 * the sql parser isn't strict enough).
	 */
	foreach(exec_location_opt, on_clause)
	{
		DefElem    *defel = (DefElem *) lfirst(exec_location_opt);

		/* only one element is allowed! */
		if(exec_location_str)
			ereport(ERROR,
					(errcode(ERRCODE_SYNTAX_ERROR),
					 errmsg("ON clause must not have more than one element."),
							   errOmitLocation(true)));

		if (strcmp(defel->defname, "all") == 0)
		{
		  /* in HAWQ 2.0, we don't support ON ALL any more. */
      ereport(ERROR,
          (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
          errmsg("the ON ALL syntax for external tables is deprecated"),
          errOmitLocation(true)));

			/* result: "ALL_SEGMENTS" */
			/*
			exec_location_str = (char *) palloc(12 + 1);
			exec_location_str = "ALL_SEGMENTS";
			*preferred_segment_num = GetAllWorkerHostNum();
			*/
		}
		else if (strcmp(defel->defname, "hostname") == 0)
		{
		  /* in HAWQ 2.0, we don't support ON HOST any more. */
      ereport(ERROR,
          (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
          errmsg("the ON HOST syntax for external tables is deprecated"),
          errOmitLocation(true)));

			/* result: "HOST:<hostname>" */
			/*
			value_str = strVal(defel->arg);
			exec_location_str = (char *) palloc(5 + 1 + strlen(value_str) + 1);
			sprintf((char *) exec_location_str, "HOST:%s", value_str);
			*preferred_segment_num = GetAllWorkerHostNum();
			*/
		}
		else if (strcmp(defel->defname, "eachhost") == 0)
		{
		  /* in HAWQ 2.0, we don't support EACHHOST any more. */
      ereport(ERROR,
          (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
          errmsg("the ON EACHHOST syntax for external tables is deprecated"),
          errOmitLocation(true)));

			/* result: "PER_HOST" */
			/*
			exec_location_str = (char *) palloc(8 + 1);
			exec_location_str = "PER_HOST";
			*preferred_segment_num = GetAllWorkerHostNum();
			*/
		}
		else if (strcmp(defel->defname, "master") == 0)
		{
			if(iswritable){
			  ereport(ERROR,
	 	      (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
			    errmsg("the ON master syntax for writable external tables is deprecated"),
		      errOmitLocation(true)));
			}
			/* result: "MASTER_ONLY" */
			exec_location_str = (char *) palloc(11 + 1);
			exec_location_str = "MASTER_ONLY";
		  *preferred_segment_num = -1;
		}
		else if (strcmp(defel->defname, "segment") == 0)
		{
			if(iswritable){
			  ereport(ERROR,
				  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
			    errmsg("the ON segment syntax for writable external tables is deprecated"),
	        errOmitLocation(true)));
			}
			/* result: "SEGMENT_ID:<segid>" */
			value_int = intVal(defel->arg);
			exec_location_str = (char *) palloc(10 + 1 + 8 + 1);
			sprintf((char *) exec_location_str, "SEGMENT_ID:%d", value_int);
			*preferred_segment_num = value_int + 1;
		}
		else if (strcmp(defel->defname, "random") == 0)
		{
			/* result: "TOTAL_SEGS:<number>" */
			value_int = intVal(defel->arg);
			exec_location_str = (char *) palloc(10 + 1 + 8 + 1);
			sprintf((char *) exec_location_str, "TOTAL_SEGS:%d", value_int);
			*preferred_segment_num = value_int;
		}
		else
		{
			ereport(ERROR,
					(errcode(ERRCODE_GP_INTERNAL_ERROR),
					 errmsg("Unknown location code for EXECUTE in tablecmds."),
							   errOmitLocation(true)));
		}
	}

	/* convert to text[] */
	astate = NULL;
	len = VARHDRSZ + strlen(exec_location_str);
	t = (text *) palloc(len + 1);
	SET_VARSIZE(t, len);
	sprintf((char *) VARDATA(t), "%s", exec_location_str);


	astate = accumArrayResult(astate, PointerGetDatum(t),
							  false, TEXTOID,
							  CurrentMemoryContext);

	if (astate)
		result = makeArrayResult(astate, CurrentMemoryContext);
	else
		result = (Datum) 0;

	return result;
}

/*
 * transform format name to format code and validate that
 * the format is supported. Currently the only supported formats
 * are "text" (type 't') ,"csv" (type 'c') and "custom" (type 'b')
 */
static char transformFormatType(char *formatname)
{
	char	result = '\0';

	if(pg_strcasecmp(formatname, "text") == 0)
		result = 't';
	else if(pg_strcasecmp(formatname, "csv") == 0)
		result = 'c';
	else if(pg_strcasecmp(formatname, "custom") == 0)
		result = 'b';
	else
		ereport(ERROR,
				(errcode(ERRCODE_SYNTAX_ERROR),
				 errmsg("unsupported format '%s'", formatname),
				 errhint("available formats are \"text\", \"csv\", or \"custom\""),
						   errOmitLocation(true)));

	return result;
}


/*
 * Transform the FORMAT options into a text field. Parse the
 * options and validate them for their respective format type.
 *
 * The result is a text field that includes the format string.
 */
static Datum transformFormatOpts(char formattype, List *formatOpts, int numcols, bool iswritable)
{
	ListCell   *option;
	Datum		result;
	char *format_str = NULL;
	char *delim = NULL;
	char *null_print = NULL;
	char *quote = NULL;
	char *escape = NULL;
	char *eol_str = NULL;
	char *formatter = NULL;
	bool header_line = false;
	bool fill_missing = false;
	List *force_notnull = NIL;
	List *force_quote = NIL;
	Size len;
	StringInfoData fnn, fq, nl;

	Assert(fmttype_is_custom(formattype) || 
		   fmttype_is_text(formattype) ||
		   fmttype_is_csv(formattype));
	
	/* Extract options from the statement node tree */
	if (fmttype_is_text(formattype) || fmttype_is_csv(formattype))
	{
		foreach(option, formatOpts)
		{
			DefElem    *defel = (DefElem *) lfirst(option);

			if (strcmp(defel->defname, "delimiter") == 0)
			{
				if (delim)
					ereport(ERROR,
							(errcode(ERRCODE_SYNTAX_ERROR),
							 errmsg("conflicting or redundant options"),
									   errOmitLocation(true)));
				delim = strVal(defel->arg);
			}
			else if (strcmp(defel->defname, "null") == 0)
			{
				if (null_print)
					ereport(ERROR,
							(errcode(ERRCODE_SYNTAX_ERROR),
							 errmsg("conflicting or redundant options"),
									   errOmitLocation(true)));
				null_print = strVal(defel->arg);
			}
			else if (strcmp(defel->defname, "header") == 0)
			{
				if (header_line)
					ereport(ERROR,
							(errcode(ERRCODE_SYNTAX_ERROR),
							 errmsg("conflicting or redundant options"),
									   errOmitLocation(true)));
				header_line = intVal(defel->arg);
			}
			else if (strcmp(defel->defname, "quote") == 0)
			{
				if (quote)
					ereport(ERROR,
							(errcode(ERRCODE_SYNTAX_ERROR),
							 errmsg("conflicting or redundant options"),
									   errOmitLocation(true)));
				quote = strVal(defel->arg);
			}
			else if (strcmp(defel->defname, "escape") == 0)
			{
				if (escape)
					ereport(ERROR,
							(errcode(ERRCODE_SYNTAX_ERROR),
							 errmsg("conflicting or redundant options"),
									   errOmitLocation(true)));
				escape = strVal(defel->arg);
			}
			else if (strcmp(defel->defname, "force_notnull") == 0)
			{
				if (force_notnull)
					ereport(ERROR,
							(errcode(ERRCODE_SYNTAX_ERROR),
							 errmsg("conflicting or redundant options"),
									   errOmitLocation(true)));
					
				force_notnull = (List *) defel->arg;
			}
			else if (strcmp(defel->defname, "force_quote") == 0)
			{
				if (force_quote)
					ereport(ERROR,
							(errcode(ERRCODE_SYNTAX_ERROR),
							 errmsg("conflicting or redundant options"),
									   errOmitLocation(true)));
					
				force_quote = (List *) defel->arg;
			}
			else if (strcmp(defel->defname, "fill_missing_fields") == 0)
			{
				if (fill_missing)
					ereport(ERROR,
							(errcode(ERRCODE_SYNTAX_ERROR),
							 errmsg("conflicting or redundant options"),
									   errOmitLocation(true)));
				fill_missing = intVal(defel->arg);
			}
			else if (strcmp(defel->defname, "newline") == 0)
			{
				if (eol_str)
					ereport(ERROR,
							(errcode(ERRCODE_SYNTAX_ERROR),
							 errmsg("conflicting or redundant options"),
									   errOmitLocation(true)));
				eol_str = strVal(defel->arg);
			}
			else if (strcmp(defel->defname, "formatter") == 0)
			{
				ereport(ERROR,
						(errcode(ERRCODE_SYNTAX_ERROR),
						 errmsg("formatter option only valid for custom formatters"),
						 errOmitLocation(true)));
			}
			else
				elog(ERROR, "option \"%s\" not recognized",
					 defel->defname);
		}

		/*
		 * Set defaults
		 */
		if (!delim)
			delim = fmttype_is_csv(formattype) ? "," : "\t";

		if (!null_print)
			null_print = fmttype_is_csv(formattype) ? "" : "\\N";

		if (fmttype_is_csv(formattype))
		{
			if (!quote)
				quote = "\"";
			if (!escape)
				escape = quote;
		}

		if (!fmttype_is_csv(formattype) && !escape)
			escape = "\\";			/* default escape for text mode */

		/*
		 * re-construct the FORCE NOT NULL list string.
		 * TODO: is there no existing util function that does this? can't find.
		 */
		if(force_notnull)
		{
			ListCell   *l;
			bool 		is_first_col = true;

			initStringInfo(&fnn);
			appendStringInfo(&fnn, " force not null");

			foreach(l, force_notnull)
			{
				const char	   *col_name = strVal(lfirst(l));

				appendStringInfo(&fnn, (is_first_col ? " %s" : ",%s"),
								 quote_identifier(col_name));
				is_first_col = false;
			}
		}

		/*
		 * re-construct the FORCE QUOTE list string.
		 */
		if(force_quote)
		{
			ListCell   *l;
			bool 		is_first_col = true;

			initStringInfo(&fq);
			appendStringInfo(&fq, " force quote");

			foreach(l, force_quote)
			{
				const char	   *col_name = strVal(lfirst(l));

				appendStringInfo(&fq, (is_first_col ? " %s" : ",%s"),
								 quote_identifier(col_name));
				is_first_col = false;
			}
		}

		if(eol_str)
		{
			initStringInfo(&nl);
			appendStringInfo(&nl, " newline '%s'", eol_str);
		}
		
		/* verify all user supplied control char combinations are legal */
		ValidateControlChars(false,
							 !iswritable,
							 fmttype_is_csv(formattype),
							 delim,
							 null_print,
							 quote,
							 escape,
							 force_quote,
							 force_notnull,
							 header_line,
							 fill_missing,
							 eol_str,
							 numcols);
	
		/*
		 * build the format option string that will get stored in the catalog.
		 */
	
		len = 9 + 1 + 1 + strlen(delim) + 1 +		/* "delimiter 'x' of 'off'" */
			  1 +									/* space					*/
			  4 + 1 + 1 + strlen(null_print) + 1 +	/* "null 'str'"				*/
			  1 +									/* space					*/
			  6 + 1 + 1 + strlen(escape) + 1;		/* "escape 'c' or 'off' 	*/
	
		if (fmttype_is_csv(formattype))
			len +=	1 +								/* space					*/
					5 + 1 + 3;						/* "quote 'x'"				*/
	
		len += header_line ? strlen(" header") : 0;
		len += fill_missing ? strlen(" fill missing fields") : 0;
		len += force_notnull ? strlen(fnn.data) : 0;
		len += force_quote ? strlen(fq.data) : 0;
		len += (eol_str ? (1 + 7 + 1 + 1 + strlen(eol_str) + 1) : 0); /* space x 2, newline 'xx/xxxx' */
	
		/* +1 leaves room for sprintf's trailing null */
		format_str = (char *) palloc(len + 1);
	
		if(fmttype_is_text(formattype))
		{
			sprintf((char *) format_str, "delimiter '%s' null '%s' escape '%s'%s%s%s",
					delim, null_print, escape, (header_line ? " header":""),
					(fill_missing ? " fill missing fields":""), (eol_str ?  nl.data : ""));
		}
		else if (fmttype_is_csv(formattype))
		{
			
			sprintf((char *) format_str, "delimiter '%s' null '%s' escape '%s' quote '%s'%s%s%s%s%s",
					delim, null_print, escape, quote, (header_line ? " header" : ""),
					(fill_missing ? " fill missing fields":""),
					(force_notnull ? fnn.data :""), (force_quote ? fq.data :""),
					(eol_str ?  nl.data : ""));
		}
		else
		{
			/* should never happen */
			Assert(false);
		}

	}
	else
	{
		/* custom format */
		
		int 		len = 0;
		const int	maxlen = 8 * 1024 - 1;
		StringInfoData key_modified;
		
		initStringInfo(&key_modified);
		
		format_str = (char *) palloc0(maxlen + 1);
		
		foreach(option, formatOpts)
		{
			DefElem    *defel = (DefElem *) lfirst(option);
			char	   *key = defel->defname;
			bool need_free_value = false;
			char	   *val = defGetString(defel, &need_free_value);
			
			if (strcmp(key, "formatter") == 0)
			{
				if (formatter)
					ereport(ERROR,
							(errcode(ERRCODE_SYNTAX_ERROR),
							 errmsg("conflicting or redundant options"),
									   errOmitLocation(true)));
					
				formatter = strVal(defel->arg);
			}
			
			/* MPP-14467 - replace any space chars with meta char */
			resetStringInfo(&key_modified);
			appendStringInfoString(&key_modified, key);
			replaceStringInfoString(&key_modified, " ", "<gpx20>");
			
			sprintf((char *) format_str + len, "%s '%s' ", key_modified.data, val);
			len += strlen(key_modified.data) + strlen(val) + 4;
			
			if (need_free_value)
			{
				pfree(val);
				val = NULL;
			}

			AssertImply(need_free_value, NULL == val);

			if (len > maxlen)
				ereport(ERROR,
						(errcode(ERRCODE_SYNTAX_ERROR),
						 errmsg("format options must be less than %d bytes in size", maxlen),
								   errOmitLocation(true)));			
		}
		
		if(!formatter)
			ereport(ERROR,
					(errcode(ERRCODE_SYNTAX_ERROR),
					 errmsg("no formatter function specified"),
							   errOmitLocation(true)));
	}
	

	/* convert c string to text datum */
	result = DirectFunctionCall1(textin, CStringGetDatum(format_str));

	/* clean up */
	if (format_str) pfree(format_str);
	if (force_notnull) pfree(fnn.data);
	if (force_quote) pfree(fq.data);
	if (eol_str) pfree(nl.data);
	
	return result;

}

/* ALTER TABLE EXCHANGE
 *
 * NB different signature from non-partitioned table Prep functions.
 */
static void
ATPrepExchange(Relation rel, AlterPartitionCmd *pc)
{
	PgPartRule   	   	*prule 	= NULL;
	Relation			 oldrel = NULL;
	Relation			 newrel = NULL;
	
	if (Gp_role == GP_ROLE_DISPATCH)
	{
		AlterPartitionId *pid = (AlterPartitionId *) pc->partid;
		bool				is_split;
		
		is_split = ((AlterPartitionCmd *)pc->arg2)->arg2 != NULL;
		
		if (is_split)
			return;
		
		prule = get_part_rule(rel, pid, true, true,
							  CurrentMemoryContext, NULL, false);
		if (prule)
		{
			/* cannot exchange a hash partition */
			if ('h' == prule->pNode->part->parkind)
				ereport(ERROR,
						(errcode(ERRCODE_DEPENDENT_OBJECTS_STILL_EXIST),
						 errmsg("cannot exchange HASH partition%s "
								"of relation \"%s\"", prule->partIdStr,
								RelationGetRelationName(rel))));
		}
		oldrel = heap_open(prule->topRule->parchildrelid,
						   AccessExclusiveLock);
		newrel = heap_openrv((RangeVar *)pc->arg1,
							 AccessExclusiveLock);
	}
	else
	{
		oldrel = heap_openrv((RangeVar *)pc->partid,
							 AccessExclusiveLock);
		newrel = heap_openrv((RangeVar *)pc->arg1,
							 AccessExclusiveLock);
		
	}
	ATSimplePermissions(rel, false);
	ATSimplePermissions(oldrel, false);
	ATSimplePermissions(newrel, false);
	
	/* Check that old and new look the same, error if not. */
	is_exchangeable(rel, oldrel, newrel, true);
	
	heap_close(oldrel, NoLock);
	heap_close(newrel, NoLock);
}

/*
 * Return a palloc'd string representing an AlterTableCmd type for use
 * in a message pattern like "can't %s a partitioned table".  The default
 * return string is "alter".
 *
 * This may pose a challenge for localization.  
 */
static
char *alterTableCmdString(AlterTableType subtype)
{
	char *cmdstring = NULL;
	
	switch (subtype)
	{
		case AT_AddColumn: /* add column */
		case AT_AddColumnRecurse: /* internal to command/tablecmds.c*/
			cmdstring = pstrdup("add a column to");
			break;
			
		case AT_ColumnDefault: /* alter column default */
			cmdstring = pstrdup("alter a column default of");
			break;
			
		case AT_DropNotNull: /* alter column drop not null */
		case AT_SetNotNull: /* alter column set not null */
			cmdstring = pstrdup("alter a column null setting of");
			break;
			
		case AT_SetStatistics: /* alter column statistics */
		case AT_SetStorage: /* alter column storage */
			break;
			
		case AT_DropColumn: /* drop column */
		case AT_DropColumnRecurse: /* internal to commands/tablecmds.c */
			cmdstring = pstrdup("drop a column from");
			break;
			
		case AT_AddIndex: /* add index */
		case AT_ReAddIndex: /* internal to commands/tablecmds.c */
			break;
			
		case AT_AddConstraint: /* add constraint */
		case AT_AddConstraintRecurse: /* internal to commands/tablecmds.c */
			cmdstring = pstrdup("add a constraint to");
			break;
			
		case AT_ProcessedConstraint: /* pre-processed add constraint (local in parser/analyze.c) */
			break;
			
		case AT_DropConstraint: /* drop constraint */
			cmdstring = pstrdup("drop a constraint from");
			break;
			
		case AT_DropConstraintQuietly: /* drop constraint, no error/warning (local in commands/tablecmds.c) */
			break;
			
		case AT_AlterColumnType: /* alter column type */
			cmdstring = pstrdup("alter a column datatype of");
			break;
			
		case AT_ChangeOwner: /* change owner */
			cmdstring = pstrdup("alter the owner of");
			break;
			
		case AT_ClusterOn: /* CLUSTER ON */
		case AT_DropCluster: /* SET WITHOUT CLUSTER */
			break;
			
		case AT_DropOids: /* SET WITHOUT OIDS */
			cmdstring = pstrdup("alter the oid setting of");
			break;
			
		case AT_SetTableSpace: /* SET TABLESPACE */
		case AT_SetRelOptions: /* SET (...) -- AM specific parameters */
		case AT_ResetRelOptions: /* RESET (...) -- AM specific parameters */
			break;
			
		case AT_EnableTrig: /* ENABLE TRIGGER name */
		case AT_DisableTrig: /* DISABLE TRIGGER name */
		case AT_EnableTrigAll: /* ENABLE TRIGGER ALL */
		case AT_DisableTrigAll: /* DISABLE TRIGGER ALL */
		case AT_EnableTrigUser: /* ENABLE TRIGGER USER */
		case AT_DisableTrigUser: /* DISABLE TRIGGER USER */
			cmdstring = pstrdup("enable or disable triggers on");
			break;
			
		case AT_AddInherit: /* INHERIT parent */
		case AT_DropInherit: /* NO INHERIT parent */
			cmdstring = pstrdup("alter inheritance on");
			break;
			
		case AT_SetDistributedBy: /* SET DISTRIBUTED BY */
			break;
			
		case AT_PartAdd: /* Add */
		case AT_PartAlter: /* Alter */
		case AT_PartCoalesce: /* Coalesce */
		case AT_PartDrop: /* Drop */
			break;
			
		case AT_PartExchange: /* Exchange */
			cmdstring = pstrdup("exchange a part into");
			break;
			
		case AT_PartMerge: /* Merge */
			cmdstring = pstrdup("merge parts of");
			break;
			
		case AT_PartModify: /* Modify */
		case AT_PartRename: /* Rename */
		case AT_PartSetTemplate: /* Set Subpartition Template */
			break;
			
		case AT_PartSplit: /* Split */
			cmdstring = pstrdup("split parts of");
			break;
			
		case AT_PartTruncate: /* Truncate */
		case AT_PartAddInternal: /* CREATE TABLE time partition addition */
			break;
	}
	
	if ( cmdstring == NULL )
	{
		cmdstring = pstrdup("alter");
	}
	
	return cmdstring;
}

static void 
InvokeProtocolValidation(Oid procOid, char *procName, bool iswritable, List *locs, List* fmtopts)
{
	
	ExtProtocolValidatorData   *validator_data;
	FmgrInfo				   *validator_udf;
	FunctionCallInfoData		fcinfo;
	
	validator_data = (ExtProtocolValidatorData *) palloc0 (sizeof(ExtProtocolValidatorData));
	validator_udf = palloc(sizeof(FmgrInfo));
	fmgr_info(procOid, validator_udf);
	
	validator_data->type 		= T_ExtProtocolValidatorData;
	validator_data->url_list 	= locs;
	validator_data->format_opts = fmtopts;
	validator_data->errmsg		= NULL;
	validator_data->direction 	= (iswritable ? EXT_VALIDATE_WRITE :
											    EXT_VALIDATE_READ);
	
	InitFunctionCallInfoData(/* FunctionCallInfoData */ fcinfo, 
							 /* FmgrInfo */ validator_udf, 
							 /* nArgs */ 0, 
							 /* Call Context */ (Node *) validator_data, 
							 /* ResultSetInfo */ NULL);
	
	/* invoke validator. if this function returns - validation passed */
	FunctionCallInvoke(&fcinfo);

	/* We do not expect a null result */
	if (fcinfo.isnull)
		elog(ERROR, "validator function %u returned NULL", 
					fcinfo.flinfo->fn_oid);

	pfree(validator_data);
	pfree(validator_udf);
}
