From 3c0afde11a12bb3ca7c68a30ad0dedaa0d1adef5 Mon Sep 17 00:00:00 2001
From: Bruce Momjian <bruce@momjian.us>
Date: Fri, 25 Nov 2011 15:40:51 -0500
Subject: [PATCH] Modify pg_dump to use error-free memory allocation macros. 
 This avoids ignoring errors and call-site error checking.

---
 src/bin/pg_dump/Makefile              |   8 +-
 src/bin/pg_dump/common.c              | 977 +------------------------
 src/bin/pg_dump/common.h              |  24 +
 src/bin/pg_dump/compress_io.c         |  45 +-
 src/bin/pg_dump/dumpcatalog.c         | 978 ++++++++++++++++++++++++++
 src/bin/pg_dump/dumputils.c           |   1 +
 src/bin/pg_dump/pg_backup_archiver.c  |  92 +--
 src/bin/pg_dump/pg_backup_custom.c    |  23 +-
 src/bin/pg_dump/pg_backup_db.c        |  21 +-
 src/bin/pg_dump/pg_backup_directory.c |  25 +-
 src/bin/pg_dump/pg_backup_files.c     |  13 +-
 src/bin/pg_dump/pg_backup_null.c      |   5 +-
 src/bin/pg_dump/pg_backup_tar.c       |  27 +-
 src/bin/pg_dump/pg_dump.c             | 361 +++++-----
 src/bin/pg_dump/pg_dump.h             |   5 -
 src/bin/pg_dump/pg_dump_sort.c        |  23 +-
 src/bin/pg_dump/pg_dumpall.c          |  65 +-
 src/bin/pg_dump/pg_restore.c          |  25 +-
 18 files changed, 1357 insertions(+), 1361 deletions(-)
 create mode 100644 src/bin/pg_dump/common.h
 create mode 100644 src/bin/pg_dump/dumpcatalog.c

diff --git a/src/bin/pg_dump/Makefile b/src/bin/pg_dump/Makefile
index 8410af13783..9d13bec7933 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 dumputils.o compress_io.o $(WIN32RES)
+	pg_backup_directory.o common.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 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_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_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)
@@ -50,4 +50,4 @@ uninstall:
 	rm -f $(addprefix '$(DESTDIR)$(bindir)'/, pg_dump$(X) pg_restore$(X) pg_dumpall$(X))
 
 clean distclean maintainer-clean:
-	rm -f pg_dump$(X) pg_restore$(X) pg_dumpall$(X) $(OBJS) pg_dump.o common.o pg_dump_sort.o pg_restore.o pg_dumpall.o kwlookup.c $(KEYWRDOBJS)
+	rm -f pg_dump$(X) pg_restore$(X) pg_dumpall$(X) $(OBJS) pg_dump.o dumpcatalog.o pg_dump_sort.o pg_restore.o pg_dumpall.o kwlookup.c $(KEYWRDOBJS)
diff --git a/src/bin/pg_dump/common.c b/src/bin/pg_dump/common.c
index bd81a2c3db1..1a3f4cb6e8e 100644
--- a/src/bin/pg_dump/common.c
+++ b/src/bin/pg_dump/common.c
@@ -1,10 +1,8 @@
 /*-------------------------------------------------------------------------
  *
  * 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.
+ *	  common routines between 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
@@ -16,977 +14,16 @@
  *-------------------------------------------------------------------------
  */
 #include "postgres_fe.h"
+#include "pg_backup.h"
+#include "common.h"
 
 #include <ctype.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.	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 *) 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;
-			}
-		}
-	}
-}
-
-/*
- * 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 **) 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;
-}
-
-
 /*
  * 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.
+ * We also report the program name and close the database connection.
  */
 
 char *
@@ -1020,7 +57,7 @@ pg_calloc(size_t nmemb, size_t size)
 
 	tmp = calloc(nmemb, size);
 	if (!tmp)
-		exit_horribly(NULL, NULL, "out of memory\n");
+		exit_horribly(NULL, NULL, _("out of memory\n"));
 	return tmp;
 }
 
@@ -1031,6 +68,6 @@ pg_realloc(void *ptr, size_t size)
 
 	tmp = realloc(ptr, size);
 	if (!tmp)
-		exit_horribly(NULL, NULL, "out of memory\n");
+		exit_horribly(NULL, NULL, _("out of memory\n"));
 	return tmp;
 }
diff --git a/src/bin/pg_dump/common.h b/src/bin/pg_dump/common.h
new file mode 100644
index 00000000000..742d9f68c6c
--- /dev/null
+++ b/src/bin/pg_dump/common.h
@@ -0,0 +1,24 @@
+/*-------------------------------------------------------------------------
+ *
+ * common.h
+ *	  Common header file for the pg_dump, pg_dumpall, 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
+ *
+ *-------------------------------------------------------------------------
+ */
+
+#ifndef COMMON_H
+#define COMMON_H
+
+#include "postgres_fe.h"
+
+extern char *pg_strdup(const char *string);
+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 */
diff --git a/src/bin/pg_dump/compress_io.c b/src/bin/pg_dump/compress_io.c
index 8540a75d113..8375762ff5a 100644
--- a/src/bin/pg_dump/compress_io.c
+++ b/src/bin/pg_dump/compress_io.c
@@ -53,6 +53,7 @@
  */
 
 #include "compress_io.h"
+#include "common.h"
 
 /*----------------------
  * Compressor API
@@ -135,9 +136,7 @@ AllocateCompressor(int compression, WriteFunc writeF)
 		die_horribly(NULL, modulename, "not built with zlib support\n");
 #endif
 
-	cs = (CompressorState *) calloc(1, sizeof(CompressorState));
-	if (cs == NULL)
-		die_horribly(NULL, modulename, "out of memory\n");
+	cs = (CompressorState *) pg_calloc(1, sizeof(CompressorState));
 	cs->writeF = writeF;
 	cs->comprAlg = alg;
 
@@ -221,9 +220,7 @@ InitCompressorZlib(CompressorState *cs, int level)
 {
 	z_streamp	zp;
 
-	zp = cs->zp = (z_streamp) malloc(sizeof(z_stream));
-	if (cs->zp == NULL)
-		die_horribly(NULL, modulename, "out of memory\n");
+	zp = cs->zp = (z_streamp) pg_malloc(sizeof(z_stream));
 	zp->zalloc = Z_NULL;
 	zp->zfree = Z_NULL;
 	zp->opaque = Z_NULL;
@@ -233,12 +230,9 @@ InitCompressorZlib(CompressorState *cs, int level)
 	 * actually allocate one extra byte because some routines want to append a
 	 * trailing zero byte to the zlib output.
 	 */
-	cs->zlibOut = (char *) malloc(ZLIB_OUT_SIZE + 1);
+	cs->zlibOut = (char *) pg_malloc(ZLIB_OUT_SIZE + 1);
 	cs->zlibOutSize = ZLIB_OUT_SIZE;
 
