/*
 * 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.
 */

/*-------------------------------------------------------------------------
 *
 * cluster.c
 *	  CLUSTER a table on an index.
 *
 * There is hardly anything left of Paul Brown's original implementation...
 *
 *
 * Portions Copyright (c) 2006-2008, Greenplum inc
 * Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
 * Portions Copyright (c) 1994-5, Regents of the University of California
 *
 *
 * IDENTIFICATION
 *	  $PostgreSQL: pgsql/src/backend/commands/cluster.c,v 1.154.2.2 2007/09/29 18:05:28 tgl Exp $
 *
 *-------------------------------------------------------------------------
 */
#include "postgres.h"

#include "access/genam.h"
#include "access/heapam.h"
#include "access/xact.h"
#include "catalog/catalog.h"
#include "catalog/catquery.h"
#include "catalog/dependency.h"
#include "catalog/heap.h"
#include "catalog/index.h"
#include "catalog/indexing.h"
#include "catalog/namespace.h"
#include "catalog/pg_attribute_encoding.h"
#include "catalog/pg_type.h"
#include "catalog/toasting.h"
#include "catalog/aoseg.h"
#include "catalog/aoblkdir.h"
#include "catalog/pg_tablespace.h"
#include "commands/cluster.h"
#include "commands/tablecmds.h"
#include "miscadmin.h"
#include "utils/acl.h"
#include "utils/fmgroids.h"
#include "utils/inval.h"
#include "utils/lsyscache.h"
#include "utils/memutils.h"
#include "utils/syscache.h"
#include "utils/relcache.h"
#include "cdb/cdbvars.h"
#include "cdb/cdbdisp.h"
#include "cdb/cdboidsync.h"
#include "cdb/cdbpersistentfilesysobj.h"
#include "cdb/dispatcher.h"
#include "cdb/dispatcher.h"


/*
 * This struct is used to pass around the information on tables to be
 * clustered. We need this so we can make a list of them when invoked without
 * a specific table/index pair.
 */
typedef struct
{
	Oid			tableOid;
	Oid			indexOid;
} RelToCluster;


static bool cluster_rel(RelToCluster *rv, bool recheck, ClusterStmt *stmt, bool printError);
static void rebuild_relation(Relation OldHeap, Oid indexOid, ClusterStmt *stmt);
static void copy_heap_data(Oid OIDNewHeap, Oid OIDOldHeap, Oid OIDOldIndex);
static List *get_tables_to_cluster(MemoryContext cluster_context);



/*---------------------------------------------------------------------------
 * This cluster code allows for clustering multiple tables at once. Because
 * of this, we cannot just run everything on a single transaction, or we
 * would be forced to acquire exclusive locks on all the tables being
 * clustered, simultaneously --- very likely leading to deadlock.
 *
 * To solve this we follow a similar strategy to VACUUM code,
 * clustering each relation in a separate transaction. For this to work,
 * we need to:
 *	- provide a separate memory context so that we can pass information in
 *	  a way that survives across transactions
 *	- start a new transaction every time a new relation is clustered
 *	- check for validity of the information on to-be-clustered relations,
 *	  as someone might have deleted a relation behind our back, or
 *	  clustered one on a different index
 *	- end the transaction
 *
 * The single-relation case does not have any such overhead.
 *
 * We also allow a relation being specified without index.	In that case,
 * the indisclustered bit will be looked up, and an ERROR will be thrown
 * if there is no index with the bit set.
 *---------------------------------------------------------------------------
 */
