From 9a7d49d1fba666c8bfb9df0065545e85d54dbc41 Mon Sep 17 00:00:00 2001
From: Bruce Momjian <bruce@momjian.us>
Date: Sat, 26 Nov 2011 22:34:36 -0500
Subject: [PATCH] Move pg_dump memory routines into pg_dumpmem.c/h and restore
 common.c with its original functions.  The previous function migration would
 cause too many difficulties in back-patching.

---
 src/bin/pg_dump/Makefile                |   6 +-
 src/bin/pg_dump/common.c                | 982 +++++++++++++++++++++++-
 src/bin/pg_dump/compress_io.c           |   2 +-
 src/bin/pg_dump/dumpcatalog.c           | 978 -----------------------
 src/bin/pg_dump/dumpmem.c               |  73 ++
 src/bin/pg_dump/{common.h => dumpmem.h} |  12 +-
 src/bin/pg_dump/dumputils.c             |   2 +-
 src/bin/pg_dump/pg_backup_archiver.c    |   2 +-
 src/bin/pg_dump/pg_backup_custom.c      |   2 +-
 src/bin/pg_dump/pg_backup_db.c          |   2 +-
 src/bin/pg_dump/pg_backup_directory.c   |   2 +-
 src/bin/pg_dump/pg_backup_files.c       |   2 +-
 src/bin/pg_dump/pg_backup_null.c        |   2 +-
 src/bin/pg_dump/pg_backup_tar.c         |   2 +-
 src/bin/pg_dump/pg_dump.c               |   2 +-
 src/bin/pg_dump/pg_dump_sort.c          |   2 +-
 src/bin/pg_dump/pg_restore.c            |   2 +-
 17 files changed, 1038 insertions(+), 1037 deletions(-)
 delete mode 100644 src/bin/pg_dump/dumpcatalog.c
 create mode 100644 src/bin/pg_dump/dumpmem.c
 rename src/bin/pg_dump/{common.h => dumpmem.h} (75%)

diff --git a/src/bin/pg_dump/Makefile b/src/bin/pg_dump/Makefile
index 9d13bec7933..4e8e421ba1e 100644
--- a/src/bin/pg_dump/Makefile
+++ b/src/bin/pg_dump/Makefile
@@ -20,7 +20,7 @@ override CPPFLAGS := -I$(libpq_srcdir) $(CPPFLAGS)
 
 OBJS=	pg_backup_archiver.o pg_backup_db.o pg_backup_custom.o \
 	pg_backup_files.o pg_backup_null.o pg_backup_tar.o \
-	pg_backup_directory.o common.o dumputils.o compress_io.o $(WIN32RES)
+	pg_backup_directory.o dumpmem.o dumputils.o compress_io.o $(WIN32RES)
 
 KEYWRDOBJS = keywords.o kwlookup.o
 
@@ -29,8 +29,8 @@ kwlookup.c: % : $(top_srcdir)/src/backend/parser/%
 
 all: pg_dump pg_restore pg_dumpall
 
-pg_dump: pg_dump.o dumpcatalog.o pg_dump_sort.o $(OBJS) $(KEYWRDOBJS) | submake-libpq submake-libpgport
-	$(CC) $(CFLAGS) pg_dump.o dumpcatalog.o pg_dump_sort.o $(KEYWRDOBJS) $(OBJS) $(libpq_pgport) $(LDFLAGS) $(LDFLAGS_EX) $(LIBS) -o $@$(X)
+pg_dump: pg_dump.o common.o pg_dump_sort.o $(OBJS) $(KEYWRDOBJS) | submake-libpq submake-libpgport
+	$(CC) $(CFLAGS) pg_dump.o common.o pg_dump_sort.o $(KEYWRDOBJS) $(OBJS) $(libpq_pgport) $(LDFLAGS) $(LDFLAGS_EX) $(LIBS) -o $@$(X)
 
 pg_restore: pg_restore.o $(OBJS) $(KEYWRDOBJS) | submake-libpq submake-libpgport
 	$(CC) $(CFLAGS) pg_restore.o $(KEYWRDOBJS) $(OBJS) $(libpq_pgport) $(LDFLAGS) $(LDFLAGS_EX) $(LIBS) -o $@$(X)
diff --git a/src/bin/pg_dump/common.c b/src/bin/pg_dump/common.c
index 1a3f4cb6e8e..6f921f7758c 100644
--- a/src/bin/pg_dump/common.c
+++ b/src/bin/pg_dump/common.c
@@ -1,8 +1,8 @@
 /*-------------------------------------------------------------------------
  *
  * common.c
- *	  common routines between pg_dump and pg_restore (but not pg_dumpall
- *	  because there is no failure location to report).
+ *	catalog routines used by pg_dump;  long ago these were shared
+ *	by another dump tool, but not anymore.  
  *
  * Portions Copyright (c) 1996-2011, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
@@ -14,60 +14,966 @@
  *-------------------------------------------------------------------------
  */
 #include "postgres_fe.h"
