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

/*-------------------------------------------------------------------------
 *
 * cdbdatabaseinfo.c
 *
 *-------------------------------------------------------------------------
 */
#include "c.h"
#include "postgres.h"
#include "miscadmin.h"
#include "pgstat.h"
#include "utils/palloc.h"
#include <fcntl.h>
#include <unistd.h>
#include <sys/stat.h>
#include "storage/fd.h"
#include "storage/relfilenode.h"
#include "storage/dbdirnode.h"
#include "cdb/cdbdatabaseinfo.h"
#include "catalog/catalog.h"
#include "access/relscan.h"
#include "access/heapam.h"
#include "access/transam.h"
#include "catalog/pg_tablespace.h"
#include "cdb/cdbpersistentdatabase.h"
#include "cdb/cdbdirectopen.h"
#include "catalog/pg_appendonly.h"
#include "access/aosegfiles.h"
#include "access/appendonlytid.h"
#include "utils/guc.h"
#include "cdb/cdbpersistentfilesysobj.h"
#include "commands/dbcommands.h"

/*-------------------------------------------------------------------------
 * Local static type declarations
 *------------------------------------------------------------------------- */

/* hash table entry for relation ids */
typedef struct RelationIdEntry
{
	Oid			 relationId;  	/* key */
	DbInfoRel 	*dbInfoRel;   	/* pointer */
} RelationIdEntry;


/*-------------------------------------------------------------------------
 * Debugging functions
 *------------------------------------------------------------------------- */

#ifdef suppress

/*
 * DatabaseInfo_Check()
 *   Validate that the DatabaseInfo returned is consistent.
 */
void DatabaseInfo_Check(DatabaseInfo *info)
{
	int sr;
	int rsf;

	/*
	 * Compare Stored Relations to Relation Segment Files.
	 */
	sr = 0;
	rsf = 0;
	while (true)
	{
		int cmp;

		cmp = TablespaceRelFile_Compare(
						&info->pgClassStoredRelations[sr].tablespaceRelFile,
						&info->relSegFiles[rsf].tablespaceRelFile);
		if (cmp != 0)
		{
			elog(WARNING, "In database %u, stored relation doesn't match relation file on disk "
						"(stored tablespace %u, disk file tablespace %u, "
						"stored relation %u, disk file relation %u)",
						info->database,
						info->pgClassStoredRelations[sr].tablespaceRelFile.tablespace,
						info->relSegFiles[rsf].tablespaceRelFile.tablespace,
						info->pgClassStoredRelations[sr].tablespaceRelFile.relation,
						info->relSegFiles[rsf].tablespaceRelFile.relation);
			return;
		}

		/*
		 * Skip multiple relation segment files.
		 */
		while (true)
		{
			rsf++;
			if (rsf >= info->relSegFilesCount)
				break;
			if (TablespaceRelFile_Compare(
						&info->pgClassStoredRelations[sr].tablespaceRelFile,
						&info->relSegFiles[rsf].tablespaceRelFile) != 0)
				break;
		}

		sr++;

		if (sr >= info->pgClassStoredRelationsCount ||
			rsf >= info->relSegFilesCount)
		{
			if (sr < info->pgClassStoredRelationsCount)
			{
				elog(WARNING, "In database %u, extra stored relation (tablespace %u, relation %u)",
				     info->database,
					 info->pgClassStoredRelations[sr].tablespaceRelFile.tablespace,
					 info->pgClassStoredRelations[sr].tablespaceRelFile.relation);
				return;
			}

			if (rsf < info->relSegFilesCount)
			{
				elog(WARNING, "In database %u, extra relation file on disk (tablespace %u, relation %u)",
				     info->database,
					 info->relSegFiles[rsf].tablespaceRelFile.tablespace,
					 info->relSegFiles[rsf].tablespaceRelFile.relation);
				return;
			}
			break;
		}
	}
}

/*
 * DatabaseInfo_Trace()
 *   Output debugging information about the DatabaseInfo
 */
void DatabaseInfo_Trace(DatabaseInfo *info)
{
	int t;
	int sr;
	int rsf;
	int grn;
	int m;

	for (t = 0; t < info->tablespacesCount; t++)
		elog(WARNING, "Database Info: Tablespace #%d is %u",
			 t, info->tablespaces[t]);

	for (sr = 0; sr < info->pgClassStoredRelationsCount; sr++)
		elog(WARNING, "Database Info: Stored relation (tablespace %u, relation %u, isBufferPoolRealtion %s, TID %s)",
			 info->pgClassStoredRelations[sr].tablespaceRelFile.tablespace, 
			 info->pgClassStoredRelations[sr].tablespaceRelFile.relation,
			 (info->pgClassStoredRelations[sr].isBufferPoolRelation ? "true" : "false"),
			 ItemPointerToString(&info->pgClassStoredRelations[sr].pgClassTid));

	for (rsf = 0; rsf < info->relSegFilesCount; rsf++)
		elog(WARNING, "Database Info: Relation segment file (tablespace %u, relation %u, segment file num %d)",
			 info->relSegFiles[rsf].tablespaceRelFile.tablespace, 
			 info->relSegFiles[rsf].tablespaceRelFile.relation, 
			 info->relSegFiles[rsf].segmentFileNum);

	for (grn = 0; grn < info->gpRelationNodesCount; grn++)
		elog(WARNING, "Database Info: Tablespace %u, relation %u node information (persistent TID %s, perstent serial number " INT64_FORMAT ")",
			 info->gpRelationNodes[grn].tablespaceRelFile.tablespace, 
			 info->gpRelationNodes[grn].tablespaceRelFile.relation, 
			 ItemPointerToString(&info->gpRelationNodes[grn].persistentTid),
			 info->gpRelationNodes[grn].persistentSerialNum);

	for (m = 0; m < info->miscEntriesCount; m++)
		elog(WARNING, "Database Info: Misc entry #%d (tablespace %u, directory = %s, name '%s')",
			 m, 
			 info->miscEntries[m].tablespace,
			 (info->miscEntries[m].isDir ? "true" : "false"),
			 info->miscEntries[m].name);
}


/*
 * DatabaseInfo_FindDbInfoRel()
 *   Lookup an entry in the info hash table.
 *   
 * Note: called nowhere in the source, purely available for debugging.
 */
static DbInfoRel *DatabaseInfo_FindDbInfoRel(
	HTAB 				*dbInfoRelHashTable,
	
	Oid					relfilenodeOid)
{
	DbInfoRel *dbInfoRel;

	bool found;
	
	dbInfoRel = 
			(DbInfoRel*) 
					hash_search(dbInfoRelHashTable,
								(void *) &relfilenodeOid,
								HASH_FIND,
								&found);
	if (!found)
	{
		elog(ERROR, "pg_class entry (relfilenode %u) not found",
			 relfilenodeOid);
		return NULL;
	}

	return dbInfoRel;
}