void
cluster(ClusterStmt *stmt)
{
	if (stmt->relation != NULL)
	{
		/* This is the single-relation case. */
		Oid			tableOid,
					indexOid = InvalidOid;
		Relation	rel;
		RelToCluster rvtc;

		/* Find and lock the table */
		rel = heap_openrv(stmt->relation, AccessExclusiveLock);

		tableOid = RelationGetRelid(rel);

		/* Check permissions */
		if (!pg_class_ownercheck(tableOid, GetUserId()))
			aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_CLASS,
						   RelationGetRelationName(rel));

		/*
		 * Reject clustering a remote temp table ... their local buffer manager
		 * is not going to cope.
		 */
		if (isOtherTempNamespace(RelationGetNamespace(rel)))
			ereport(ERROR,
					(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
					 errmsg("cannot cluster temporary tables of other sessions")));

		if (stmt->indexname == NULL)
		{
			ListCell   *index;

			/* We need to find the index that has indisclustered set. */
			foreach(index, RelationGetIndexList(rel))
			{
				HeapTuple	idxtuple;
				Form_pg_index indexForm;
				cqContext	*idxcqCtx;

				indexOid = lfirst_oid(index);

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

				idxtuple = caql_getnext(idxcqCtx);

				if (!HeapTupleIsValid(idxtuple))
					elog(ERROR, "cache lookup failed for index %u", indexOid);
				indexForm = (Form_pg_index) GETSTRUCT(idxtuple);
				if (indexForm->indisclustered)
				{
					caql_endscan(idxcqCtx);
					break;
				}
				caql_endscan(idxcqCtx);

				indexOid = InvalidOid;
			}

			if (!OidIsValid(indexOid))
				ereport(ERROR,
						(errcode(ERRCODE_UNDEFINED_OBJECT),
						 errmsg("there is no previously clustered index for table \"%s\"",
								stmt->relation->relname),
						 errOmitLocation(true)));
		}
		else
		{
			/*
			 * The index is expected to be in the same namespace as the
			 * relation.
			 */
			indexOid = get_relname_relid(stmt->indexname,
										 rel->rd_rel->relnamespace);
			if (!OidIsValid(indexOid))
				ereport(ERROR,
						(errcode(ERRCODE_UNDEFINED_OBJECT),
					   errmsg("index \"%s\" for table \"%s\" does not exist",
							  stmt->indexname, stmt->relation->relname)));
		}

		/* All other checks are done in cluster_rel() */
		rvtc.tableOid = tableOid;
		rvtc.indexOid = indexOid;

		/* close relation, keep lock till commit */
		heap_close(rel, NoLock);

		/* Do the job */
		cluster_rel(&rvtc, false, stmt, true);

		if (Gp_role == GP_ROLE_DISPATCH)
		{
			dispatch_statement_node((Node *) stmt, NULL, NULL, NULL);
		}
	}
	else
	{
		/*
		 * This is the "multi relation" case. We need to cluster all tables
		 * that have some index with indisclustered set.
		 */
		MemoryContext cluster_context;
		List	   *rvs;
		ListCell   *rv;

		/*
		 * We cannot run this form of CLUSTER inside a user transaction block;
		 * we'd be holding locks way too long.
		 */
		PreventTransactionChain((void *) stmt, "CLUSTER");

		/*
		 * Create special memory context for cross-transaction storage.
		 *
		 * Since it is a child of PortalContext, it will go away even in case
		 * of error.
		 */
		cluster_context = AllocSetContextCreate(PortalContext,
												"Cluster",
												ALLOCSET_DEFAULT_MINSIZE,
												ALLOCSET_DEFAULT_INITSIZE,
												ALLOCSET_DEFAULT_MAXSIZE);

		/*
		 * Build the list of relations to cluster.	Note that this lives in
		 * cluster_context.
		 */
		rvs = get_tables_to_cluster(cluster_context);

		/* Commit to get out of starting transaction */
		CommitTransactionCommand();

		/* Ok, now that we've got them all, cluster them one by one */
		foreach(rv, rvs)
		{
			RelToCluster *rvtc = (RelToCluster *) lfirst(rv);

			/* Start a new transaction for each relation. */
			StartTransactionCommand();
			/* functions in indexes may want a snapshot set */
			ActiveSnapshot = CopySnapshot(GetTransactionSnapshot());

			if (Gp_role == GP_ROLE_DISPATCH)
				stmt->new_ind_oids = NIL; /* reset OID map for each iteration */

			bool dispatch = cluster_rel(rvtc, true, stmt, false);

			if (Gp_role == GP_ROLE_DISPATCH && dispatch)
			{

				stmt->relation = makeNode(RangeVar);
				stmt->relation->schemaname = get_namespace_name(get_rel_namespace(rvtc->tableOid));
				stmt->relation->relname = get_rel_name(rvtc->tableOid);
				dispatch_statement_node((Node *) stmt, NULL, NULL, NULL);
			}
			CommitTransactionCommand();
		}

		/* Start a new transaction for the cleanup work. */
		StartTransactionCommand();

		/* Clean up working storage */
		MemoryContextDelete(cluster_context);


	}


}

/*
 * cluster_rel
 *
 * This clusters the table by creating a new, clustered table and
 * swapping the relfilenodes of the new table and the old table, so
 * the OID of the original table is preserved.	Thus we do not lose
 * GRANT, inheritance nor references to this table (this was a bug
 * in releases thru 7.3).
 *
 * Also create new indexes and swap the filenodes with the old indexes the
 * same way we do for the relation.  Since we are effectively bulk-loading
 * the new table, it's better to create the indexes afterwards than to fill
 * them incrementally while we load the table.
 *
 * Note that we don't support clustering on an AO table. If printError is true,
 * this function errors out when the relation is an AO table. Otherwise,
 * this functions prints out a warning message when the relation is an AO table.
 */
static bool
cluster_rel(RelToCluster *rvtc, bool recheck, ClusterStmt *stmt, bool printError)
{
	Relation	OldHeap;

	/* Check for user-requested abort. */
	CHECK_FOR_INTERRUPTS();

	/*
	 * We grab exclusive access to the target rel and index for the duration
	 * of the transaction.	(This is redundant for the single-transaction
	 * case, since cluster() already did it.)  The index lock is taken inside
	 * check_index_is_clusterable.
	 */
	OldHeap = try_relation_open(rvtc->tableOid, AccessExclusiveLock, false);

	/* If the table has gone away, we can skip processing it */
	if (!OldHeap)
	{
		return false;
	}
	/*
	 * We don't support cluster on an AO table. We print out
	 * a warning/error to the user, and simply return.
	 */
	if (RelationIsAoRows(OldHeap) || RelationIsParquet(OldHeap))
	{
		int elevel = WARNING;
		
		if (printError)
			elevel = ERROR;
		
		ereport(elevel,
				(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
				 errmsg("cannot cluster append-only table \"%s\": not supported",
						RelationGetRelationName(OldHeap))));
		
		relation_close(OldHeap, AccessExclusiveLock);
		return false;
	}
	
	/*
	 * Since we may open a new transaction for each relation, we have to check
	 * that the relation still is what we think it is.
	 *
	 * If this is a single-transaction CLUSTER, we can skip these tests. We
	 * *must* skip the one on indisclustered since it would reject an attempt
	 * to cluster a not-previously-clustered index.
	 */
	if (recheck)
	{
		HeapTuple	tuple;
		Form_pg_index indexForm;
		cqContext	*idxcqCtx;

		/* Check that the user still owns the relation */
		if (!pg_class_ownercheck(rvtc->tableOid, GetUserId()))
		{
			relation_close(OldHeap, AccessExclusiveLock);
			return false;
		}

		/*
		 * Silently skip a temp table for a remote session.  Only doing this
		 * check in the "recheck" case is appropriate (which currently means
		 * somebody is executing a database-wide CLUSTER), because there is
		 * another check in cluster() which will stop any attempt to cluster
		 * remote temp tables by name.  There is another check in
		 * check_index_is_clusterable which is redundant, but we leave it for
		 * extra safety.
		 */
		if (isOtherTempNamespace(RelationGetNamespace(OldHeap)))
		{
			relation_close(OldHeap, AccessExclusiveLock);
			return false;		
		}

		/*
		 * Check that the index still exists
		 */
		if (0 == caql_getcount(
					NULL,
					cql("SELECT COUNT(*) FROM pg_class "
						" WHERE oid = :1 ",
						ObjectIdGetDatum(rvtc->indexOid))))
		{
			relation_close(OldHeap, AccessExclusiveLock);
			return false;
		}

		/*
		 * Check that the index is still the one with indisclustered set.
		 */
		idxcqCtx = caql_beginscan(
				NULL,
				cql("SELECT * FROM pg_index "
					" WHERE indexrelid = :1 ",
					ObjectIdGetDatum(rvtc->indexOid)));

		tuple = caql_getnext(idxcqCtx);

		if (!HeapTupleIsValid(tuple))	/* probably can't happen */
		{
			caql_endscan(idxcqCtx);
			relation_close(OldHeap, AccessExclusiveLock);
			return false;
		}
		indexForm = (Form_pg_index) GETSTRUCT(tuple);
		if (!indexForm->indisclustered)
		{
			caql_endscan(idxcqCtx);
			relation_close(OldHeap, AccessExclusiveLock);
			return false;
		}
		caql_endscan(idxcqCtx);

	}

	/* Check index is valid to cluster on */
	check_index_is_clusterable(OldHeap, rvtc->indexOid, recheck);

	/* rebuild_relation does all the dirty work */
	rebuild_relation(OldHeap, rvtc->indexOid, stmt);

	/* NB: rebuild_relation does heap_close() on OldHeap */
	return true;
}