-	if (cs->zlibOut == NULL)
-		die_horribly(NULL, modulename, "out of memory\n");
-
 	if (deflateInit(zp, level) != Z_OK)
 		die_horribly(NULL, modulename,
 					 "could not initialize compression library: %s\n",
@@ -338,21 +332,15 @@ ReadDataFromArchiveZlib(ArchiveHandle *AH, ReadFunc readF)
 	char	   *buf;
 	size_t		buflen;
 
-	zp = (z_streamp) malloc(sizeof(z_stream));
-	if (zp == NULL)
-		die_horribly(NULL, modulename, "out of memory\n");
+	zp = (z_streamp) pg_malloc(sizeof(z_stream));
 	zp->zalloc = Z_NULL;
 	zp->zfree = Z_NULL;
 	zp->opaque = Z_NULL;
 
-	buf = malloc(ZLIB_IN_SIZE);
-	if (buf == NULL)
-		die_horribly(NULL, modulename, "out of memory\n");
+	buf = pg_malloc(ZLIB_IN_SIZE);
 	buflen = ZLIB_IN_SIZE;
 
-	out = malloc(ZLIB_OUT_SIZE + 1);
-	if (out == NULL)
-		die_horribly(NULL, modulename, "out of memory\n");
+	out = pg_malloc(ZLIB_OUT_SIZE + 1);
 
 	if (inflateInit(zp) != Z_OK)
 		die_horribly(NULL, modulename,
@@ -417,9 +405,7 @@ ReadDataFromArchiveNone(ArchiveHandle *AH, ReadFunc readF)
 	char	   *buf;
 	size_t		buflen;
 
-	buf = malloc(ZLIB_OUT_SIZE);
-	if (buf == NULL)
-		die_horribly(NULL, modulename, "out of memory\n");
+	buf = pg_malloc(ZLIB_OUT_SIZE);
 	buflen = ZLIB_OUT_SIZE;
 
 	while ((cnt = readF(AH, &buf, &buflen)))
@@ -491,10 +477,7 @@ cfopen_read(const char *path, const char *mode)
 		if (fp == NULL)
 		{
 			int			fnamelen = strlen(path) + 4;
-			char	   *fname = malloc(fnamelen);
-
-			if (fname == NULL)
-				die_horribly(NULL, modulename, "Out of memory\n");
+			char	   *fname = pg_malloc(fnamelen);
 
 			snprintf(fname, fnamelen, "%s%s", path, ".gz");
 			fp = cfopen(fname, mode, 1);
@@ -525,10 +508,7 @@ cfopen_write(const char *path, const char *mode, int compression)
 	{
 #ifdef HAVE_LIBZ
 		int			fnamelen = strlen(path) + 4;
-		char	   *fname = malloc(fnamelen);
-
-		if (fname == NULL)
-			die_horribly(NULL, modulename, "Out of memory\n");
+		char	   *fname = pg_malloc(fnamelen);
 
 		snprintf(fname, fnamelen, "%s%s", path, ".gz");
 		fp = cfopen(fname, mode, 1);
@@ -548,10 +528,7 @@ cfopen_write(const char *path, const char *mode, int compression)
 cfp *
 cfopen(const char *path, const char *mode, int compression)
 {
-	cfp		   *fp = malloc(sizeof(cfp));
-
-	if (fp == NULL)
-		die_horribly(NULL, modulename, "Out of memory\n");
+	cfp		   *fp = pg_malloc(sizeof(cfp));
 
 	if (compression != 0)
 	{
diff --git a/src/bin/pg_dump/dumpcatalog.c b/src/bin/pg_dump/dumpcatalog.c
new file mode 100644
index 00000000000..9747d473198
--- /dev/null
+++ b/src/bin/pg_dump/dumpcatalog.c
@@ -0,0 +1,978 @@
+/*-------------------------------------------------------------------------
+ *
+ * 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/dumputils.c b/src/bin/pg_dump/dumputils.c
index acce7f82fa4..5cc012d9e3c 100644
--- a/src/bin/pg_dump/dumputils.c
+++ b/src/bin/pg_dump/dumputils.c
@@ -16,6 +16,7 @@
 
 #include <ctype.h>
 
+#include "common.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 f47af264cba..8fb838276fc 100644
--- a/src/bin/pg_dump/pg_backup_archiver.c
+++ b/src/bin/pg_dump/pg_backup_archiver.c
@@ -21,6 +21,7 @@
  */
 
 #include "pg_backup_db.h"
+#include "common.h"
 #include "dumputils.h"
 
 #include <ctype.h>
@@ -541,7 +542,7 @@ restore_toc_entry(ArchiveHandle *AH, TocEntry *te,
 		{
 			ahlog(AH, 1, "connecting to new database \"%s\"\n", te->tag);
 			_reconnectToDB(AH, te->tag);
-			ropt->dbname = strdup(te->tag);
+			ropt->dbname = pg_strdup(te->tag);
 		}
 	}
 
@@ -660,7 +661,7 @@ NewRestoreOptions(void)
 {
 	RestoreOptions *opts;
 
-	opts = (RestoreOptions *) calloc(1, sizeof(RestoreOptions));
+	opts = (RestoreOptions *) pg_calloc(1, sizeof(RestoreOptions));
 
 	/* set any fields that shouldn't default to zeroes */
 	opts->format = archUnknown;
@@ -759,9 +760,7 @@ ArchiveEntry(Archive *AHX,
 	ArchiveHandle *AH = (ArchiveHandle *) AHX;
 	TocEntry   *newToc;
 
-	newToc = (TocEntry *) calloc(1, sizeof(TocEntry));
-	if (!newToc)
-		die_horribly(AH, modulename, "out of memory\n");
+	newToc = (TocEntry *) pg_calloc(1, sizeof(TocEntry));
 
 	AH->tocCount++;
 	if (dumpId > AH->maxDumpId)
@@ -776,19 +775,19 @@ ArchiveEntry(Archive *AHX,
 	newToc->dumpId = dumpId;
 	newToc->section = section;
 
-	newToc->tag = strdup(tag);
-	newToc->namespace = namespace ? strdup(namespace) : NULL;
-	newToc->tablespace = tablespace ? strdup(tablespace) : NULL;
-	newToc->owner = strdup(owner);
+	newToc->tag = pg_strdup(tag);
+	newToc->namespace = namespace ? pg_strdup(namespace) : NULL;
+	newToc->tablespace = tablespace ? pg_strdup(tablespace) : NULL;
+	newToc->owner = pg_strdup(owner);
 	newToc->withOids = withOids;
-	newToc->desc = strdup(desc);
-	newToc->defn = strdup(defn);
-	newToc->dropStmt = strdup(dropStmt);
-	newToc->copyStmt = copyStmt ? strdup(copyStmt) : NULL;
+	newToc->desc = pg_strdup(desc);
+	newToc->defn = pg_strdup(defn);
+	newToc->dropStmt = pg_strdup(dropStmt);
+	newToc->copyStmt = copyStmt ? pg_strdup(copyStmt) : NULL;
 
 	if (nDeps > 0)
 	{
-		newToc->dependencies = (DumpId *) malloc(nDeps * sizeof(DumpId));
+		newToc->dependencies = (DumpId *) pg_malloc(nDeps * sizeof(DumpId));
 		memcpy(newToc->dependencies, deps, nDeps * sizeof(DumpId));
 		newToc->nDeps = nDeps;
 	}
@@ -1032,7 +1031,7 @@ SortTocFromFile(Archive *AHX, RestoreOptions *ropt)
 	bool		incomplete_line;
 
 	/* Allocate space for the 'wanted' array, and init it */
-	ropt->idWanted = (bool *) malloc(sizeof(bool) * AH->maxDumpId);
+	ropt->idWanted = (bool *) pg_malloc(sizeof(bool) * AH->maxDumpId);
 	memset(ropt->idWanted, 0, sizeof(bool) * AH->maxDumpId);
 
 	/* Setup the file */
@@ -1120,7 +1119,7 @@ InitDummyWantedList(Archive *AHX, RestoreOptions *ropt)
 	ArchiveHandle *AH = (ArchiveHandle *) AHX;
 
 	/* Allocate space for the 'wanted' array, and init it to 1's */
-	ropt->idWanted = (bool *) malloc(sizeof(bool) * AH->maxDumpId);
+	ropt->idWanted = (bool *) pg_malloc(sizeof(bool) * AH->maxDumpId);
 	memset(ropt->idWanted, 1, sizeof(bool) * AH->maxDumpId);
 }
 
@@ -1155,9 +1154,7 @@ archprintf(Archive *AH, const char *fmt,...)
 		if (p != NULL)
 			free(p);
 		bSize *= 2;
-		p = (char *) malloc(bSize);
-		if (p == NULL)
-			exit_horribly(AH, modulename, "out of memory\n");
+		p = (char *) pg_malloc(bSize);
 		va_start(ap, fmt);
 		cnt = vsnprintf(p, bSize, fmt, ap);
 		va_end(ap);
@@ -1286,9 +1283,7 @@ ahprintf(ArchiveHandle *AH, const char *fmt,...)
 		if (p != NULL)
 			free(p);
 		bSize *= 2;
-		p = (char *) malloc(bSize);
-		if (p == NULL)
-			die_horribly(AH, modulename, "out of memory\n");
+		p = (char *) pg_malloc(bSize);
 		va_start(ap, fmt);
 		cnt = vsnprintf(p, bSize, fmt, ap);
 		va_end(ap);
@@ -1756,10 +1751,7 @@ ReadStr(ArchiveHandle *AH)
 		buf = NULL;
 	else
 	{
-		buf = (char *) malloc(l + 1);
-		if (!buf)
-			die_horribly(AH, modulename, "out of memory\n");
-
+		buf = (char *) pg_malloc(l + 1);
 		if ((*AH->ReadBufPtr) (AH, (void *) buf, l) != l)
 			die_horribly(AH, modulename, "unexpected end of file\n");
 
@@ -1785,7 +1777,7 @@ _discoverArchiveFormat(ArchiveHandle *AH)
 		free(AH->lookahead);
 
 	AH->lookaheadSize = 512;
-	AH->lookahead = calloc(1, 512);
+	AH->lookahead = pg_calloc(1, 512);
 	AH->lookaheadLen = 0;
 	AH->lookaheadPos = 0;
 
@@ -1950,9 +1942,7 @@ _allocAH(const char *FileSpec, const ArchiveFormat fmt,
 	write_msg(modulename, "allocating AH for %s, format %d\n", FileSpec, fmt);
 #endif
 
-	AH = (ArchiveHandle *) calloc(1, sizeof(ArchiveHandle));
-	if (!AH)
-		die_horribly(AH, modulename, "out of memory\n");
+	AH = (ArchiveHandle *) pg_calloc(1, sizeof(ArchiveHandle));
 
 	/* AH->debugLevel = 100; */
 
@@ -1979,12 +1969,12 @@ _allocAH(const char *FileSpec, const ArchiveFormat fmt,
 	AH->offSize = sizeof(pgoff_t);
 	if (FileSpec)
 	{
-		AH->fSpec = strdup(FileSpec);
+		AH->fSpec = pg_strdup(FileSpec);
 
 		/*
 		 * Not used; maybe later....
 		 *
-		 * AH->workDir = strdup(FileSpec); for(i=strlen(FileSpec) ; i > 0 ;
+		 * AH->workDir = pg_strdup(FileSpec); for(i=strlen(FileSpec) ; i > 0 ;
 		 * i--) if (AH->workDir[i-1] == '/')
 		 */
 	}
@@ -1996,9 +1986,7 @@ _allocAH(const char *FileSpec, const ArchiveFormat fmt,
 	AH->currTablespace = NULL;	/* ditto */
 	AH->currWithOids = -1;		/* force SET */
 
-	AH->toc = (TocEntry *) calloc(1, sizeof(TocEntry));
-	if (!AH->toc)
-		die_horribly(AH, modulename, "out of memory\n");
+	AH->toc = (TocEntry *) pg_calloc(1, sizeof(TocEntry));
 
 	AH->toc->next = AH->toc;
 	AH->toc->prev = AH->toc;
@@ -2169,7 +2157,7 @@ ReadToc(ArchiveHandle *AH)
 
 	for (i = 0; i < AH->tocCount; i++)
 	{
-		te = (TocEntry *) calloc(1, sizeof(TocEntry));
+		te = (TocEntry *) pg_calloc(1, sizeof(TocEntry));
 		te->dumpId = ReadInt(AH);
 
 		if (te->dumpId > AH->maxDumpId)
@@ -2255,7 +2243,7 @@ ReadToc(ArchiveHandle *AH)
 		if (AH->version >= K_VERS_1_5)
 		{
 			depSize = 100;
-			deps = (DumpId *) malloc(sizeof(DumpId) * depSize);
+			deps = (DumpId *) pg_malloc(sizeof(DumpId) * depSize);
 			depIdx = 0;
 			for (;;)
 			{
@@ -2315,7 +2303,7 @@ static void
 processEncodingEntry(ArchiveHandle *AH, TocEntry *te)
 {
 	/* te->defn should have the form SET client_encoding = 'foo'; */
-	char	   *defn = strdup(te->defn);
+	char	   *defn = pg_strdup(te->defn);
 	char	   *ptr1;
 	char	   *ptr2 = NULL;
 	int			encoding;
@@ -2660,7 +2648,7 @@ _becomeUser(ArchiveHandle *AH, const char *user)
 	 */
 	if (AH->currUser)
 		free(AH->currUser);
-	AH->currUser = strdup(user);
+	AH->currUser = pg_strdup(user);
 }
 
 /*
@@ -2729,7 +2717,7 @@ _selectOutputSchema(ArchiveHandle *AH, const char *schemaName)
 
 	if (AH->currSchema)
 		free(AH->currSchema);
-	AH->currSchema = strdup(schemaName);
+	AH->currSchema = pg_strdup(schemaName);
 
 	destroyPQExpBuffer(qry);
 }
@@ -2790,7 +2778,7 @@ _selectTablespace(ArchiveHandle *AH, const char *tablespace)
 
 	if (AH->currTablespace)
 		free(AH->currTablespace);
-	AH->currTablespace = strdup(want);
+	AH->currTablespace = pg_strdup(want);
 
 	destroyPQExpBuffer(qry);
 }
@@ -2872,7 +2860,7 @@ _getObjectDescription(PQExpBuffer buf, TocEntry *te, ArchiveHandle *AH)
 		strcmp(type, "OPERATOR FAMILY") == 0)
 	{
 		/* Chop "DROP " off the front and make a modifiable copy */
-		char	   *first = strdup(te->dropStmt + 5);
+		char	   *first = pg_strdup(te->dropStmt + 5);
 		char	   *last;
 
 		/* point to last character in string */
@@ -3279,7 +3267,7 @@ restore_toc_entries_parallel(ArchiveHandle *AH)
 
 	ahlog(AH, 2, "entering restore_toc_entries_parallel\n");
 
-	slots = (ParallelSlot *) calloc(sizeof(ParallelSlot), n_slots);
+	slots = (ParallelSlot *) pg_calloc(sizeof(ParallelSlot), n_slots);
 
 	/* Adjust dependency information */
 	fix_dependencies(AH);
@@ -3431,7 +3419,7 @@ restore_toc_entries_parallel(ArchiveHandle *AH)
 				par_list_remove(next_work_item);
 
 				/* this memory is dealloced in mark_work_done() */
-				args = malloc(sizeof(RestoreArgs));
+				args = pg_malloc(sizeof(RestoreArgs));
 				args->AH = CloneArchive(AH);
 				args->te = next_work_item;
 
@@ -3550,7 +3538,7 @@ reap_child(ParallelSlot *slots, int n_slots, int *work_status)
 
 	/* first time around only, make space for handles to listen on */
 	if (handles == NULL)
-		handles = (HANDLE *) calloc(sizeof(HANDLE), n_slots);
+		handles = (HANDLE *) pg_calloc(sizeof(HANDLE), n_slots);
 
 	/* set up list of handles to listen to */
 	for (snum = 0, tnum = 0; snum < n_slots; snum++)
@@ -3898,7 +3886,7 @@ fix_dependencies(ArchiveHandle *AH)
 	 * the TOC items are marked as not being in any parallel-processing list.
 	 */
 	maxDumpId = AH->maxDumpId;
-	tocsByDumpId = (TocEntry **) calloc(maxDumpId, sizeof(TocEntry *));
+	tocsByDumpId = (TocEntry **) pg_calloc(maxDumpId, sizeof(TocEntry *));
 	for (te = AH->toc->next; te != AH->toc; te = te->next)
 	{
 		tocsByDumpId[te->dumpId - 1] = te;
@@ -3958,7 +3946,7 @@ fix_dependencies(ArchiveHandle *AH)
 				{
 					if (strcmp(te2->desc, "BLOBS") == 0)
 					{
-						te->dependencies = (DumpId *) malloc(sizeof(DumpId));
+						te->dependencies = (DumpId *) pg_malloc(sizeof(DumpId));
 						te->dependencies[0] = te2->dumpId;
 						te->nDeps++;
 						te->depCount++;
@@ -4000,7 +3988,7 @@ fix_dependencies(ArchiveHandle *AH)
 	for (te = AH->toc->next; te != AH->toc; te = te->next)
 	{
 		if (te->nRevDeps > 0)
-			te->revDeps = (DumpId *) malloc(te->nRevDeps * sizeof(DumpId));
+			te->revDeps = (DumpId *) pg_malloc(te->nRevDeps * sizeof(DumpId));
 		te->nRevDeps = 0;
 	}
 
@@ -4092,7 +4080,7 @@ identify_locking_dependencies(TocEntry *te)
 	 * that all the entry types we are interested in here are POST_DATA, so
 	 * they will all have been changed this way.)
 	 */
-	lockids = (DumpId *) malloc(te->nDeps * sizeof(DumpId));
+	lockids = (DumpId *) pg_malloc(te->nDeps * sizeof(DumpId));
 	nlockids = 0;
 	for (i = 0; i < te->nDeps; i++)
 	{
@@ -4204,9 +4192,7 @@ CloneArchive(ArchiveHandle *AH)
 	ArchiveHandle *clone;
 
 	/* Make a "flat" copy */
-	clone = (ArchiveHandle *) malloc(sizeof(ArchiveHandle));
-	if (clone == NULL)
-		die_horribly(AH, modulename, "out of memory\n");
+	clone = (ArchiveHandle *) pg_malloc(sizeof(ArchiveHandle));
 	memcpy(clone, AH, sizeof(ArchiveHandle));
 
 	/* Handle format-independent fields ... none at the moment */
@@ -4220,7 +4206,7 @@ CloneArchive(ArchiveHandle *AH)
 
 	/* savedPassword must be local in case we change it while connecting */
 	if (clone->savedPassword)
-		clone->savedPassword = strdup(clone->savedPassword);
+		clone->savedPassword = pg_strdup(clone->savedPassword);
 
 	/* clone has its own error count, too */
 	clone->public.n_errors = 0;
diff --git a/src/bin/pg_dump/pg_backup_custom.c b/src/bin/pg_dump/pg_backup_custom.c
index 55ff39a4fe8..bfdf482a6b2 100644
--- a/src/bin/pg_dump/pg_backup_custom.c
+++ b/src/bin/pg_dump/pg_backup_custom.c
@@ -25,6 +25,7 @@
  */
 
 #include "compress_io.h"
+#include "common.h"
 
 /*--------
  * Routines in the format interface
@@ -126,16 +127,12 @@ InitArchiveFmt_Custom(ArchiveHandle *AH)
 	AH->DeClonePtr = _DeClone;
 
 	/* Set up a private area. */
-	ctx = (lclContext *) calloc(1, sizeof(lclContext));
-	if (ctx == NULL)
-		die_horribly(AH, modulename, "out of memory\n");
+	ctx = (lclContext *) pg_calloc(1, sizeof(lclContext));
 	AH->formatData = (void *) ctx;
 
 	/* Initialize LO buffering */
 	AH->lo_buf_size = LOBBUFSIZE;
-	AH->lo_buf = (void *) malloc(LOBBUFSIZE);
-	if (AH->lo_buf == NULL)
-		die_horribly(AH, modulename, "out of memory\n");
+	AH->lo_buf = (void *) pg_malloc(LOBBUFSIZE);
 
 	ctx->filePos = 0;
 
@@ -199,7 +196,7 @@ _ArchiveEntry(ArchiveHandle *AH, TocEntry *te)
 {
 	lclTocEntry *ctx;
 
-	ctx = (lclTocEntry *) calloc(1, sizeof(lclTocEntry));
+	ctx = (lclTocEntry *) pg_calloc(1, sizeof(lclTocEntry));
 	if (te->dataDumper)
 		ctx->dataState = K_OFFSET_POS_NOT_SET;
 	else
@@ -240,7 +237,7 @@ _ReadExtraToc(ArchiveHandle *AH, TocEntry *te)
 
 	if (ctx == NULL)
 	{
-		ctx = (lclTocEntry *) calloc(1, sizeof(lclTocEntry));
+		ctx = (lclTocEntry *) pg_calloc(1, sizeof(lclTocEntry));
 		te->formatData = (void *) ctx;
 	}
 
@@ -566,7 +563,7 @@ _skipData(ArchiveHandle *AH)
 		{
 			if (buf)
 				free(buf);
-			buf = (char *) malloc(blkLen);
+			buf = (char *) pg_malloc(blkLen);
 			buflen = blkLen;
 		}
 		cnt = fread(buf, 1, blkLen, AH->FH);
@@ -774,9 +771,7 @@ _Clone(ArchiveHandle *AH)
 {
 	lclContext *ctx = (lclContext *) AH->formatData;
 
-	AH->formatData = (lclContext *) malloc(sizeof(lclContext));
-	if (AH->formatData == NULL)
-		die_horribly(AH, modulename, "out of memory\n");
+	AH->formatData = (lclContext *) pg_malloc(sizeof(lclContext));
 	memcpy(AH->formatData, ctx, sizeof(lclContext));
 	ctx = (lclContext *) AH->formatData;
 
@@ -901,9 +896,7 @@ _CustomReadFunc(ArchiveHandle *AH, char **buf, size_t *buflen)
 	if (blkLen > *buflen)
 	{
 		free(*buf);
-		*buf = (char *) malloc(blkLen);
-		if (!(*buf))
-			die_horribly(AH, modulename, "out of memory\n");
+		*buf = (char *) pg_malloc(blkLen);
 		*buflen = blkLen;
 	}
 
diff --git a/src/bin/pg_dump/pg_backup_db.c b/src/bin/pg_dump/pg_backup_db.c
index 600728d1985..a58eb2da701 100644
--- a/src/bin/pg_dump/pg_backup_db.c
+++ b/src/bin/pg_dump/pg_backup_db.c
@@ -11,6 +11,7 @@
  */
 
 #include "pg_backup_db.h"
+#include "common.h"
 #include "dumputils.h"
 
 #include <unistd.h>
@@ -55,7 +56,7 @@ _check_database_version(ArchiveHandle *AH)
 
 	remoteversion = _parse_version(AH, remoteversion_str);
 
-	AH->public.remoteVersionStr = strdup(remoteversion_str);
+	AH->public.remoteVersionStr = pg_strdup(remoteversion_str);
 	AH->public.remoteVersion = remoteversion;
 	if (!AH->archiveRemoteVersion)
 		AH->archiveRemoteVersion = AH->public.remoteVersionStr;
@@ -150,11 +151,8 @@ _connectDB(ArchiveHandle *AH, const char *reqdb, const char *requser)
 	do
 	{
 #define PARAMS_ARRAY_SIZE	7
-		const char **keywords = malloc(PARAMS_ARRAY_SIZE * sizeof(*keywords));
-		const char **values = malloc(PARAMS_ARRAY_SIZE * sizeof(*values));
-
-		if (!keywords || !values)
-			die_horribly(AH, modulename, "out of memory\n");
+		const char **keywords = pg_malloc(PARAMS_ARRAY_SIZE * sizeof(*keywords));
+		const char **values = pg_malloc(PARAMS_ARRAY_SIZE * sizeof(*values));
 
 		keywords[0] = "host";
 		values[0] = PQhost(AH->connection);
@@ -257,11 +255,8 @@ ConnectDatabase(Archive *AHX,
 	do
 	{
 #define PARAMS_ARRAY_SIZE	7
-		const char **keywords = malloc(PARAMS_ARRAY_SIZE * sizeof(*keywords));
-		const char **values = malloc(PARAMS_ARRAY_SIZE * sizeof(*values));
-
-		if (!keywords || !values)
-			die_horribly(AH, modulename, "out of memory\n");
+		const char **keywords = pg_malloc(PARAMS_ARRAY_SIZE * sizeof(*keywords));
+		const char **values = pg_malloc(PARAMS_ARRAY_SIZE * sizeof(*values));
 
 		keywords[0] = "host";
 		values[0] = pghost;
@@ -397,10 +392,8 @@ ExecuteSqlCommandBuf(ArchiveHandle *AH, const char *buf, size_t bufLen)
 			ExecuteSqlCommand(AH, buf, "could not execute query");
 		else
 		{
-			char   *str = (char *) malloc(bufLen + 1);
+			char   *str = (char *) pg_malloc(bufLen + 1);
 
-			if (!str)
-				die_horribly(AH, modulename, "out of memory\n");
 			memcpy(str, buf, bufLen);
 			str[bufLen] = '\0';
 			ExecuteSqlCommand(AH, str, "could not execute query");
diff --git a/src/bin/pg_dump/pg_backup_directory.c b/src/bin/pg_dump/pg_backup_directory.c
index 2e110acfff0..4f9fcc2be55 100644
--- a/src/bin/pg_dump/pg_backup_directory.c
+++ b/src/bin/pg_dump/pg_backup_directory.c
@@ -34,6 +34,7 @@
  */
 
 #include "compress_io.h"
+#include "common.h"
 
 #include <dirent.h>
 #include <sys/stat.h>
@@ -125,9 +126,7 @@ InitArchiveFmt_Directory(ArchiveHandle *AH)
 	AH->DeClonePtr = NULL;
 
 	/* Set up our private context */
-	ctx = (lclContext *) calloc(1, sizeof(lclContext));
-	if (ctx == NULL)
-		die_horribly(AH, modulename, "out of memory\n");
+	ctx = (lclContext *) pg_calloc(1, sizeof(lclContext));
 	AH->formatData = (void *) ctx;
 
 	ctx->dataFH = NULL;
@@ -135,9 +134,7 @@ InitArchiveFmt_Directory(ArchiveHandle *AH)
 
 	/* Initialize LO buffering */
 	AH->lo_buf_size = LOBBUFSIZE;
-	AH->lo_buf = (void *) malloc(LOBBUFSIZE);
-	if (AH->lo_buf == NULL)
-		die_horribly(AH, modulename, "out of memory\n");
+	AH->lo_buf = (void *) pg_malloc(LOBBUFSIZE);
 
 	/*
 	 * Now open the TOC file
@@ -196,16 +193,14 @@ _ArchiveEntry(ArchiveHandle *AH, TocEntry *te)
 	lclTocEntry *tctx;
 	char		fn[MAXPGPATH];
 
-	tctx = (lclTocEntry *) calloc(1, sizeof(lclTocEntry));
-	if (!tctx)
-		die_horribly(AH, modulename, "out of memory\n");
+	tctx = (lclTocEntry *) pg_calloc(1, sizeof(lclTocEntry));
 	if (te->dataDumper)
 	{
 		snprintf(fn, MAXPGPATH, "%d.dat", te->dumpId);
-		tctx->filename = strdup(fn);
+		tctx->filename = pg_strdup(fn);
 	}
 	else if (strcmp(te->desc, "BLOBS") == 0)
-		tctx->filename = strdup("blobs.toc");
+		tctx->filename = pg_strdup("blobs.toc");
 	else
 		tctx->filename = NULL;
 
@@ -247,9 +242,7 @@ _ReadExtraToc(ArchiveHandle *AH, TocEntry *te)
 
 	if (tctx == NULL)
 	{
-		tctx = (lclTocEntry *) calloc(1, sizeof(lclTocEntry));
-		if (!tctx)
-			die_horribly(AH, modulename, "out of memory\n");
+		tctx = (lclTocEntry *) pg_calloc(1, sizeof(lclTocEntry));
 		te->formatData = (void *) tctx;
 	}
 
@@ -355,9 +348,7 @@ _PrintFileData(ArchiveHandle *AH, char *filename, RestoreOptions *ropt)
 		die_horribly(AH, modulename, "could not open input file \"%s\": %s\n",
 					 filename, strerror(errno));
 
-	buf = malloc(ZLIB_OUT_SIZE);
-	if (buf == NULL)
-		die_horribly(NULL, modulename, "out of memory\n");
+	buf = pg_malloc(ZLIB_OUT_SIZE);
 	buflen = ZLIB_OUT_SIZE;
 
 	while ((cnt = cfread(buf, buflen, cfp)))
diff --git a/src/bin/pg_dump/pg_backup_files.c b/src/bin/pg_dump/pg_backup_files.c
index afd53bff8e2..76366e190bc 100644
--- a/src/bin/pg_dump/pg_backup_files.c
+++ b/src/bin/pg_dump/pg_backup_files.c
@@ -26,6 +26,7 @@
  */
 
 #include "pg_backup_archiver.h"
+#include "common.h"
 
 static void _ArchiveEntry(ArchiveHandle *AH, TocEntry *te);
 static void _StartData(ArchiveHandle *AH, TocEntry *te);
@@ -103,15 +104,13 @@ InitArchiveFmt_Files(ArchiveHandle *AH)
 	/*
 	 * Set up some special context used in compressing data.
 	 */
-	ctx = (lclContext *) calloc(1, sizeof(lclContext));
+	ctx = (lclContext *) pg_calloc(1, sizeof(lclContext));
 	AH->formatData = (void *) ctx;
 	ctx->filePos = 0;
 
 	/* Initialize LO buffering */
 	AH->lo_buf_size = LOBBUFSIZE;
-	AH->lo_buf = (void *) malloc(LOBBUFSIZE);
-	if (AH->lo_buf == NULL)
-		die_horribly(AH, modulename, "out of memory\n");
+	AH->lo_buf = (void *) pg_malloc(LOBBUFSIZE);
 
 	/*
 	 * Now open the TOC file
@@ -183,7 +182,7 @@ _ArchiveEntry(ArchiveHandle *AH, TocEntry *te)
 	lclTocEntry *ctx;
 	char		fn[K_STD_BUF_SIZE];
 
-	ctx = (lclTocEntry *) calloc(1, sizeof(lclTocEntry));
+	ctx = (lclTocEntry *) pg_calloc(1, sizeof(lclTocEntry));
 	if (te->dataDumper)
 	{
 #ifdef HAVE_LIBZ
@@ -194,7 +193,7 @@ _ArchiveEntry(ArchiveHandle *AH, TocEntry *te)
 #else
 		sprintf(fn, "%d.dat", te->dumpId);
 #endif
-		ctx->filename = strdup(fn);
+		ctx->filename = pg_strdup(fn);
 	}
 	else
 	{
@@ -222,7 +221,7 @@ _ReadExtraToc(ArchiveHandle *AH, TocEntry *te)
 
 	if (ctx == NULL)
 	{
-		ctx = (lclTocEntry *) calloc(1, sizeof(lclTocEntry));
+		ctx = (lclTocEntry *) pg_calloc(1, sizeof(lclTocEntry));
 		te->formatData = (void *) ctx;
 	}
 
diff --git a/src/bin/pg_dump/pg_backup_null.c b/src/bin/pg_dump/pg_backup_null.c
index bf1e6e68bf2..252e7a403bf 100644
--- a/src/bin/pg_dump/pg_backup_null.c
+++ b/src/bin/pg_dump/pg_backup_null.c
@@ -23,6 +23,7 @@
  */
 
 #include "pg_backup_archiver.h"
+#include "common.h"
 #include "dumputils.h"
 
 #include <unistd.h>				/* for dup */
@@ -67,9 +68,7 @@ InitArchiveFmt_Null(ArchiveHandle *AH)
 
 	/* Initialize LO buffering */
 	AH->lo_buf_size = LOBBUFSIZE;
-	AH->lo_buf = (void *) malloc(LOBBUFSIZE);
-	if (AH->lo_buf == NULL)
-		die_horribly(AH, NULL, "out of memory\n");
+	AH->lo_buf = (void *) pg_malloc(LOBBUFSIZE);
 
 	/*
 	 * Now prevent reading...
diff --git a/src/bin/pg_dump/pg_backup_tar.c b/src/bin/pg_dump/pg_backup_tar.c
index 4642132d715..94133cf50db 100644
--- a/src/bin/pg_dump/pg_backup_tar.c
+++ b/src/bin/pg_dump/pg_backup_tar.c
@@ -28,6 +28,7 @@
 #include "pg_backup.h"
 #include "pg_backup_archiver.h"
 #include "pg_backup_tar.h"
+#include "common.h"
 
 #include <sys/stat.h>
 #include <ctype.h>
@@ -159,16 +160,14 @@ InitArchiveFmt_Tar(ArchiveHandle *AH)
 	/*
 	 * Set up some special context used in compressing data.
 	 */
-	ctx = (lclContext *) calloc(1, sizeof(lclContext));
+	ctx = (lclContext *) pg_calloc(1, sizeof(lclContext));
 	AH->formatData = (void *) ctx;
 	ctx->filePos = 0;
 	ctx->isSpecialScript = 0;
 
 	/* Initialize LO buffering */
 	AH->lo_buf_size = LOBBUFSIZE;
-	AH->lo_buf = (void *) malloc(LOBBUFSIZE);
-	if (AH->lo_buf == NULL)
-		die_horribly(AH, modulename, "out of memory\n");
+	AH->lo_buf = (void *) pg_malloc(LOBBUFSIZE);
 
 	/*
 	 * Now open the tar file, and load the TOC if we're in read mode.
@@ -267,7 +266,7 @@ _ArchiveEntry(ArchiveHandle *AH, TocEntry *te)
 	lclTocEntry *ctx;
 	char		fn[K_STD_BUF_SIZE];
 
-	ctx = (lclTocEntry *) calloc(1, sizeof(lclTocEntry));
+	ctx = (lclTocEntry *) pg_calloc(1, sizeof(lclTocEntry));
 	if (te->dataDumper != NULL)
 	{
 #ifdef HAVE_LIBZ
@@ -278,7 +277,7 @@ _ArchiveEntry(ArchiveHandle *AH, TocEntry *te)
 #else
 		sprintf(fn, "%d.dat", te->dumpId);
 #endif
-		ctx->filename = strdup(fn);
+		ctx->filename = pg_strdup(fn);
 	}
 	else
 	{
@@ -306,7 +305,7 @@ _ReadExtraToc(ArchiveHandle *AH, TocEntry *te)
 
 	if (ctx == NULL)
 	{
-		ctx = (lclTocEntry *) calloc(1, sizeof(lclTocEntry));
+		ctx = (lclTocEntry *) pg_calloc(1, sizeof(lclTocEntry));
 		te->formatData = (void *) ctx;
 	}
 
@@ -379,7 +378,7 @@ tarOpen(ArchiveHandle *AH, const char *filename, char mode)
 	}
 	else
 	{
-		tm = calloc(1, sizeof(TAR_MEMBER));
+		tm = pg_calloc(1, sizeof(TAR_MEMBER));
 
 #ifndef WIN32
 		tm->tmpFH = tmpfile();
@@ -432,7 +431,7 @@ tarOpen(ArchiveHandle *AH, const char *filename, char mode)
 #endif
 
 		tm->AH = AH;
-		tm->targetFile = strdup(filename);
+		tm->targetFile = pg_strdup(filename);
 	}
 
 	tm->mode = mode;
@@ -665,7 +664,7 @@ _PrintTocData(ArchiveHandle *AH, TocEntry *te, RestoreOptions *ropt)
 		ahprintf(AH, "\\.\n");
 
 		/* Get a copy of the COPY statement and clean it up */
-		tmpCopy = strdup(te->copyStmt);
+		tmpCopy = pg_strdup(te->copyStmt);
 		for (i = 0; i < strlen(tmpCopy); i++)
 			tmpCopy[i] = pg_tolower((unsigned char) tmpCopy[i]);
 
@@ -1010,9 +1009,7 @@ tarPrintf(ArchiveHandle *AH, TAR_MEMBER *th, const char *fmt,...)
 		if (p != NULL)
 			free(p);
 		bSize *= 2;
-		p = (char *) malloc(bSize);
-		if (p == NULL)
-			die_horribly(AH, modulename, "out of memory\n");
+		p = (char *) pg_malloc(bSize);
 		va_start(ap, fmt);
 		cnt = vsnprintf(p, bSize, fmt, ap);
 		va_end(ap);
@@ -1125,7 +1122,7 @@ static TAR_MEMBER *
 _tarPositionTo(ArchiveHandle *AH, const char *filename)
 {
 	lclContext *ctx = (lclContext *) AH->formatData;
-	TAR_MEMBER *th = calloc(1, sizeof(TAR_MEMBER));
+	TAR_MEMBER *th = pg_calloc(1, sizeof(TAR_MEMBER));
 	char		c;
 	char		header[512];
 	size_t		i,
@@ -1295,7 +1292,7 @@ _tarGetHeader(ArchiveHandle *AH, TAR_MEMBER *th)
 					 tag, sum, chk, buf);
 	}
 
-	th->targetFile = strdup(tag);
+	th->targetFile = pg_strdup(tag);
 	th->fileLen = len;
 
 	return 1;
diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c
index 28a527357f9..76ff4d17e2c 100644
--- a/src/bin/pg_dump/pg_dump.c
+++ b/src/bin/pg_dump/pg_dump.c
@@ -57,6 +57,7 @@
 #include "libpq/libpq-fs.h"
 
 #include "pg_backup_archiver.h"
+#include "common.h"
 #include "dumputils.h"
 
 extern char *optarg;
@@ -438,7 +439,7 @@ main(int argc, char **argv)
 				break;
 
 			case 'S':			/* Username for superuser in plain text output */
-				outputSuperuser = strdup(optarg);
+				outputSuperuser = pg_strdup(optarg);
 				break;
 
 			case 't':			/* include table(s) */
@@ -1585,7 +1586,7 @@ makeTableDataInfo(TableInfo *tbinfo, bool oids)
 {
 	TableDataInfo *tdinfo;
 
-	tdinfo = (TableDataInfo *) malloc(sizeof(TableDataInfo));
+	tdinfo = (TableDataInfo *) pg_malloc(sizeof(TableDataInfo));
 
 	tdinfo->dobj.objType = DO_TABLE_DATA;
 
@@ -2181,7 +2182,7 @@ getBlobs(Archive *AH)
 		/*
 		 * Each large object has its own BLOB archive entry.
 		 */
-		binfo = (BlobInfo *) malloc(ntups * sizeof(BlobInfo));
+		binfo = (BlobInfo *) pg_malloc(ntups * sizeof(BlobInfo));
 
 		for (i = 0; i < ntups; i++)
 		{
@@ -2190,13 +2191,13 @@ getBlobs(Archive *AH)
 			binfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, 0));
 			AssignDumpId(&binfo[i].dobj);
 
-			binfo[i].dobj.name = strdup(PQgetvalue(res, i, 0));
+			binfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, 0));
 			if (!PQgetisnull(res, i, 1))
-				binfo[i].rolname = strdup(PQgetvalue(res, i, 1));
+				binfo[i].rolname = pg_strdup(PQgetvalue(res, i, 1));
 			else
 				binfo[i].rolname = "";
 			if (!PQgetisnull(res, i, 2))
-				binfo[i].blobacl = strdup(PQgetvalue(res, i, 2));
+				binfo[i].blobacl = pg_strdup(PQgetvalue(res, i, 2));
 			else
 				binfo[i].blobacl = NULL;
 		}
@@ -2205,11 +2206,11 @@ getBlobs(Archive *AH)
 		 * If we have any large objects, a "BLOBS" archive entry is needed.
 		 * This is just a placeholder for sorting; it carries no data now.
 		 */
-		bdata = (DumpableObject *) malloc(sizeof(DumpableObject));
+		bdata = (DumpableObject *) pg_malloc(sizeof(DumpableObject));
 		bdata->objType = DO_BLOB_DATA;
 		bdata->catId = nilCatalogId;
 		AssignDumpId(bdata);
-		bdata->name = strdup("BLOBS");
+		bdata->name = pg_strdup("BLOBS");
 	}
 
 	PQclear(res);
@@ -2608,15 +2609,15 @@ getNamespaces(int *numNamespaces)
 	 */
 	if (g_fout->remoteVersion < 70300)
 	{
-		nsinfo = (NamespaceInfo *) malloc(2 * sizeof(NamespaceInfo));
+		nsinfo = (NamespaceInfo *) pg_malloc(2 * sizeof(NamespaceInfo));
 
 		nsinfo[0].dobj.objType = DO_NAMESPACE;
 		nsinfo[0].dobj.catId.tableoid = 0;
 		nsinfo[0].dobj.catId.oid = 0;
 		AssignDumpId(&nsinfo[0].dobj);
-		nsinfo[0].dobj.name = strdup("public");
-		nsinfo[0].rolname = strdup("");
-		nsinfo[0].nspacl = strdup("");
+		nsinfo[0].dobj.name = pg_strdup("public");
+		nsinfo[0].rolname = pg_strdup("");
+		nsinfo[0].nspacl = pg_strdup("");
 
 		selectDumpableNamespace(&nsinfo[0]);
 
@@ -2624,9 +2625,9 @@ getNamespaces(int *numNamespaces)
 		nsinfo[1].dobj.catId.tableoid = 0;
 		nsinfo[1].dobj.catId.oid = 1;
 		AssignDumpId(&nsinfo[1].dobj);
-		nsinfo[1].dobj.name = strdup("pg_catalog");
-		nsinfo[1].rolname = strdup("");
-		nsinfo[1].nspacl = strdup("");
+		nsinfo[1].dobj.name = pg_strdup("pg_catalog");
+		nsinfo[1].rolname = pg_strdup("");
+		nsinfo[1].nspacl = pg_strdup("");
 
 		selectDumpableNamespace(&nsinfo[1]);
 
@@ -2655,7 +2656,7 @@ getNamespaces(int *numNamespaces)
 
 	ntups = PQntuples(res);
 
-	nsinfo = (NamespaceInfo *) malloc(ntups * sizeof(NamespaceInfo));
+	nsinfo = (NamespaceInfo *) pg_malloc(ntups * sizeof(NamespaceInfo));
 
 	i_tableoid = PQfnumber(res, "tableoid");
 	i_oid = PQfnumber(res, "oid");
@@ -2669,9 +2670,9 @@ getNamespaces(int *numNamespaces)
 		nsinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
 		nsinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
 		AssignDumpId(&nsinfo[i].dobj);
-		nsinfo[i].dobj.name = strdup(PQgetvalue(res, i, i_nspname));
-		nsinfo[i].rolname = strdup(PQgetvalue(res, i, i_rolname));
-		nsinfo[i].nspacl = strdup(PQgetvalue(res, i, i_nspacl));
+		nsinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_nspname));
+		nsinfo[i].rolname = pg_strdup(PQgetvalue(res, i, i_rolname));
+		nsinfo[i].nspacl = pg_strdup(PQgetvalue(res, i, i_nspacl));
 
 		/* Decide whether to dump this namespace */
 		selectDumpableNamespace(&nsinfo[i]);
@@ -2776,7 +2777,7 @@ getExtensions(int *numExtensions)
 
 	ntups = PQntuples(res);
 
-	extinfo = (ExtensionInfo *) malloc(ntups * sizeof(ExtensionInfo));
+	extinfo = (ExtensionInfo *) pg_malloc(ntups * sizeof(ExtensionInfo));
 
 	i_tableoid = PQfnumber(res, "tableoid");
 	i_oid = PQfnumber(res, "oid");
@@ -2793,12 +2794,12 @@ getExtensions(int *numExtensions)
 		extinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
 		extinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
 		AssignDumpId(&extinfo[i].dobj);
-		extinfo[i].dobj.name = strdup(PQgetvalue(res, i, i_extname));
-		extinfo[i].namespace = strdup(PQgetvalue(res, i, i_nspname));
+		extinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_extname));
+		extinfo[i].namespace = pg_strdup(PQgetvalue(res, i, i_nspname));
 		extinfo[i].relocatable = *(PQgetvalue(res, i, i_extrelocatable)) == 't';
-		extinfo[i].extversion = strdup(PQgetvalue(res, i, i_extversion));
-		extinfo[i].extconfig = strdup(PQgetvalue(res, i, i_extconfig));
-		extinfo[i].extcondition = strdup(PQgetvalue(res, i, i_extcondition));
+		extinfo[i].extversion = pg_strdup(PQgetvalue(res, i, i_extversion));
+		extinfo[i].extconfig = pg_strdup(PQgetvalue(res, i, i_extconfig));
+		extinfo[i].extcondition = pg_strdup(PQgetvalue(res, i, i_extcondition));
 
 		/* Decide whether we want to dump it */
 		selectDumpableExtension(&(extinfo[i]));
@@ -2929,7 +2930,7 @@ getTypes(int *numTypes)
 
 	ntups = PQntuples(res);
 
-	tyinfo = (TypeInfo *) malloc(ntups * sizeof(TypeInfo));
+	tyinfo = (TypeInfo *) pg_malloc(ntups * sizeof(TypeInfo));
 
 	i_tableoid = PQfnumber(res, "tableoid");
 	i_oid = PQfnumber(res, "oid");
@@ -2951,10 +2952,10 @@ getTypes(int *numTypes)
 		tyinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
 		tyinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
 		AssignDumpId(&tyinfo[i].dobj);
-		tyinfo[i].dobj.name = strdup(PQgetvalue(res, i, i_typname));
+		tyinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_typname));
 		tyinfo[i].dobj.namespace = findNamespace(atooid(PQgetvalue(res, i, i_typnamespace)),
 												 tyinfo[i].dobj.catId.oid);
-		tyinfo[i].rolname = strdup(PQgetvalue(res, i, i_rolname));
+		tyinfo[i].rolname = pg_strdup(PQgetvalue(res, i, i_rolname));
 		tyinfo[i].typelem = atooid(PQgetvalue(res, i, i_typelem));
 		tyinfo[i].typrelid = atooid(PQgetvalue(res, i, i_typrelid));
 		tyinfo[i].typrelkind = *PQgetvalue(res, i, i_typrelkind);
@@ -2995,11 +2996,11 @@ getTypes(int *numTypes)
 		if (tyinfo[i].dobj.dump && (tyinfo[i].typtype == TYPTYPE_BASE ||
 									tyinfo[i].typtype == TYPTYPE_RANGE))
 		{
-			stinfo = (ShellTypeInfo *) malloc(sizeof(ShellTypeInfo));
+			stinfo = (ShellTypeInfo *) pg_malloc(sizeof(ShellTypeInfo));
 			stinfo->dobj.objType = DO_SHELL_TYPE;
 			stinfo->dobj.catId = nilCatalogId;
 			AssignDumpId(&stinfo->dobj);
-			stinfo->dobj.name = strdup(tyinfo[i].dobj.name);
+			stinfo->dobj.name = pg_strdup(tyinfo[i].dobj.name);
 			stinfo->dobj.namespace = tyinfo[i].dobj.namespace;
 			stinfo->baseType = &(tyinfo[i]);
 			tyinfo[i].shellType = stinfo;
@@ -3134,7 +3135,7 @@ getOperators(int *numOprs)
 	ntups = PQntuples(res);
 	*numOprs = ntups;
 
-	oprinfo = (OprInfo *) malloc(ntups * sizeof(OprInfo));
+	oprinfo = (OprInfo *) pg_malloc(ntups * sizeof(OprInfo));
 
 	i_tableoid = PQfnumber(res, "tableoid");
 	i_oid = PQfnumber(res, "oid");
@@ -3149,10 +3150,10 @@ getOperators(int *numOprs)
 		oprinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
 		oprinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
 		AssignDumpId(&oprinfo[i].dobj);
-		oprinfo[i].dobj.name = strdup(PQgetvalue(res, i, i_oprname));
+		oprinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_oprname));
 		oprinfo[i].dobj.namespace = findNamespace(atooid(PQgetvalue(res, i, i_oprnamespace)),
 												  oprinfo[i].dobj.catId.oid);
-		oprinfo[i].rolname = strdup(PQgetvalue(res, i, i_rolname));
+		oprinfo[i].rolname = pg_strdup(PQgetvalue(res, i, i_rolname));
 		oprinfo[i].oprcode = atooid(PQgetvalue(res, i, i_oprcode));
 
 		/* Decide whether we want to dump it */
@@ -3218,7 +3219,7 @@ getCollations(int *numCollations)
 	ntups = PQntuples(res);
 	*numCollations = ntups;
 
-	collinfo = (CollInfo *) malloc(ntups * sizeof(CollInfo));
+	collinfo = (CollInfo *) pg_malloc(ntups * sizeof(CollInfo));
 
 	i_tableoid = PQfnumber(res, "tableoid");
 	i_oid = PQfnumber(res, "oid");
@@ -3232,10 +3233,10 @@ getCollations(int *numCollations)
 		collinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
 		collinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
 		AssignDumpId(&collinfo[i].dobj);
-		collinfo[i].dobj.name = strdup(PQgetvalue(res, i, i_collname));
+		collinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_collname));
 		collinfo[i].dobj.namespace = findNamespace(atooid(PQgetvalue(res, i, i_collnamespace)),
 												 collinfo[i].dobj.catId.oid);
-		collinfo[i].rolname = strdup(PQgetvalue(res, i, i_rolname));
+		collinfo[i].rolname = pg_strdup(PQgetvalue(res, i, i_rolname));
 
 		/* Decide whether we want to dump it */
 		selectDumpableObject(&(collinfo[i].dobj));
@@ -3296,7 +3297,7 @@ getConversions(int *numConversions)
 	ntups = PQntuples(res);
 	*numConversions = ntups;
 
-	convinfo = (ConvInfo *) malloc(ntups * sizeof(ConvInfo));
+	convinfo = (ConvInfo *) pg_malloc(ntups * sizeof(ConvInfo));
 
 	i_tableoid = PQfnumber(res, "tableoid");
 	i_oid = PQfnumber(res, "oid");
@@ -3310,10 +3311,10 @@ getConversions(int *numConversions)
 		convinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
 		convinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
 		AssignDumpId(&convinfo[i].dobj);
-		convinfo[i].dobj.name = strdup(PQgetvalue(res, i, i_conname));
+		convinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_conname));
 		convinfo[i].dobj.namespace = findNamespace(atooid(PQgetvalue(res, i, i_connamespace)),
 												 convinfo[i].dobj.catId.oid);
-		convinfo[i].rolname = strdup(PQgetvalue(res, i, i_rolname));
+		convinfo[i].rolname = pg_strdup(PQgetvalue(res, i, i_rolname));
 
 		/* Decide whether we want to dump it */
 		selectDumpableObject(&(convinfo[i].dobj));
@@ -3386,7 +3387,7 @@ getOpclasses(int *numOpclasses)
 	ntups = PQntuples(res);
 	*numOpclasses = ntups;
 
-	opcinfo = (OpclassInfo *) malloc(ntups * sizeof(OpclassInfo));
+	opcinfo = (OpclassInfo *) pg_malloc(ntups * sizeof(OpclassInfo));
 
 	i_tableoid = PQfnumber(res, "tableoid");
 	i_oid = PQfnumber(res, "oid");
@@ -3400,10 +3401,10 @@ getOpclasses(int *numOpclasses)
 		opcinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
 		opcinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
 		AssignDumpId(&opcinfo[i].dobj);
-		opcinfo[i].dobj.name = strdup(PQgetvalue(res, i, i_opcname));
+		opcinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_opcname));
 		opcinfo[i].dobj.namespace = findNamespace(atooid(PQgetvalue(res, i, i_opcnamespace)),
 												  opcinfo[i].dobj.catId.oid);
-		opcinfo[i].rolname = strdup(PQgetvalue(res, i, i_rolname));
+		opcinfo[i].rolname = pg_strdup(PQgetvalue(res, i, i_rolname));
 
 		/* Decide whether we want to dump it */
 		selectDumpableObject(&(opcinfo[i].dobj));
@@ -3473,7 +3474,7 @@ getOpfamilies(int *numOpfamilies)
 	ntups = PQntuples(res);
 	*numOpfamilies = ntups;
 
-	opfinfo = (OpfamilyInfo *) malloc(ntups * sizeof(OpfamilyInfo));
+	opfinfo = (OpfamilyInfo *) pg_malloc(ntups * sizeof(OpfamilyInfo));
 
 	i_tableoid = PQfnumber(res, "tableoid");
 	i_oid = PQfnumber(res, "oid");
@@ -3487,10 +3488,10 @@ getOpfamilies(int *numOpfamilies)
 		opfinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
 		opfinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
 		AssignDumpId(&opfinfo[i].dobj);
-		opfinfo[i].dobj.name = strdup(PQgetvalue(res, i, i_opfname));
+		opfinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_opfname));
 		opfinfo[i].dobj.namespace = findNamespace(atooid(PQgetvalue(res, i, i_opfnamespace)),
 												  opfinfo[i].dobj.catId.oid);
-		opfinfo[i].rolname = strdup(PQgetvalue(res, i, i_rolname));
+		opfinfo[i].rolname = pg_strdup(PQgetvalue(res, i, i_rolname));
 
 		/* Decide whether we want to dump it */
 		selectDumpableObject(&(opfinfo[i].dobj));
@@ -3613,7 +3614,7 @@ getAggregates(int *numAggs)
 	ntups = PQntuples(res);
 	*numAggs = ntups;
 
-	agginfo = (AggInfo *) malloc(ntups * sizeof(AggInfo));
+	agginfo = (AggInfo *) pg_malloc(ntups * sizeof(AggInfo));
 
 	i_tableoid = PQfnumber(res, "tableoid");
 	i_oid = PQfnumber(res, "oid");
@@ -3630,22 +3631,22 @@ getAggregates(int *numAggs)
 		agginfo[i].aggfn.dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
 		agginfo[i].aggfn.dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
 		AssignDumpId(&agginfo[i].aggfn.dobj);
-		agginfo[i].aggfn.dobj.name = strdup(PQgetvalue(res, i, i_aggname));
+		agginfo[i].aggfn.dobj.name = pg_strdup(PQgetvalue(res, i, i_aggname));
 		agginfo[i].aggfn.dobj.namespace = findNamespace(atooid(PQgetvalue(res, i, i_aggnamespace)),
 											agginfo[i].aggfn.dobj.catId.oid);
-		agginfo[i].aggfn.rolname = strdup(PQgetvalue(res, i, i_rolname));
+		agginfo[i].aggfn.rolname = pg_strdup(PQgetvalue(res, i, i_rolname));
 		if (strlen(agginfo[i].aggfn.rolname) == 0)
 			write_msg(NULL, "WARNING: owner of aggregate function \"%s\" appears to be invalid\n",
 					  agginfo[i].aggfn.dobj.name);
 		agginfo[i].aggfn.lang = InvalidOid;		/* not currently interesting */
 		agginfo[i].aggfn.prorettype = InvalidOid;		/* not saved */
-		agginfo[i].aggfn.proacl = strdup(PQgetvalue(res, i, i_aggacl));
+		agginfo[i].aggfn.proacl = pg_strdup(PQgetvalue(res, i, i_aggacl));
 		agginfo[i].aggfn.nargs = atoi(PQgetvalue(res, i, i_pronargs));
 		if (agginfo[i].aggfn.nargs == 0)
 			agginfo[i].aggfn.argtypes = NULL;
 		else
 		{
-			agginfo[i].aggfn.argtypes = (Oid *) malloc(agginfo[i].aggfn.nargs * sizeof(Oid));
+			agginfo[i].aggfn.argtypes = (Oid *) pg_malloc(agginfo[i].aggfn.nargs * sizeof(Oid));
 			if (g_fout->remoteVersion >= 70300)
 				parseOidArray(PQgetvalue(res, i, i_proargtypes),
 							  agginfo[i].aggfn.argtypes,
@@ -3775,7 +3776,7 @@ getFuncs(int *numFuncs)
 
 	*numFuncs = ntups;
 
-	finfo = (FuncInfo *) calloc(ntups, sizeof(FuncInfo));
+	finfo = (FuncInfo *) pg_calloc(ntups, sizeof(FuncInfo));
 
 	i_tableoid = PQfnumber(res, "tableoid");
 	i_oid = PQfnumber(res, "oid");
@@ -3794,20 +3795,20 @@ getFuncs(int *numFuncs)
 		finfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
 		finfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
 		AssignDumpId(&finfo[i].dobj);
-		finfo[i].dobj.name = strdup(PQgetvalue(res, i, i_proname));
+		finfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_proname));
 		finfo[i].dobj.namespace =
 			findNamespace(atooid(PQgetvalue(res, i, i_pronamespace)),
 						  finfo[i].dobj.catId.oid);
-		finfo[i].rolname = strdup(PQgetvalue(res, i, i_rolname));
+		finfo[i].rolname = pg_strdup(PQgetvalue(res, i, i_rolname));
 		finfo[i].lang = atooid(PQgetvalue(res, i, i_prolang));
 		finfo[i].prorettype = atooid(PQgetvalue(res, i, i_prorettype));
-		finfo[i].proacl = strdup(PQgetvalue(res, i, i_proacl));
+		finfo[i].proacl = pg_strdup(PQgetvalue(res, i, i_proacl));
 		finfo[i].nargs = atoi(PQgetvalue(res, i, i_pronargs));
 		if (finfo[i].nargs == 0)
 			finfo[i].argtypes = NULL;
 		else
 		{
-			finfo[i].argtypes = (Oid *) malloc(finfo[i].nargs * sizeof(Oid));
+			finfo[i].argtypes = (Oid *) pg_malloc(finfo[i].nargs * sizeof(Oid));
 			parseOidArray(PQgetvalue(res, i, i_proargtypes),
 						  finfo[i].argtypes, finfo[i].nargs);
 		}
@@ -4204,7 +4205,7 @@ getTables(int *numTables)
 	 * only one, because we don't yet know which tables might be inheritance
 	 * ancestors of the target table.
 	 */
-	tblinfo = (TableInfo *) calloc(ntups, sizeof(TableInfo));
+	tblinfo = (TableInfo *) pg_calloc(ntups, sizeof(TableInfo));
 
 	i_reltableoid = PQfnumber(res, "tableoid");
 	i_reloid = PQfnumber(res, "oid");
@@ -4250,11 +4251,11 @@ getTables(int *numTables)
 		tblinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_reltableoid));
 		tblinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_reloid));
 		AssignDumpId(&tblinfo[i].dobj);
-		tblinfo[i].dobj.name = strdup(PQgetvalue(res, i, i_relname));
+		tblinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_relname));
 		tblinfo[i].dobj.namespace = findNamespace(atooid(PQgetvalue(res, i, i_relnamespace)),
 												  tblinfo[i].dobj.catId.oid);