#endif

/*-------------------------------------------------------------------------
 * Local static function definitions
 *------------------------------------------------------------------------- */

/*
 * DatabaseInfo_Grow()
 *   Used for extensible arrays.
 *
 * XXX - Why not just use repalloc?
 */
static void DatabaseInfo_Grow(
	void 	**array,
	int32	arrayCount,
	int32	*arrayMaxCount,
	int32	elementLen)
{
	void *newArray;
	
	(*arrayMaxCount) *= 2;
	newArray = palloc((*arrayMaxCount)*elementLen);
	memcpy(
		newArray, 
		(*array), 
		arrayCount*elementLen);
	pfree(*array);
	*array = newArray;
}

/*
 * DatabaseInfo_DbInfoRelHashTableInit()
 *    Construct a hash table of DbInfoRel
 */
static HTAB*
DatabaseInfo_DbInfoRelHashTableInit()
{
	HASHCTL			info;
	int				hash_flags;

	/* Set key and entry sizes. */
	MemSet(&info, 0, sizeof(info));
	info.keysize = sizeof(Oid);
	info.entrysize = sizeof(DbInfoRel);
	info.hash = tag_hash;

	hash_flags = (HASH_ELEM | HASH_FUNCTION);

	return hash_create("DbInfoRel", 100, &info, hash_flags);
}

/*
 * DatabaseInfo_RelationIdHashTableInit()
 *    Construct a hash table of RelationIdEntry
 */
static HTAB*
DatabaseInfo_RelationIdHashTableInit()
{
	HASHCTL			info;
	int				hash_flags;

	/* Set key and entry sizes. */
	MemSet(&info, 0, sizeof(info));
	info.keysize = sizeof(Oid);
	info.entrysize = sizeof(RelationIdEntry);
	info.hash = tag_hash;

	hash_flags = (HASH_ELEM | HASH_FUNCTION);

	return hash_create("RelationId", 100, &info, hash_flags);
}


/*
 * DatabaseInfo_PgAppendOnlyHashTableInit()
 *    Construct a hash table of PgAppendOnlyHashEntry
 */
static HTAB *
DatabaseInfo_PgAppendOnlyHashTableInit()
{
	HASHCTL			info;
	int				hash_flags;

	/* Set key and entry sizes. */
	MemSet(&info, 0, sizeof(info));
	info.keysize = sizeof(Oid);
	info.entrysize = sizeof(PgAppendOnlyHashEntry);
	info.hash = tag_hash;

	hash_flags = (HASH_ELEM | HASH_FUNCTION);

	return hash_create("PgAppendOnly", 100, &info, hash_flags);
}


/*
 * DatabaseInfo_AddRelationId()
 *   Add an entry to a dbInfoRel hash table
 */
static void DatabaseInfo_AddRelationId(
	HTAB 		*relationIdHashTable,
	DbInfoRel 	*dbInfoRel)
{
	RelationIdEntry *relationIdEntry;

	bool found;
	
	relationIdEntry = 
			(RelationIdEntry*) 
					hash_search(relationIdHashTable,
								(void *) &dbInfoRel->relationOid,
								HASH_ENTER,
								&found);
	if (found)
	{
		elog(ERROR, "Duplicate pg_class entry (relation id %u)",
			 dbInfoRel->relationOid);
	}

	relationIdEntry->dbInfoRel = dbInfoRel;
}

/*
 * DatabaseInfo_FindRelationId()
 *   Lookup an entry to a dbInfoRel hash table
 */
static DbInfoRel *DatabaseInfo_FindRelationId(
	HTAB 		*dbInfoRelHashTable,
	Oid			 relationId)
{
	RelationIdEntry *relationIdEntry;

	bool found;
	
	relationIdEntry = 
			(RelationIdEntry*) 
					hash_search(dbInfoRelHashTable,
								(void *) &relationId,
								HASH_FIND,
								&found);
	if (!found)
	{
		elog(ERROR, "pg_class entry (relation id %u) not found",
			 relationId);
		return NULL;
	}

	return relationIdEntry->dbInfoRel;
}

/*
 * DatabaseInfo_AddPgAppendOnly()
 *   Add an entry to a pgAppendOnly hash table.
 */
static void DatabaseInfo_AddPgAppendOnly(
	HTAB 				*pgAppendOnlyHashTable,	
	Oid					 relationId,
	AppendOnlyEntry 	*aoEntry)
{
	PgAppendOnlyHashEntry *pgAppendOnlyHashEntry;

	bool found;
	
	pgAppendOnlyHashEntry = 
			(PgAppendOnlyHashEntry*) 
					hash_search(pgAppendOnlyHashTable,
								(void *) &relationId,
								HASH_ENTER,
								&found);
	if (found)
		elog(ERROR, "More than one pg_appendonly entry (relation id %u)",
			 relationId);

	pgAppendOnlyHashEntry->aoEntry = aoEntry;
}


/*
 * DatabaseInfo_FindPgAppendOnly()
 *   Lookup an entry to a pgAppendOnly hash table.
 */
static AppendOnlyEntry *DatabaseInfo_FindPgAppendOnly(
	HTAB 				*pgAppendOnlyHashTable,
	
	Oid					relationId)
{
	PgAppendOnlyHashEntry *pgAppendOnlyHashEntry;

	bool found;
	
	pgAppendOnlyHashEntry = 
			(PgAppendOnlyHashEntry*) 
					hash_search(pgAppendOnlyHashTable,
								(void *) &relationId,
								HASH_FIND,
								&found);
	if (!found)
	{
		elog(ERROR, "pg_appendonly entry (relation id %u) not found",
			 relationId);
		return NULL;
	}

	return pgAppendOnlyHashEntry->aoEntry;
}


/*
 * DatabaseInfo_AddTablespace()
 *   Add a tablespace to the DatabaseInfo
 */
static void DatabaseInfo_AddTablespace(
	DatabaseInfo 		*info,
	Oid 				tablespace)
{
	int t;

	t = 0;
	while (true)
	{
		if (t >= info->tablespacesCount)
		{
			Assert(t == info->tablespacesCount);
			if (t >= info->tablespacesMaxCount)
			{
				DatabaseInfo_Grow(
								(void**)&info->tablespaces,
								info->tablespacesCount,
								&info->tablespacesMaxCount,
								sizeof(Oid));
			}
			info->tablespaces[info->tablespacesCount++] = tablespace;
			break;
		}
		
		if (info->tablespaces[t] == tablespace)
			break;
	
		t++;
	}
}