/*
 * Verify that the specified index is a legitimate index to cluster on
 *
 * Side effect: obtains exclusive lock on the index.  The caller should
 * already have exclusive lock on the table, so the index lock is likely
 * redundant, but it seems best to grab it anyway to ensure the index
 * definition can't change under us.
 */
void
check_index_is_clusterable(Relation OldHeap, Oid indexOid, bool recheck)
{
	Relation	OldIndex;

	OldIndex = index_open(indexOid, AccessExclusiveLock);

	/*
	 * Check that index is in fact an index on the given relation
	 */
	if (OldIndex->rd_index == NULL ||
		OldIndex->rd_index->indrelid != RelationGetRelid(OldHeap))
		ereport(ERROR,
				(errcode(ERRCODE_WRONG_OBJECT_TYPE),
				 errmsg("\"%s\" is not an index for table \"%s\"",
						RelationGetRelationName(OldIndex),
						RelationGetRelationName(OldHeap))));

	/*
	 * Disallow clustering on incomplete indexes (those that might not index
	 * every row of the relation).	We could relax this by making a separate
	 * seqscan pass over the table to copy the missing rows, but that seems
	 * expensive and tedious.
	 */
	if (!heap_attisnull(OldIndex->rd_indextuple, Anum_pg_index_indpred))
		ereport(ERROR,
				(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
				 errmsg("cannot cluster on partial index \"%s\"",
						RelationGetRelationName(OldIndex))));

	if (!OldIndex->rd_am->amclusterable)
		ereport(ERROR,
				(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
				 errmsg("cannot cluster on index \"%s\" because access method does not support clustering",
						RelationGetRelationName(OldIndex))));

	if (!OldIndex->rd_am->amindexnulls)
	{
		AttrNumber	colno;

		/*
		 * If the AM doesn't index nulls, then it's a partial index unless we
		 * can prove all the rows are non-null.  Note we only need look at the
		 * first column; multicolumn-capable AMs are *required* to index nulls
		 * in columns after the first.
		 */
		colno = OldIndex->rd_index->indkey.values[0];
		if (colno > 0)
		{
			/* ordinary user attribute */
			if (!OldHeap->rd_att->attrs[colno - 1]->attnotnull)
				ereport(ERROR,
						(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
						 errmsg("cannot cluster on index \"%s\" because access method does not handle null values",
								RelationGetRelationName(OldIndex)),
						 recheck
						 ? errhint("You may be able to work around this by marking column \"%s\" NOT NULL, or use ALTER TABLE ... SET WITHOUT CLUSTER to remove the cluster specification from the table.",
								   NameStr(OldHeap->rd_att->attrs[colno - 1]->attname))
						 : errhint("You may be able to work around this by marking column \"%s\" NOT NULL.",
								   NameStr(OldHeap->rd_att->attrs[colno - 1]->attname))));
		}
		else if (colno < 0)
		{
			/* system column --- okay, always non-null */
		}
		else
			/* index expression, lose... */
			ereport(ERROR,
					(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
					 errmsg("cannot cluster on expressional index \"%s\" because its index access method does not handle null values",
							RelationGetRelationName(OldIndex))));
	}

	/*
	 * Disallow if index is left over from a failed CREATE INDEX CONCURRENTLY;
	 * it might well not contain entries for every heap row.
	 */
	if (!OldIndex->rd_index->indisvalid)
		ereport(ERROR,
				(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
				 errmsg("cannot cluster on invalid index \"%s\"",
						RelationGetRelationName(OldIndex))));

	/*
	 * Disallow clustering system relations.  This will definitely NOT work
	 * for shared relations (we have no way to update pg_class rows in other
	 * databases), nor for nailed-in-cache relations (the relfilenode values
	 * for those are hardwired, see relcache.c).  It might work for other
	 * system relations, but I ain't gonna risk it.
	 */
	if (IsSystemRelation(OldHeap))
		ereport(ERROR,
				(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
				 errmsg("\"%s\" is a system catalog",
						RelationGetRelationName(OldHeap))));

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

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

	/* Drop relcache refcnt on OldIndex, but keep lock */
	index_close(OldIndex, NoLock);
}

