/*-------------------------------------------------------------------------
 *
 * common.c
 *	  common routines between pg_dump and pg4_dump
 *
 * Since pg4_dump is long-dead code, there is no longer any useful distinction
 * between this file and pg_dump.c.
 *
 * Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
 * Portions Copyright (c) 1994, Regents of the University of California
 *
 *
 * IDENTIFICATION
 *	  $PostgreSQL: pgsql/src/bin/pg_dump/common.c,v 1.94 2006/10/09 23:36:59 tgl Exp $
 *
 *-------------------------------------------------------------------------
 */
#include "postgres_fe.h"

#include <ctype.h>

#include "dumputils.h"
#include "postgres.h"
#include "catalog/pg_class.h"

#include "pg_backup_archiver.h"


/*
 * Variables for mapping DumpId to DumpableObject
 */
static DumpableObject **dumpIdMap = NULL;
static int	allocedDumpIds = 0;
static DumpId lastDumpId = 0;

/*
 * Variables for mapping CatalogId to DumpableObject
 */
static bool catalogIdMapValid = false;
static DumpableObject **catalogIdMap = NULL;
static int	numCatalogIds = 0;

/*
 * These variables are static to avoid the notational cruft of having to pass
 * them into findTableByOid() and friends.
 */
static TableInfo *tblinfo;
static TypeInfo *typinfo;
static TypeStorageOptions *typestorageoptions;
static FuncInfo *funinfo;
static OprInfo *oprinfo;
static int	numTables;
static int	numTypes;
static int  numTypeStorageOptions;
static int	numFuncs;
static int	numOperators;

static void flagInhTables(TableInfo *tbinfo, int numTables,
			  InhInfo *inhinfo, int numInherits);
static void flagInhAttrs(TableInfo *tbinfo, int numTables,
			 InhInfo *inhinfo, int numInherits);
static int	DOCatalogIdCompare(const void *p1, const void *p2);
static void findParentsByOid(TableInfo *self,
				 InhInfo *inhinfo, int numInherits);
static int	strInArray(const char *pattern, char **arr, int arr_size);

void		reset(void);
/*
 * getSchemaData
 *	  Collect information about all potentially dumpable objects
 */