static void DatabaseInfo_AddExtraSegmentFile(
	DatabaseInfo 		*info,
	Oid 				tablespace,
	Oid					relfilenode,
	int32				segmentFileNum,
	int64				eof)
{
	DbInfoExtraSegmentFile	*dbInfoExtraSegmentFile;

	if (info->extraSegmentFilesCount>= info->extraSegmentFilesMaxCount)
	{
		DatabaseInfo_Grow(
						(void**)&info->extraSegmentFiles,
						info->extraSegmentFilesCount,
						&info->extraSegmentFilesMaxCount,
						sizeof(DbInfoExtraSegmentFile));
	}

	dbInfoExtraSegmentFile = 
					&info->extraSegmentFiles[info->extraSegmentFilesCount];
	info->extraSegmentFilesCount++;
	
	dbInfoExtraSegmentFile->relfilenode = relfilenode;
	dbInfoExtraSegmentFile->segmentFileNum = segmentFileNum;
	dbInfoExtraSegmentFile->tablespaceOid = tablespace;
	dbInfoExtraSegmentFile->eof = eof;
}

static void DatabaseInfo_AddAppendOnlyCatalogSegmentInfo(
	DbInfoRel 				*dbInfoRel,
	int32 					segmentFileNum,
	int64					logicalEof)
{
	DbInfoAppendOnlyCatalogSegmentInfo 	*appendOnlyCatalogSegmentInfo;

	if (dbInfoRel->appendOnlyCatalogSegmentInfoCount >= dbInfoRel->appendOnlyCatalogSegmentInfoMaxCount)
	{
		DatabaseInfo_Grow(
						(void**)&dbInfoRel->appendOnlyCatalogSegmentInfo,
						dbInfoRel->appendOnlyCatalogSegmentInfoCount,
						&dbInfoRel->appendOnlyCatalogSegmentInfoMaxCount,
						sizeof(DbInfoAppendOnlyCatalogSegmentInfo));
	}

	appendOnlyCatalogSegmentInfo = &dbInfoRel->appendOnlyCatalogSegmentInfo[dbInfoRel->appendOnlyCatalogSegmentInfoCount];
	dbInfoRel->appendOnlyCatalogSegmentInfoCount++;

	appendOnlyCatalogSegmentInfo->segmentFileNum = segmentFileNum;
	appendOnlyCatalogSegmentInfo->logicalEof = logicalEof;

	if (Debug_persistent_print)
		elog(Persistent_DebugPrintLevel(), 
			 "DatabaseInfo_AddAppendOnlyCatalogSegmentInfo: relation id %u, relation name %s, relfilenode %u, segment file #%d, EOF " INT64_FORMAT,
			 dbInfoRel->relationOid,
			 dbInfoRel->relname,
			 dbInfoRel->relfilenodeOid,
			 segmentFileNum,
			 logicalEof);

}


static void DatabaseInfo_AddPgClassStoredRelation(
	DatabaseInfo 		*info,
	HTAB 				*dbInfoRelHashTable,
	HTAB				*relationIdHashTable,
	Oid 				relfilenode,
	ItemPointer			pgClassTid,
	Oid					relationOid,
	char				*relname,
	Oid					reltablespace,
	char				relkind,
	char				relstorage,
	Oid					relam,
	int					relnatts)
{
	DbInfoRel	*dbInfoRel;
	bool		 found;

	dbInfoRel = 
			(DbInfoRel*) 
					hash_search(dbInfoRelHashTable,
								(void *) &relfilenode,
								HASH_ENTER,
								&found);
	if (found)
		elog(ERROR, "More than one pg_class entry ('%s' %u and '%s' %u) references the same relfilenode %u",
			 dbInfoRel->relname,
			 dbInfoRel->relationOid,
			 relname,
			 relationOid,
			 relfilenode);

	dbInfoRel->inPgClass = true;
	dbInfoRel->pgClassTid = *pgClassTid;
	dbInfoRel->relationOid = relationOid;
	dbInfoRel->relname = pstrdup(relname);
	dbInfoRel->reltablespace = reltablespace;
	dbInfoRel->relkind = relkind;
	dbInfoRel->relstorage = relstorage;
	dbInfoRel->relam = relam;
	dbInfoRel->relnatts = relnatts;

	dbInfoRel->gpRelationNodesMaxCount = 1;
	dbInfoRel->gpRelationNodes = 
			palloc0(dbInfoRel->gpRelationNodesMaxCount * sizeof(DbInfoGpRelationNode));
	dbInfoRel->gpRelationNodesCount = 0;
	
	dbInfoRel->appendOnlyCatalogSegmentInfoMaxCount= 1;
	dbInfoRel->appendOnlyCatalogSegmentInfo = 
			palloc0(dbInfoRel->appendOnlyCatalogSegmentInfoMaxCount * sizeof(DbInfoAppendOnlyCatalogSegmentInfo));
	dbInfoRel->appendOnlyCatalogSegmentInfoCount = 0;
	
	dbInfoRel->physicalSegmentFilesMaxCount = 1;
	dbInfoRel->physicalSegmentFiles = 
			palloc0(dbInfoRel->physicalSegmentFilesMaxCount * sizeof(DbInfoSegmentFile));
	dbInfoRel->physicalSegmentFilesCount = 0;

	DatabaseInfo_AddRelationId(
						relationIdHashTable,
						dbInfoRel);
}

static bool DatabaseInfo_AddGpRelationNode(
	DatabaseInfo		*info,
	HTAB 				*dbInfoRelHashTable,
	Oid					relfilenode,
	int32				segmentFileNum,
	ItemPointer			persistentTid,
	int64				persistentSerialNum,
	ItemPointer			gpRelationNodeTid)
{
	DbInfoRel *dbInfoRel;
	bool found;

	DbInfoGpRelationNode *dbInfoGpRelationNode;

	dbInfoRel = 
			(DbInfoRel*) 
					hash_search(dbInfoRelHashTable,
								(void *) &relfilenode,
								HASH_FIND,
								&found);

	//Changes to solve MPP-16346
	if(!dbInfoRel)
			return found;

	if (found)
	{
		if (dbInfoRel->gpRelationNodesCount >= dbInfoRel->gpRelationNodesMaxCount)
		{
			DatabaseInfo_Grow(
							(void**)&dbInfoRel->gpRelationNodes,
							dbInfoRel->gpRelationNodesCount,
							&dbInfoRel->gpRelationNodesMaxCount,
							sizeof(DbInfoGpRelationNode));
		}

		dbInfoGpRelationNode = 
						&dbInfoRel->gpRelationNodes[dbInfoRel->gpRelationNodesCount];
		dbInfoRel->gpRelationNodesCount++;
	}
	else
	{
		if (info->parentlessGpRelationNodesCount >= dbInfoRel->physicalSegmentFilesMaxCount)
		{
			DatabaseInfo_Grow(
							(void**)&info->parentlessGpRelationNodes,
							info->parentlessGpRelationNodesCount,
							&info->parentlessGpRelationNodesMaxCount,
							sizeof(DbInfoGpRelationNode));
		}

		dbInfoGpRelationNode = 
						&info->parentlessGpRelationNodes[info->parentlessGpRelationNodesCount];
		info->parentlessGpRelationNodesCount++;
	}
	
	dbInfoGpRelationNode->gpRelationNodeTid = *gpRelationNodeTid;
	dbInfoGpRelationNode->relfilenodeOid = relfilenode;
	dbInfoGpRelationNode->segmentFileNum = segmentFileNum;
	dbInfoGpRelationNode->persistentTid = *persistentTid;
	dbInfoGpRelationNode->persistentSerialNum = persistentSerialNum;
	dbInfoGpRelationNode->logicalEof = 0;	// This will obtained from the other sources later (e.g. aoseg ).

	if (Debug_persistent_print)
		elog(Persistent_DebugPrintLevel(), 
			 "DatabaseInfo_AddGpRelationNode: gp_relation_node TID %s, relfilenode %u, segment file #%d, persistent serial number " INT64_FORMAT ", persistent TID %s",
			 ItemPointerToString(gpRelationNodeTid),
			 relfilenode,
			 segmentFileNum,
			 persistentSerialNum,
			 ItemPointerToString(persistentTid));
	
	return found;
}