-#include "pg_backup.h"
-#include "common.h"
 
 #include <ctype.h>
 
+#include "catalog/pg_class.h"
+
+#include "pg_backup_archiver.h"
+#include "dumpmem.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.	For each of these arrays, we
+ * build a sorted-by-OID index array immediately after it's built, and then
+ * we use binary search in findTableByOid() and friends.  (qsort'ing the base
+ * arrays themselves would be simpler, but it doesn't work because pg_dump.c
+ * may have already established pointers between items.)
+ */
+static TableInfo *tblinfo;
+static TypeInfo *typinfo;
+static FuncInfo *funinfo;
+static OprInfo *oprinfo;
+static int	numTables;
+static int	numTypes;
+static int	numFuncs;
+static int	numOperators;
+static int	numCollations;
+static DumpableObject **tblinfoindex;
+static DumpableObject **typinfoindex;
+static DumpableObject **funinfoindex;
+static DumpableObject **oprinfoindex;
+static DumpableObject **collinfoindex;
+
+
+static void flagInhTables(TableInfo *tbinfo, int numTables,
+			  InhInfo *inhinfo, int numInherits);
+static void flagInhAttrs(TableInfo *tblinfo, int numTables);
+static DumpableObject **buildIndexArray(void *objArray, int numObjs,
+				Size objSize);
+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);
+
+
 /*
- * 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.
- * We also report the program name and close the database connection.
+ * getSchemaData
+ *	  Collect information about all potentially dumpable objects
  */
+TableInfo *
+getSchemaData(int *numTablesPtr)
+{
+	ExtensionInfo *extinfo;
+	InhInfo    *inhinfo;
+	CollInfo   *collinfo;
+	int			numNamespaces;
+	int			numExtensions;
+	int			numAggregates;
+	int			numInherits;
+	int			numRules;
+	int			numProcLangs;
+	int			numCasts;
+	int			numOpclasses;
+	int			numOpfamilies;
+	int			numConversions;
+	int			numTSParsers;
+	int			numTSTemplates;
+	int			numTSDicts;
+	int			numTSConfigs;
+	int			numForeignDataWrappers;
+	int			numForeignServers;
+	int			numDefaultACLs;
+
+	if (g_verbose)
+		write_msg(NULL, "reading schemas\n");
+	getNamespaces(&numNamespaces);
+
+	/*
+	 * getTables should be done as soon as possible, so as to minimize the
+	 * window between starting our transaction and acquiring per-table locks.
+	 * However, we have to do getNamespaces first because the tables get
+	 * linked to their containing namespaces during getTables.
+	 */
+	if (g_verbose)
+		write_msg(NULL, "reading user-defined tables\n");
+	tblinfo = getTables(&numTables);
+	tblinfoindex = buildIndexArray(tblinfo, numTables, sizeof(TableInfo));
+
+	if (g_verbose)
+		write_msg(NULL, "reading extensions\n");
+	extinfo = getExtensions(&numExtensions);
+
+	if (g_verbose)
+		write_msg(NULL, "reading user-defined functions\n");
+	funinfo = getFuncs(&numFuncs);
+	funinfoindex = buildIndexArray(funinfo, numFuncs, sizeof(FuncInfo));
+
+	/* this must be after getTables and getFuncs */
+	if (g_verbose)
+		write_msg(NULL, "reading user-defined types\n");
+	typinfo = getTypes(&numTypes);
+	typinfoindex = buildIndexArray(typinfo, numTypes, sizeof(TypeInfo));
+
+	/* this must be after getFuncs, too */
+	if (g_verbose)
+		write_msg(NULL, "reading procedural languages\n");
+	getProcLangs(&numProcLangs);
+
+	if (g_verbose)
+		write_msg(NULL, "reading user-defined aggregate functions\n");
+	getAggregates(&numAggregates);
+
+	if (g_verbose)
+		write_msg(NULL, "reading user-defined operators\n");
+	oprinfo = getOperators(&numOperators);
+	oprinfoindex = buildIndexArray(oprinfo, numOperators, sizeof(OprInfo));
+
+	if (g_verbose)
+		write_msg(NULL, "reading user-defined operator classes\n");
+	getOpclasses(&numOpclasses);
+
+	if (g_verbose)
+		write_msg(NULL, "reading user-defined operator families\n");
+	getOpfamilies(&numOpfamilies);
+
+	if (g_verbose)
+		write_msg(NULL, "reading user-defined text search parsers\n");
+	getTSParsers(&numTSParsers);
+
+	if (g_verbose)
+		write_msg(NULL, "reading user-defined text search templates\n");
+	getTSTemplates(&numTSTemplates);
 
-char *
-pg_strdup(const char *string)
+	if (g_verbose)
+		write_msg(NULL, "reading user-defined text search dictionaries\n");
+	getTSDictionaries(&numTSDicts);
+
+	if (g_verbose)
+		write_msg(NULL, "reading user-defined text search configurations\n");
+	getTSConfigurations(&numTSConfigs);
+
+	if (g_verbose)
+		write_msg(NULL, "reading user-defined foreign-data wrappers\n");
+	getForeignDataWrappers(&numForeignDataWrappers);
+
+	if (g_verbose)
+		write_msg(NULL, "reading user-defined foreign servers\n");
+	getForeignServers(&numForeignServers);
+
+	if (g_verbose)
+		write_msg(NULL, "reading default privileges\n");
+	getDefaultACLs(&numDefaultACLs);
+
+	if (g_verbose)
+		write_msg(NULL, "reading user-defined collations\n");
+	collinfo = getCollations(&numCollations);
+	collinfoindex = buildIndexArray(collinfo, numCollations, sizeof(CollInfo));
+
+	if (g_verbose)
+		write_msg(NULL, "reading user-defined conversions\n");
+	getConversions(&numConversions);
+
+	if (g_verbose)
+		write_msg(NULL, "reading type casts\n");
+	getCasts(&numCasts);
+
+	if (g_verbose)
+		write_msg(NULL, "reading table inheritance information\n");
+	inhinfo = getInherits(&numInherits);
+
+	if (g_verbose)
+		write_msg(NULL, "reading rewrite rules\n");
+	getRules(&numRules);
+
+	/*
+	 * Identify extension member objects and mark them as not to be dumped.
+	 * This must happen after reading all objects that can be direct members
+	 * of extensions, but before we begin to process table subsidiary objects.
+	 */
+	if (g_verbose)
+		write_msg(NULL, "finding extension members\n");
+	getExtensionMembership(extinfo, numExtensions);
+
+	/* 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);
+
+	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)
 {
-	char	   *tmp;
+	int			i,
+				j;
+	int			numParents;
+	TableInfo **parents;
+
+	for (i = 0; i < numTables; i++)
+	{
+		/* Sequences and views never have parents */
+		if (tblinfo[i].relkind == RELKIND_SEQUENCE ||
+			tblinfo[i].relkind == RELKIND_VIEW)
+			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);
 