TableInfo *
getSchemaData(int *numTablesPtr)
{
	NamespaceInfo *nsinfo;
	AggInfo    *agginfo;
	InhInfo    *inhinfo;
	RuleInfo   *ruleinfo;
	ProcLangInfo *proclanginfo;
	CastInfo   *castinfo;
	OpclassInfo *opcinfo;
	ConvInfo   *convinfo;
	FdwInfo    *fdwinfo;
	ExtProtInfo *ptcinfo;
	ForeignServerInfo *srvinfo;
	int			numNamespaces;
	int			numAggregates;
	int			numInherits;
	int			numRules;
	int			numProcLangs;
	int			numCasts;
	int			numOpclasses;
	int			numConversions;
	int			numForeignDataWrappers;
	int			numForeignServers;
	int			numExtProtocols;

	if (g_verbose)
		write_msg(NULL, "reading schemas\n");
	nsinfo = getNamespaces(&numNamespaces);

	if (g_verbose)
		write_msg(NULL, "reading user-defined functions\n");
	funinfo = getFuncs(&numFuncs);

	/* this must be after getFuncs */
	if (g_verbose)
		write_msg(NULL, "reading user-defined types\n");
	typinfo = getTypes(&numTypes);

	/* this must be after getFuncs */
	if (g_verbose)
		write_msg(NULL, "reading type storage options\n");
	typestorageoptions = getTypeStorageOptions(&numTypeStorageOptions);

	/* this must be after getFuncs, too */
	if (g_verbose)
		write_msg(NULL, "reading procedural languages\n");
	proclanginfo = getProcLangs(&numProcLangs);

	if (g_verbose)
		write_msg(NULL, "reading user-defined aggregate functions\n");
	agginfo = getAggregates(&numAggregates);

	if (g_verbose)
		write_msg(NULL, "reading user-defined operators\n");
	oprinfo = getOperators(&numOperators);

	if (testExtProtocolSupport())
	{
		if (g_verbose)
			write_msg(NULL, "reading user-defined external protocols\n");
		ptcinfo = getExtProtocols(&numExtProtocols);
	}

	if (g_verbose)
		write_msg(NULL, "reading user-defined operator classes\n");
	opcinfo = getOpclasses(&numOpclasses);

	if (testSqlMedSupport())
	{
		if (g_verbose)
			write_msg(NULL, "reading user-defined foreign-data wrappers\n");
		fdwinfo = getForeignDataWrappers(&numForeignDataWrappers);

		if (g_verbose)
			write_msg(NULL, "reading user-defined foreign servers\n");
		srvinfo = getForeignServers(&numForeignServers);
	}
	else
	{
		fdwinfo = NULL;
		srvinfo = NULL;
		numForeignDataWrappers = 0;
		numForeignServers = 0;
	}

	if (g_verbose)
		write_msg(NULL, "reading user-defined conversions\n");
	convinfo = getConversions(&numConversions);

	if (g_verbose)
		write_msg(NULL, "reading user-defined tables\n");
	tblinfo = getTables(&numTables);

	if (g_verbose)
		write_msg(NULL, "reading table inheritance information\n");
	inhinfo = getInherits(&numInherits);

	if (g_verbose)
		write_msg(NULL, "reading rewrite rules\n");
	ruleinfo = getRules(&numRules);

	if (g_verbose)
		write_msg(NULL, "reading type casts\n");
	castinfo = getCasts(&numCasts);

	/* Link tables to parents, mark parents of target tables interesting */
	if (g_verbose)
		write_msg(NULL, "finding inheritance relationships\n");
	flagInhTables(tblinfo, numTables, inhinfo, numInherits);

	if (g_verbose)
		write_msg(NULL, "reading column info for interesting tables\n");
	getTableAttrs(tblinfo, numTables);

	if (g_verbose)
		write_msg(NULL, "flagging inherited columns in subtables\n");
	flagInhAttrs(tblinfo, numTables, inhinfo, numInherits);

	if (g_verbose)
		write_msg(NULL, "reading indexes\n");
	getIndexes(tblinfo, numTables);

	if (g_verbose)
		write_msg(NULL, "reading constraints\n");
	getConstraints(tblinfo, numTables);

	if (g_verbose)
		write_msg(NULL, "reading triggers\n");
	getTriggers(tblinfo, numTables);

	*numTablesPtr = numTables;
	return tblinfo;
}

/* flagInhTables -
 *	 Fill in parent link fields of every target table, and mark
 *	 parents of target tables as interesting
 *
 * Note that only direct ancestors of targets are marked interesting.
 * This is sufficient; we don't much care whether they inherited their
 * attributes or not.
 *
 * modifies tblinfo
 */
static void
flagInhTables(TableInfo *tblinfo, int numTables,
			  InhInfo *inhinfo, int numInherits)
{
	int			i,
				j;
	int			numParents;
	TableInfo **parents;

	for (i = 0; i < numTables; i++)
	{
		/* Sequences, views and external tables never have parents */
		if (tblinfo[i].relkind == RELKIND_SEQUENCE ||
			tblinfo[i].relkind == RELKIND_VIEW ||
			tblinfo[i].relstorage == RELSTORAGE_EXTERNAL ||
			tblinfo[i].relstorage == RELSTORAGE_FOREIGN)
			continue;

		/* Don't bother computing anything for non-target tables, either */
		if (!tblinfo[i].dobj.dump)
			continue;

		/* Find all the immediate parent tables */
		findParentsByOid(&tblinfo[i], inhinfo, numInherits);

		/* Mark the parents as interesting for getTableAttrs */
		numParents = tblinfo[i].numParents;
		parents = tblinfo[i].parents;
		for (j = 0; j < numParents; j++)
			parents[j]->interesting = true;
	}
}