static void DatabaseInfo_AddMiscEntry(
	DatabaseInfo		 	*info,
	Oid 					tablespace,
	bool					isDir,
	char					*name)
{
	MiscEntry 	*miscEntry;

	if (info->miscEntriesCount >= info->miscEntriesMaxCount)
	{
		DatabaseInfo_Grow(
						(void**)&info->miscEntries,
						info->miscEntriesCount,
						&info->miscEntriesMaxCount,
						sizeof(MiscEntry));
	}

	miscEntry = &info->miscEntries[info->miscEntriesCount];
	info->miscEntriesCount++;
	
	miscEntry->tablespace = tablespace;
	miscEntry->isDir = isDir;
	miscEntry->name = pstrdup(name);

}

static void DatabaseInfo_AddPhysicalSegmentFile(
	DbInfoRel 				*dbInfoRel,
	int32 					segmentFileNum,
	int64					eof)
{
	DbInfoSegmentFile 	*dbInfoSegmentFile;

	if (dbInfoRel->physicalSegmentFilesCount >= dbInfoRel->physicalSegmentFilesMaxCount)
	{
		DatabaseInfo_Grow(
						(void**)&dbInfoRel->physicalSegmentFiles,
						dbInfoRel->physicalSegmentFilesCount,
						&dbInfoRel->physicalSegmentFilesMaxCount,
						sizeof(DbInfoSegmentFile));
	}

	dbInfoSegmentFile = &dbInfoRel->physicalSegmentFiles[dbInfoRel->physicalSegmentFilesCount];
	dbInfoRel->physicalSegmentFilesCount++;
	
	dbInfoSegmentFile->segmentFileNum = segmentFileNum;
	dbInfoSegmentFile->eof = eof;

}

static void DatabaseInfo_AddRelSegFile(
	DatabaseInfo 			*info,
	HTAB 					*dbInfoRelHashTable,
	Oid 					tablespace,
	Oid						relfilenode,
	int32					segmentFileNum,
	int64					eof)
{
	DbInfoRel	*dbInfoRel;
	bool		 found;

	/* Lookup the relfilenode in our catalog cache */
	dbInfoRel = (DbInfoRel*) \
		hash_search(dbInfoRelHashTable, 
					(void *) &relfilenode,
					HASH_FIND,
					&found);

	/* 
	 * If the relfilenode doesn't exist in the catalog then add it to the list
	 * of orphaned relfilenodes.
	 */
	if (!found || dbInfoRel->reltablespace != tablespace)
	{
		DatabaseInfo_AddExtraSegmentFile(
									info,
									tablespace,
									relfilenode,
									segmentFileNum,
									eof);
		return;
	}

	DatabaseInfo_AddPhysicalSegmentFile(
										dbInfoRel,
										segmentFileNum,
										eof);
}

static void DatabaseInfo_AddFile(
	DatabaseInfo		 	*info,
	HTAB 					*dbInfoRelHashTable,
	Oid 					tablespace,
	char					*dbDirPath,
	char					*name,
	bool                    isHdfs,
	Oid                     table_oid)
{
	int64 eof;
	int itemCount;
	Oid relfilenode;
	uint32 segmentFileNum;
	char path[MAXPGPATH];
	int	fileFlags = O_RDONLY | PG_BINARY;
	int	fileMode = 0400;
						/* File mode is S_IRUSR 00400 user has read permission */
	File file;

	sprintf(path, "%s/%s", dbDirPath, name);
	
	/*
	 * Open the file for read.
	 */	
	file = PathNameOpenFile(path, fileFlags, fileMode);
	if(file < 0)
	{
		ereport(ERROR,
				(errcode_for_file_access(),
				 errmsg("Could not open segment file '%s'", 
						path)));
	}
	eof = FileSeek(file, 0L, SEEK_END);
	if (eof < 0) {
		ereport(ERROR,
				(errcode_for_file_access(),
				 errmsg("Could not seek to end of file \"%s\" : %m",
						path)));
	}
	FileClose(file);

	itemCount = sscanf(name, isHdfs?"%u/%u":"%u.%u", &relfilenode, &segmentFileNum);

	// UNDONE: sscanf is a rather poor scanner.
	// UNDONE: For right now, just assume properly named files....
	if (itemCount == 0)
	{
		DatabaseInfo_AddMiscEntry(info, tablespace, false, name);
		return;
	}
	else if (itemCount == 1)
		segmentFileNum = 0;
	else
		Assert(itemCount == 2);

	if(isHdfs){
		DatabaseInfo_AddRelSegFile(info, dbInfoRelHashTable, tablespace, table_oid, relfilenode, eof);
	}else{
		DatabaseInfo_AddRelSegFile(info, dbInfoRelHashTable, tablespace, relfilenode, segmentFileNum, eof);
	}
}

/*
 * DatabaseInfo_Scan()
 *   Scans the file-system to fill the DatabaseInfo with:
 *     - miscEntry             : non-relation database files
 *     - physicalSegmentFiles  : relation segment files
 */