-	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;
+		/* 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;
+	}
 }
 
-void *
-pg_malloc(size_t size)
+/* 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)
 {
-	void	   *tmp;
+	int			i,
+				j,
+				k;
+
+	for (i = 0; i < numTables; i++)
+	{
+		TableInfo  *tbinfo = &(tblinfo[i]);
+		int			numParents;
+		TableInfo **parents;
+		TableInfo  *parent;
+
+		/* Sequences and views never have parents */
+		if (tbinfo->relkind == RELKIND_SEQUENCE ||
+			tbinfo->relkind == RELKIND_VIEW)
+			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 *) pg_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 = pg_strdup("NULL");
+
+							attrDef->dobj.name = pg_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;
+			}
+		}
+	}
+}
+
+/*
+ * 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->ext_member = false;	/* 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 freely intermixed,
+ * the code would work, but possibly be very slow.	In the current usage
+ * pattern that does not happen, indeed we build the list at most twice.
+ */
+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;
+}
+
+/*
+ * Find a DumpableObject by OID, in a pre-sorted array of one type of object
+ *
+ * Returns NULL for unknown OID
+ */
+static DumpableObject *
+findObjectByOid(Oid oid, DumpableObject **indexArray, int numObjs)
+{
+	DumpableObject **low;
+	DumpableObject **high;
+
+	/*
+	 * This is the same as findObjectByCatalogId except we assume we need not
+	 * look at table OID because the objects are all the same type.
+	 *
+	 * 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 (numObjs <= 0)
+		return NULL;
+	low = indexArray;
+	high = indexArray + (numObjs - 1);
+	while (low <= high)
+	{
+		DumpableObject **middle;
+		int			difference;
+
+		middle = low + (high - low) / 2;
+		difference = oidcmp((*middle)->catId.oid, oid);
+		if (difference == 0)
+			return *middle;
+		else if (difference < 0)
+			low = middle + 1;
+		else
+			high = middle - 1;
+	}
+	return NULL;
+}
+
+/*
+ * Build an index array of DumpableObject pointers, sorted by OID
+ */
+static DumpableObject **
+buildIndexArray(void *objArray, int numObjs, Size objSize)
+{
+	DumpableObject **ptrs;
+	int			i;
+
+	ptrs = (DumpableObject **) pg_malloc(numObjs * sizeof(DumpableObject *));
+	for (i = 0; i < numObjs; i++)
+		ptrs[i] = (DumpableObject *) ((char *) objArray + i * objSize);
+
+	/* We can use DOCatalogIdCompare to sort since its first key is OID */
+	if (numObjs > 1)
+		qsort((void *) ptrs, numObjs, sizeof(DumpableObject *),
+			  DOCatalogIdCompare);
+
+	return ptrs;
+}
+
+/*
+ * qsort comparator for pointers to DumpableObjects
+ */
+static int
+DOCatalogIdCompare(const void *p1, const void *p2)
+{
+	const DumpableObject *obj1 = *(DumpableObject * const *) p1;
+	const DumpableObject *obj2 = *(DumpableObject * const *) 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
+ */
+TableInfo *
+findTableByOid(Oid oid)
+{
+	return (TableInfo *) findObjectByOid(oid, tblinfoindex, numTables);
+}
+
+/*
+ * findTypeByOid
+ *	  finds the entry (in typinfo) of the type with the given oid
+ *	  returns NULL if not found
+ */
+TypeInfo *
+findTypeByOid(Oid oid)
+{
+	return (TypeInfo *) findObjectByOid(oid, typinfoindex, numTypes);
+}
+
+/*
+ * findFuncByOid
+ *	  finds the entry (in funinfo) of the function with the given oid
+ *	  returns NULL if not found
+ */
+FuncInfo *
+findFuncByOid(Oid oid)
+{
+	return (FuncInfo *) findObjectByOid(oid, funinfoindex, numFuncs);
+}
+
+/*
+ * findOprByOid
+ *	  finds the entry (in oprinfo) of the operator with the given oid
+ *	  returns NULL if not found
+ */
+OprInfo *
+findOprByOid(Oid oid)
+{
+	return (OprInfo *) findObjectByOid(oid, oprinfoindex, numOperators);
+}
+
+/*
+ * findCollationByOid
+ *	  finds the entry (in collinfo) of the collation with the given oid
+ *	  returns NULL if not found
+ */
+CollInfo *
+findCollationByOid(Oid oid)
+{
+	return (CollInfo *) findObjectByOid(oid, collinfoindex, numCollations);
+}
+
+
+/*
+ * 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;
+}
+
+
+/*
+ * 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);
 
-	tmp = malloc(size);
-	if (!tmp)
-		exit_horribly(NULL, NULL, "out of memory\n");
-	return tmp;
+	if (list->tail)
+		list->tail->next = cell;
+	else
+		list->head = cell;
+	list->tail = cell;
 }
 
-void *
-pg_calloc(size_t nmemb, size_t size)
+bool
+simple_oid_list_member(SimpleOidList *list, Oid val)
 {
-	void	   *tmp;
+	SimpleOidListCell *cell;
 
-	tmp = calloc(nmemb, size);
-	if (!tmp)
-		exit_horribly(NULL, NULL, _("out of memory\n"));
-	return tmp;
+	for (cell = list->head; cell; cell = cell->next)
+	{
+		if (cell->val == val)
+			return true;
+	}
+	return false;
 }
 
-void *
-pg_realloc(void *ptr, size_t size)
+bool
+simple_string_list_member(SimpleStringList *list, const char *val)
 {
-	void	   *tmp;
+	SimpleStringListCell *cell;
 
-	tmp = realloc(ptr, size);
-	if (!tmp)
-		exit_horribly(NULL, NULL, _("out of memory\n"));
-	return tmp;
+	for (cell = list->head; cell; cell = cell->next)
+	{
+		if (strcmp(cell->val, val) == 0)
+			return true;
+	}
+	return false;
 }
diff --git a/src/bin/pg_dump/compress_io.c b/src/bin/pg_dump/compress_io.c
index 8375762ff5a..8c1e2b8e509 100644
--- a/src/bin/pg_dump/compress_io.c
+++ b/src/bin/pg_dump/compress_io.c
@@ -53,7 +53,7 @@
  */
 
 #include "compress_io.h"
-#include "common.h"
+#include "dumpmem.h"
 
 /*----------------------
  * Compressor API
diff --git a/src/bin/pg_dump/dumpcatalog.c b/src/bin/pg_dump/dumpcatalog.c
deleted file mode 100644
index 9747d473198..00000000000
--- a/src/bin/pg_dump/dumpcatalog.c
+++ /dev/null
@@ -1,978 +0,0 @@
-/*-------------------------------------------------------------------------
- *
- * common.c
- *	  catalog routines used by pg_dump
- *
- * Portions Copyright (c) 1996-2011, PostgreSQL Global Development Group
- * Portions Copyright (c) 1994, Regents of the University of California
- *
- *
- * IDENTIFICATION
- *	  src/bin/pg_dump/dumpcatalog.c
- *
- *-------------------------------------------------------------------------
- */
-#include "postgres_fe.h"
-
-#include <ctype.h>
-
-#include "catalog/pg_class.h"
-
-#include "pg_backup_archiver.h"
-#include "common.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.	For each of these arrays, we
- * build a sorted-by-OID index array immediately after it's built, and then
- * we use binary search in findTableByOid() and friends.  (qsort'ing the base
- * arrays themselves would be simpler, but it doesn't work because pg_dump.c
- * may have already established pointers between items.)
- */
-static TableInfo *tblinfo;
-static TypeInfo *typinfo;
-static FuncInfo *funinfo;
-static OprInfo *oprinfo;
-static int	numTables;
-static int	numTypes;
-static int	numFuncs;
-static int	numOperators;
-static int	numCollations;
-static DumpableObject **tblinfoindex;
-static DumpableObject **typinfoindex;
-static DumpableObject **funinfoindex;
-static DumpableObject **oprinfoindex;
-static DumpableObject **collinfoindex;
-
-
-static void flagInhTables(TableInfo *tbinfo, int numTables,
-			  InhInfo *inhinfo, int numInherits);
-static void flagInhAttrs(TableInfo *tblinfo, int numTables);
-static DumpableObject **buildIndexArray(void *objArray, int numObjs,
-				Size objSize);
-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);
-
-
-/*
- * getSchemaData
- *	  Collect information about all potentially dumpable objects
- */
-TableInfo *
-getSchemaData(int *numTablesPtr)
-{
-	ExtensionInfo *extinfo;
-	InhInfo    *inhinfo;
-	CollInfo   *collinfo;
-	int			numNamespaces;
-	int			numExtensions;
-	int			numAggregates;
-	int			numInherits;
-	int			numRules;
-	int			numProcLangs;
-	int			numCasts;
-	int			numOpclasses;
-	int			numOpfamilies;
-	int			numConversions;
-	int			numTSParsers;
-	int			numTSTemplates;
-	int			numTSDicts;
-	int			numTSConfigs;
-	int			numForeignDataWrappers;
-	int			numForeignServers;
-	int			numDefaultACLs;
-
-	if (g_verbose)
-		write_msg(NULL, "reading schemas\n");
-	getNamespaces(&numNamespaces);
-
-	/*
-	 * getTables should be done as soon as possible, so as to minimize the
-	 * window between starting our transaction and acquiring per-table locks.
-	 * However, we have to do getNamespaces first because the tables get
-	 * linked to their containing namespaces during getTables.
-	 */
-	if (g_verbose)
-		write_msg(NULL, "reading user-defined tables\n");
-	tblinfo = getTables(&numTables);
-	tblinfoindex = buildIndexArray(tblinfo, numTables, sizeof(TableInfo));
-
-	if (g_verbose)
-		write_msg(NULL, "reading extensions\n");
-	extinfo = getExtensions(&numExtensions);
-
-	if (g_verbose)
-		write_msg(NULL, "reading user-defined functions\n");
-	funinfo = getFuncs(&numFuncs);
-	funinfoindex = buildIndexArray(funinfo, numFuncs, sizeof(FuncInfo));
-
-	/* this must be after getTables and getFuncs */
-	if (g_verbose)
-		write_msg(NULL, "reading user-defined types\n");
-	typinfo = getTypes(&numTypes);
-	typinfoindex = buildIndexArray(typinfo, numTypes, sizeof(TypeInfo));
-
-	/* this must be after getFuncs, too */
-	if (g_verbose)
-		write_msg(NULL, "reading procedural languages\n");
-	getProcLangs(&numProcLangs);
-
-	if (g_verbose)
-		write_msg(NULL, "reading user-defined aggregate functions\n");
-	getAggregates(&numAggregates);
-
-	if (g_verbose)
-		write_msg(NULL, "reading user-defined operators\n");
-	oprinfo = getOperators(&numOperators);
-	oprinfoindex = buildIndexArray(oprinfo, numOperators, sizeof(OprInfo));
-
-	if (g_verbose)
-		write_msg(NULL, "reading user-defined operator classes\n");
-	getOpclasses(&numOpclasses);
-
-	if (g_verbose)
-		write_msg(NULL, "reading user-defined operator families\n");
-	getOpfamilies(&numOpfamilies);
-
-	if (g_verbose)
-		write_msg(NULL, "reading user-defined text search parsers\n");
-	getTSParsers(&numTSParsers);
-
-	if (g_verbose)
-		write_msg(NULL, "reading user-defined text search templates\n");
-	getTSTemplates(&numTSTemplates);
-
-	if (g_verbose)
-		write_msg(NULL, "reading user-defined text search dictionaries\n");
-	getTSDictionaries(&numTSDicts);
-
-	if (g_verbose)
-		write_msg(NULL, "reading user-defined text search configurations\n");
-	getTSConfigurations(&numTSConfigs);
-
-	if (g_verbose)
-		write_msg(NULL, "reading user-defined foreign-data wrappers\n");
-	getForeignDataWrappers(&numForeignDataWrappers);
-
-	if (g_verbose)
-		write_msg(NULL, "reading user-defined foreign servers\n");
-	getForeignServers(&numForeignServers);
-
-	if (g_verbose)
-		write_msg(NULL, "reading default privileges\n");
-	getDefaultACLs(&numDefaultACLs);
-
-	if (g_verbose)
-		write_msg(NULL, "reading user-defined collations\n");
-	collinfo = getCollations(&numCollations);
-	collinfoindex = buildIndexArray(collinfo, numCollations, sizeof(CollInfo));
-
-	if (g_verbose)
-		write_msg(NULL, "reading user-defined conversions\n");
-	getConversions(&numConversions);
-
-	if (g_verbose)
-		write_msg(NULL, "reading type casts\n");
-	getCasts(&numCasts);
-
-	if (g_verbose)
-		write_msg(NULL, "reading table inheritance information\n");
-	inhinfo = getInherits(&numInherits);
-
-	if (g_verbose)
-		write_msg(NULL, "reading rewrite rules\n");
-	getRules(&numRules);
-
-	/*
-	 * Identify extension member objects and mark them as not to be dumped.
-	 * This must happen after reading all objects that can be direct members
-	 * of extensions, but before we begin to process table subsidiary objects.
-	 */
-	if (g_verbose)
-		write_msg(NULL, "finding extension members\n");
-	getExtensionMembership(extinfo, numExtensions);
-
-	/* 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);
-
-	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 and views never have parents */
-		if (tblinfo[i].relkind == RELKIND_SEQUENCE ||
-			tblinfo[i].relkind == RELKIND_VIEW)
-			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)
-{
-	int			i,
-				j,
-				k;
-
-	for (i = 0; i < numTables; i++)
-	{
-		TableInfo  *tbinfo = &(tblinfo[i]);
-		int			numParents;
-		TableInfo **parents;
-		TableInfo  *parent;
-
-		/* Sequences and views never have parents */
-		if (tbinfo->relkind == RELKIND_SEQUENCE ||
-			tbinfo->relkind == RELKIND_VIEW)
-			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 *) pg_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 = pg_strdup("NULL");
-
-							attrDef->dobj.name = pg_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;
-			}
-		}
-	}
-}
-
-/*
- * 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->ext_member = false;	/* 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 freely intermixed,
- * the code would work, but possibly be very slow.	In the current usage
- * pattern that does not happen, indeed we build the list at most twice.
- */
-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;
-}
-
-/*
- * Find a DumpableObject by OID, in a pre-sorted array of one type of object
- *
- * Returns NULL for unknown OID
- */
-static DumpableObject *
-findObjectByOid(Oid oid, DumpableObject **indexArray, int numObjs)
-{
-	DumpableObject **low;
-	DumpableObject **high;
-
-	/*
-	 * This is the same as findObjectByCatalogId except we assume we need not
-	 * look at table OID because the objects are all the same type.
-	 *
-	 * 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 (numObjs <= 0)
-		return NULL;
-	low = indexArray;
-	high = indexArray + (numObjs - 1);
-	while (low <= high)
-	{
-		DumpableObject **middle;
-		int			difference;
-
-		middle = low + (high - low) / 2;
-		difference = oidcmp((*middle)->catId.oid, oid);
-		if (difference == 0)
-			return *middle;
-		else if (difference < 0)
-			low = middle + 1;
-		else
-			high = middle - 1;
-	}
-	return NULL;
-}
-
-/*
- * Build an index array of DumpableObject pointers, sorted by OID
- */
-static DumpableObject **
-buildIndexArray(void *objArray, int numObjs, Size objSize)
-{
-	DumpableObject **ptrs;
-	int			i;
-
-	ptrs = (DumpableObject **) pg_malloc(numObjs * sizeof(DumpableObject *));
-	for (i = 0; i < numObjs; i++)
-		ptrs[i] = (DumpableObject *) ((char *) objArray + i * objSize);
-
-	/* We can use DOCatalogIdCompare to sort since its first key is OID */
-	if (numObjs > 1)
-		qsort((void *) ptrs, numObjs, sizeof(DumpableObject *),
-			  DOCatalogIdCompare);
-
-	return ptrs;
-}
-
-/*
- * qsort comparator for pointers to DumpableObjects
- */
-static int
-DOCatalogIdCompare(const void *p1, const void *p2)
-{
-	const DumpableObject *obj1 = *(DumpableObject * const *) p1;
-	const DumpableObject *obj2 = *(DumpableObject * const *) 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
- */
-TableInfo *
-findTableByOid(Oid oid)
-{
-	return (TableInfo *) findObjectByOid(oid, tblinfoindex, numTables);
-}
-
-/*
- * findTypeByOid
- *	  finds the entry (in typinfo) of the type with the given oid
- *	  returns NULL if not found
- */
-TypeInfo *
-findTypeByOid(Oid oid)
-{
-	return (TypeInfo *) findObjectByOid(oid, typinfoindex, numTypes);
-}
-
-/*
- * findFuncByOid
- *	  finds the entry (in funinfo) of the function with the given oid
- *	  returns NULL if not found
- */
-FuncInfo *
-findFuncByOid(Oid oid)
-{
-	return (FuncInfo *) findObjectByOid(oid, funinfoindex, numFuncs);
-}
-
-/*
- * findOprByOid
- *	  finds the entry (in oprinfo) of the operator with the given oid
- *	  returns NULL if not found
- */
-OprInfo *
-findOprByOid(Oid oid)
-{
-	return (OprInfo *) findObjectByOid(oid, oprinfoindex, numOperators);
-}
-
-/*
- * findCollationByOid
- *	  finds the entry (in collinfo) of the collation with the given oid
- *	  returns NULL if not found
- */
-CollInfo *
-findCollationByOid(Oid oid)
-{
-	return (CollInfo *) findObjectByOid(oid, collinfoindex, numCollations);
-}
-
-
-/*
- * 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;
-}
-
-
-/*
- * 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;
-}
diff --git a/src/bin/pg_dump/dumpmem.c b/src/bin/pg_dump/dumpmem.c
new file mode 100644
index 00000000000..a50f4f596b4
--- /dev/null
+++ b/src/bin/pg_dump/dumpmem.c
@@ -0,0 +1,73 @@
+/*-------------------------------------------------------------------------
+ *
+ * dumpmem.c
+ *	  memory routines used by pg_dump and pg_restore (but not pg_dumpall
+ *	  because there is no failure location to report).
+ *
+ * Portions Copyright (c) 1996-2011, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1994, Regents of the University of California
+ *
+ *
+ * IDENTIFICATION
+ *	  src/bin/pg_dump/dumpmem.c
+ *
+ *-------------------------------------------------------------------------
+ */
+#include "postgres_fe.h"
+#include "pg_backup.h"
+#include "dumpmem.h"
+
+#include <ctype.h>
+
+/*
+ * 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.
+ * We also report the program name and close the database connection.
+ */
+
+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;
+}
diff --git a/src/bin/pg_dump/common.h b/src/bin/pg_dump/dumpmem.h
similarity index 75%
rename from src/bin/pg_dump/common.h
rename to src/bin/pg_dump/dumpmem.h
index 742d9f68c6c..f70b32065e6 100644
--- a/src/bin/pg_dump/common.h
+++ b/src/bin/pg_dump/dumpmem.h
@@ -1,18 +1,18 @@
 /*-------------------------------------------------------------------------
  *
- * common.h
- *	  Common header file for the pg_dump, pg_dumpall, and pg_restore
+ * dumpmem.h
+ *	  Common header file for the pg_dump and pg_restore
  *
  * Portions Copyright (c) 1996-2011, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * src/bin/pg_dump/common.h
+ * src/bin/pg_dump/dumpmem.h
  *
  *-------------------------------------------------------------------------
  */
 
-#ifndef COMMON_H
-#define COMMON_H
+#ifndef DUMPMEM_H
+#define DUMPMEM_H
 
 #include "postgres_fe.h"
 
@@ -21,4 +21,4 @@ extern void *pg_malloc(size_t size);
 extern void *pg_calloc(size_t nmemb, size_t size);
 extern void *pg_realloc(void *ptr, size_t size);
 
-#endif   /* COMMON_H */
+#endif   /* DUMPMEM_H */
diff --git a/src/bin/pg_dump/dumputils.c b/src/bin/pg_dump/dumputils.c
index 5cc012d9e3c..92b9d28e7f1 100644
--- a/src/bin/pg_dump/dumputils.c
+++ b/src/bin/pg_dump/dumputils.c
@@ -16,7 +16,7 @@
 
 #include <ctype.h>
 
-#include "common.h"
+#include "dumpmem.h"
 #include "dumputils.h"
 
 #include "parser/keywords.h"
diff --git a/src/bin/pg_dump/pg_backup_archiver.c b/src/bin/pg_dump/pg_backup_archiver.c
index 8fb838276fc..164d593ff9e 100644
--- a/src/bin/pg_dump/pg_backup_archiver.c
+++ b/src/bin/pg_dump/pg_backup_archiver.c
@@ -21,7 +21,7 @@
  */
 
 #include "pg_backup_db.h"
-#include "common.h"
+#include "dumpmem.h"
 #include "dumputils.h"
 
 #include <ctype.h>
diff --git a/src/bin/pg_dump/pg_backup_custom.c b/src/bin/pg_dump/pg_backup_custom.c
index bfdf482a6b2..b2f3196bf9c 100644
--- a/src/bin/pg_dump/pg_backup_custom.c
+++ b/src/bin/pg_dump/pg_backup_custom.c
@@ -25,7 +25,7 @@
  */
 
 #include "compress_io.h"
-#include "common.h"
+#include "dumpmem.h"
 
 /*--------
  * Routines in the format interface
diff --git a/src/bin/pg_dump/pg_backup_db.c b/src/bin/pg_dump/pg_backup_db.c
index a58eb2da701..bd1b8efac82 100644
--- a/src/bin/pg_dump/pg_backup_db.c
+++ b/src/bin/pg_dump/pg_backup_db.c
@@ -11,7 +11,7 @@
  */
 
 #include "pg_backup_db.h"
-#include "common.h"
+#include "dumpmem.h"
 #include "dumputils.h"
 
 #include <unistd.h>
diff --git a/src/bin/pg_dump/pg_backup_directory.c b/src/bin/pg_dump/pg_backup_directory.c
index 4f9fcc2be55..bd18ec517da 100644
--- a/src/bin/pg_dump/pg_backup_directory.c
+++ b/src/bin/pg_dump/pg_backup_directory.c
@@ -34,7 +34,7 @@
  */
 
 #include "compress_io.h"
-#include "common.h"
+#include "dumpmem.h"
 
 #include <dirent.h>
 #include <sys/stat.h>
diff --git a/src/bin/pg_dump/pg_backup_files.c b/src/bin/pg_dump/pg_backup_files.c
index 76366e190bc..85373b5f8ce 100644
--- a/src/bin/pg_dump/pg_backup_files.c
+++ b/src/bin/pg_dump/pg_backup_files.c
@@ -26,7 +26,7 @@
  */
 
 #include "pg_backup_archiver.h"
-#include "common.h"
+#include "dumpmem.h"
 
 static void _ArchiveEntry(ArchiveHandle *AH, TocEntry *te);
 static void _StartData(ArchiveHandle *AH, TocEntry *te);
diff --git a/src/bin/pg_dump/pg_backup_null.c b/src/bin/pg_dump/pg_backup_null.c
index 252e7a403bf..201f0d9a212 100644
--- a/src/bin/pg_dump/pg_backup_null.c
+++ b/src/bin/pg_dump/pg_backup_null.c
@@ -23,7 +23,7 @@
  */
 
 #include "pg_backup_archiver.h"
-#include "common.h"
+#include "dumpmem.h"
 #include "dumputils.h"
 
 #include <unistd.h>				/* for dup */
diff --git a/src/bin/pg_dump/pg_backup_tar.c b/src/bin/pg_dump/pg_backup_tar.c
index 94133cf50db..39ce417d86d 100644
--- a/src/bin/pg_dump/pg_backup_tar.c
+++ b/src/bin/pg_dump/pg_backup_tar.c
@@ -28,7 +28,7 @@
 #include "pg_backup.h"
 #include "pg_backup_archiver.h"
 #include "pg_backup_tar.h"
-#include "common.h"
+#include "dumpmem.h"
 
 #include <sys/stat.h>
 #include <ctype.h>
diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c
index e11ba4db749..ec932e4063f 100644
--- a/src/bin/pg_dump/pg_dump.c
+++ b/src/bin/pg_dump/pg_dump.c
@@ -57,7 +57,7 @@
 #include "libpq/libpq-fs.h"
 
 #include "pg_backup_archiver.h"
-#include "common.h"
+#include "dumpmem.h"
 #include "dumputils.h"
 
 extern char *optarg;
diff --git a/src/bin/pg_dump/pg_dump_sort.c b/src/bin/pg_dump/pg_dump_sort.c
index 3bb220d1966..80234506752 100644
--- a/src/bin/pg_dump/pg_dump_sort.c
+++ b/src/bin/pg_dump/pg_dump_sort.c
@@ -14,7 +14,7 @@
  *-------------------------------------------------------------------------
  */
 #include "pg_backup_archiver.h"
-#include "common.h"
+#include "dumpmem.h"
 
 static const char *modulename = gettext_noop("sorter");
 
diff --git a/src/bin/pg_dump/pg_restore.c b/src/bin/pg_dump/pg_restore.c
index a810ed60b4e..ea68f5175c1 100644
--- a/src/bin/pg_dump/pg_restore.c
+++ b/src/bin/pg_dump/pg_restore.c
@@ -39,7 +39,7 @@
  *-------------------------------------------------------------------------
  */
 
-#include "common.h"
+#include "dumpmem.h"
 #include "pg_backup_archiver.h"
 #include "dumputils.h"
 
-- 
GitLab