/* flagInhAttrs -
 *	 for each dumpable table in tblinfo, flag its inherited attributes
 * so when we dump the table out, we don't dump out the inherited attributes
 *
 * modifies tblinfo
 */
static void
flagInhAttrs(TableInfo *tblinfo, int numTables,
			 InhInfo *inhinfo, int numInherits)
{
	int			i,
				j,
				k;

	for (i = 0; i < numTables; i++)
	{
		TableInfo  *tbinfo = &(tblinfo[i]);
		int			numParents;
		TableInfo **parents;
		TableInfo  *parent;

		/* Sequences, views and external tables never have parents */
		if (tbinfo->relkind == RELKIND_SEQUENCE ||
			tbinfo->relkind == RELKIND_VIEW ||
			tbinfo->relstorage == RELSTORAGE_EXTERNAL ||
			tbinfo->relstorage == RELSTORAGE_FOREIGN)
			continue;

		/* Don't bother computing anything for non-target tables, either */
		if (!tbinfo->dobj.dump)
			continue;

		numParents = tbinfo->numParents;
		parents = tbinfo->parents;

		if (numParents == 0)
			continue;			/* nothing to see here, move along */

		/*----------------------------------------------------------------
		 * For each attr, check the parent info: if no parent has an attr
		 * with the same name, then it's not inherited. If there *is* an
		 * attr with the same name, then only dump it if:
		 *
		 * - it is NOT NULL and zero parents are NOT NULL
		 *	 OR
		 * - it has a default value AND the default value does not match
		 *	 all parent default values, or no parents specify a default.
		 *
		 * See discussion on -hackers around 2-Apr-2001.
		 *----------------------------------------------------------------
		 */
		for (j = 0; j < tbinfo->numatts; j++)
		{
			bool		foundAttr;		/* Attr was found in a parent */
			bool		foundNotNull;	/* Attr was NOT NULL in a parent */
			bool		defaultsMatch;	/* All non-empty defaults match */
			bool		defaultsFound;	/* Found a default in a parent */
			AttrDefInfo *attrDef;

			foundAttr = false;
			foundNotNull = false;
			defaultsMatch = true;
			defaultsFound = false;

			attrDef = tbinfo->attrdefs[j];

			for (k = 0; k < numParents; k++)
			{
				int			inhAttrInd;

				parent = parents[k];
				inhAttrInd = strInArray(tbinfo->attnames[j],
										parent->attnames,
										parent->numatts);

				if (inhAttrInd != -1)
				{
					AttrDefInfo *inhDef = parent->attrdefs[inhAttrInd];

					foundAttr = true;
					foundNotNull |= parent->notnull[inhAttrInd];
					if (inhDef != NULL)
					{
						defaultsFound = true;

						/*
						 * If any parent has a default and the child doesn't,
						 * we have to emit an explicit DEFAULT NULL clause for
						 * the child, else the parent's default will win.
						 */
						if (attrDef == NULL)
						{
							attrDef = (AttrDefInfo *) malloc(sizeof(AttrDefInfo));
							attrDef->dobj.objType = DO_ATTRDEF;
							attrDef->dobj.catId.tableoid = 0;
							attrDef->dobj.catId.oid = 0;
							AssignDumpId(&attrDef->dobj);
							attrDef->adtable = tbinfo;
							attrDef->adnum = j + 1;
							attrDef->adef_expr = strdup("NULL");

							attrDef->dobj.name = strdup(tbinfo->dobj.name);
							attrDef->dobj.namespace = tbinfo->dobj.namespace;

							attrDef->dobj.dump = tbinfo->dobj.dump;

							attrDef->separate = false;
							addObjectDependency(&tbinfo->dobj,
												attrDef->dobj.dumpId);

							tbinfo->attrdefs[j] = attrDef;
						}
						if (strcmp(attrDef->adef_expr, inhDef->adef_expr) != 0)
						{
							defaultsMatch = false;

							/*
							 * Whenever there is a non-matching parent
							 * default, add a dependency to force the parent
							 * default to be dumped first, in case the
							 * defaults end up being dumped as separate
							 * commands.  Otherwise the parent default will
							 * override the child's when it is applied.
							 */
							addObjectDependency(&attrDef->dobj,
												inhDef->dobj.dumpId);
						}
					}
				}
			}

			/*
			 * Based on the scan of the parents, decide if we can rely on the
			 * inherited attr
			 */
			if (foundAttr)		/* Attr was inherited */
			{
				/* Set inherited flag by default */
				tbinfo->inhAttrs[j] = true;
				tbinfo->inhAttrDef[j] = true;
				tbinfo->inhNotNull[j] = true;

				/*
				 * Clear it if attr had a default, but parents did not, or
				 * mismatch
				 */
				if ((attrDef != NULL) && (!defaultsFound || !defaultsMatch))
				{
					tbinfo->inhAttrs[j] = false;
					tbinfo->inhAttrDef[j] = false;
				}

				/*
				 * Clear it if NOT NULL and none of the parents were NOT NULL
				 */
				if (tbinfo->notnull[j] && !foundNotNull)
				{
					tbinfo->inhAttrs[j] = false;
					tbinfo->inhNotNull[j] = false;
				}

				/* Clear it if attr has local definition */
				if (tbinfo->attislocal[j])
					tbinfo->inhAttrs[j] = false;
			}
		}

		/*
		 * Check for inherited CHECK constraints.  We assume a constraint is
		 * inherited if its name matches the name of any constraint in the
		 * parent.	Originally this code tried to compare the expression
		 * texts, but that can fail if the parent and child tables are in
		 * different schemas, because reverse-listing of function calls may
		 * produce different text (schema-qualified or not) depending on
		 * search path.  We really need a more bulletproof way of detecting
		 * inherited constraints --- pg_constraint should record this
		 * explicitly!
		 */
		for (j = 0; j < tbinfo->ncheck; j++)
		{
			ConstraintInfo *constr;

			constr = &(tbinfo->checkexprs[j]);

			for (k = 0; k < numParents; k++)
			{
				int			l;

				parent = parents[k];
				for (l = 0; l < parent->ncheck; l++)
				{
					ConstraintInfo *pconstr = &(parent->checkexprs[l]);

					if (strcmp(pconstr->dobj.name, constr->dobj.name) == 0)
					{
						constr->coninherited = true;
						break;
					}
				}
				if (constr->coninherited)
					break;
			}
		}
	}
}