static void 
DatabaseInfo_Scan(
	DatabaseInfo 		*info,
	HTAB 				*dbInfoRelHashTable,
	Oid 				 tablespace,
	Oid 				 database)
{
	char				*dbDirPath;
	DIR					*xldir, *xldir1;
	struct dirent		*xlde,*xlde1;
	char				 fromfile[MAXPGPATH],fromfile1[MAXPGPATH];

	/* Lookup the database path and allocate a directory scan structure */
	dbDirPath = GetDatabasePath(
						(tablespace == GLOBALTABLESPACE_OID ? 0 : database), 
						tablespace);
	
	xldir = AllocateDir(dbDirPath);
	if (xldir == NULL)
		ereport(ERROR,
				(errcode_for_file_access(),
				 errmsg("Could not open database directory \"%s\": %m", dbDirPath)));

	/* Scan through the directory */
	while ((xlde = ReadDir(xldir, dbDirPath)) != NULL)
	{
		if (strcmp(xlde->d_name, ".") == 0 ||
			strcmp(xlde->d_name, "..") == 0)
			continue;

		/* Odd... On snow leopard, we get back "/" as a subdir, which is wrong. Ingore it */
		if (xlde->d_name[0] == '/' && xlde->d_name[1] == '\0')
			continue;

		snprintf(fromfile, MAXPGPATH, "%s/%s", dbDirPath, xlde->d_name);

		if(IsLocalPath(fromfile)){//on local disk
			struct stat fst;
			
			if (lstat(fromfile, &fst) < 0)
				ereport(ERROR,
						(errcode_for_file_access(),
						 errmsg("could not stat file \"%s\": %m", fromfile)));

			if (S_ISDIR(fst.st_mode))
			{
				DatabaseInfo_AddMiscEntry(
										info, 
										tablespace,
										/* isDir */ true, 
										xlde->d_name);
			}
			else if (S_ISREG(fst.st_mode))
			{
				DatabaseInfo_AddFile(
									info,
									dbInfoRelHashTable,
									tablespace,
									dbDirPath,
									xlde->d_name,
									false,
									InvalidOid);
			}
		}else{//on hdfs
			int ret = HdfsIsDirOrFile(fromfile);
			if(ret == -1){//fetch info error
				ereport(ERROR,
							(errcode_for_file_access(),
							 errmsg("error to fetch info for path \"%s\": %m", fromfile)));
			}else if(ret == 0){//direcotry
				if(strcmp(xlde->d_name, dbDirPath) == 0){ //database level
					DatabaseInfo_AddMiscEntry(
										info,
										tablespace,
										/* isDir */ true,
										xlde->d_name);
				}else{ //table level, need to recursive list file in this directory
					xldir1 = AllocateDir(fromfile);
					if (xldir1 == NULL)
							ereport(ERROR,
									(errcode_for_file_access(),
									 errmsg("Could not open database directory \"%s\": %m", fromfile)));
					while ((xlde1 = ReadDir(xldir1, fromfile)) != NULL)
						{
							if (strcmp(xlde1->d_name, ".") == 0 ||
								strcmp(xlde1->d_name, "..") == 0)
								continue;

							/* Odd... On snow leopard, we get back "/" as a subdir, which is wrong. Ingore it */
							if (xlde1->d_name[0] == '/' && xlde1->d_name[1] == '\0')
								continue;

							snprintf(fromfile1, MAXPGPATH, "%s/%s", fromfile, xlde1->d_name);

							if(!IsLocalPath(fromfile1)){//on hdfs
								int ret = HdfsIsDirOrFile(fromfile1);
								if(ret != 1){//fetch info error
										ereport(ERROR,
													(errcode_for_file_access(),
													 errmsg("error to fetch file path \"%s\": %m", fromfile1)));
								}else{
									DatabaseInfo_AddFile(
														info,
														dbInfoRelHashTable,
														tablespace,
														fromfile,
														xlde1->d_name,
														true,
														pg_atoi(xlde->d_name, 4, 0));
								}
							}
					}
					FreeDir(xldir1);
				}
			}else if(ret == 1){//file
				//just skip for PG_VERSION file
			}
		}
	}

	FreeDir(xldir);
}

/*
 * A compare function for 2 RelationSegmentFile.
 */
static int
DbInfoRelPtrArray_Compare(const void *entry1, const void *entry2)
{
	const DbInfoRel *dbInfoRel1 = *((DbInfoRel**)entry1);
	const DbInfoRel *dbInfoRel2 = *((DbInfoRel**)entry2);

	if (dbInfoRel1->relfilenodeOid == dbInfoRel2->relfilenodeOid)
		return 0;
	else if (dbInfoRel1->relfilenodeOid > dbInfoRel2->relfilenodeOid)
		return 1;
	else
		return -1;
}

static int
DbInfoGpRelationNode_Compare(const void *entry1, const void *entry2)
{
	const DbInfoGpRelationNode *info1 = (DbInfoGpRelationNode*) entry1;
	const DbInfoGpRelationNode *info2 = (DbInfoGpRelationNode*) entry2;

	if (info1->relfilenodeOid == info2->relfilenodeOid)
	{
		if (info1->segmentFileNum == info2->segmentFileNum)
			return 0;
		else if (info1->segmentFileNum > info2->segmentFileNum)
			return 1;
		else
			return -1;
	}
	else if (info1->relfilenodeOid > info2->relfilenodeOid)
		return 1;
	else
		return -1;
}

static int
DbInfoSegmentFile_Compare(const void *entry1, const void *entry2)
{
	const DbInfoSegmentFile *info1 = (DbInfoSegmentFile *) entry1;
	const DbInfoSegmentFile *info2 = (DbInfoSegmentFile *) entry2;

	if (info1->segmentFileNum == info2->segmentFileNum)
		return 0;
	else if (info1->segmentFileNum > info2->segmentFileNum)
		return 1;
	else
		return -1;
}

static int
DbInfoAppendOnlyCatalogSegmentInfo_Compare(const void *entry1, const void *entry2)
{
	const DbInfoAppendOnlyCatalogSegmentInfo *info1 = 
		(DbInfoAppendOnlyCatalogSegmentInfo *) entry1;
	const DbInfoAppendOnlyCatalogSegmentInfo *info2 = 
		(DbInfoAppendOnlyCatalogSegmentInfo *) entry2;

	if (info1->segmentFileNum == info2->segmentFileNum)
		return 0;
	else if (info1->segmentFileNum > info2->segmentFileNum)
		return 1;
	else
		return -1;
}

static void
DatabaseInfo_CollectGpRelationNode(
	DatabaseInfo 		*info,
	HTAB				*dbInfoRelHashTable)
{
	HeapScanDesc		scan;
	Relation			gp_relfile_node_rel;
	HeapTuple			tuple;

	gp_relfile_node_rel =
			DirectOpen_GpRelfileNodeOpen(
							info->defaultTablespace, 
							info->database);
	scan = heap_beginscan(gp_relfile_node_rel, SnapshotNow, 0, NULL);
	while ((tuple = heap_getnext(scan, ForwardScanDirection)) != NULL)
	{
		bool			nulls[Natts_gp_relfile_node];
		Datum			values[Natts_gp_relfile_node];

		Oid				relfilenode;
		int32			segmentFileNum;
		ItemPointerData	persistentTid;
		int64			persistentSerialNum;
		
		heap_deform_tuple(tuple, RelationGetDescr(gp_relfile_node_rel), values, nulls);

		GpRelfileNode_GetValues(
							values,
							&relfilenode,
							&segmentFileNum,
							&persistentTid,
							&persistentSerialNum);
		
		if (!DatabaseInfo_AddGpRelationNode(
									info,
									dbInfoRelHashTable,
									relfilenode,
									segmentFileNum,
									&persistentTid,
									persistentSerialNum,
									&tuple->t_self))
		{
			elog(WARNING, "Did not find matching pg_class entry for gp_relation_node entry relfilenode %u (parentless!!!)",
				 relfilenode);
		}
	}
	heap_endscan(scan);

	DirectOpen_GpRelfileNodeClose(gp_relfile_node_rel);
}