-		tblinfo[i].rolname = strdup(PQgetvalue(res, i, i_rolname));
-		tblinfo[i].relacl = strdup(PQgetvalue(res, i, i_relacl));
+		tblinfo[i].rolname = pg_strdup(PQgetvalue(res, i, i_rolname));
+		tblinfo[i].relacl = pg_strdup(PQgetvalue(res, i, i_relacl));
 		tblinfo[i].relkind = *(PQgetvalue(res, i, i_relkind));
 		tblinfo[i].relpersistence = *(PQgetvalue(res, i, i_relpersistence));
 		tblinfo[i].hasindex = (strcmp(PQgetvalue(res, i, i_relhasindex), "t") == 0);
@@ -4267,7 +4268,7 @@ getTables(int *numTables)
 		if (PQgetisnull(res, i, i_reloftype))
 			tblinfo[i].reloftype = NULL;
 		else
-			tblinfo[i].reloftype = strdup(PQgetvalue(res, i, i_reloftype));
+			tblinfo[i].reloftype = pg_strdup(PQgetvalue(res, i, i_reloftype));
 		tblinfo[i].ncheck = atoi(PQgetvalue(res, i, i_relchecks));
 		if (PQgetisnull(res, i, i_owning_tab))
 		{
@@ -4279,9 +4280,9 @@ getTables(int *numTables)
 			tblinfo[i].owning_tab = atooid(PQgetvalue(res, i, i_owning_tab));
 			tblinfo[i].owning_col = atoi(PQgetvalue(res, i, i_owning_col));
 		}