/*
 * MPP-1890
 *
 * If the user explicitly DROP'ed a CHECK constraint on a child but it
 * still exists on the parent when they dump and restore that constraint
 * will exist on the child since it will again inherit it from the
 * parent. Therefore we look here for constraints that exist on the
 * parent but not on the child and mark them to be dropped from the
 * child after the child table is defined.
 *
 * Loop through each parent and for each parent constraint see if it
 * exists on the child as well. If it doesn't it means that the child
 * dropped it. Mark it.
 */
void
DetectChildConstraintDropped(TableInfo *tbinfo, PQExpBuffer q)
{
	TableInfo  *parent;
	TableInfo **parents = tbinfo->parents;
	int			j,
				k,
				l;
	int			numParents = tbinfo->numParents;

	for (k = 0; k < numParents; k++)
	{
		parent = parents[k];

		/* for each CHECK constraint of this parent */
		for (l = 0; l < parent->ncheck; l++)
		{
			ConstraintInfo *pconstr = &(parent->checkexprs[l]);
			ConstraintInfo *cconstr;
			bool		constr_on_child = false;

			/* for each child CHECK constraint */
			for (j = 0; j < tbinfo->ncheck; j++)
			{
				cconstr = &(tbinfo->checkexprs[j]);

				if (strcmp(pconstr->dobj.name, cconstr->dobj.name) == 0)
				{
					/* parent constr exists on child. hence wasn't dropped */
					constr_on_child = true;
					break;
				}

			}

			/* this parent constr is not on child, issue a DROP for it */
			if (!constr_on_child)
			{
				appendPQExpBuffer(q, "ALTER TABLE %s.",
								  fmtId(tbinfo->dobj.namespace->dobj.name));
				appendPQExpBuffer(q, "%s ",
								  fmtId(tbinfo->dobj.name));
				appendPQExpBuffer(q, "DROP CONSTRAINT %s;\n",
								  fmtId(pconstr->dobj.name));

				constr_on_child = false;
			}
		}
	}

}