static void
DatabaseInfo_HandleAppendOnly(
	DatabaseInfo		*info,
	HTAB				*dbInfoRelHashTable,
	HTAB				*relationIdHashTable,
	HTAB				*pgAppendOnlyHashTable)
{
	HASH_SEQ_STATUS iterateStatus;

	hash_seq_init(&iterateStatus, dbInfoRelHashTable);

	while (true)
	{
		DbInfoRel *dbInfoRel;

		dbInfoRel = 
				(DbInfoRel*)
						hash_seq_search(&iterateStatus);
		if (dbInfoRel == NULL)
			break;
	
		if (dbInfoRel->relstorage == RELSTORAGE_AOROWS || dbInfoRel->relstorage == RELSTORAGE_PARQUET)
		{
			AppendOnlyEntry 	*aoEntry;
			DbInfoRel 			*aosegDbInfoRel;
			int i;
				
			aoEntry = DatabaseInfo_FindPgAppendOnly(
											pgAppendOnlyHashTable,
											dbInfoRel->relationOid);
			if (Debug_persistent_print)
				elog(Persistent_DebugPrintLevel(), 
					 "DatabaseInfo_AddPgClassStoredRelation: Append-Only entry for relation id %u, relation name %s, "
				     "blocksize %d, pagesize %d, safefswritesize %d, compresslevel %d, major version %d, minor version %d, "
				     " checksum %s, compresstype %s, columnstore %s, segrelid %u, segidxid %u, blkdirrelid %u, blkdiridxid %u",
				     dbInfoRel->relationOid,
				     dbInfoRel->relname,
					 aoEntry->blocksize,
					 aoEntry->pagesize,
					 aoEntry->safefswritesize,
					 aoEntry->compresslevel,
					 aoEntry->majorversion,
					 aoEntry->minorversion,
					 (aoEntry->checksum ? "true" : "false"),
					 (aoEntry->compresstype ? aoEntry->compresstype : "NULL"),
					 (aoEntry->columnstore ? "true" : "false"),
					 aoEntry->segrelid,
					 aoEntry->segidxid,
					 aoEntry->blkdirrelid,
					 aoEntry->blkdiridxid);

			/*
			 * Translate the ao[cs]seg relation id to relfilenode.
			 */

			aosegDbInfoRel = DatabaseInfo_FindRelationId(
												relationIdHashTable,
												aoEntry->segrelid);
			Assert(aosegDbInfoRel != NULL);

			FileSegInfo **aoSegfileArray;
			int totalAoSegFiles;

			Relation pg_aoseg_rel;

			pg_aoseg_rel =
					DirectOpen_PgAoSegOpenDynamic(
										aoEntry->segrelid,
										MyDatabaseTableSpace,
										info->database,
										aosegDbInfoRel->relfilenodeOid);

			aoSegfileArray =
					GetAllFileSegInfo_pg_aoseg_rel(
											dbInfoRel->relname,
											aoEntry,
											pg_aoseg_rel,
											SnapshotNow,
											-1,
											&totalAoSegFiles);
			for (i = 0; i < totalAoSegFiles; i++)
			{
				DatabaseInfo_AddAppendOnlyCatalogSegmentInfo(
														dbInfoRel,
														aoSegfileArray[i]->segno,
														aoSegfileArray[i]->eof);
			}

			DirectOpen_PgAoSegClose(pg_aoseg_rel);
		}
	}
}

static void
DatabaseInfo_CollectPgAppendOnly(
	DatabaseInfo 		*info,
	HTAB				*pgAppendOnlyHashTable)
{
	Relation	pg_appendonly_rel;

	HeapScanDesc scan;
	HeapTuple	tuple;

	pg_appendonly_rel = 
				DirectOpen_PgAppendOnlyOpen(
									info->defaultTablespace, 
									info->database);
	scan = heap_beginscan(pg_appendonly_rel, SnapshotNow, 0, NULL);
	while ((tuple = heap_getnext(scan, ForwardScanDirection)) != NULL)
	{
		bool			nulls[Natts_pg_appendonly];
		Datum			values[Natts_pg_appendonly];
				
		AppendOnlyEntry *aoEntry;

		Oid 			relationId;
				
		heap_deform_tuple(tuple, RelationGetDescr(pg_appendonly_rel), values, nulls);

		aoEntry = GetAppendOnlyEntryFromTuple(
									pg_appendonly_rel,
									RelationGetDescr(pg_appendonly_rel),
									tuple,
									&relationId);

		Assert(aoEntry != NULL);

		if (Debug_persistent_print)
			elog(Persistent_DebugPrintLevel(), 
				 "DatabaseInfo_Collect: Append-Only entry for relation id %u, "
				 "blocksize %d, pagesize %d, safefswritesize %d, compresslevel %d, major version %d, minor version %d, "
				 " checksum %s, compresstype %s, columnstore %s, segrelid %u, segidxid %u, blkdirrelid %u, blkdiridxid %u",
				 relationId,
				 aoEntry->blocksize,
				 aoEntry->pagesize,
				 aoEntry->safefswritesize,
				 aoEntry->compresslevel,
				 aoEntry->majorversion,
				 aoEntry->minorversion,
				 (aoEntry->checksum ? "true" : "false"),
				 (aoEntry->compresstype ? aoEntry->compresstype : "NULL"),
				 (aoEntry->columnstore ? "true" : "false"),
				 aoEntry->segrelid,
				 aoEntry->segidxid,
				 aoEntry->blkdirrelid,
				 aoEntry->blkdiridxid);

		DatabaseInfo_AddPgAppendOnly(
								pgAppendOnlyHashTable,
								relationId,
								aoEntry);
	}
	heap_endscan(scan);

	DirectOpen_PgAppendOnlyClose(pg_appendonly_rel);
	
}