-		tblinfo[i].reltablespace = strdup(PQgetvalue(res, i, i_reltablespace));
-		tblinfo[i].reloptions = strdup(PQgetvalue(res, i, i_reloptions));
-		tblinfo[i].toast_reloptions = strdup(PQgetvalue(res, i, i_toastreloptions));
+		tblinfo[i].reltablespace = pg_strdup(PQgetvalue(res, i, i_reltablespace));
+		tblinfo[i].reloptions = pg_strdup(PQgetvalue(res, i, i_reloptions));
+		tblinfo[i].toast_reloptions = pg_strdup(PQgetvalue(res, i, i_toastreloptions));
 
 		/* other fields were zeroed above */
 
@@ -4395,7 +4396,7 @@ getInherits(int *numInherits)
 
 	*numInherits = ntups;
 
-	inhinfo = (InhInfo *) malloc(ntups * sizeof(InhInfo));
+	inhinfo = (InhInfo *) pg_malloc(ntups * sizeof(InhInfo));
 
 	i_inhrelid = PQfnumber(res, "inhrelid");
 	i_inhparent = PQfnumber(res, "inhparent");
@@ -4660,8 +4661,8 @@ getIndexes(TableInfo tblinfo[], int numTables)
 		i_tablespace = PQfnumber(res, "tablespace");
 		i_options = PQfnumber(res, "options");
 