/*
 * AssignDumpId
 *		Given a newly-created dumpable object, assign a dump ID,
 *		and enter the object into the lookup table.
 *
 * The caller is expected to have filled in objType and catId,
 * but not any of the other standard fields of a DumpableObject.
 */
void
AssignDumpId(DumpableObject *dobj)
{
	dobj->dumpId = ++lastDumpId;
	dobj->name = NULL;			/* must be set later */
	dobj->namespace = NULL;		/* may be set later */
	dobj->dump = true;			/* default assumption */
	dobj->dependencies = NULL;
	dobj->nDeps = 0;
	dobj->allocDeps = 0;

	while (dobj->dumpId >= allocedDumpIds)
	{
		int			newAlloc;

		if (allocedDumpIds <= 0)
		{
			newAlloc = 256;
			dumpIdMap = (DumpableObject **)
				pg_malloc(newAlloc * sizeof(DumpableObject *));
		}
		else
		{
			newAlloc = allocedDumpIds * 2;
			dumpIdMap = (DumpableObject **)
				pg_realloc(dumpIdMap, newAlloc * sizeof(DumpableObject *));
		}
		memset(dumpIdMap + allocedDumpIds, 0,
			   (newAlloc - allocedDumpIds) * sizeof(DumpableObject *));
		allocedDumpIds = newAlloc;
	}
	dumpIdMap[dobj->dumpId] = dobj;

	/* mark catalogIdMap invalid, but don't rebuild it yet */
	catalogIdMapValid = false;
}

/*
 * Assign a DumpId that's not tied to a DumpableObject.
 *
 * This is used when creating a "fixed" ArchiveEntry that doesn't need to
 * participate in the sorting logic.
 */
DumpId
createDumpId(void)
{
	return ++lastDumpId;
}

/*
 * Return the largest DumpId so far assigned
 */
DumpId
getMaxDumpId(void)
{
	return lastDumpId;
}

/*
 * Find a DumpableObject by dump ID
 *
 * Returns NULL for invalid ID
 */
DumpableObject *
findObjectByDumpId(DumpId dumpId)
{
	if (dumpId <= 0 || dumpId >= allocedDumpIds)
		return NULL;			/* out of range? */
	return dumpIdMap[dumpId];
}

/*
 * Find a DumpableObject by catalog ID
 *
 * Returns NULL for unknown ID
 *
 * We use binary search in a sorted list that is built on first call.
 * If AssignDumpId() and findObjectByCatalogId() calls were intermixed,
 * the code would work, but possibly be very slow.	In the current usage
 * pattern that does not happen, indeed we only need to build the list once.
 */
DumpableObject *
findObjectByCatalogId(CatalogId catalogId)
{
	DumpableObject **low;
	DumpableObject **high;

	if (!catalogIdMapValid)
	{
		if (catalogIdMap)
			free(catalogIdMap);
		getDumpableObjects(&catalogIdMap, &numCatalogIds);
		if (numCatalogIds > 1)
			qsort((void *) catalogIdMap, numCatalogIds,
				  sizeof(DumpableObject *), DOCatalogIdCompare);
		catalogIdMapValid = true;
	}

	/*
	 * We could use bsearch() here, but the notational cruft of calling
	 * bsearch is nearly as bad as doing it ourselves; and the generalized
	 * bsearch function is noticeably slower as well.
	 */
	if (numCatalogIds <= 0)
		return NULL;
	low = catalogIdMap;
	high = catalogIdMap + (numCatalogIds - 1);
	while (low <= high)
	{
		DumpableObject **middle;
		int			difference;

		middle = low + (high - low) / 2;
		/* comparison must match DOCatalogIdCompare, below */
		difference = oidcmp((*middle)->catId.oid, catalogId.oid);
		if (difference == 0)
			difference = oidcmp((*middle)->catId.tableoid, catalogId.tableoid);
		if (difference == 0)
			return *middle;
		else if (difference < 0)
			low = middle + 1;
		else
			high = middle - 1;
	}
	return NULL;
}