/*
 * mark_index_clustered: mark the specified index as the one clustered on
 *
 * With indexOid == InvalidOid, will mark all indexes of rel not-clustered.
 */
void
mark_index_clustered(Relation rel, Oid indexOid)
{
	HeapTuple	indexTuple;
	Form_pg_index indexForm;
	Relation	pg_index;
	ListCell   *index;
	cqContext  *idxcqCtx;

	/*
	 * If the index is already marked clustered, no need to do anything.
	 */
	if (OidIsValid(indexOid))
	{
		idxcqCtx = caql_beginscan(
				NULL,
				cql("SELECT * FROM pg_index "
					" WHERE indexrelid = :1 ",
					ObjectIdGetDatum(indexOid)));

		indexTuple = caql_getnext(idxcqCtx);

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

		if (indexForm->indisclustered)
		{
			caql_endscan(idxcqCtx);
			return;
		}

		caql_endscan(idxcqCtx);
	}

	/*
	 * Check each index of the relation and set/clear the bit as needed.
	 */
	pg_index = heap_open(IndexRelationId, RowExclusiveLock);

	foreach(index, RelationGetIndexList(rel))
	{
		cqContext	cqc;
		cqContext  *pcqCtx;
		Oid			thisIndexOid = lfirst_oid(index);

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

		indexTuple = caql_getfirst(
				pcqCtx,
				cql("SELECT * FROM pg_index "
					" WHERE indexrelid = :1 "
					" FOR UPDATE ",
					ObjectIdGetDatum(thisIndexOid)));

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

		/*
		 * Unset the bit if set.  We know it's wrong because we checked this
		 * earlier.
		 */
		if (indexForm->indisclustered)
		{
			indexForm->indisclustered = false;

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

			/* Ensure we see the update in the index's relcache entry */
			CacheInvalidateRelcacheByRelid(thisIndexOid);
		}
		else if (thisIndexOid == indexOid)
		{
			indexForm->indisclustered = true;

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

			/* Ensure we see the update in the index's relcache entry */
			CacheInvalidateRelcacheByRelid(thisIndexOid);
		}
		heap_freetuple(indexTuple);
	}

	heap_close(pg_index, RowExclusiveLock);
}

/*
 * rebuild_relation: rebuild an existing relation in index order
 *
 * OldHeap: table to rebuild --- must be opened and exclusive-locked!
 * indexOid: index to cluster by
 *
 * NB: this routine closes OldHeap at the right time; caller should not.
 */
static void
rebuild_relation(Relation OldHeap, Oid indexOid, ClusterStmt *stmt)
{
	Oid			tableOid = RelationGetRelid(OldHeap);
	Oid			tableSpace = OldHeap->rd_rel->reltablespace;
	Oid			OIDNewHeap;
	char		NewHeapName[NAMEDATALEN];
	ObjectAddress object;

	/* Mark the correct index as clustered */
	mark_index_clustered(OldHeap, indexOid);

	/* Close relcache entry, but keep lock until transaction commit */
	heap_close(OldHeap, NoLock);

	/*
	 * 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", tableOid);

	OIDNewHeap = make_new_heap(tableOid, NewHeapName, tableSpace,
					&stmt->oidInfo, true /* createAoBlockDirectory */);

	/*
	 * We don't need CommandCounterIncrement() because make_new_heap did it.
	 */

	/*
	 * Copy the heap data into the new table in the desired order.
	 */
	copy_heap_data(OIDNewHeap, tableOid, indexOid);

	/* To make the new heap's data visible (probably not needed?). */
	CommandCounterIncrement();

	/* Swap the physical files of the old and new heaps. */
	swap_relation_files(tableOid, OIDNewHeap, true);

	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 at this point).	We do not need CommandCounterIncrement()
	 * because reindex_relation does it.
	 */
	reindex_relation(tableOid, false, false, false, &stmt->new_ind_oids,
					 Gp_role == GP_ROLE_DISPATCH);
}

/*
 * Create the new table that we will fill with correctly-ordered data.
 */