static void
DatabaseInfo_CollectPgClass(
	DatabaseInfo 		*info,
	HTAB				*dbInfoRelHashTable,
	HTAB				*relationIdHashTable,
	int					*count)
{
	Relation	pg_class_rel;

	HeapScanDesc scan;
	HeapTuple	tuple;

	/*
	 * Iterate through all the relations of the database and determine which
	 * database directories are active.  I.e. Fill up the tablespaces array.
	 */
	*count = 0;
	pg_class_rel = 
			DirectOpen_PgClassOpen(
							info->defaultTablespace, 
							info->database);
	scan = heap_beginscan(pg_class_rel, SnapshotNow, 0, NULL);
	while ((tuple = heap_getnext(scan, ForwardScanDirection)) != NULL)
	{
		Oid 			relationOid;

		Form_pg_class	form_pg_class;

		Oid 			reltablespace;

		char			relkind;
		char			relstorage;

		int 			relnatts;

		relationOid = HeapTupleGetOid(tuple);

		form_pg_class = (Form_pg_class) GETSTRUCT(tuple);

		reltablespace = form_pg_class->reltablespace;

		if (reltablespace == 0)
		{
			if (relstorage_is_ao(form_pg_class->relstorage))
				reltablespace = get_database_dts(info->database);
			else
				reltablespace = info->defaultTablespace;
		}

		/*
		 *	Skip non-storage relations.
		 */
		relkind = form_pg_class->relkind;

		if (relkind == RELKIND_VIEW ||
			relkind == RELKIND_COMPOSITE_TYPE)
			continue;

		relstorage = form_pg_class->relstorage;

		if (relstorage == RELSTORAGE_EXTERNAL)
			continue;

		relnatts = form_pg_class->relnatts;

		DatabaseInfo_AddTablespace(
									info, 
									reltablespace);

		DatabaseInfo_AddPgClassStoredRelation(
											info,
											dbInfoRelHashTable,
											relationIdHashTable,
											form_pg_class->relfilenode,
											&tuple->t_self,
											relationOid,
											form_pg_class->relname.data,
											reltablespace,
											relkind,
											relstorage,
											form_pg_class->relam,
											relnatts);

		(*count)++;
	}
	heap_endscan(scan);

	DirectOpen_PgClassClose(pg_class_rel);

}

/*
 * DatabaseInfo_SortRelArray()
 *   Builds the sorted RelArray structure based on a RelHash
 */
static void
DatabaseInfo_SortRelArray(
	DatabaseInfo		*info, 
	HTAB				*dbInfoRelHashTable,
	int					 count)
{
	HASH_SEQ_STATUS		  iterateStatus;
	DbInfoRel			**dbInfoRelPtrArray;
	int					  d;

	/* This function will populate the dbInfoRelArray */
	Assert(info->dbInfoRelArray == NULL);

	/* Construct an array of pointers by scanning through the hash table */
	dbInfoRelPtrArray = (DbInfoRel**) palloc(sizeof(DbInfoRel*) * count);
	hash_seq_init(&iterateStatus, dbInfoRelHashTable);
	for (d = 0; d < count; d++)
	{
		dbInfoRelPtrArray[d] = (DbInfoRel*) hash_seq_search(&iterateStatus);

		/* should have as many entries in the hash scan as "count" */
		if (dbInfoRelPtrArray[d] == NULL)
			elog(ERROR, "insufficient #/entries in dbInfoRelHashTable");
	}

	/* double check that the hash contained the right number of elements */
	if (hash_seq_search(&iterateStatus) != NULL)
		elog(ERROR, "too many entries in dbInfoRelHashTable");
	
	/* sort the pointer array */
	qsort(dbInfoRelPtrArray,
		  count, 
		  sizeof(DbInfoRel*),
		  DbInfoRelPtrArray_Compare);
		   
	/*
	 * Finally convert the sorted pointer array into a sorted record array.
	 */
	info->dbInfoRelArray = (DbInfoRel*) palloc(sizeof(DbInfoRel)*count);
	for (d = 0; d < count; d++)
	{
		info->dbInfoRelArray[d] = *(dbInfoRelPtrArray[d]);
		
		/*
		 * For each record in the array we have three lists:
		 *   - gpRelationNodes
		 *   - appendOnlyCatalogSegmentInfo
		 *   - physicalSegmentFiles 
		 *
		 * All three of which need to be sorted on segmentFileNum otherwise
		 * we will not be able to merge the lists correctly.
		 *
		 * XXX - this seems like a bad design, it seems like we have three
		 * sources of information on the same thing, which should be able
		 * to be satisfied with a single Hash rather than trying to keep 
		 * around three different lists and have code spread throughout the
		 * source trying to deal with merging the lists.
		 */
		if (info->dbInfoRelArray[d].gpRelationNodes)
			qsort(info->dbInfoRelArray[d].gpRelationNodes,
				  info->dbInfoRelArray[d].gpRelationNodesCount,
				  sizeof(DbInfoGpRelationNode),
				  DbInfoGpRelationNode_Compare);
		if (info->dbInfoRelArray[d].appendOnlyCatalogSegmentInfo)
			qsort(info->dbInfoRelArray[d].appendOnlyCatalogSegmentInfo,
				  info->dbInfoRelArray[d].appendOnlyCatalogSegmentInfoCount,
				  sizeof(DbInfoAppendOnlyCatalogSegmentInfo),
				  DbInfoAppendOnlyCatalogSegmentInfo_Compare);
		if (info->dbInfoRelArray[d].physicalSegmentFiles)
			qsort(info->dbInfoRelArray[d].physicalSegmentFiles,
				  info->dbInfoRelArray[d].physicalSegmentFilesCount,
				  sizeof(DbInfoSegmentFile),
				  DbInfoSegmentFile_Compare);
	}
	info->dbInfoRelArrayCount = count;

	/* Release the temporary pointer array and return */
	pfree(dbInfoRelPtrArray);
	return;
}



/*-------------------------------------------------------------------------
 * Exported function definitions
 *------------------------------------------------------------------------- */