static int
DOCatalogIdCompare(const void *p1, const void *p2)
{
	DumpableObject *obj1 = *(DumpableObject **) p1;
	DumpableObject *obj2 = *(DumpableObject **) p2;
	int			cmpval;

	/*
	 * Compare OID first since it's usually unique, whereas there will only be
	 * a few distinct values of tableoid.
	 */
	cmpval = oidcmp(obj1->catId.oid, obj2->catId.oid);
	if (cmpval == 0)
		cmpval = oidcmp(obj1->catId.tableoid, obj2->catId.tableoid);
	return cmpval;
}

/*
 * Build an array of pointers to all known dumpable objects
 *
 * This simply creates a modifiable copy of the internal map.
 */
void
getDumpableObjects(DumpableObject ***objs, int *numObjs)
{
	int			i,
				j;

	*objs = (DumpableObject **)
		pg_malloc(allocedDumpIds * sizeof(DumpableObject *));
	j = 0;
	for (i = 1; i < allocedDumpIds; i++)
	{
		if (dumpIdMap[i])
			(*objs)[j++] = dumpIdMap[i];
	}
	*numObjs = j;
}

/*
 * Add a dependency link to a DumpableObject
 *
 * Note: duplicate dependencies are currently not eliminated
 */
void
addObjectDependency(DumpableObject *dobj, DumpId refId)
{
	if (dobj->nDeps >= dobj->allocDeps)
	{
		if (dobj->allocDeps <= 0)
		{
			dobj->allocDeps = 16;
			dobj->dependencies = (DumpId *)
				pg_malloc(dobj->allocDeps * sizeof(DumpId));
		}
		else
		{
			dobj->allocDeps *= 2;
			dobj->dependencies = (DumpId *)
				pg_realloc(dobj->dependencies,
						   dobj->allocDeps * sizeof(DumpId));
		}
	}
	dobj->dependencies[dobj->nDeps++] = refId;
}

/*
 * Remove a dependency link from a DumpableObject
 *
 * If there are multiple links, all are removed
 */
void
removeObjectDependency(DumpableObject *dobj, DumpId refId)
{
	int			i;
	int			j = 0;

	for (i = 0; i < dobj->nDeps; i++)
	{
		if (dobj->dependencies[i] != refId)
			dobj->dependencies[j++] = dobj->dependencies[i];
	}
	dobj->nDeps = j;
}


/*
 * findTableByOid
 *	  finds the entry (in tblinfo) of the table with the given oid
 *	  returns NULL if not found
 *
 * NOTE:  should hash this, but just do linear search for now
 */
TableInfo *
findTableByOid(Oid oid)
{
	int			i;

	for (i = 0; i < numTables; i++)
	{
		if (tblinfo[i].dobj.catId.oid == oid)
			return &tblinfo[i];
	}
	return NULL;
}

/*
 * findTypeByOid
 *	  finds the entry (in typinfo) of the type with the given oid
 *	  returns NULL if not found
 *
 * NOTE:  should hash this, but just do linear search for now
 */
TypeInfo *
findTypeByOid(Oid oid)
{
	int			i;

	for (i = 0; i < numTypes; i++)
	{
		if (typinfo[i].dobj.catId.oid == oid)
			return &typinfo[i];
	}
	return NULL;
}

/*
 * findFuncByOid
 *	  finds the entry (in funinfo) of the function with the given oid
 *	  returns NULL if not found
 *
 * NOTE:  should hash this, but just do linear search for now
 */