Oid
make_new_heap(Oid OIDOldHeap, const char *NewName, Oid NewTableSpace,
			  TableOidInfo * oidInfo, bool createAoBlockDirectory)
{
	TupleDesc	OldHeapDesc,
				tupdesc;
	Oid			OIDNewHeap = InvalidOid;
	Relation	OldHeap;
	Oid 		tOid = InvalidOid;
	Oid			tiOid = InvalidOid;
	Oid			aOid = InvalidOid;
	Oid			aiOid = InvalidOid;
	Oid			*comptypeOid = NULL;
	Oid         blkdirOid = InvalidOid;
	Oid         blkdirIdxOid = InvalidOid;
	Oid			*toastComptypeOid = NULL;
	Oid			*aosegComptypeOid = NULL;
	Oid			*aoblkdirComptypeOid = NULL;
	HeapTuple	tuple;
	Datum		reloptions;
	bool		isNull;
	bool		is_part;
	cqContext  *pcqCtx;
	GpPolicy *targetPolicy = NULL;

	OldHeap = heap_open(OIDOldHeap, AccessExclusiveLock);
	OldHeapDesc = RelationGetDescr(OldHeap);

	is_part = !rel_needs_long_lock(OIDOldHeap);

	/* 
	 * Allocate new Oids for the heap, or check that all oids have been passed
	 * in from the master, depending on current GpRole.
	 */
	Assert(oidInfo);
	populate_oidInfo(oidInfo, NewTableSpace, OldHeap->rd_rel->relisshared, true);

	/* 
	 * Extract the oids from the oidInfo, this is used to ensure oid
	 * synchronization between the master and segments.  
	 *
	 * It is the responsibility of the caller to make sure the oidInfo is
	 * correctly dispatched.
	 */
	OIDNewHeap = oidInfo->relOid;
	tOid = oidInfo->toastOid;
	tiOid = oidInfo->toastIndexOid;
	toastComptypeOid = &oidInfo->toastComptypeOid;
	aOid = oidInfo->aosegOid;
	aiOid = oidInfo->aosegIndexOid;
	aosegComptypeOid = &oidInfo->aosegComptypeOid;
	comptypeOid = &oidInfo->comptypeOid;
	blkdirOid = oidInfo->aoblkdirOid;
	blkdirIdxOid = oidInfo->aoblkdirIndexOid;
	aoblkdirComptypeOid = &oidInfo->aoblkdirComptypeOid;

	/*
	 * Need to make a copy of the tuple descriptor, since
	 * heap_create_with_catalog modifies it.
	 */
	tupdesc = CreateTupleDescCopyConstr(OldHeapDesc);

	/*
	 * Use options of the old heap for new heap.
	 */
	pcqCtx = caql_beginscan(
			NULL,
			cql("SELECT * FROM pg_class "
				" WHERE oid = :1 ",
				ObjectIdGetDatum(OIDOldHeap)));

	tuple = caql_getnext(pcqCtx);

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

	reloptions = caql_getattr(pcqCtx, Anum_pg_class_reloptions, &isNull);

	if (isNull)
		reloptions = (Datum) 0;

	targetPolicy = GpPolicyFetch(CurrentMemoryContext, OIDOldHeap);
	Assert(targetPolicy);
	OIDNewHeap = heap_create_with_catalog(NewName,
										  RelationGetNamespace(OldHeap),
										  NewTableSpace,
										  OIDNewHeap,
										  OldHeap->rd_rel->relowner,
										  tupdesc,
										  OldHeap->rd_rel->relam,
										  OldHeap->rd_rel->relkind,
										  OldHeap->rd_rel->relstorage,
										  OldHeap->rd_rel->relisshared,
										  true,
										  /* bufferPoolBulkLoad */ false,
										  0,
										  ONCOMMIT_NOOP,
                                          targetPolicy,                         /*CDB*/
										  reloptions,
										  allowSystemTableModsDDL,
										  comptypeOid,
						 				  /* persistentTid */ NULL,
						 				  /* persistentSerialNum */ NULL);

	pfree(targetPolicy);

	if(oidInfo)
		oidInfo->relOid = OIDNewHeap;

	caql_endscan(pcqCtx);

	/*
	 * Advance command counter so that the newly-created relation's catalog
	 * tuples will be visible to heap_open.
	 */
	CommandCounterIncrement();

	/*
	 * If necessary, create a TOAST table for the new relation, or an Append
	 * Only segment table. Note that AlterTableCreateXXXTable ends with
	 * CommandCounterIncrement(), so that the new tables will be visible for
	 * insertion.
	 */
	AlterTableCreateToastTableWithOid(OIDNewHeap, tOid, tiOid,
									  toastComptypeOid, is_part);
	AlterTableCreateAoSegTableWithOid(OIDNewHeap, aOid, aiOid,
									  aosegComptypeOid, is_part);

    if ( createAoBlockDirectory )
    {
	    AlterTableCreateAoBlkdirTableWithOid(OIDNewHeap, blkdirOid, blkdirIdxOid,
										 aoblkdirComptypeOid, is_part);
    }

	cloneAttributeEncoding(OIDOldHeap,
						   OIDNewHeap,
						   RelationGetNumberOfAttributes(OldHeap));

	heap_close(OldHeap, NoLock);

	return OIDNewHeap;
}

/*
 * Do the physical copying of heap data.
 */
static void
copy_heap_data(Oid OIDNewHeap, Oid OIDOldHeap, Oid OIDOldIndex)
{
	Relation	NewHeap,
				OldHeap,
				OldIndex;
	TupleDesc	oldTupDesc;
	TupleDesc	newTupDesc;
	int			natts;
	Datum	   *values;
	bool	   *isnull;
	IndexScanDesc scan;
	HeapTuple	tuple;

	/*
	 * Open the relations we need.
	 */
	NewHeap = heap_open(OIDNewHeap, AccessExclusiveLock);
	OldHeap = heap_open(OIDOldHeap, AccessExclusiveLock);
	OldIndex = index_open(OIDOldIndex, AccessExclusiveLock);

	/*
	 * Their tuple descriptors should be exactly alike, but here we only need
	 * assume that they have the same number of columns.
	 */
	oldTupDesc = RelationGetDescr(OldHeap);
	newTupDesc = RelationGetDescr(NewHeap);
	Assert(newTupDesc->natts == oldTupDesc->natts);

	/* Preallocate values/nulls arrays */
	natts = newTupDesc->natts;
	values = (Datum *) palloc0(natts * sizeof(Datum));
	isnull = (bool *) palloc0(natts * sizeof(bool));

	/*
	 * Scan through the OldHeap on the OldIndex and copy each tuple into the
	 * NewHeap.
	 */
	scan = index_beginscan(OldHeap, OldIndex,
						   SnapshotNow, 0, (ScanKey) NULL);

	while ((tuple = index_getnext(scan, ForwardScanDirection)) != NULL)
	{
		/*
		 * We cannot simply pass the tuple to heap_insert(), for several
		 * reasons:
		 *
		 * 1. heap_insert() will overwrite the commit-status fields of the
		 * tuple it's handed.  This would trash the source relation, which is
		 * bad news if we abort later on.  (This was a bug in releases thru
		 * 7.0)
		 *
		 * 2. We'd like to squeeze out the values of any dropped columns, both
		 * to save space and to ensure we have no corner-case failures. (It's
		 * possible for example that the new table hasn't got a TOAST table
		 * and so is unable to store any large values of dropped cols.)
		 *
		 * 3. The tuple might not even be legal for the new table; this is
		 * currently only known to happen as an after-effect of ALTER TABLE
		 * SET WITHOUT OIDS.
		 *
		 * So, we must reconstruct the tuple from component Datums.
		 */
		HeapTuple	copiedTuple;
		int			i;

		heap_deform_tuple(tuple, oldTupDesc, values, isnull);

		/* Be sure to null out any dropped columns */
		for (i = 0; i < natts; i++)
		{
			if (newTupDesc->attrs[i]->attisdropped)
				isnull[i] = true;
		}

		copiedTuple = heap_form_tuple(newTupDesc, values, isnull);

		/* Preserve OID, if any */
		if (NewHeap->rd_rel->relhasoids)
			HeapTupleSetOid(copiedTuple, HeapTupleGetOid(tuple));

		simple_heap_insert(NewHeap, copiedTuple);

		heap_freetuple(copiedTuple);

		CHECK_FOR_INTERRUPTS();
	}

	index_endscan(scan);

	pfree(values);
	pfree(isnull);

	index_close(OldIndex, NoLock);
	heap_close(OldHeap, NoLock);
	heap_close(NewHeap, NoLock);
}