-		indxinfo = (IndxInfo *) malloc(ntups * sizeof(IndxInfo));
-		constrinfo = (ConstraintInfo *) malloc(ntups * sizeof(ConstraintInfo));
+		indxinfo = (IndxInfo *) pg_malloc(ntups * sizeof(IndxInfo));
+		constrinfo = (ConstraintInfo *) pg_malloc(ntups * sizeof(ConstraintInfo));
 
 		for (j = 0; j < ntups; j++)
 		{
@@ -4671,13 +4672,13 @@ getIndexes(TableInfo tblinfo[], int numTables)
 			indxinfo[j].dobj.catId.tableoid = atooid(PQgetvalue(res, j, i_tableoid));
 			indxinfo[j].dobj.catId.oid = atooid(PQgetvalue(res, j, i_oid));
 			AssignDumpId(&indxinfo[j].dobj);
-			indxinfo[j].dobj.name = strdup(PQgetvalue(res, j, i_indexname));
+			indxinfo[j].dobj.name = pg_strdup(PQgetvalue(res, j, i_indexname));
 			indxinfo[j].dobj.namespace = tbinfo->dobj.namespace;
 			indxinfo[j].indextable = tbinfo;
-			indxinfo[j].indexdef = strdup(PQgetvalue(res, j, i_indexdef));
+			indxinfo[j].indexdef = pg_strdup(PQgetvalue(res, j, i_indexdef));
 			indxinfo[j].indnkeys = atoi(PQgetvalue(res, j, i_indnkeys));
-			indxinfo[j].tablespace = strdup(PQgetvalue(res, j, i_tablespace));
-			indxinfo[j].options = strdup(PQgetvalue(res, j, i_options));
+			indxinfo[j].tablespace = pg_strdup(PQgetvalue(res, j, i_tablespace));
+			indxinfo[j].options = pg_strdup(PQgetvalue(res, j, i_options));
 
 			/*
 			 * In pre-7.4 releases, indkeys may contain more entries than
@@ -4688,7 +4689,7 @@ getIndexes(TableInfo tblinfo[], int numTables)
 			 * have to allocate enough space to keep parseOidArray from
 			 * complaining.
 			 */
-			indxinfo[j].indkeys = (Oid *) malloc(INDEX_MAX_KEYS * sizeof(Oid));
+			indxinfo[j].indkeys = (Oid *) pg_malloc(INDEX_MAX_KEYS * sizeof(Oid));
 			parseOidArray(PQgetvalue(res, j, i_indkey),
 						  indxinfo[j].indkeys, INDEX_MAX_KEYS);
 			indxinfo[j].indisclustered = (PQgetvalue(res, j, i_indisclustered)[0] == 't');
@@ -4707,13 +4708,13 @@ getIndexes(TableInfo tblinfo[], int numTables)
 				constrinfo[j].dobj.catId.tableoid = atooid(PQgetvalue(res, j, i_contableoid));
 				constrinfo[j].dobj.catId.oid = atooid(PQgetvalue(res, j, i_conoid));
 				AssignDumpId(&constrinfo[j].dobj);
-				constrinfo[j].dobj.name = strdup(PQgetvalue(res, j, i_conname));
+				constrinfo[j].dobj.name = pg_strdup(PQgetvalue(res, j, i_conname));
 				constrinfo[j].dobj.namespace = tbinfo->dobj.namespace;
 				constrinfo[j].contable = tbinfo;
 				constrinfo[j].condomain = NULL;
 				constrinfo[j].contype = contype;
 				if (contype == 'x')
-					constrinfo[j].condef = strdup(PQgetvalue(res, j, i_condef));
+					constrinfo[j].condef = pg_strdup(PQgetvalue(res, j, i_condef));
 				else
 					constrinfo[j].condef = NULL;
 				constrinfo[j].confrelid = InvalidOid;
@@ -4808,7 +4809,7 @@ getConstraints(TableInfo tblinfo[], int numTables)
 		i_confrelid = PQfnumber(res, "confrelid");
 		i_condef = PQfnumber(res, "condef");
 
-		constrinfo = (ConstraintInfo *) malloc(ntups * sizeof(ConstraintInfo));
+		constrinfo = (ConstraintInfo *) pg_malloc(ntups * sizeof(ConstraintInfo));
 
 		for (j = 0; j < ntups; j++)
 		{
@@ -4816,12 +4817,12 @@ getConstraints(TableInfo tblinfo[], int numTables)
 			constrinfo[j].dobj.catId.tableoid = atooid(PQgetvalue(res, j, i_contableoid));
 			constrinfo[j].dobj.catId.oid = atooid(PQgetvalue(res, j, i_conoid));
 			AssignDumpId(&constrinfo[j].dobj);
-			constrinfo[j].dobj.name = strdup(PQgetvalue(res, j, i_conname));
+			constrinfo[j].dobj.name = pg_strdup(PQgetvalue(res, j, i_conname));
 			constrinfo[j].dobj.namespace = tbinfo->dobj.namespace;
 			constrinfo[j].contable = tbinfo;
 			constrinfo[j].condomain = NULL;
 			constrinfo[j].contype = 'f';
-			constrinfo[j].condef = strdup(PQgetvalue(res, j, i_condef));
+			constrinfo[j].condef = pg_strdup(PQgetvalue(res, j, i_condef));
 			constrinfo[j].confrelid = atooid(PQgetvalue(res, j, i_confrelid));
 			constrinfo[j].conindex = 0;
 			constrinfo[j].condeferrable = false;
@@ -4891,7 +4892,7 @@ getDomainConstraints(TypeInfo *tyinfo)
 	i_conname = PQfnumber(res, "conname");
 	i_consrc = PQfnumber(res, "consrc");
 
-	constrinfo = (ConstraintInfo *) malloc(ntups * sizeof(ConstraintInfo));
+	constrinfo = (ConstraintInfo *) pg_malloc(ntups * sizeof(ConstraintInfo));
 
 	tyinfo->nDomChecks = ntups;
 	tyinfo->domChecks = constrinfo;
@@ -4902,12 +4903,12 @@ getDomainConstraints(TypeInfo *tyinfo)
 		constrinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
 		constrinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
 		AssignDumpId(&constrinfo[i].dobj);
-		constrinfo[i].dobj.name = strdup(PQgetvalue(res, i, i_conname));
+		constrinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_conname));
 		constrinfo[i].dobj.namespace = tyinfo->dobj.namespace;
 		constrinfo[i].contable = NULL;
 		constrinfo[i].condomain = tyinfo;
 		constrinfo[i].contype = 'c';
-		constrinfo[i].condef = strdup(PQgetvalue(res, i, i_consrc));
+		constrinfo[i].condef = pg_strdup(PQgetvalue(res, i, i_consrc));
 		constrinfo[i].confrelid = InvalidOid;
 		constrinfo[i].conindex = 0;
 		constrinfo[i].condeferrable = false;
@@ -4989,7 +4990,7 @@ getRules(int *numRules)
 
 	*numRules = ntups;
 
-	ruleinfo = (RuleInfo *) malloc(ntups * sizeof(RuleInfo));
+	ruleinfo = (RuleInfo *) pg_malloc(ntups * sizeof(RuleInfo));
 
 	i_tableoid = PQfnumber(res, "tableoid");
 	i_oid = PQfnumber(res, "oid");
@@ -5007,7 +5008,7 @@ getRules(int *numRules)
 		ruleinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
 		ruleinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
 		AssignDumpId(&ruleinfo[i].dobj);
-		ruleinfo[i].dobj.name = strdup(PQgetvalue(res, i, i_rulename));
+		ruleinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_rulename));
 		ruletableoid = atooid(PQgetvalue(res, i, i_ruletable));
 		ruleinfo[i].ruletable = findTableByOid(ruletableoid);
 		if (ruleinfo[i].ruletable == NULL)
@@ -5211,7 +5212,7 @@ getTriggers(TableInfo tblinfo[], int numTables)
 		i_tginitdeferred = PQfnumber(res, "tginitdeferred");
 		i_tgdef = PQfnumber(res, "tgdef");
 