FuncInfo *
findFuncByOid(Oid oid)
{
	int			i;

	for (i = 0; i < numFuncs; i++)
	{
		if (funinfo[i].dobj.catId.oid == oid)
			return &funinfo[i];
	}
	return NULL;
}

/*
 * findOprByOid
 *	  finds the entry (in oprinfo) of the operator with the given oid
 *	  returns NULL if not found
 *
 * NOTE:  should hash this, but just do linear search for now
 */
OprInfo *
findOprByOid(Oid oid)
{
	int			i;

	for (i = 0; i < numOperators; i++)
	{
		if (oprinfo[i].dobj.catId.oid == oid)
			return &oprinfo[i];
	}
	return NULL;
}


/*
 * findParentsByOid
 *	  find a table's parents in tblinfo[]
 */
static void
findParentsByOid(TableInfo *self,
				 InhInfo *inhinfo, int numInherits)
{
	Oid			oid = self->dobj.catId.oid;
	int			i,
				j;
	int			numParents;

	numParents = 0;
	for (i = 0; i < numInherits; i++)
	{
		if (inhinfo[i].inhrelid == oid)
			numParents++;
	}

	self->numParents = numParents;

	if (numParents > 0)
	{
		self->parents = (TableInfo **)
			pg_malloc(sizeof(TableInfo *) * numParents);
		j = 0;
		for (i = 0; i < numInherits; i++)
		{
			if (inhinfo[i].inhrelid == oid)
			{
				TableInfo  *parent;

				parent = findTableByOid(inhinfo[i].inhparent);
				if (parent == NULL)
				{
					write_msg(NULL, "failed sanity check, parent OID %u of table \"%s\" (OID %u) not found\n",
							  inhinfo[i].inhparent,
							  self->dobj.name,
							  oid);
					exit_nicely();
				}
				self->parents[j++] = parent;
			}
		}
	}
	else
		self->parents = NULL;
}

/*
 * parseOidArray
 *	  parse a string of numbers delimited by spaces into a character array
 *
 * Note: actually this is used for both Oids and potentially-signed
 * attribute numbers.  This should cause no trouble, but we could split
 * the function into two functions with different argument types if it does.
 */

void
parseOidArray(const char *str, Oid *array, int arraysize)
{
	int			j,
				argNum;
	char		temp[100];
	char		s;

	argNum = 0;
	j = 0;
	for (;;)
	{
		s = *str++;
		if (s == ' ' || s == '\0')
		{
			if (j > 0)
			{
				if (argNum >= arraysize)
				{
					write_msg(NULL, "could not parse numeric array \"%s\": too many numbers\n", str);
					exit_nicely();
				}
				temp[j] = '\0';
				array[argNum++] = atooid(temp);
				j = 0;
			}
			if (s == '\0')
				break;
		}
		else
		{
			if (!(isdigit((unsigned char) s) || s == '-') ||
				j >= sizeof(temp) - 1)
			{
				write_msg(NULL, "could not parse numeric array \"%s\": invalid character in number\n", str);
				exit_nicely();
			}
			temp[j++] = s;
		}
	}

	while (argNum < arraysize)
		array[argNum++] = InvalidOid;
}


/*
 * strInArray:
 *	  takes in a string and a string array and the number of elements in the
 * string array.
 *	  returns the index if the string is somewhere in the array, -1 otherwise
 */

static int
strInArray(const char *pattern, char **arr, int arr_size)
{
	int			i;

	for (i = 0; i < arr_size; i++)
	{
		if (strcmp(pattern, arr[i]) == 0)
			return i;
	}
	return -1;
}


/* cdb addition */
void
reset(void)
{
	free(dumpIdMap);
	dumpIdMap = NULL;
	allocedDumpIds = 0;
	lastDumpId = 0;

/*
 * Variables for mapping CatalogId to DumpableObject
 */
	catalogIdMapValid = false;
	free(catalogIdMap);
	catalogIdMap = NULL;
	numCatalogIds = 0;

	numTables = 0;
	numTypes = 0;
	numFuncs = 0;
	numOperators = 0;
}