/*
 * Change dependency links for objects that are being swapped.
 *
 * 'tabletype' can be "TOAST table", "aoseg", "aoblkdir".
 * It is used for printing error messages.
 */
static void
changeDependencyLinks(Oid baseOid1, Oid baseOid2, Oid oid1, Oid oid2,
					  const char *tabletype)
{
	ObjectAddress baseobject, newobject;
	long		count;

	/* Delete old dependencies */
	if (oid1)
	{
		count = deleteDependencyRecordsFor(RelationRelationId, oid1);
		if (count != 1)
			elog(ERROR, "expected one dependency record for %s table, found %ld",
				 tabletype, count);
	}
	
	if (oid2)
	{
		count = deleteDependencyRecordsFor(RelationRelationId, oid2);
		if (count != 1)
			elog(ERROR, "expected one dependency record for %s table, found %ld",
				 tabletype, count);
	}

	/* Register new dependencies */
	baseobject.classId = RelationRelationId;
	baseobject.objectSubId = 0;
	newobject.classId = RelationRelationId;
	newobject.objectSubId = 0;
	
	if (oid1)
	{
		baseobject.objectId = baseOid1;
		newobject.objectId = oid1;
		recordDependencyOn(&newobject, &baseobject, DEPENDENCY_INTERNAL);
	}
	
	if (oid2)
	{
		baseobject.objectId = baseOid2;
		newobject.objectId = oid2;
		recordDependencyOn(&newobject, &baseobject, DEPENDENCY_INTERNAL);
	}
}

/*
 * Swap the physical files of two given relations.
 *
 * We swap the physical identity (reltablespace and relfilenode) while
 * keeping the same logical identities of the two relations.
 *
 * Also swap any TOAST links, so that the toast data moves along with
 * the main-table data. GPDB: also swap aoseg, aoblkdir links.
 */