DatabaseInfo *
DatabaseInfo_Collect(
	Oid			database,
	Oid 		defaultTablespace,
	bool        collectGpRelationNodeInfo,
	bool		collectAppendOnlyCatalogSegmentInfo,
	bool		scanFileSystem)
{
	DatabaseInfo		 *info;	
	HTAB				 *dbInfoRelHashTable;
	HTAB				 *relationIdHashTable;
	HTAB				 *pgAppendOnlyHashTable;
	int					  count;
	int					  t;

	/* Create local hash tables */
	dbInfoRelHashTable	  = DatabaseInfo_DbInfoRelHashTableInit();
	relationIdHashTable	  = DatabaseInfo_RelationIdHashTableInit();
	pgAppendOnlyHashTable = DatabaseInfo_PgAppendOnlyHashTableInit();

	/* Setup an initial empty DatabaseInfo */
	info = (DatabaseInfo*)palloc0(sizeof(DatabaseInfo));
	info->database							  = database;
	info->defaultTablespace					  = defaultTablespace;
	info->collectGpRelationNodeInfo           = collectGpRelationNodeInfo;
	info->collectAppendOnlyCatalogSegmentInfo = collectAppendOnlyCatalogSegmentInfo;

	/* 
	 * Allocate the extensible arrays:
	 *   - tablespaces
	 *   - miscEntries
	 *   - extraSegmentFiles
	 *   - parentlessGpRelationNodes
	 */
	info->tablespacesMaxCount = 10;
	info->tablespaces		  = palloc0(info->tablespacesMaxCount*sizeof(Oid));

	info->miscEntriesMaxCount = 50;
	info->miscEntries		  = palloc0(info->miscEntriesMaxCount*sizeof(MiscEntry));

	info->extraSegmentFilesMaxCount = 10;
	info->extraSegmentFiles	  = \
		palloc0(info->extraSegmentFilesMaxCount*sizeof(DbInfoExtraSegmentFile));

	info->parentlessGpRelationNodesMaxCount = 10;
	info->parentlessGpRelationNodes =  \
		palloc0(info->parentlessGpRelationNodesMaxCount*sizeof(DbInfoGpRelationNode));

	/* 
	 * During the init process, the tempalte0 and postgres are a little special,
	 * they exist only on the local. But the others will be on hdfs and local!.
	 * XXX:mat3: I'll change this later.
	 */
	if (defaultTablespace != DEFAULTTABLESPACE_OID)
		DatabaseInfo_AddTablespace(info, DEFAULTTABLESPACE_OID);

	/* 
	 * Start Collecting information: 
	 *   - from pg_class
	 *   - from pg_appendonly [if specified]
	 *   - from gp_relation_node [if specified]
	 *   - from file system
	 */
	DatabaseInfo_CollectPgClass(info, dbInfoRelHashTable, relationIdHashTable, &count);
	DatabaseInfo_CollectPgAppendOnly(info, pgAppendOnlyHashTable);

	if (info->collectAppendOnlyCatalogSegmentInfo)
	{
		/*
		 * We need the dbInfoRel hash table to translate pg_appendonly.segrelid
		 * to the ao[cs]seg relfilenode.
		 */
		DatabaseInfo_HandleAppendOnly(info, 
									  dbInfoRelHashTable, 
									  relationIdHashTable, 
									  pgAppendOnlyHashTable);
	}

	/*
	 * Note: this information has not yet been populated when this function is
	 * called during bootstrap or as part of upgrade.  In this case we will be
	 * using the results of this function in order to build the gp_relation
	 * table.
	 */
	if (info->collectGpRelationNodeInfo)
	{
		DatabaseInfo_CollectGpRelationNode(info, dbInfoRelHashTable);
	}

	/*
	 * Scan each used directory for its relation segment files and misc
	 * files/dirs as found within the filesystem.  This /may/ contain some files
	 * not referenced in gp_relation_node that are from crashed backends, but
	 * in general should agree with the set of entries in gp_relation_node.
	 *
	 * Files not present in gp_relation_node will not be mirrored and probably
	 * require removal to maintain database/filesystem consistency.
	 */
	if (scanFileSystem)
	{
		for (t = 0; t < info->tablespacesCount; t++)
		{
			DatabaseInfo_Scan(info, dbInfoRelHashTable, info->tablespaces[t], database);
		}
	}

	/* Convert the dbInfoRelHash into array and sort it. */
	DatabaseInfo_SortRelArray(info, dbInfoRelHashTable, count);
	
	/* Cleanup memory */
	hash_destroy(dbInfoRelHashTable);
	hash_destroy(relationIdHashTable);
	hash_destroy(pgAppendOnlyHashTable);

	/* Return the built DatabaseInfo */
	return info;
}

void 
DatabaseInfo_AlignAppendOnly(
	DatabaseInfo 			*info,

	DbInfoRel 				*dbInfoRel)
{
	int a;
	int g;

	/*
	 * Process the ao[cs]seg entries against the gp_relation_node entries.
	 */
	g = 0;
	for (a = 0; a < dbInfoRel->appendOnlyCatalogSegmentInfoCount; a++)
	{
		DbInfoAppendOnlyCatalogSegmentInfo	*appendOnlyCatalogSegmentInfo =
									&dbInfoRel->appendOnlyCatalogSegmentInfo[a];

		while (true)
		{
			if (g >= dbInfoRel->gpRelationNodesCount)
			{
				if (appendOnlyCatalogSegmentInfo->logicalEof > 0)
					elog(ERROR, "Append-Only relation '%s' segment file #%d has data (logical EOF " INT64_FORMAT ") in the aoseg entry but no gp_relation_node entry!",
						 dbInfoRel->relname,
						 appendOnlyCatalogSegmentInfo->segmentFileNum,
						 appendOnlyCatalogSegmentInfo->logicalEof);

				// Otherwise, ignore ao[cs]seg entries with EOF == 0 and no gp_relation_node entry.
				break;
			}

			if (dbInfoRel->gpRelationNodes[g].segmentFileNum < appendOnlyCatalogSegmentInfo->segmentFileNum)
			{
				if (dbInfoRel->gpRelationNodes[g].segmentFileNum == 0)
				{
					/*
					 * Segment file #0 with always have a gp_relation_node entry, but often doesn't have an aoseg entry.
					 */
					g++;
					continue;
				}
				
				elog(ERROR, "Append-Only relation '%s' gp_relation_node entry for segment file #%d without an aoseg entry (case #1)",
					 dbInfoRel->relname,
					 dbInfoRel->gpRelationNodes[g].segmentFileNum);
			}
			else if (dbInfoRel->gpRelationNodes[g].segmentFileNum == appendOnlyCatalogSegmentInfo->segmentFileNum)
			{
				dbInfoRel->gpRelationNodes[g].logicalEof = appendOnlyCatalogSegmentInfo->logicalEof;
				g++;
				break;
			}
			else
			{
				Assert (dbInfoRel->gpRelationNodes[g].segmentFileNum > appendOnlyCatalogSegmentInfo->segmentFileNum);
				elog(ERROR, "Append-Only relation '%s' gp_relation_node entry for segment file #%d without an aoseg entry",
					 dbInfoRel->relname,
					 dbInfoRel->gpRelationNodes[g].segmentFileNum);
			}
			g++;	// Not reached.  Protect against overly smart compliers looking at exit conditions...
		}
	}

	/*
	 * Drain remaining gp_relation_node entries...
	 */
	while (true)
	{
		if (g >= dbInfoRel->gpRelationNodesCount)
			break;

		if (dbInfoRel->gpRelationNodes[g].segmentFileNum > 0)
			elog(ERROR, "Append-Only relation '%s' gp_relation_node entry for segment file #%d without an aoseg entry (case #2)",
				 dbInfoRel->relname,
				 dbInfoRel->gpRelationNodes[g].segmentFileNum);

		g++;
	}
}