-		tginfo = (TriggerInfo *) malloc(ntups * sizeof(TriggerInfo));
+		tginfo = (TriggerInfo *) pg_malloc(ntups * sizeof(TriggerInfo));
 
 		for (j = 0; j < ntups; j++)
 		{
@@ -5219,13 +5220,13 @@ getTriggers(TableInfo tblinfo[], int numTables)
 			tginfo[j].dobj.catId.tableoid = atooid(PQgetvalue(res, j, i_tableoid));
 			tginfo[j].dobj.catId.oid = atooid(PQgetvalue(res, j, i_oid));
 			AssignDumpId(&tginfo[j].dobj);
-			tginfo[j].dobj.name = strdup(PQgetvalue(res, j, i_tgname));
+			tginfo[j].dobj.name = pg_strdup(PQgetvalue(res, j, i_tgname));
 			tginfo[j].dobj.namespace = tbinfo->dobj.namespace;
 			tginfo[j].tgtable = tbinfo;
 			tginfo[j].tgenabled = *(PQgetvalue(res, j, i_tgenabled));
 			if (i_tgdef >= 0)
 			{
-				tginfo[j].tgdef = strdup(PQgetvalue(res, j, i_tgdef));
+				tginfo[j].tgdef = pg_strdup(PQgetvalue(res, j, i_tgdef));
 
 				/* remaining fields are not valid if we have tgdef */
 				tginfo[j].tgfname = NULL;
@@ -5243,17 +5244,17 @@ getTriggers(TableInfo tblinfo[], int numTables)
 			{
 				tginfo[j].tgdef = NULL;
 
-				tginfo[j].tgfname = strdup(PQgetvalue(res, j, i_tgfname));
+				tginfo[j].tgfname = pg_strdup(PQgetvalue(res, j, i_tgfname));
 				tginfo[j].tgtype = atoi(PQgetvalue(res, j, i_tgtype));
 				tginfo[j].tgnargs = atoi(PQgetvalue(res, j, i_tgnargs));
-				tginfo[j].tgargs = strdup(PQgetvalue(res, j, i_tgargs));
+				tginfo[j].tgargs = pg_strdup(PQgetvalue(res, j, i_tgargs));
 				tginfo[j].tgisconstraint = *(PQgetvalue(res, j, i_tgisconstraint)) == 't';
 				tginfo[j].tgdeferrable = *(PQgetvalue(res, j, i_tgdeferrable)) == 't';
 				tginfo[j].tginitdeferred = *(PQgetvalue(res, j, i_tginitdeferred)) == 't';
 
 				if (tginfo[j].tgisconstraint)
 				{
-					tginfo[j].tgconstrname = strdup(PQgetvalue(res, j, i_tgconstrname));
+					tginfo[j].tgconstrname = pg_strdup(PQgetvalue(res, j, i_tgconstrname));
 					tginfo[j].tgconstrrelid = atooid(PQgetvalue(res, j, i_tgconstrrelid));
 					if (OidIsValid(tginfo[j].tgconstrrelid))
 					{
@@ -5264,7 +5265,7 @@ getTriggers(TableInfo tblinfo[], int numTables)
 									  tginfo[j].tgconstrrelid);
 							exit_nicely();
 						}
-						tginfo[j].tgconstrrelname = strdup(PQgetvalue(res, j, i_tgconstrrelname));
+						tginfo[j].tgconstrrelname = pg_strdup(PQgetvalue(res, j, i_tgconstrrelname));
 					}
 					else
 						tginfo[j].tgconstrrelname = NULL;
@@ -5381,7 +5382,7 @@ getProcLangs(int *numProcLangs)
 
 	*numProcLangs = ntups;
 
-	planginfo = (ProcLangInfo *) malloc(ntups * sizeof(ProcLangInfo));
+	planginfo = (ProcLangInfo *) pg_malloc(ntups * sizeof(ProcLangInfo));
 
 	i_tableoid = PQfnumber(res, "tableoid");
 	i_oid = PQfnumber(res, "oid");
@@ -5401,7 +5402,7 @@ getProcLangs(int *numProcLangs)
 		planginfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
 		AssignDumpId(&planginfo[i].dobj);
 
-		planginfo[i].dobj.name = strdup(PQgetvalue(res, i, i_lanname));
+		planginfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_lanname));
 		planginfo[i].lanpltrusted = *(PQgetvalue(res, i, i_lanpltrusted)) == 't';
 		planginfo[i].lanplcallfoid = atooid(PQgetvalue(res, i, i_lanplcallfoid));
 		if (i_laninline >= 0)
@@ -5413,13 +5414,13 @@ getProcLangs(int *numProcLangs)
 		else
 			planginfo[i].lanvalidator = InvalidOid;
 		if (i_lanacl >= 0)
-			planginfo[i].lanacl = strdup(PQgetvalue(res, i, i_lanacl));
+			planginfo[i].lanacl = pg_strdup(PQgetvalue(res, i, i_lanacl));
 		else
-			planginfo[i].lanacl = strdup("{=U}");
+			planginfo[i].lanacl = pg_strdup("{=U}");
 		if (i_lanowner >= 0)
-			planginfo[i].lanowner = strdup(PQgetvalue(res, i, i_lanowner));
+			planginfo[i].lanowner = pg_strdup(PQgetvalue(res, i, i_lanowner));
 		else
-			planginfo[i].lanowner = strdup("");
+			planginfo[i].lanowner = pg_strdup("");
 
 		if (g_fout->remoteVersion < 70300)
 		{
@@ -5502,7 +5503,7 @@ getCasts(int *numCasts)
 
 	*numCasts = ntups;
 
-	castinfo = (CastInfo *) malloc(ntups * sizeof(CastInfo));
+	castinfo = (CastInfo *) pg_malloc(ntups * sizeof(CastInfo));
 
 	i_tableoid = PQfnumber(res, "tableoid");
 	i_oid = PQfnumber(res, "oid");
@@ -5784,24 +5785,24 @@ getTableAttrs(TableInfo *tblinfo, int numTables)
 		i_attfdwoptions = PQfnumber(res, "attfdwoptions");
 
 		tbinfo->numatts = ntups;
-		tbinfo->attnames = (char **) malloc(ntups * sizeof(char *));
-		tbinfo->atttypnames = (char **) malloc(ntups * sizeof(char *));
-		tbinfo->atttypmod = (int *) malloc(ntups * sizeof(int));
-		tbinfo->attstattarget = (int *) malloc(ntups * sizeof(int));
-		tbinfo->attstorage = (char *) malloc(ntups * sizeof(char));
-		tbinfo->typstorage = (char *) malloc(ntups * sizeof(char));
-		tbinfo->attisdropped = (bool *) malloc(ntups * sizeof(bool));
-		tbinfo->attlen = (int *) malloc(ntups * sizeof(int));
-		tbinfo->attalign = (char *) malloc(ntups * sizeof(char));
-		tbinfo->attislocal = (bool *) malloc(ntups * sizeof(bool));
-		tbinfo->notnull = (bool *) malloc(ntups * sizeof(bool));
-		tbinfo->attrdefs = (AttrDefInfo **) malloc(ntups * sizeof(AttrDefInfo *));
-		tbinfo->attoptions = (char **) malloc(ntups * sizeof(char *));
-		tbinfo->attcollation = (Oid *) malloc(ntups * sizeof(Oid));
-		tbinfo->attfdwoptions = (char **) malloc(ntups * sizeof(char *));
-		tbinfo->inhAttrs = (bool *) malloc(ntups * sizeof(bool));
-		tbinfo->inhAttrDef = (bool *) malloc(ntups * sizeof(bool));
-		tbinfo->inhNotNull = (bool *) malloc(ntups * sizeof(bool));
+		tbinfo->attnames = (char **) pg_malloc(ntups * sizeof(char *));
+		tbinfo->atttypnames = (char **) pg_malloc(ntups * sizeof(char *));
+		tbinfo->atttypmod = (int *) pg_malloc(ntups * sizeof(int));
+		tbinfo->attstattarget = (int *) pg_malloc(ntups * sizeof(int));
+		tbinfo->attstorage = (char *) pg_malloc(ntups * sizeof(char));
+		tbinfo->typstorage = (char *) pg_malloc(ntups * sizeof(char));
+		tbinfo->attisdropped = (bool *) pg_malloc(ntups * sizeof(bool));
+		tbinfo->attlen = (int *) pg_malloc(ntups * sizeof(int));
+		tbinfo->attalign = (char *) pg_malloc(ntups * sizeof(char));
+		tbinfo->attislocal = (bool *) pg_malloc(ntups * sizeof(bool));
+		tbinfo->notnull = (bool *) pg_malloc(ntups * sizeof(bool));
+		tbinfo->attrdefs = (AttrDefInfo **) pg_malloc(ntups * sizeof(AttrDefInfo *));
+		tbinfo->attoptions = (char **) pg_malloc(ntups * sizeof(char *));
+		tbinfo->attcollation = (Oid *) pg_malloc(ntups * sizeof(Oid));
+		tbinfo->attfdwoptions = (char **) pg_malloc(ntups * sizeof(char *));
+		tbinfo->inhAttrs = (bool *) pg_malloc(ntups * sizeof(bool));
+		tbinfo->inhAttrDef = (bool *) pg_malloc(ntups * sizeof(bool));
+		tbinfo->inhNotNull = (bool *) pg_malloc(ntups * sizeof(bool));
 		hasdefaults = false;
 
 		for (j = 0; j < ntups; j++)
@@ -5812,8 +5813,8 @@ getTableAttrs(TableInfo *tblinfo, int numTables)
 						  tbinfo->dobj.name);
 				exit_nicely();
 			}
-			tbinfo->attnames[j] = strdup(PQgetvalue(res, j, i_attname));
-			tbinfo->atttypnames[j] = strdup(PQgetvalue(res, j, i_atttypname));
+			tbinfo->attnames[j] = pg_strdup(PQgetvalue(res, j, i_attname));
+			tbinfo->atttypnames[j] = pg_strdup(PQgetvalue(res, j, i_atttypname));
 			tbinfo->atttypmod[j] = atoi(PQgetvalue(res, j, i_atttypmod));
 			tbinfo->attstattarget[j] = atoi(PQgetvalue(res, j, i_attstattarget));
 			tbinfo->attstorage[j] = *(PQgetvalue(res, j, i_attstorage));
@@ -5823,9 +5824,9 @@ getTableAttrs(TableInfo *tblinfo, int numTables)
 			tbinfo->attalign[j] = *(PQgetvalue(res, j, i_attalign));
 			tbinfo->attislocal[j] = (PQgetvalue(res, j, i_attislocal)[0] == 't');
 			tbinfo->notnull[j] = (PQgetvalue(res, j, i_attnotnull)[0] == 't');
-			tbinfo->attoptions[j] = strdup(PQgetvalue(res, j, i_attoptions));
+			tbinfo->attoptions[j] = pg_strdup(PQgetvalue(res, j, i_attoptions));
 			tbinfo->attcollation[j] = atooid(PQgetvalue(res, j, i_attcollation));
-			tbinfo->attfdwoptions[j] = strdup(PQgetvalue(res, j, i_attfdwoptions));
+			tbinfo->attfdwoptions[j] = pg_strdup(PQgetvalue(res, j, i_attfdwoptions));
 			tbinfo->attrdefs[j] = NULL; /* fix below */
 			if (PQgetvalue(res, j, i_atthasdef)[0] == 't')
 				hasdefaults = true;
@@ -5889,7 +5890,7 @@ getTableAttrs(TableInfo *tblinfo, int numTables)
 			check_sql_result(res, g_conn, q->data, PGRES_TUPLES_OK);
 
 			numDefaults = PQntuples(res);
-			attrdefs = (AttrDefInfo *) malloc(numDefaults * sizeof(AttrDefInfo));
+			attrdefs = (AttrDefInfo *) pg_malloc(numDefaults * sizeof(AttrDefInfo));
 
 			for (j = 0; j < numDefaults; j++)
 			{
@@ -5901,9 +5902,9 @@ getTableAttrs(TableInfo *tblinfo, int numTables)
 				AssignDumpId(&attrdefs[j].dobj);
 				attrdefs[j].adtable = tbinfo;
 				attrdefs[j].adnum = adnum = atoi(PQgetvalue(res, j, 2));
-				attrdefs[j].adef_expr = strdup(PQgetvalue(res, j, 3));
+				attrdefs[j].adef_expr = pg_strdup(PQgetvalue(res, j, 3));
 
-				attrdefs[j].dobj.name = strdup(tbinfo->dobj.name);
+				attrdefs[j].dobj.name = pg_strdup(tbinfo->dobj.name);
 				attrdefs[j].dobj.namespace = tbinfo->dobj.namespace;
 
 				attrdefs[j].dobj.dump = tbinfo->dobj.dump;
@@ -6048,7 +6049,7 @@ getTableAttrs(TableInfo *tblinfo, int numTables)
 				exit_nicely();
 			}
 
-			constrs = (ConstraintInfo *) malloc(numConstrs * sizeof(ConstraintInfo));
+			constrs = (ConstraintInfo *) pg_malloc(numConstrs * sizeof(ConstraintInfo));
 			tbinfo->checkexprs = constrs;
 
 			for (j = 0; j < numConstrs; j++)
@@ -6059,12 +6060,12 @@ getTableAttrs(TableInfo *tblinfo, int numTables)
 				constrs[j].dobj.catId.tableoid = atooid(PQgetvalue(res, j, 0));
 				constrs[j].dobj.catId.oid = atooid(PQgetvalue(res, j, 1));
 				AssignDumpId(&constrs[j].dobj);
-				constrs[j].dobj.name = strdup(PQgetvalue(res, j, 2));
+				constrs[j].dobj.name = pg_strdup(PQgetvalue(res, j, 2));
 				constrs[j].dobj.namespace = tbinfo->dobj.namespace;
 				constrs[j].contable = tbinfo;
 				constrs[j].condomain = NULL;
 				constrs[j].contype = 'c';
-				constrs[j].condef = strdup(PQgetvalue(res, j, 3));
+				constrs[j].condef = pg_strdup(PQgetvalue(res, j, 3));
 				constrs[j].confrelid = InvalidOid;
 				constrs[j].conindex = 0;
 				constrs[j].condeferrable = false;
@@ -6157,7 +6158,7 @@ getTSParsers(int *numTSParsers)
 	ntups = PQntuples(res);
 	*numTSParsers = ntups;
 
-	prsinfo = (TSParserInfo *) malloc(ntups * sizeof(TSParserInfo));
+	prsinfo = (TSParserInfo *) pg_malloc(ntups * sizeof(TSParserInfo));
 
 	i_tableoid = PQfnumber(res, "tableoid");
 	i_oid = PQfnumber(res, "oid");
@@ -6175,7 +6176,7 @@ getTSParsers(int *numTSParsers)
 		prsinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
 		prsinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
 		AssignDumpId(&prsinfo[i].dobj);
-		prsinfo[i].dobj.name = strdup(PQgetvalue(res, i, i_prsname));
+		prsinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_prsname));
 		prsinfo[i].dobj.namespace = findNamespace(atooid(PQgetvalue(res, i, i_prsnamespace)),
 												  prsinfo[i].dobj.catId.oid);
 		prsinfo[i].prsstart = atooid(PQgetvalue(res, i, i_prsstart));
@@ -6240,7 +6241,7 @@ getTSDictionaries(int *numTSDicts)
 	ntups = PQntuples(res);
 	*numTSDicts = ntups;
 
-	dictinfo = (TSDictInfo *) malloc(ntups * sizeof(TSDictInfo));
+	dictinfo = (TSDictInfo *) pg_malloc(ntups * sizeof(TSDictInfo));
 
 	i_tableoid = PQfnumber(res, "tableoid");
 	i_oid = PQfnumber(res, "oid");
@@ -6256,15 +6257,15 @@ getTSDictionaries(int *numTSDicts)
 		dictinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
 		dictinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
 		AssignDumpId(&dictinfo[i].dobj);