void
swap_relation_files(Oid r1, Oid r2, bool swap_stats)
{
	Relation	relRelation;
	HeapTuple	reltup1,
			reltup2, reltup0;
	Form_pg_class relform1,
				relform2;
	Oid			swaptemp;
	char		swapchar;
	bool		isAO1, isAO2;
	cqContext	cqc1;
	cqContext	cqc2;
	cqContext  *pcqCtx1;
	cqContext  *pcqCtx2;

	/* 
	 * We need writable copies of both pg_class tuples.
	 */
	relRelation = heap_open(RelationRelationId, RowExclusiveLock);

	/* NOTE: jic 20120925 a bit of a trick here.  Normally, to update
	 * a single tuple, the preferred method is caql_getfirst(), which
	 * returns a writeable copy.  However, in this case, we use
	 * caql_beginscan() and copy it manually.  We use the caql context
	 * for the beginscan/endscan block to update *both* tuples,
	 * because it is cheaper than two single updates
	 */
	pcqCtx1 = caql_beginscan(
			caql_addrel(cqclr(&cqc1), relRelation),
			cql("SELECT * FROM pg_class "
				" WHERE oid = :1 "
				" FOR UPDATE ",
				ObjectIdGetDatum(r1)));

	reltup0 = caql_getnext(pcqCtx1); /* this is the real "current"
									  * tuple for this context */

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

	/* copy the tuple so we can update it */
	reltup1 = heap_copytuple(reltup0);

	if (!HeapTupleIsValid(reltup1))
		elog(ERROR, "cache lookup failed for relation %u", r1);
	relform1 = (Form_pg_class) GETSTRUCT(reltup1);

	pcqCtx2 = caql_addrel(cqclr(&cqc2), relRelation);

	reltup2 = caql_getfirst(
			pcqCtx2,	
			cql("SELECT * FROM pg_class "
				" WHERE oid = :1 "
				" FOR UPDATE ",
				ObjectIdGetDatum(r2)));

	if (!HeapTupleIsValid(reltup2))
		elog(ERROR, "cache lookup failed for relation %u", r2);
	relform2 = (Form_pg_class) GETSTRUCT(reltup2);
	
	isAO1 = (relform1->relstorage == RELSTORAGE_AOROWS ||
			 relform1->relstorage == RELSTORAGE_PARQUET);
	isAO2 = (relform2->relstorage == RELSTORAGE_AOROWS ||
			 relform2->relstorage == RELSTORAGE_PARQUET);

	if (Debug_persistent_print)
		elog(Persistent_DebugPrintLevel(), 
			 "swap_relation_files (#1): ENTER relation '%s', relation id %u, relfilenode %u, reltablespace %u, relstorage '%c'",
			 relform1->relname.data,
			 r1,
			 relform1->relfilenode,
			 relform1->reltablespace,
			 relform1->relstorage);
	if (Debug_persistent_print)
		elog(Persistent_DebugPrintLevel(), 
			 "swap_relation_files (#2): ENTER relation '%s', relation id %u, relfilenode %u, reltablespace %u, relstorage '%c'",
			 relform2->relname.data,
			 r2,
			 relform2->relfilenode,
			 relform2->reltablespace,
			 relform2->relstorage);

	/*
	 * Actually swap the fields in the two tuples
	 */
	swaptemp = relform1->relfilenode;
	relform1->relfilenode = relform2->relfilenode;
	relform2->relfilenode = swaptemp;

	swaptemp = relform1->reltablespace;
	relform1->reltablespace = relform2->reltablespace;
	relform2->reltablespace = swaptemp;

	swaptemp = relform1->reltoastrelid;
	relform1->reltoastrelid = relform2->reltoastrelid;
	relform2->reltoastrelid = swaptemp;

	/* we should not swap reltoastidxid */

	/*
	 * Swap the AO auxiliary relations and their indexes. Unlike the toast
	 * relations, we need to swap the index oids as well.
	 */
	if (isAO1 && isAO2)
	{
		SwapAppendonlyEntries(r1, r2);
	}
	else if (isAO1)
	{
		TransferAppendonlyEntry(r1, r2);
	}
	else if (isAO2)
	{
		TransferAppendonlyEntry(r2, r1);
	}
	
	/* swap size statistics too, since new rel has freshly-updated stats */
	if (swap_stats)
	{
		int4		swap_pages;
		float4		swap_tuples;

		swap_pages = relform1->relpages;
		relform1->relpages = relform2->relpages;
		relform2->relpages = swap_pages;

		swap_tuples = relform1->reltuples;
		relform1->reltuples = relform2->reltuples;
		relform2->reltuples = swap_tuples;
	}

	/*
	 * Swap relstorage so we will later know how to drop the temporary table with
	 * the right Storage Manager (i.e. Buffer Pool or Append-Only).
	 */
	swapchar = relform1->relstorage;
	relform1->relstorage = relform2->relstorage;
	relform2->relstorage = swapchar;

	if (Debug_persistent_print)
		elog(Persistent_DebugPrintLevel(), 
			 "swap_relation_files (#1): UPDATE relation '%s', relation id %u, relfilenode %u, reltablespace %u, relstorage '%c'",
			 relform1->relname.data,
			 r1,
			 relform1->relfilenode,
			 relform1->reltablespace,
			 relform1->relstorage);
	if (Debug_persistent_print)
		elog(Persistent_DebugPrintLevel(), 
			 "swap_relation_files (#2): UPDATE relation '%s', relation id %u, relfilenode %u, reltablespace %u, relstorage '%c'",
			 relform2->relname.data,
			 r2,
			 relform2->relfilenode,
			 relform2->reltablespace,
			 relform2->relstorage);

	/* XXX XXX: jic 20120925 don't **EVER** do this -- 
	 * First, fake out caql and make the "current" tuple reltup2, 
	 * then update it.  
	 * Then restore the "current" tuple (reltup0) and update it with
	 * the modified reltup1.  Note that if the "current" does not get
	 * restored then the underlying ReleaseSysCache() in the
	 * caql_endscan() could explode.
	 */

	caql_get_current(pcqCtx1) = reltup2;
	caql_update_current(pcqCtx1, reltup2);

	caql_get_current(pcqCtx1) = reltup0; /* restore real "current" */
	caql_update_current(pcqCtx1, reltup1);
	/* and Update indexes (implicit) */

	caql_endscan(pcqCtx1);

	/*
	 * If we have toast tables associated with the relations being swapped,
	 * change their dependency links to re-associate them with their new
	 * owning relations.  Otherwise the wrong one will get dropped ...
	 *
	 * NOTE: it is possible that only one table has a toast table; this can
	 * happen in CLUSTER if there were dropped columns in the old table, and
	 * in ALTER TABLE when adding or changing type of columns.
	 *
	 * NOTE: at present, a TOAST table's only dependency is the one on its
	 * owning table.  If more are ever created, we'd need to use something
	 * more selective than deleteDependencyRecordsFor() to get rid of only the
	 * link we want.
	 */
	if (relform1->reltoastrelid || relform2->reltoastrelid)
	{
		changeDependencyLinks(r1, r2,
							  relform1->reltoastrelid, relform2->reltoastrelid,
							  "TOAST");
	}

	CommandCounterIncrement();

	/*
	 * Blow away the old relcache entries now.	We need this kluge because
	 * relcache.c keeps a link to the smgr relation for the physical file, and
	 * that will be out of date as soon as we do CommandCounterIncrement.
	 * Whichever of the rels is the second to be cleared during cache
	 * invalidation will have a dangling reference to an already-deleted smgr
	 * relation.  Rather than trying to avoid this by ordering operations just
	 * so, it's easiest to not have the relcache entries there at all.
	 * (Fortunately, since one of the entries is local in our transaction,
	 * it's sufficient to clear out our own relcache this way; the problem
	 * cannot arise for other backends when they see our update on the
	 * non-local relation.)
	 */
	RelationForgetRelation(r1);
	RelationForgetRelation(r2);

	/* Clean up. */
	heap_freetuple(reltup1);
	heap_freetuple(reltup2);

	heap_close(relRelation, RowExclusiveLock);
}