/* end cdb_addition */


/*
 * Support for simple list operations
 */

void
simple_oid_list_append(SimpleOidList *list, Oid val)
{
	SimpleOidListCell *cell;

	cell = (SimpleOidListCell *) pg_malloc(sizeof(SimpleOidListCell));
	cell->next = NULL;
	cell->val = val;

	if (list->tail)
		list->tail->next = cell;
	else
		list->head = cell;
	list->tail = cell;
}

void
simple_string_list_append(SimpleStringList *list, const char *val)
{
	SimpleStringListCell *cell;

	/* this calculation correctly accounts for the null trailing byte */
	cell = (SimpleStringListCell *)
		pg_malloc(sizeof(SimpleStringListCell) + strlen(val));
	cell->next = NULL;
	strcpy(cell->val, val);

	if (list->tail)
		list->tail->next = cell;
	else
		list->head = cell;
	list->tail = cell;
}

bool
simple_oid_list_member(SimpleOidList *list, Oid val)
{
	SimpleOidListCell *cell;

	for (cell = list->head; cell; cell = cell->next)
	{
		if (cell->val == val)
			return true;
	}
	return false;
}

bool
simple_string_list_member(SimpleStringList *list, const char *val)
{
	SimpleStringListCell *cell;

	for (cell = list->head; cell; cell = cell->next)
	{
		if (strcmp(cell->val, val) == 0)
			return true;
	}
	return false;
}


/*
 * openFileAndAppendToList: Read parameters from file
 * and append values to given list.
 * (Used to read multiple include/exclude tables.)
 *
 * reason - list name, to be logged.
 *
 * File format: one value per line.
 */
bool
open_file_and_append_to_list(const char *fileName, SimpleStringList *list, const char *reason)
{

	char buf[1024];

	write_msg(NULL, "Opening file %s for %s\n", fileName, reason);

	FILE* file = fopen(fileName, "r");

	if (file == NULL)
		return false;

	int lineNum = 0;
	while (fgets(buf, sizeof(buf), file) != NULL)
	{
		int size = strlen(buf);
		if (buf[size-1] == '\n')
			buf[size-1] = '\0'; /* remove new line */

		write_msg(NULL, "Line #%d, value: %s\n", ++lineNum, buf);
		simple_string_list_append(list, buf);
	}
	write_msg(NULL, "Got %d lines from file %s\n", lineNum, fileName);
	if (fclose(file) != 0)
		return false;

	write_msg(NULL, "Finished reading file %s successfully\n", fileName);

	return true;

}


/*
 * Safer versions of some standard C library functions. If an
 * out-of-memory condition occurs, these functions will bail out
 * safely; therefore, their return value is guaranteed to be non-NULL.
 *
 * XXX need to refactor things so that these can be in a file that can be
 * shared by pg_dumpall and pg_restore as well as pg_dump.
 */

char *
pg_strdup(const char *string)
{
	char	   *tmp;

	if (!string)
		exit_horribly(NULL, NULL, "cannot duplicate null pointer\n");
	tmp = strdup(string);
	if (!tmp)
		exit_horribly(NULL, NULL, "out of memory\n");
	return tmp;
}

void *
pg_malloc(size_t size)
{
	void	   *tmp;

	tmp = malloc(size);
	if (!tmp)
		exit_horribly(NULL, NULL, "out of memory\n");
	return tmp;
}

void *
pg_calloc(size_t nmemb, size_t size)
{
	void	   *tmp;

	tmp = calloc(nmemb, size);
	if (!tmp)
		exit_horribly(NULL, NULL, "out of memory\n");
	return tmp;
}

void *
pg_realloc(void *ptr, size_t size)
{
	void	   *tmp;

	tmp = realloc(ptr, size);
	if (!tmp)
		exit_horribly(NULL, NULL, "out of memory\n");
	return tmp;
}