-		dictinfo[i].dobj.name = strdup(PQgetvalue(res, i, i_dictname));
+		dictinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_dictname));
 		dictinfo[i].dobj.namespace = findNamespace(atooid(PQgetvalue(res, i, i_dictnamespace)),
 												 dictinfo[i].dobj.catId.oid);
-		dictinfo[i].rolname = strdup(PQgetvalue(res, i, i_rolname));
+		dictinfo[i].rolname = pg_strdup(PQgetvalue(res, i, i_rolname));
 		dictinfo[i].dicttemplate = atooid(PQgetvalue(res, i, i_dicttemplate));
 		if (PQgetisnull(res, i, i_dictinitoption))
 			dictinfo[i].dictinitoption = NULL;
 		else
-			dictinfo[i].dictinitoption = strdup(PQgetvalue(res, i, i_dictinitoption));
+			dictinfo[i].dictinitoption = pg_strdup(PQgetvalue(res, i, i_dictinitoption));
 
 		/* Decide whether we want to dump it */
 		selectDumpableObject(&(dictinfo[i].dobj));
@@ -6319,7 +6320,7 @@ getTSTemplates(int *numTSTemplates)
 	ntups = PQntuples(res);
 	*numTSTemplates = ntups;
 
-	tmplinfo = (TSTemplateInfo *) malloc(ntups * sizeof(TSTemplateInfo));
+	tmplinfo = (TSTemplateInfo *) pg_malloc(ntups * sizeof(TSTemplateInfo));
 
 	i_tableoid = PQfnumber(res, "tableoid");
 	i_oid = PQfnumber(res, "oid");
@@ -6334,7 +6335,7 @@ getTSTemplates(int *numTSTemplates)
 		tmplinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
 		tmplinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
 		AssignDumpId(&tmplinfo[i].dobj);
-		tmplinfo[i].dobj.name = strdup(PQgetvalue(res, i, i_tmplname));
+		tmplinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_tmplname));
 		tmplinfo[i].dobj.namespace = findNamespace(atooid(PQgetvalue(res, i, i_tmplnamespace)),
 												 tmplinfo[i].dobj.catId.oid);
 		tmplinfo[i].tmplinit = atooid(PQgetvalue(res, i, i_tmplinit));
@@ -6394,7 +6395,7 @@ getTSConfigurations(int *numTSConfigs)
 	ntups = PQntuples(res);
 	*numTSConfigs = ntups;
 
-	cfginfo = (TSConfigInfo *) malloc(ntups * sizeof(TSConfigInfo));
+	cfginfo = (TSConfigInfo *) pg_malloc(ntups * sizeof(TSConfigInfo));
 
 	i_tableoid = PQfnumber(res, "tableoid");
 	i_oid = PQfnumber(res, "oid");
@@ -6409,10 +6410,10 @@ getTSConfigurations(int *numTSConfigs)
 		cfginfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
 		cfginfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
 		AssignDumpId(&cfginfo[i].dobj);
-		cfginfo[i].dobj.name = strdup(PQgetvalue(res, i, i_cfgname));
+		cfginfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_cfgname));
 		cfginfo[i].dobj.namespace = findNamespace(atooid(PQgetvalue(res, i, i_cfgnamespace)),
 												  cfginfo[i].dobj.catId.oid);
-		cfginfo[i].rolname = strdup(PQgetvalue(res, i, i_rolname));
+		cfginfo[i].rolname = pg_strdup(PQgetvalue(res, i, i_rolname));
 		cfginfo[i].cfgparser = atooid(PQgetvalue(res, i, i_cfgparser));
 
 		/* Decide whether we want to dump it */
@@ -6493,7 +6494,7 @@ getForeignDataWrappers(int *numForeignDataWrappers)
 	ntups = PQntuples(res);
 	*numForeignDataWrappers = ntups;
 
-	fdwinfo = (FdwInfo *) malloc(ntups * sizeof(FdwInfo));
+	fdwinfo = (FdwInfo *) pg_malloc(ntups * sizeof(FdwInfo));
 
 	i_tableoid = PQfnumber(res, "tableoid");
 	i_oid = PQfnumber(res, "oid");
@@ -6510,13 +6511,13 @@ getForeignDataWrappers(int *numForeignDataWrappers)
 		fdwinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
 		fdwinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
 		AssignDumpId(&fdwinfo[i].dobj);
-		fdwinfo[i].dobj.name = strdup(PQgetvalue(res, i, i_fdwname));
+		fdwinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_fdwname));
 		fdwinfo[i].dobj.namespace = NULL;
-		fdwinfo[i].rolname = strdup(PQgetvalue(res, i, i_rolname));
-		fdwinfo[i].fdwhandler = strdup(PQgetvalue(res, i, i_fdwhandler));
-		fdwinfo[i].fdwvalidator = strdup(PQgetvalue(res, i, i_fdwvalidator));
-		fdwinfo[i].fdwoptions = strdup(PQgetvalue(res, i, i_fdwoptions));
-		fdwinfo[i].fdwacl = strdup(PQgetvalue(res, i, i_fdwacl));
+		fdwinfo[i].rolname = pg_strdup(PQgetvalue(res, i, i_rolname));
+		fdwinfo[i].fdwhandler = pg_strdup(PQgetvalue(res, i, i_fdwhandler));
+		fdwinfo[i].fdwvalidator = pg_strdup(PQgetvalue(res, i, i_fdwvalidator));
+		fdwinfo[i].fdwoptions = pg_strdup(PQgetvalue(res, i, i_fdwoptions));
+		fdwinfo[i].fdwacl = pg_strdup(PQgetvalue(res, i, i_fdwacl));
 
 		/* Decide whether we want to dump it */
 		selectDumpableObject(&(fdwinfo[i].dobj));
@@ -6580,7 +6581,7 @@ getForeignServers(int *numForeignServers)
 	ntups = PQntuples(res);
 	*numForeignServers = ntups;
 
-	srvinfo = (ForeignServerInfo *) malloc(ntups * sizeof(ForeignServerInfo));
+	srvinfo = (ForeignServerInfo *) pg_malloc(ntups * sizeof(ForeignServerInfo));
 
 	i_tableoid = PQfnumber(res, "tableoid");
 	i_oid = PQfnumber(res, "oid");
@@ -6598,14 +6599,14 @@ getForeignServers(int *numForeignServers)
 		srvinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
 		srvinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
 		AssignDumpId(&srvinfo[i].dobj);
-		srvinfo[i].dobj.name = strdup(PQgetvalue(res, i, i_srvname));
+		srvinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_srvname));
 		srvinfo[i].dobj.namespace = NULL;
-		srvinfo[i].rolname = strdup(PQgetvalue(res, i, i_rolname));
+		srvinfo[i].rolname = pg_strdup(PQgetvalue(res, i, i_rolname));
 		srvinfo[i].srvfdw = atooid(PQgetvalue(res, i, i_srvfdw));
-		srvinfo[i].srvtype = strdup(PQgetvalue(res, i, i_srvtype));
-		srvinfo[i].srvversion = strdup(PQgetvalue(res, i, i_srvversion));
-		srvinfo[i].srvoptions = strdup(PQgetvalue(res, i, i_srvoptions));
-		srvinfo[i].srvacl = strdup(PQgetvalue(res, i, i_srvacl));
+		srvinfo[i].srvtype = pg_strdup(PQgetvalue(res, i, i_srvtype));
+		srvinfo[i].srvversion = pg_strdup(PQgetvalue(res, i, i_srvversion));
+		srvinfo[i].srvoptions = pg_strdup(PQgetvalue(res, i, i_srvoptions));
+		srvinfo[i].srvacl = pg_strdup(PQgetvalue(res, i, i_srvacl));
 
 		/* Decide whether we want to dump it */
 		selectDumpableObject(&(srvinfo[i].dobj));
@@ -6665,7 +6666,7 @@ getDefaultACLs(int *numDefaultACLs)
 	ntups = PQntuples(res);
 	*numDefaultACLs = ntups;
 
-	daclinfo = (DefaultACLInfo *) malloc(ntups * sizeof(DefaultACLInfo));
+	daclinfo = (DefaultACLInfo *) pg_malloc(ntups * sizeof(DefaultACLInfo));
 
 	i_oid = PQfnumber(res, "oid");
 	i_tableoid = PQfnumber(res, "tableoid");
@@ -6683,7 +6684,7 @@ getDefaultACLs(int *numDefaultACLs)
 		daclinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
 		AssignDumpId(&daclinfo[i].dobj);
 		/* cheesy ... is it worth coming up with a better object name? */
-		daclinfo[i].dobj.name = strdup(PQgetvalue(res, i, i_defaclobjtype));
+		daclinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_defaclobjtype));
 
 		if (nspid != InvalidOid)
 			daclinfo[i].dobj.namespace = findNamespace(nspid,
@@ -6691,9 +6692,9 @@ getDefaultACLs(int *numDefaultACLs)
 		else
 			daclinfo[i].dobj.namespace = NULL;
 
-		daclinfo[i].defaclrole = strdup(PQgetvalue(res, i, i_defaclrole));
+		daclinfo[i].defaclrole = pg_strdup(PQgetvalue(res, i, i_defaclrole));
 		daclinfo[i].defaclobjtype = *(PQgetvalue(res, i, i_defaclobjtype));
-		daclinfo[i].defaclacl = strdup(PQgetvalue(res, i, i_defaclacl));
+		daclinfo[i].defaclacl = pg_strdup(PQgetvalue(res, i, i_defaclacl));
 
 		/* Decide whether we want to dump it */
 		selectDumpableDefaultACL(&(daclinfo[i]));
@@ -7021,7 +7022,7 @@ collectComments(Archive *fout, CommentItem **items)
 
 	ntups = PQntuples(res);
 
-	comments = (CommentItem *) malloc(ntups * sizeof(CommentItem));
+	comments = (CommentItem *) pg_malloc(ntups * sizeof(CommentItem));
 
 	for (i = 0; i < ntups; i++)
 	{
@@ -7174,7 +7175,7 @@ dumpNamespace(Archive *fout, NamespaceInfo *nspinfo)
 	delq = createPQExpBuffer();
 	labelq = createPQExpBuffer();
 
-	qnspname = strdup(fmtId(nspinfo->dobj.name));
+	qnspname = pg_strdup(fmtId(nspinfo->dobj.name));
 
 	appendPQExpBuffer(delq, "DROP SCHEMA %s;\n", qnspname);
 
@@ -7233,7 +7234,7 @@ dumpExtension(Archive *fout, ExtensionInfo *extinfo)
 	delq = createPQExpBuffer();
 	labelq = createPQExpBuffer();
 
-	qextname = strdup(fmtId(extinfo->dobj.name));
+	qextname = pg_strdup(fmtId(extinfo->dobj.name));
 
 	appendPQExpBuffer(delq, "DROP EXTENSION %s;\n", qextname);
 
@@ -8634,7 +8635,7 @@ dumpProcLang(Archive *fout, ProcLangInfo *plang)
 	delqry = createPQExpBuffer();
 	labelq = createPQExpBuffer();
 
-	qlanname = strdup(fmtId(plang->dobj.name));
+	qlanname = pg_strdup(fmtId(plang->dobj.name));
 
 	/*
 	 * If dumping a HANDLER clause, treat the language as being in the handler
@@ -9723,7 +9724,7 @@ convertRegProcReference(const char *proc)
 		char	   *paren;
 		bool		inquote;
 
-		name = strdup(proc);
+		name = pg_strdup(proc);
 		/* find non-double-quoted left paren */
 		inquote = false;
 		for (paren = name; *paren; paren++)
@@ -9770,7 +9771,7 @@ convertOperatorReference(const char *opr)
 		bool		inquote;
 		bool		sawdot;
 
-		name = strdup(opr);
+		name = pg_strdup(opr);
 		/* find non-double-quoted left paren, and check for non-quoted dot */
 		inquote = false;
 		sawdot = false;
@@ -9789,7 +9790,7 @@ convertOperatorReference(const char *opr)
 		/* If not schema-qualified, don't need to add OPERATOR() */
 		if (!sawdot)
 			return name;
-		oname = malloc(strlen(name) + 11);
+		oname = pg_malloc(strlen(name) + 11);
 		sprintf(oname, "OPERATOR(%s)", name);
 		free(name);
 		return oname;
@@ -9836,7 +9837,7 @@ convertTSFunction(Oid funcOid)
 		exit_nicely();
 	}
 
-	result = strdup(PQgetvalue(res, 0, 0));
+	result = pg_strdup(PQgetvalue(res, 0, 0));
 
 	PQclear(res);
 
@@ -9962,11 +9963,11 @@ dumpOpclass(Archive *fout, OpclassInfo *opcinfo)
 	opckeytype = PQgetvalue(res, 0, i_opckeytype);
 	opcdefault = PQgetvalue(res, 0, i_opcdefault);
 	/* opcfamily will still be needed after we PQclear res */
-	opcfamily = strdup(PQgetvalue(res, 0, i_opcfamily));
+	opcfamily = pg_strdup(PQgetvalue(res, 0, i_opcfamily));
 	opcfamilyname = PQgetvalue(res, 0, i_opcfamilyname);
 	opcfamilynsp = PQgetvalue(res, 0, i_opcfamilynsp);
 	/* amname will still be needed after we PQclear res */
-	amname = strdup(PQgetvalue(res, 0, i_amname));
+	amname = pg_strdup(PQgetvalue(res, 0, i_amname));
 
 	/*
 	 * DROP must be fully qualified in case same name appears in pg_catalog
@@ -10409,7 +10410,7 @@ dumpOpfamily(Archive *fout, OpfamilyInfo *opfinfo)
 	i_amname = PQfnumber(res, "amname");
 
 	/* amname will still be needed after we PQclear res */
-	amname = strdup(PQgetvalue(res, 0, i_amname));
+	amname = pg_strdup(PQgetvalue(res, 0, i_amname));
 
 	/*
 	 * DROP must be fully qualified in case same name appears in pg_catalog
@@ -11429,7 +11430,7 @@ dumpForeignDataWrapper(Archive *fout, FdwInfo *fdwinfo)
 	delq = createPQExpBuffer();
 	labelq = createPQExpBuffer();
 
-	qfdwname = strdup(fmtId(fdwinfo->dobj.name));
+	qfdwname = pg_strdup(fmtId(fdwinfo->dobj.name));
 
 	appendPQExpBuffer(q, "CREATE FOREIGN DATA WRAPPER %s",
 					  qfdwname);
@@ -11508,7 +11509,7 @@ dumpForeignServer(Archive *fout, ForeignServerInfo *srvinfo)
 	labelq = createPQExpBuffer();
 	query = createPQExpBuffer();
 
-	qsrvname = strdup(fmtId(srvinfo->dobj.name));
+	qsrvname = pg_strdup(fmtId(srvinfo->dobj.name));
 
 	/* look up the foreign-data wrapper */
 	selectSourceSchema("pg_catalog");
@@ -12091,7 +12092,7 @@ collectSecLabels(Archive *fout, SecLabelItem **items)
 
 	ntups = PQntuples(res);
 
-	labels = (SecLabelItem *) malloc(ntups * sizeof(SecLabelItem));
+	labels = (SecLabelItem *) pg_malloc(ntups * sizeof(SecLabelItem));
 
 	for (i = 0; i < ntups; i++)
 	{
@@ -12126,7 +12127,7 @@ dumpTable(Archive *fout, TableInfo *tbinfo)
 			dumpTableSchema(fout, tbinfo);
 
 		/* Handle the ACL here */
-		namecopy = strdup(fmtId(tbinfo->dobj.name));
+		namecopy = pg_strdup(fmtId(tbinfo->dobj.name));
 		dumpACL(fout, tbinfo->dobj.catId, tbinfo->dobj.dumpId,
 				(tbinfo->relkind == RELKIND_SEQUENCE) ? "SEQUENCE" :
 				"TABLE",
@@ -12160,8 +12161,8 @@ dumpTable(Archive *fout, TableInfo *tbinfo)
 				char	   *attnamecopy;
 				char	   *acltag;
 
-				attnamecopy = strdup(fmtId(attname));
-				acltag = malloc(strlen(tbinfo->dobj.name) + strlen(attname) + 2);
+				attnamecopy = pg_strdup(fmtId(attname));
+				acltag = pg_malloc(strlen(tbinfo->dobj.name) + strlen(attname) + 2);
 				sprintf(acltag, "%s.%s", tbinfo->dobj.name, attname);
 				/* Column's GRANT type is always TABLE */
 				dumpACL(fout, tbinfo->dobj.catId, tbinfo->dobj.dumpId, "TABLE",
@@ -12296,8 +12297,8 @@ dumpTableSchema(Archive *fout, TableInfo *tbinfo)
 			check_sql_result(res, g_conn, query->data, PGRES_TUPLES_OK);
 			i_srvname = PQfnumber(res, "srvname");
 			i_ftoptions = PQfnumber(res, "ftoptions");
-			srvname = strdup(PQgetvalue(res, 0, i_srvname));
-			ftoptions = strdup(PQgetvalue(res, 0, i_ftoptions));
+			srvname = pg_strdup(PQgetvalue(res, 0, i_srvname));
+			ftoptions = pg_strdup(PQgetvalue(res, 0, i_ftoptions));
 			PQclear(res);
 		}
 		else
@@ -13968,7 +13969,7 @@ getExtensionMembership(ExtensionInfo extinfo[], int numExtensions)
 					 */
 					makeTableDataInfo(configtbl, false);
 					if (strlen(extconditionarray[j]) > 0)
-						configtbl->dataObj->filtercond = strdup(extconditionarray[j]);
+						configtbl->dataObj->filtercond = pg_strdup(extconditionarray[j]);
 				}
 			}
 		}