/*
 * Get a list of tables that the current user owns and
 * have indisclustered set.  Return the list in a List * of rvsToCluster
 * with the tableOid and the indexOid on which the table is already
 * clustered.
 */
static List *
get_tables_to_cluster(MemoryContext cluster_context)
{
	cqContext	*pcqCtx;		
	HeapTuple	indexTuple;
	Form_pg_index index;
	MemoryContext old_context;
	RelToCluster *rvtc;
	List	   *rvs = NIL;

	/*
	 * Get all indexes that have indisclustered set and are owned by
	 * appropriate user. System relations or nailed-in relations cannot ever
	 * have indisclustered set, because CLUSTER will refuse to set it when
	 * called with one of them as argument.
	 */

	/* XXX XXX: could bind "AND indrelid = :2 ", GetUserId */
	pcqCtx = caql_beginscan(
			NULL,
			cql("SELECT * FROM pg_index "
				" WHERE indisclustered = :1 ",
				BoolGetDatum(true)));

	while (HeapTupleIsValid(indexTuple = caql_getnext(pcqCtx)))
	{
		index = (Form_pg_index) GETSTRUCT(indexTuple);

		if (!pg_class_ownercheck(index->indrelid, GetUserId()))
			continue;

		/*
		 * We have to build the list in a different memory context so it will
		 * survive the cross-transaction processing
		 */
		old_context = MemoryContextSwitchTo(cluster_context);

		rvtc = (RelToCluster *) palloc(sizeof(RelToCluster));
		rvtc->tableOid = index->indrelid;
		rvtc->indexOid = index->indexrelid;
		rvs = lcons(rvtc, rvs);

		MemoryContextSwitchTo(old_context);
	}
	caql_endscan(pcqCtx);

	return rvs;
}


/*
 * populate_oidInfo - Fill in a new OidInfo structure 
 *
 * Note: it would be desirable not to allocate more oids than are really needed,
 * but we don't have enough context here to really know (when called from ALTER
 * TABLE any of them could be needed).
 */
void populate_oidInfo(TableOidInfo *oidInfo, Oid TableSpace, bool relisshared, 
					  bool withTypes)
{
	/* Valid pointers only please */
	Assert(oidInfo);

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

	switch (Gp_role)
	{
		/*
		 * In Utility or dispatch mode we must allocate new relfilenodes.
		 * It may be desirable to put more restrictions on utility mode, it is
		 * dangerous to allow segment relfilenodes to drift.
		 */
		case GP_ROLE_UTILITY:
		case GP_ROLE_DISPATCH:
		{
			Relation	pg_class_desc;
			Relation	pg_type_desc;

			pg_class_desc = heap_open(RelationRelationId, RowExclusiveLock);

			/* Get new oids for pg_class entities */
			oidInfo->relOid = 
				GetNewRelFileNode(TableSpace, relisshared,  pg_class_desc, relstorage_is_ao(pg_class_desc->rd_rel->relstorage));
			oidInfo->toastOid = 
				GetNewRelFileNode(TableSpace, relisshared,  pg_class_desc, false);
			oidInfo->toastIndexOid = 
				GetNewRelFileNode(TableSpace, relisshared,  pg_class_desc, false);
			oidInfo->aosegOid = 
				GetNewRelFileNode(TableSpace, relisshared,  pg_class_desc, false);
			oidInfo->aosegIndexOid = 
				GetNewRelFileNode(TableSpace, relisshared,  pg_class_desc, false);
			oidInfo->aoblkdirOid = 
				GetNewRelFileNode(TableSpace, relisshared,  pg_class_desc, false);
			oidInfo->aoblkdirIndexOid = 
				GetNewRelFileNode(TableSpace, relisshared,  pg_class_desc, false);

			/* gonna update, so don't unlock */
			heap_close(pg_class_desc, NoLock);  

			/* Get new oids for pg_type entities */
			if (withTypes)
			{
				pg_type_desc = heap_open(TypeRelationId, RowExclusiveLock);

				oidInfo->comptypeOid = 
					GetNewRelFileNode(TableSpace, relisshared,  pg_type_desc, false);
				oidInfo->toastComptypeOid = 
					GetNewRelFileNode(TableSpace, relisshared,  pg_type_desc, false);
				oidInfo->aosegComptypeOid = 
					GetNewRelFileNode(TableSpace, relisshared,  pg_type_desc, false);
				oidInfo->aoblkdirComptypeOid = 
					GetNewRelFileNode(TableSpace, relisshared,  pg_type_desc, false);

				/* We don't need to keep the pg_type lock */
				heap_close(pg_type_desc, RowExclusiveLock);
			}
			break;
		}

		/* 
		 * In EXECUTE mode we expect to have recieved a valid oidInfo from
		 * the master.  Perform some small validations and return. 
		 */
		case GP_ROLE_EXECUTE:
		{
			if (oidInfo->relOid == 0 ||
				oidInfo->toastOid == 0 ||
				oidInfo->toastIndexOid == 0 ||
				oidInfo->aosegOid == 0 ||
				oidInfo->aosegIndexOid == 0 ||
				oidInfo->aoblkdirOid == 0 ||
				oidInfo->aoblkdirIndexOid == 0 ||
				(withTypes && (
					oidInfo->comptypeOid == 0 ||
					oidInfo->toastComptypeOid == 0 ||
					oidInfo->aosegComptypeOid == 0 ||
					oidInfo->aoblkdirComptypeOid == 0)
					)
				)
			{
				elog(ERROR, "segment recieved incomplete oidInfo from master");
			}
			break;
		}

		/* Unexpected mode? */
		default:
		{
			elog(ERROR, "populate_oidInfo from unexpected dispatch mode");
			break;
		}
	}
}
 
 