@@ -14141,7 +14142,7 @@ selectSourceSchema(const char *schemaName)
 	destroyPQExpBuffer(query);
 	if (curSchemaName)
 		free(curSchemaName);
-	curSchemaName = strdup(schemaName);
+	curSchemaName = pg_strdup(schemaName);
 }
 
 /*
@@ -14162,13 +14163,13 @@ getFormattedTypeName(Oid oid, OidOptions opts)
 	if (oid == 0)
 	{
 		if ((opts & zeroAsOpaque) != 0)
-			return strdup(g_opaque_type);
+			return pg_strdup(g_opaque_type);
 		else if ((opts & zeroAsAny) != 0)
-			return strdup("'any'");
+			return pg_strdup("'any'");
 		else if ((opts & zeroAsStar) != 0)
-			return strdup("*");
+			return pg_strdup("*");
 		else if ((opts & zeroAsNone) != 0)
-			return strdup("NONE");
+			return pg_strdup("NONE");
 	}
 
 	query = createPQExpBuffer();
@@ -14207,12 +14208,12 @@ getFormattedTypeName(Oid oid, OidOptions opts)
 	if (g_fout->remoteVersion >= 70100)
 	{
 		/* already quoted */
-		result = strdup(PQgetvalue(res, 0, 0));
+		result = pg_strdup(PQgetvalue(res, 0, 0));
 	}
 	else
 	{
 		/* may need to quote it */
-		result = strdup(fmtId(PQgetvalue(res, 0, 0)));
+		result = pg_strdup(fmtId(PQgetvalue(res, 0, 0)));
 	}
 
 	PQclear(res);
@@ -14285,7 +14286,7 @@ myFormatType(const char *typname, int32 typmod)
 	if (isarray)
 		appendPQExpBuffer(buf, "[]");
 
-	result = strdup(buf->data);
+	result = pg_strdup(buf->data);
 	destroyPQExpBuffer(buf);
 
 	return result;
diff --git a/src/bin/pg_dump/pg_dump.h b/src/bin/pg_dump/pg_dump.h
index 3d5d534269f..c248e755992 100644
--- a/src/bin/pg_dump/pg_dump.h
+++ b/src/bin/pg_dump/pg_dump.h
@@ -521,11 +521,6 @@ extern void simple_string_list_append(SimpleStringList *list, const char *val);
 extern bool simple_oid_list_member(SimpleOidList *list, Oid val);
 extern bool simple_string_list_member(SimpleStringList *list, const char *val);
 
-extern char *pg_strdup(const char *string);
-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);
-
 extern void check_conn_and_db(void);
 extern void exit_nicely(void);
 
diff --git a/src/bin/pg_dump/pg_dump_sort.c b/src/bin/pg_dump/pg_dump_sort.c
index 6b6c073eb6a..3bb220d1966 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"
 
 static const char *modulename = gettext_noop("sorter");
 
@@ -227,10 +227,7 @@ sortDumpableObjects(DumpableObject **objs, int numObjs)
 	if (numObjs <= 0)
 		return;
 
-	ordering = (DumpableObject **) malloc(numObjs * sizeof(DumpableObject *));
-	if (ordering == NULL)
-		exit_horribly(NULL, modulename, "out of memory\n");
-
+	ordering = (DumpableObject **) pg_malloc(numObjs * sizeof(DumpableObject *));
 	while (!TopoSort(objs, numObjs, ordering, &nOrdering))
 		findDependencyLoops(ordering, nOrdering, numObjs);
 
@@ -301,9 +298,7 @@ TopoSort(DumpableObject **objs,
 		return true;
 
 	/* Create workspace for the above-described heap */
-	pendingHeap = (int *) malloc(numObjs * sizeof(int));
-	if (pendingHeap == NULL)
-		exit_horribly(NULL, modulename, "out of memory\n");
+	pendingHeap = (int *) pg_malloc(numObjs * sizeof(int));
 
 	/*
 	 * Scan the constraints, and for each item in the input, generate a count
@@ -312,13 +307,9 @@ TopoSort(DumpableObject **objs,
 	 * We also make a map showing the input-order index of the item with
 	 * dumpId j.
 	 */
-	beforeConstraints = (int *) malloc((maxDumpId + 1) * sizeof(int));
-	if (beforeConstraints == NULL)
-		exit_horribly(NULL, modulename, "out of memory\n");
+	beforeConstraints = (int *) pg_malloc((maxDumpId + 1) * sizeof(int));
 	memset(beforeConstraints, 0, (maxDumpId + 1) * sizeof(int));
-	idMap = (int *) malloc((maxDumpId + 1) * sizeof(int));
-	if (idMap == NULL)
-		exit_horribly(NULL, modulename, "out of memory\n");
+	idMap = (int *) pg_malloc((maxDumpId + 1) * sizeof(int));
 	for (i = 0; i < numObjs; i++)
 	{
 		obj = objs[i];
@@ -516,9 +507,7 @@ findDependencyLoops(DumpableObject **objs, int nObjs, int totObjs)
 	bool		fixedloop;
 	int			i;
 
-	workspace = (DumpableObject **) malloc(totObjs * sizeof(DumpableObject *));
-	if (workspace == NULL)
-		exit_horribly(NULL, modulename, "out of memory\n");
+	workspace = (DumpableObject **) pg_malloc(totObjs * sizeof(DumpableObject *));
 	initiallen = 0;
 	fixedloop = false;
 
diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c
index d138da568ea..4782e6889be 100644
--- a/src/bin/pg_dump/pg_dumpall.c
+++ b/src/bin/pg_dump/pg_dumpall.c
@@ -60,6 +60,9 @@ static PGconn *connectDatabase(const char *dbname, const char *pghost, const cha
 static PGresult *executeQuery(PGconn *conn, const char *query);
 static void executeCommand(PGconn *conn, const char *query);
 
+char *pg_strdup(const char *string);
+void *pg_malloc(size_t size);
+
 static char pg_dump_bin[MAXPGPATH];
 static PQExpBuffer pgdumpopts;
 static bool skip_acls = false;
@@ -916,7 +919,7 @@ dumpGroups(PGconn *conn)
 		if (strlen(grolist) < 3)
 			continue;
 
-		grolist = strdup(grolist);
+		grolist = pg_strdup(grolist);
 		grolist[0] = '(';
 		grolist[strlen(grolist) - 1] = ')';
 		printfPQExpBuffer(buf,
@@ -1040,7 +1043,7 @@ dumpTablespaces(PGconn *conn)
 		char	   *fspcname;
 
 		/* needed for buildACLCommands() */
-		fspcname = strdup(fmtId(spcname));
+		fspcname = pg_strdup(fmtId(spcname));
 
 		appendPQExpBuffer(buf, "CREATE TABLESPACE %s", fspcname);
 		appendPQExpBuffer(buf, " OWNER %s", fmtId(spcowner));
@@ -1189,11 +1192,11 @@ dumpCreateDB(PGconn *conn)
 	if (PQntuples(res) > 0)
 	{
 		if (!PQgetisnull(res, 0, 0))
-			default_encoding = strdup(PQgetvalue(res, 0, 0));
+			default_encoding = pg_strdup(PQgetvalue(res, 0, 0));
 		if (!PQgetisnull(res, 0, 1))
-			default_collate = strdup(PQgetvalue(res, 0, 1));
+			default_collate = pg_strdup(PQgetvalue(res, 0, 1));
 		if (!PQgetisnull(res, 0, 2))
-			default_ctype = strdup(PQgetvalue(res, 0, 2));
+			default_ctype = pg_strdup(PQgetvalue(res, 0, 2));
 	}
 
 	PQclear(res);
@@ -1283,7 +1286,7 @@ dumpCreateDB(PGconn *conn)
 		char	   *dbtablespace = PQgetvalue(res, i, 9);
 		char	   *fdbname;
 
-		fdbname = strdup(fmtId(dbname));
+		fdbname = pg_strdup(fmtId(dbname));
 
 		resetPQExpBuffer(buf);
 
@@ -1519,7 +1522,7 @@ makeAlterConfigCommand(PGconn *conn, const char *arrayitem,
 	char	   *mine;
 	PQExpBuffer buf = createPQExpBuffer();
 
-	mine = strdup(arrayitem);
+	mine = pg_strdup(arrayitem);
 	pos = strchr(mine, '=');
 	if (pos == NULL)
 		return;
@@ -1688,14 +1691,8 @@ connectDatabase(const char *dbname, const char *pghost, const char *pgport,
 	do
 	{
 #define PARAMS_ARRAY_SIZE	7
-		const char **keywords = malloc(PARAMS_ARRAY_SIZE * sizeof(*keywords));
-		const char **values = malloc(PARAMS_ARRAY_SIZE * sizeof(*values));
-
-		if (!keywords || !values)
-		{
-			fprintf(stderr, _("%s: out of memory\n"), progname);
-			exit(1);
-		}
+		const char **keywords = pg_malloc(PARAMS_ARRAY_SIZE * sizeof(*keywords));
+		const char **values = pg_malloc(PARAMS_ARRAY_SIZE * sizeof(*values));
 
 		keywords[0] = "host";
 		values[0] = pghost;
@@ -1911,3 +1908,41 @@ doShellQuoting(PQExpBuffer buf, const char *str)
 	appendPQExpBufferChar(buf, '"');
 #endif   /* WIN32 */
 }
+
+
+/*
+ *	Simpler versions of common.c functions.
+ */
+
+char *
+pg_strdup(const char *string)
+{
+	char	   *tmp;
+
+	if (!string)
+	{
+		fprintf(stderr, "cannot duplicate null pointer\n");
+		exit(1);
+	}
+	tmp = strdup(string);
+	if (!tmp)
+	{
+		fprintf(stderr, _("%s: out of memory\n"), progname);
+		exit(1);
+	}
+	return tmp;
+}
+
+void *
+pg_malloc(size_t size)
+{
+	void	   *tmp;
+
+	tmp = malloc(size);
+	if (!tmp)
+	{
+		fprintf(stderr, _("%s: out of memory\n"), progname);
+		exit(1);
+	}
+	return tmp;
+}
diff --git a/src/bin/pg_dump/pg_restore.c b/src/bin/pg_dump/pg_restore.c
index 7731d2540c7..a810ed60b4e 100644
--- a/src/bin/pg_dump/pg_restore.c
+++ b/src/bin/pg_dump/pg_restore.c
@@ -39,6 +39,7 @@
  *-------------------------------------------------------------------------
  */
 
+#include "common.h"
 #include "pg_backup_archiver.h"
 #include "dumputils.h"
 
@@ -159,21 +160,21 @@ main(int argc, char **argv)
 				opts->createDB = 1;
 				break;
 			case 'd':
-				opts->dbname = strdup(optarg);
+				opts->dbname = pg_strdup(optarg);
 				break;
 			case 'e':
 				opts->exit_on_error = true;
 				break;
 			case 'f':			/* output file name */
-				opts->filename = strdup(optarg);
+				opts->filename = pg_strdup(optarg);
 				break;
 			case 'F':
 				if (strlen(optarg) != 0)
-					opts->formatName = strdup(optarg);
+					opts->formatName = pg_strdup(optarg);
 				break;
 			case 'h':
 				if (strlen(optarg) != 0)
-					opts->pghost = strdup(optarg);
+					opts->pghost = pg_strdup(optarg);
 				break;
 			case 'i':
 				/* ignored, deprecated option */
@@ -188,11 +189,11 @@ main(int argc, char **argv)
 				break;
 
 			case 'L':			/* input TOC summary file name */
-				opts->tocFile = strdup(optarg);
+				opts->tocFile = pg_strdup(optarg);
 				break;
 
 			case 'n':			/* Dump data for this schema only */
-				opts->schemaNames = strdup(optarg);
+				opts->schemaNames = pg_strdup(optarg);
 				break;
 
 			case 'O':
@@ -201,7 +202,7 @@ main(int argc, char **argv)
 
 			case 'p':
 				if (strlen(optarg) != 0)
-					opts->pgport = strdup(optarg);
+					opts->pgport = pg_strdup(optarg);
 				break;
 			case 'R':
 				/* no-op, still accepted for backwards compatibility */
@@ -209,29 +210,29 @@ main(int argc, char **argv)
 			case 'P':			/* Function */
 				opts->selTypes = 1;
 				opts->selFunction = 1;
-				opts->functionNames = strdup(optarg);
+				opts->functionNames = pg_strdup(optarg);
 				break;
 			case 'I':			/* Index */
 				opts->selTypes = 1;
 				opts->selIndex = 1;
-				opts->indexNames = strdup(optarg);
+				opts->indexNames = pg_strdup(optarg);
 				break;
 			case 'T':			/* Trigger */
 				opts->selTypes = 1;
 				opts->selTrigger = 1;
-				opts->triggerNames = strdup(optarg);
+				opts->triggerNames = pg_strdup(optarg);
 				break;
 			case 's':			/* dump schema only */
 				opts->schemaOnly = 1;
 				break;
 			case 'S':			/* Superuser username */
 				if (strlen(optarg) != 0)
-					opts->superuser = strdup(optarg);
+					opts->superuser = pg_strdup(optarg);
 				break;
 			case 't':			/* Dump data for this table only */
 				opts->selTypes = 1;
 				opts->selTable = 1;
-				opts->tableNames = strdup(optarg);
+				opts->tableNames = pg_strdup(optarg);
 				break;
 
 			case 'U':
-- 
GitLab