diff --git a/contrib/pg_upgrade/function.c b/contrib/pg_upgrade/function.c
index d7c790c67d51d08862a8afb81afd3fd6c42198cb..c01ff046bbd6a780f0f88ffec68285774745d69d 100644
--- a/contrib/pg_upgrade/function.c
+++ b/contrib/pg_upgrade/function.c
@@ -36,52 +36,58 @@ install_support_functions_in_new_db(const char *db_name)
 
 	PQclear(executeQueryOrDie(conn,
 							  "CREATE OR REPLACE FUNCTION "
-				 "		binary_upgrade.set_next_pg_type_oid(OID) "
+							  "binary_upgrade.set_next_pg_type_oid(OID) "
 							  "RETURNS VOID "
 							  "AS '$libdir/pg_upgrade_support' "
 							  "LANGUAGE C STRICT;"));
 	PQclear(executeQueryOrDie(conn,
 							  "CREATE OR REPLACE FUNCTION "
-		   "		binary_upgrade.set_next_array_pg_type_oid(OID) "
+							  "binary_upgrade.set_next_array_pg_type_oid(OID) "
 							  "RETURNS VOID "
 							  "AS '$libdir/pg_upgrade_support' "
 							  "LANGUAGE C STRICT;"));
 	PQclear(executeQueryOrDie(conn,
 							  "CREATE OR REPLACE FUNCTION "
-		   "		binary_upgrade.set_next_toast_pg_type_oid(OID) "
+							  "binary_upgrade.set_next_toast_pg_type_oid(OID) "
 							  "RETURNS VOID "
 							  "AS '$libdir/pg_upgrade_support' "
 							  "LANGUAGE C STRICT;"));
 	PQclear(executeQueryOrDie(conn,
 							  "CREATE OR REPLACE FUNCTION "
-			"		binary_upgrade.set_next_heap_pg_class_oid(OID) "
+							  "binary_upgrade.set_next_heap_pg_class_oid(OID) "
 							  "RETURNS VOID "
 							  "AS '$libdir/pg_upgrade_support' "
 							  "LANGUAGE C STRICT;"));
 	PQclear(executeQueryOrDie(conn,
 							  "CREATE OR REPLACE FUNCTION "
-		   "		binary_upgrade.set_next_index_pg_class_oid(OID) "
+							  "binary_upgrade.set_next_index_pg_class_oid(OID) "
 							  "RETURNS VOID "
 							  "AS '$libdir/pg_upgrade_support' "
 							  "LANGUAGE C STRICT;"));
 	PQclear(executeQueryOrDie(conn,
 							  "CREATE OR REPLACE FUNCTION "
-		   "		binary_upgrade.set_next_toast_pg_class_oid(OID) "
+							  "binary_upgrade.set_next_toast_pg_class_oid(OID) "
 							  "RETURNS VOID "
 							  "AS '$libdir/pg_upgrade_support' "
 							  "LANGUAGE C STRICT;"));
 	PQclear(executeQueryOrDie(conn,
 							  "CREATE OR REPLACE FUNCTION "
-		 "		binary_upgrade.set_next_pg_enum_oid(OID) "
+							  "binary_upgrade.set_next_pg_enum_oid(OID) "
 							  "RETURNS VOID "
 							  "AS '$libdir/pg_upgrade_support' "
 							  "LANGUAGE C STRICT;"));
 	PQclear(executeQueryOrDie(conn,
 							  "CREATE OR REPLACE FUNCTION "
-		 "		binary_upgrade.set_next_pg_authid_oid(OID) "
+							  "binary_upgrade.set_next_pg_authid_oid(OID) "
 							  "RETURNS VOID "
 							  "AS '$libdir/pg_upgrade_support' "
 							  "LANGUAGE C STRICT;"));
+	PQclear(executeQueryOrDie(conn,
+							  "CREATE OR REPLACE FUNCTION "
+							  "binary_upgrade.create_empty_extension(text, text, bool, text, oid[], text[], text[]) "
+							  "RETURNS VOID "
+							  "AS '$libdir/pg_upgrade_support' "
+							  "LANGUAGE C;"));
 	PQfinish(conn);
 }
 
@@ -139,8 +145,8 @@ get_loadable_libraries(void)
 										"SELECT DISTINCT probin "
 										"FROM	pg_catalog.pg_proc "
 										"WHERE	prolang = 13 /* C */ AND "
-									 "		probin IS NOT NULL AND "
-										"		oid >= %u;",
+										"probin IS NOT NULL AND "
+										"oid >= %u;",
 										FirstNormalObjectId);
 		totaltups += PQntuples(ress[dbnum]);
 
diff --git a/contrib/pg_upgrade_support/pg_upgrade_support.c b/contrib/pg_upgrade_support/pg_upgrade_support.c
index b499ff80e605d03e5646e3d23bdb634e858b9d64..8b0e474dce51a5d51e89e3b15e3fb36ab41504d3 100644
--- a/contrib/pg_upgrade_support/pg_upgrade_support.c
+++ b/contrib/pg_upgrade_support/pg_upgrade_support.c
@@ -1,8 +1,9 @@
 /*
- *	pg_upgrade_sysoids.c
+ *	pg_upgrade_support.c
  *
  *	server-side functions to set backend global variables
- *	to control oid and relfilenode assignment
+ *	to control oid and relfilenode assignment, and do other special
+ *	hacks needed for pg_upgrade.
  *
  *	Copyright (c) 2010-2011, PostgreSQL Global Development Group
  *	contrib/pg_upgrade_support/pg_upgrade_support.c
@@ -12,7 +13,13 @@
 
 #include "fmgr.h"
 #include "catalog/dependency.h"
+#include "catalog/namespace.h"
 #include "catalog/pg_class.h"
+#include "catalog/pg_type.h"
+#include "commands/extension.h"
+#include "miscadmin.h"
+#include "utils/array.h"
+#include "utils/builtins.h"
 
 /* THIS IS USED ONLY FOR PG >= 9.0 */
 
@@ -42,6 +49,8 @@ Datum		set_next_toast_pg_class_oid(PG_FUNCTION_ARGS);
 Datum		set_next_pg_enum_oid(PG_FUNCTION_ARGS);
 Datum		set_next_pg_authid_oid(PG_FUNCTION_ARGS);
 
+Datum		create_empty_extension(PG_FUNCTION_ARGS);
+
 PG_FUNCTION_INFO_V1(set_next_pg_type_oid);
 PG_FUNCTION_INFO_V1(set_next_array_pg_type_oid);
 PG_FUNCTION_INFO_V1(set_next_toast_pg_type_oid);
@@ -53,6 +62,8 @@ PG_FUNCTION_INFO_V1(set_next_toast_pg_class_oid);
 PG_FUNCTION_INFO_V1(set_next_pg_enum_oid);
 PG_FUNCTION_INFO_V1(set_next_pg_authid_oid);
 
+PG_FUNCTION_INFO_V1(create_empty_extension);
+
 
 Datum
 set_next_pg_type_oid(PG_FUNCTION_ARGS)
@@ -133,3 +144,61 @@ set_next_pg_authid_oid(PG_FUNCTION_ARGS)
 	PG_RETURN_VOID();
 }
 
+Datum
+create_empty_extension(PG_FUNCTION_ARGS)
+{
+	text	   *extName = PG_GETARG_TEXT_PP(0);
+	text	   *schemaName = PG_GETARG_TEXT_PP(1);
+	bool		relocatable = PG_GETARG_BOOL(2);
+	char	   *extVersion;
+	Datum		extConfig;
+	Datum		extCondition;
+	List	   *requiredExtensions;
+
+	if (PG_ARGISNULL(3))
+		extVersion = NULL;
+	else
+		extVersion = text_to_cstring(PG_GETARG_TEXT_PP(3));
+
+	if (PG_ARGISNULL(4))
+		extConfig = PointerGetDatum(NULL);
+	else
+		extConfig = PG_GETARG_DATUM(4);
+
+	if (PG_ARGISNULL(5))
+		extCondition = PointerGetDatum(NULL);
+	else
+		extCondition = PG_GETARG_DATUM(5);
+
+	requiredExtensions = NIL;
+	if (!PG_ARGISNULL(6))
+	{
+		ArrayType  *textArray = PG_GETARG_ARRAYTYPE_P(6);
+		Datum	   *textDatums;
+		int			ndatums;
+		int			i;
+
+		deconstruct_array(textArray,
+						  TEXTOID, -1, false, 'i',
+						  &textDatums, NULL, &ndatums);
+		for (i = 0; i < ndatums; i++)
+		{
+			text   *txtname = DatumGetTextPP(textDatums[i]);
+			char   *extName = text_to_cstring(txtname);
+			Oid		extOid = get_extension_oid(extName, false);
+
+			requiredExtensions = lappend_oid(requiredExtensions, extOid);
+		}
+	}
+
+	InsertExtensionTuple(text_to_cstring(extName),
+						 GetUserId(),
+						 get_namespace_oid(text_to_cstring(schemaName), false),
+						 relocatable,
+						 extVersion,
+						 extConfig,
+						 extCondition,
+						 requiredExtensions);
+
+	PG_RETURN_VOID();
+}
diff --git a/src/backend/catalog/objectaddress.c b/src/backend/catalog/objectaddress.c
index 82989acc08839aff0f21cc50f77d43d17c67aff1..505bc35f6d3d75e24839812161c92b0dc2eb9d41 100644
--- a/src/backend/catalog/objectaddress.c
+++ b/src/backend/catalog/objectaddress.c
@@ -139,6 +139,7 @@ get_object_address(ObjectType objtype, List *objname, List *objargs,
 			address = get_object_address_unqualified(objtype, objname);
 			break;
 		case OBJECT_TYPE:
+		case OBJECT_DOMAIN:
 			address.classId = TypeRelationId;
 			address.objectId =
 				typenameTypeId(NULL, makeTypeNameFromNameList(objname));
diff --git a/src/backend/commands/comment.c b/src/backend/commands/comment.c
index bbb3f344093b678d305cbd0194afa62b98b6ef0c..faef256b1d8f38c4116e8dcf0b2764e9fe37d0e9 100644
--- a/src/backend/commands/comment.c
+++ b/src/backend/commands/comment.c
@@ -105,6 +105,7 @@ CommentObject(CommentStmt *stmt)
 							   strVal(linitial(stmt->objname)));
 			break;
 		case OBJECT_TYPE:
+		case OBJECT_DOMAIN:
 			if (!pg_type_ownercheck(address.objectId, GetUserId()))
 				aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_TYPE,
 							   format_type_be(address.objectId));
diff --git a/src/backend/commands/extension.c b/src/backend/commands/extension.c
index 41667fb3afcc78d89864173b62d4588a59984fb0..1da76aca10fac6c47571ee5287d43bd29f4d4892 100644
--- a/src/backend/commands/extension.c
+++ b/src/backend/commands/extension.c
@@ -648,13 +648,7 @@ CreateExtension(CreateExtensionStmt *stmt)
 	ExtensionControlFile *control;
 	List	   *requiredExtensions;
 	List	   *requiredSchemas;
-	Relation	rel;
-	Datum		values[Natts_pg_extension];
-	bool		nulls[Natts_pg_extension];
-	HeapTuple	tuple;
 	Oid			extensionOid;
-	ObjectAddress myself;
-	ObjectAddress nsp;
 	ListCell   *lc;
 
 	/* Must be super user */
@@ -801,7 +795,58 @@ CreateExtension(CreateExtensionStmt *stmt)
 	}
 
 	/*
-	 * Insert new tuple into pg_extension.
+	 * Insert new tuple into pg_extension, and create dependency entries.
+	 */
+	extensionOid = InsertExtensionTuple(control->name, extowner,
+										schemaOid, control->relocatable,
+										control->version,
+										PointerGetDatum(NULL),
+										PointerGetDatum(NULL),
+										requiredExtensions);
+
+	/*
+	 * Apply any comment on extension
+	 */
+	if (control->comment != NULL)
+		CreateComments(extensionOid, ExtensionRelationId, 0, control->comment);
+
+	/*
+	 * Finally, execute the extension script to create the member objects
+	 */
+	execute_extension_script(extensionOid, control, requiredSchemas,
+							 schemaName, schemaOid);
+}
+
+/*
+ * InsertExtensionTuple
+ *
+ * Insert the new pg_extension row, and create extension's dependency entries.
+ * Return the OID assigned to the new row.
+ *
+ * This is exported for the benefit of pg_upgrade, which has to create a
+ * pg_extension entry (and the extension-level dependencies) without
+ * actually running the extension's script.
+ *
+ * extConfig and extCondition should be arrays or PointerGetDatum(NULL).
+ * We declare them as plain Datum to avoid needing array.h in extension.h.
+ */
+Oid
+InsertExtensionTuple(const char *extName, Oid extOwner,
+					 Oid schemaOid, bool relocatable, const char *extVersion,
+					 Datum extConfig, Datum extCondition,
+					 List *requiredExtensions)
+{
+	Oid			extensionOid;
+	Relation	rel;
+	Datum		values[Natts_pg_extension];
+	bool		nulls[Natts_pg_extension];
+	HeapTuple	tuple;
+	ObjectAddress myself;
+	ObjectAddress nsp;
+	ListCell   *lc;
+
+	/*
+	 * Build and insert the pg_extension tuple
 	 */
 	rel = heap_open(ExtensionRelationId, RowExclusiveLock);
 
@@ -809,19 +854,26 @@ CreateExtension(CreateExtensionStmt *stmt)
 	memset(nulls, 0, sizeof(nulls));
 
 	values[Anum_pg_extension_extname - 1] =
-		DirectFunctionCall1(namein, CStringGetDatum(control->name));
-	values[Anum_pg_extension_extowner - 1] = ObjectIdGetDatum(extowner);
+		DirectFunctionCall1(namein, CStringGetDatum(extName));
+	values[Anum_pg_extension_extowner - 1] = ObjectIdGetDatum(extOwner);
 	values[Anum_pg_extension_extnamespace - 1] = ObjectIdGetDatum(schemaOid);
-	values[Anum_pg_extension_extrelocatable - 1] = BoolGetDatum(control->relocatable);
+	values[Anum_pg_extension_extrelocatable - 1] = BoolGetDatum(relocatable);
 
-	if (control->version == NULL)
+	if (extVersion == NULL)
 		nulls[Anum_pg_extension_extversion - 1] = true;
 	else
 		values[Anum_pg_extension_extversion - 1] =
-			CStringGetTextDatum(control->version);
+			CStringGetTextDatum(extVersion);
+
+	if (extConfig == PointerGetDatum(NULL))
+		nulls[Anum_pg_extension_extconfig - 1] = true;
+	else
+		values[Anum_pg_extension_extconfig - 1] = extConfig;
 
-	nulls[Anum_pg_extension_extconfig - 1] = true;
-	nulls[Anum_pg_extension_extcondition - 1] = true;
+	if (extCondition == PointerGetDatum(NULL))
+		nulls[Anum_pg_extension_extcondition - 1] = true;
+	else
+		values[Anum_pg_extension_extcondition - 1] = extCondition;
 
 	tuple = heap_form_tuple(rel->rd_att, values, nulls);
 
@@ -831,16 +883,10 @@ CreateExtension(CreateExtensionStmt *stmt)
 	heap_freetuple(tuple);
 	heap_close(rel, RowExclusiveLock);
 
-	/*
-	 * Apply any comment on extension
-	 */
-	if (control->comment != NULL)
-		CreateComments(extensionOid, ExtensionRelationId, 0, control->comment);
-
 	/*
 	 * Record dependencies on owner, schema, and prerequisite extensions
 	 */
-	recordDependencyOnOwner(ExtensionRelationId, extensionOid, extowner);
+	recordDependencyOnOwner(ExtensionRelationId, extensionOid, extOwner);
 
 	myself.classId = ExtensionRelationId;
 	myself.objectId = extensionOid;
@@ -864,11 +910,7 @@ CreateExtension(CreateExtensionStmt *stmt)
 		recordDependencyOn(&myself, &otherext, DEPENDENCY_NORMAL);
 	}
 
-	/*
-	 * Finally, execute the extension script to create the member objects
-	 */
-	execute_extension_script(extensionOid, control, requiredSchemas,
-							 schemaName, schemaOid);
+	return extensionOid;
 }
 
 
diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y
index a61f3dc7ba4ed5aeb7cb94ce8850f411cbd36385..8c630272fd0847a48d6c3c06452e0a6f18080cbb 100644
--- a/src/backend/parser/gram.y
+++ b/src/backend/parser/gram.y
@@ -4790,7 +4790,7 @@ comment_type:
 			| INDEX								{ $$ = OBJECT_INDEX; }
 			| SEQUENCE							{ $$ = OBJECT_SEQUENCE; }
 			| TABLE								{ $$ = OBJECT_TABLE; }
-			| DOMAIN_P							{ $$ = OBJECT_TYPE; }
+			| DOMAIN_P							{ $$ = OBJECT_DOMAIN; }
 			| TYPE_P							{ $$ = OBJECT_TYPE; }
 			| VIEW								{ $$ = OBJECT_VIEW; }
 			| CONVERSION_P						{ $$ = OBJECT_CONVERSION; }
diff --git a/src/bin/pg_dump/common.c b/src/bin/pg_dump/common.c
index 8c4270ca1d776aeacc15382545ba933577c2e991..9c6508e456c9e8f01f582303ad933f10cb3a5f0f 100644
--- a/src/bin/pg_dump/common.c
+++ b/src/bin/pg_dump/common.c
@@ -463,6 +463,7 @@ AssignDumpId(DumpableObject *dobj)
 	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;
diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c
index 83850a8849b48569fde4ef9937dd8496a79775f8..5561c7a6876baa5ff110a6b9bc9429e11679d4db 100644
--- a/src/bin/pg_dump/pg_dump.c
+++ b/src/bin/pg_dump/pg_dump.c
@@ -234,6 +234,9 @@ static bool binary_upgrade_set_type_oids_by_rel_oid(
 								 PQExpBuffer upgrade_buffer, Oid pg_rel_oid);
 static void binary_upgrade_set_pg_class_oids(PQExpBuffer upgrade_buffer,
 								Oid pg_class_oid, bool is_index);
+static void binary_upgrade_extension_member(PQExpBuffer upgrade_buffer,
+											DumpableObject *dobj,
+											const char *objlabel);
 static const char *getAttrName(int attrnum, TableInfo *tblInfo);
 static const char *fmtCopyColumnList(const TableInfo *ti);
 static void do_sql_command(PGconn *conn, const char *query);
@@ -1586,7 +1589,6 @@ makeTableDataInfo(TableInfo *tbinfo, bool oids)
 	AssignDumpId(&tdinfo->dobj);
 	tdinfo->dobj.name = tbinfo->dobj.name;
 	tdinfo->dobj.namespace = tbinfo->dobj.namespace;
-	tdinfo->dobj.dump = true;
 	tdinfo->tdtable = tbinfo;
 	tdinfo->oids = oids;
 	tdinfo->filtercond = NULL;				/* might get set later */
@@ -2467,6 +2469,47 @@ binary_upgrade_set_pg_class_oids(PQExpBuffer upgrade_buffer, Oid pg_class_oid,
 	destroyPQExpBuffer(upgrade_query);
 }
 
+/*
+ * If the DumpableObject is a member of an extension, add a suitable
+ * ALTER EXTENSION ADD command to the creation commands in upgrade_buffer.
+ */
+static void
+binary_upgrade_extension_member(PQExpBuffer upgrade_buffer,
+								DumpableObject *dobj,
+								const char *objlabel)
+{
+	DumpableObject *extobj = NULL;
+	int			i;
+
+	if (!dobj->ext_member)
+		return;
+
+	/*
+	 * Find the parent extension.  We could avoid this search if we wanted
+	 * to add a link field to DumpableObject, but the space costs of that
+	 * would be considerable.  We assume that member objects could only have
+	 * a direct dependency on their own extension, not any others.
+	 */
+	for (i = 0; i < dobj->nDeps; i++)
+	{
+		extobj = findObjectByDumpId(dobj->dependencies[i]);
+		if (extobj && extobj->objType == DO_EXTENSION)
+			break;
+		extobj = NULL;
+	}
+	if (extobj == NULL)
+	{
+		write_msg(NULL, "failed to find parent extension for %s", objlabel);
+		exit_nicely();
+	}
+
+	appendPQExpBuffer(upgrade_buffer,
+					  "\n-- For binary upgrade, handle extension membership the hard way\n");
+	appendPQExpBuffer(upgrade_buffer, "ALTER EXTENSION %s ADD %s;\n",
+					  fmtId(extobj->name),
+					  objlabel);
+}
+
 /*
  * getNamespaces:
  *	  read all namespaces in the system catalogs and return them in the
@@ -2633,6 +2676,8 @@ getExtensions(int *numExtensions)
 	int			i_oid;
 	int			i_extname;
 	int			i_nspname;
+	int			i_extrelocatable;
+	int			i_extversion;
 	int			i_extconfig;
 	int			i_extcondition;
 
@@ -2651,7 +2696,7 @@ getExtensions(int *numExtensions)
 	selectSourceSchema("pg_catalog");
 
 	appendPQExpBuffer(query, "SELECT x.tableoid, x.oid, "
-					  "x.extname, n.nspname, x.extconfig, x.extcondition "
+					  "x.extname, n.nspname, x.extrelocatable, x.extversion, x.extconfig, x.extcondition "
 					  "FROM pg_extension x "
 					  "JOIN pg_namespace n ON n.oid = x.extnamespace");
 
@@ -2666,6 +2711,8 @@ getExtensions(int *numExtensions)
 	i_oid = PQfnumber(res, "oid");
 	i_extname = PQfnumber(res, "extname");
 	i_nspname = PQfnumber(res, "nspname");
+	i_extrelocatable = PQfnumber(res, "extrelocatable");
+	i_extversion = PQfnumber(res, "extversion");
 	i_extconfig = PQfnumber(res, "extconfig");
 	i_extcondition = PQfnumber(res, "extcondition");
 
@@ -2677,11 +2724,13 @@ getExtensions(int *numExtensions)
 		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].relocatable = *(PQgetvalue(res, i, i_extrelocatable)) == 't';
+		if (PQgetisnull(res, i, i_extversion))
+			extinfo[i].extversion = NULL;
+		else
+			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));
-
-		/* For the moment, all extensions are considered dumpable */
-		extinfo->dobj.dump = true;
 	}
 
 	PQclear(res);
@@ -5152,9 +5201,6 @@ getProcLangs(int *numProcLangs)
 		else
 			planginfo[i].lanowner = strdup("");
 
-		/* Assume it should be dumped (getExtensionMembership may override) */
-		planginfo[i].dobj.dump = true;
-
 		if (g_fout->remoteVersion < 70300)
 		{
 			/*
@@ -5262,9 +5308,6 @@ getCasts(int *numCasts)
 		castinfo[i].castcontext = *(PQgetvalue(res, i, i_castcontext));
 		castinfo[i].castmethod = *(PQgetvalue(res, i, i_castmethod));
 
-		/* Assume it should be dumped (getExtensionMembership may override) */
-		castinfo[i].dobj.dump = true;
-
 		/*
 		 * Try to name cast as concatenation of typnames.  This is only used
 		 * for purposes of sorting.  If we fail to find either type, the name
@@ -6803,6 +6846,7 @@ dumpNamespace(Archive *fout, NamespaceInfo *nspinfo)
 {
 	PQExpBuffer q;
 	PQExpBuffer delq;
+	PQExpBuffer labelq;
 	char	   *qnspname;
 
 	/* Skip if not to be dumped */
@@ -6815,6 +6859,7 @@ dumpNamespace(Archive *fout, NamespaceInfo *nspinfo)
 
 	q = createPQExpBuffer();
 	delq = createPQExpBuffer();
+	labelq = createPQExpBuffer();
 
 	qnspname = strdup(fmtId(nspinfo->dobj.name));
 
@@ -6822,6 +6867,11 @@ dumpNamespace(Archive *fout, NamespaceInfo *nspinfo)
 
 	appendPQExpBuffer(q, "CREATE SCHEMA %s;\n", qnspname);
 
+	appendPQExpBuffer(labelq, "SCHEMA %s", qnspname);
+
+	if (binary_upgrade)
+		binary_upgrade_extension_member(q, &nspinfo->dobj, labelq->data);
+
 	ArchiveEntry(fout, nspinfo->dobj.catId, nspinfo->dobj.dumpId,
 				 nspinfo->dobj.name,
 				 NULL, NULL,
@@ -6832,12 +6882,10 @@ dumpNamespace(Archive *fout, NamespaceInfo *nspinfo)
 				 NULL, NULL);
 
 	/* Dump Schema Comments and Security Labels */
-	resetPQExpBuffer(q);
-	appendPQExpBuffer(q, "SCHEMA %s", qnspname);
-	dumpComment(fout, q->data,
+	dumpComment(fout, labelq->data,
 				NULL, nspinfo->rolname,
 				nspinfo->dobj.catId, 0, nspinfo->dobj.dumpId);
-	dumpSecLabel(fout, q->data,
+	dumpSecLabel(fout, labelq->data,
 				 NULL, nspinfo->rolname,
 				 nspinfo->dobj.catId, 0, nspinfo->dobj.dumpId);
 
@@ -6849,6 +6897,7 @@ dumpNamespace(Archive *fout, NamespaceInfo *nspinfo)
 
 	destroyPQExpBuffer(q);
 	destroyPQExpBuffer(delq);
+	destroyPQExpBuffer(labelq);
 }
 
 /*
@@ -6860,6 +6909,7 @@ dumpExtension(Archive *fout, ExtensionInfo *extinfo)
 {
 	PQExpBuffer q;
 	PQExpBuffer delq;
+	PQExpBuffer labelq;
 	char	   *qextname;
 
 	/* Skip if not to be dumped */
@@ -6868,13 +6918,69 @@ dumpExtension(Archive *fout, ExtensionInfo *extinfo)
 
 	q = createPQExpBuffer();
 	delq = createPQExpBuffer();
+	labelq = createPQExpBuffer();
 
 	qextname = strdup(fmtId(extinfo->dobj.name));
 
 	appendPQExpBuffer(delq, "DROP EXTENSION %s;\n", qextname);
 
-	appendPQExpBuffer(q, "CREATE EXTENSION %s WITH SCHEMA %s;\n",
-					  qextname, fmtId(extinfo->namespace));
+	if (!binary_upgrade)
+	{
+		appendPQExpBuffer(q, "CREATE EXTENSION %s WITH SCHEMA %s;\n",
+						  qextname, fmtId(extinfo->namespace));
+	}
+	else
+	{
+		int		i;
+		int		n;
+
+		appendPQExpBuffer(q, "-- For binary upgrade, create an empty extension and insert objects into it\n");
+		appendPQExpBuffer(q,
+						  "SELECT binary_upgrade.create_empty_extension(");
+		appendStringLiteralAH(q, extinfo->dobj.name, fout);
+		appendPQExpBuffer(q, ", ");
+		appendStringLiteralAH(q, extinfo->namespace, fout);
+		appendPQExpBuffer(q, ", ");
+		appendPQExpBuffer(q, "%s, ", extinfo->relocatable ? "true" : "false");
+		if (extinfo->extversion)
+			appendStringLiteralAH(q, extinfo->extversion, fout);
+		else
+			appendPQExpBuffer(q, "NULL");
+		appendPQExpBuffer(q, ", ");
+		/*
+		 * Note that we're pushing extconfig (an OID array) back into
+		 * pg_extension exactly as-is.  This is OK because pg_class OIDs
+		 * are preserved in binary upgrade.
+		 */
+		if (strlen(extinfo->extconfig) > 2)
+			appendStringLiteralAH(q, extinfo->extconfig, fout);
+		else
+			appendPQExpBuffer(q, "NULL");
+		appendPQExpBuffer(q, ", ");
+		if (strlen(extinfo->extcondition) > 2)
+			appendStringLiteralAH(q, extinfo->extcondition, fout);
+		else
+			appendPQExpBuffer(q, "NULL");
+		appendPQExpBuffer(q, ", ");
+		appendPQExpBuffer(q, "ARRAY[");
+		n = 0;
+		for (i = 0; i < extinfo->dobj.nDeps; i++)
+		{
+			DumpableObject *extobj;
+
+			extobj = findObjectByDumpId(extinfo->dobj.dependencies[i]);
+			if (extobj && extobj->objType == DO_EXTENSION)
+			{
+				if (n++ > 0)
+					appendPQExpBuffer(q, ",");
+				appendStringLiteralAH(q, extobj->name, fout);
+			}
+		}
+		appendPQExpBuffer(q, "]::pg_catalog.text[]");
+		appendPQExpBuffer(q, ");\n");
+	}
+
+	appendPQExpBuffer(labelq, "EXTENSION %s", qextname);
 
 	ArchiveEntry(fout, extinfo->dobj.catId, extinfo->dobj.dumpId,
 				 extinfo->dobj.name,
@@ -6886,12 +6992,10 @@ dumpExtension(Archive *fout, ExtensionInfo *extinfo)
 				 NULL, NULL);
 
 	/* Dump Extension Comments and Security Labels */
-	resetPQExpBuffer(q);
-	appendPQExpBuffer(q, "EXTENSION %s", qextname);
-	dumpComment(fout, q->data,
+	dumpComment(fout, labelq->data,
 				NULL, "",
 				extinfo->dobj.catId, 0, extinfo->dobj.dumpId);
-	dumpSecLabel(fout, q->data,
+	dumpSecLabel(fout, labelq->data,
 				 NULL, "",
 				 extinfo->dobj.catId, 0, extinfo->dobj.dumpId);
 
@@ -6899,6 +7003,7 @@ dumpExtension(Archive *fout, ExtensionInfo *extinfo)
 
 	destroyPQExpBuffer(q);
 	destroyPQExpBuffer(delq);
+	destroyPQExpBuffer(labelq);
 }
 
 /*
@@ -6932,6 +7037,7 @@ dumpEnumType(Archive *fout, TypeInfo *tyinfo)
 {
 	PQExpBuffer q = createPQExpBuffer();
 	PQExpBuffer delq = createPQExpBuffer();
+	PQExpBuffer labelq = createPQExpBuffer();
 	PQExpBuffer query = createPQExpBuffer();
 	PGresult   *res;
 	int			num,
@@ -7006,13 +7112,18 @@ dumpEnumType(Archive *fout, TypeInfo *tyinfo)
 							  enum_oid);
 			appendPQExpBuffer(q, "ALTER TYPE %s.",
 							  fmtId(tyinfo->dobj.namespace->dobj.name));
-			appendPQExpBuffer(q, "%s ADD ",
+			appendPQExpBuffer(q, "%s ADD VALUE ",
 							  fmtId(tyinfo->dobj.name));
 			appendStringLiteralAH(q, label, fout);
 			appendPQExpBuffer(q, ";\n\n");
 		}
 	}
 
+	appendPQExpBuffer(labelq, "TYPE %s", fmtId(tyinfo->dobj.name));
+
+	if (binary_upgrade)
+		binary_upgrade_extension_member(q, &tyinfo->dobj, labelq->data);
+
 	ArchiveEntry(fout, tyinfo->dobj.catId, tyinfo->dobj.dumpId,
 				 tyinfo->dobj.name,
 				 tyinfo->dobj.namespace->dobj.name,
@@ -7024,19 +7135,17 @@ dumpEnumType(Archive *fout, TypeInfo *tyinfo)
 				 NULL, NULL);
 
 	/* Dump Type Comments and Security Labels */
-	resetPQExpBuffer(q);
-
-	appendPQExpBuffer(q, "TYPE %s", fmtId(tyinfo->dobj.name));
-	dumpComment(fout, q->data,
+	dumpComment(fout, labelq->data,
 				tyinfo->dobj.namespace->dobj.name, tyinfo->rolname,
 				tyinfo->dobj.catId, 0, tyinfo->dobj.dumpId);
-	dumpSecLabel(fout, q->data,
+	dumpSecLabel(fout, labelq->data,
 				 tyinfo->dobj.namespace->dobj.name, tyinfo->rolname,
 				 tyinfo->dobj.catId, 0, tyinfo->dobj.dumpId);
 
 	PQclear(res);
 	destroyPQExpBuffer(q);
 	destroyPQExpBuffer(delq);
+	destroyPQExpBuffer(labelq);
 	destroyPQExpBuffer(query);
 }
 
@@ -7049,6 +7158,7 @@ dumpBaseType(Archive *fout, TypeInfo *tyinfo)
 {
 	PQExpBuffer q = createPQExpBuffer();
 	PQExpBuffer delq = createPQExpBuffer();
+	PQExpBuffer labelq = createPQExpBuffer();
 	PQExpBuffer query = createPQExpBuffer();
 	PGresult   *res;
 	int			ntups;
@@ -7392,6 +7502,11 @@ dumpBaseType(Archive *fout, TypeInfo *tyinfo)
 
 	appendPQExpBuffer(q, "\n);\n");
 
+	appendPQExpBuffer(labelq, "TYPE %s", fmtId(tyinfo->dobj.name));
+
+	if (binary_upgrade)
+		binary_upgrade_extension_member(q, &tyinfo->dobj, labelq->data);
+
 	ArchiveEntry(fout, tyinfo->dobj.catId, tyinfo->dobj.dumpId,
 				 tyinfo->dobj.name,
 				 tyinfo->dobj.namespace->dobj.name,
@@ -7403,19 +7518,17 @@ dumpBaseType(Archive *fout, TypeInfo *tyinfo)
 				 NULL, NULL);
 
 	/* Dump Type Comments and Security Labels */
-	resetPQExpBuffer(q);
-
-	appendPQExpBuffer(q, "TYPE %s", fmtId(tyinfo->dobj.name));
-	dumpComment(fout, q->data,
+	dumpComment(fout, labelq->data,
 				tyinfo->dobj.namespace->dobj.name, tyinfo->rolname,
 				tyinfo->dobj.catId, 0, tyinfo->dobj.dumpId);
-	dumpSecLabel(fout, q->data,
+	dumpSecLabel(fout, labelq->data,
 				 tyinfo->dobj.namespace->dobj.name, tyinfo->rolname,
 				 tyinfo->dobj.catId, 0, tyinfo->dobj.dumpId);
 
 	PQclear(res);
 	destroyPQExpBuffer(q);
 	destroyPQExpBuffer(delq);
+	destroyPQExpBuffer(labelq);
 	destroyPQExpBuffer(query);
 }
 
@@ -7428,6 +7541,7 @@ dumpDomain(Archive *fout, TypeInfo *tyinfo)
 {
 	PQExpBuffer q = createPQExpBuffer();
 	PQExpBuffer delq = createPQExpBuffer();
+	PQExpBuffer labelq = createPQExpBuffer();
 	PQExpBuffer query = createPQExpBuffer();
 	PGresult   *res;
 	int			ntups;
@@ -7534,6 +7648,11 @@ dumpDomain(Archive *fout, TypeInfo *tyinfo)
 	appendPQExpBuffer(delq, "%s;\n",
 					  fmtId(tyinfo->dobj.name));
 
+	appendPQExpBuffer(labelq, "DOMAIN %s", fmtId(tyinfo->dobj.name));
+
+	if (binary_upgrade)
+		binary_upgrade_extension_member(q, &tyinfo->dobj, labelq->data);
+
 	ArchiveEntry(fout, tyinfo->dobj.catId, tyinfo->dobj.dumpId,
 				 tyinfo->dobj.name,
 				 tyinfo->dobj.namespace->dobj.name,
@@ -7545,18 +7664,16 @@ dumpDomain(Archive *fout, TypeInfo *tyinfo)
 				 NULL, NULL);
 
 	/* Dump Domain Comments and Security Labels */
-	resetPQExpBuffer(q);
-
-	appendPQExpBuffer(q, "DOMAIN %s", fmtId(tyinfo->dobj.name));
-	dumpComment(fout, q->data,
+	dumpComment(fout, labelq->data,
 				tyinfo->dobj.namespace->dobj.name, tyinfo->rolname,
 				tyinfo->dobj.catId, 0, tyinfo->dobj.dumpId);
-	dumpSecLabel(fout, q->data,
+	dumpSecLabel(fout, labelq->data,
 				 tyinfo->dobj.namespace->dobj.name, tyinfo->rolname,
 				 tyinfo->dobj.catId, 0, tyinfo->dobj.dumpId);
 
 	destroyPQExpBuffer(q);
 	destroyPQExpBuffer(delq);
+	destroyPQExpBuffer(labelq);
 	destroyPQExpBuffer(query);
 }
 
@@ -7570,6 +7687,7 @@ dumpCompositeType(Archive *fout, TypeInfo *tyinfo)
 {
 	PQExpBuffer q = createPQExpBuffer();
 	PQExpBuffer delq = createPQExpBuffer();
+	PQExpBuffer labelq = createPQExpBuffer();
 	PQExpBuffer query = createPQExpBuffer();
 	PGresult   *res;
 	int			ntups;
@@ -7636,6 +7754,11 @@ dumpCompositeType(Archive *fout, TypeInfo *tyinfo)
 	appendPQExpBuffer(delq, "%s;\n",
 					  fmtId(tyinfo->dobj.name));
 
+	appendPQExpBuffer(labelq, "TYPE %s", fmtId(tyinfo->dobj.name));
+
+	if (binary_upgrade)
+		binary_upgrade_extension_member(q, &tyinfo->dobj, labelq->data);
+
 	ArchiveEntry(fout, tyinfo->dobj.catId, tyinfo->dobj.dumpId,
 				 tyinfo->dobj.name,
 				 tyinfo->dobj.namespace->dobj.name,
@@ -7648,19 +7771,17 @@ dumpCompositeType(Archive *fout, TypeInfo *tyinfo)
 
 
 	/* Dump Type Comments and Security Labels */
-	resetPQExpBuffer(q);
-
-	appendPQExpBuffer(q, "TYPE %s", fmtId(tyinfo->dobj.name));
-	dumpComment(fout, q->data,
+	dumpComment(fout, labelq->data,
 				tyinfo->dobj.namespace->dobj.name, tyinfo->rolname,
 				tyinfo->dobj.catId, 0, tyinfo->dobj.dumpId);
-	dumpSecLabel(fout, q->data,
+	dumpSecLabel(fout, labelq->data,
 				 tyinfo->dobj.namespace->dobj.name, tyinfo->rolname,
 				 tyinfo->dobj.catId, 0, tyinfo->dobj.dumpId);
 
 	PQclear(res);
 	destroyPQExpBuffer(q);
 	destroyPQExpBuffer(delq);
+	destroyPQExpBuffer(labelq);
 	destroyPQExpBuffer(query);
 
 	/* Dump any per-column comments */
@@ -7856,6 +7977,7 @@ dumpProcLang(Archive *fout, ProcLangInfo *plang)
 {
 	PQExpBuffer defqry;
 	PQExpBuffer delqry;
+	PQExpBuffer labelq;
 	bool		useParams;
 	char	   *qlanname;
 	char	   *lanschema;
@@ -7907,6 +8029,7 @@ dumpProcLang(Archive *fout, ProcLangInfo *plang)
 
 	defqry = createPQExpBuffer();
 	delqry = createPQExpBuffer();
+	labelq = createPQExpBuffer();
 
 	qlanname = strdup(fmtId(plang->dobj.name));
 
@@ -7967,6 +8090,11 @@ dumpProcLang(Archive *fout, ProcLangInfo *plang)
 	}
 	appendPQExpBuffer(defqry, ";\n");
 
+	appendPQExpBuffer(labelq, "LANGUAGE %s", qlanname);
+
+	if (binary_upgrade)
+		binary_upgrade_extension_member(defqry, &plang->dobj, labelq->data);
+
 	ArchiveEntry(fout, plang->dobj.catId, plang->dobj.dumpId,
 				 plang->dobj.name,
 				 lanschema, NULL, plang->lanowner,
@@ -7976,12 +8104,10 @@ dumpProcLang(Archive *fout, ProcLangInfo *plang)
 				 NULL, NULL);
 
 	/* Dump Proc Lang Comments and Security Labels */
-	resetPQExpBuffer(defqry);
-	appendPQExpBuffer(defqry, "LANGUAGE %s", qlanname);
-	dumpComment(fout, defqry->data,
+	dumpComment(fout, labelq->data,
 				NULL, "",
 				plang->dobj.catId, 0, plang->dobj.dumpId);
-	dumpSecLabel(fout, defqry->data,
+	dumpSecLabel(fout, labelq->data,
 				 NULL, "",
 				 plang->dobj.catId, 0, plang->dobj.dumpId);
 
@@ -7995,6 +8121,7 @@ dumpProcLang(Archive *fout, ProcLangInfo *plang)
 
 	destroyPQExpBuffer(defqry);
 	destroyPQExpBuffer(delqry);
+	destroyPQExpBuffer(labelq);
 }
 
 /*
@@ -8130,6 +8257,7 @@ dumpFunc(Archive *fout, FuncInfo *finfo)
 	PQExpBuffer query;
 	PQExpBuffer q;
 	PQExpBuffer delqry;
+	PQExpBuffer labelq;
 	PQExpBuffer asPart;
 	PGresult   *res;
 	char	   *funcsig;		/* identity signature */
@@ -8169,6 +8297,7 @@ dumpFunc(Archive *fout, FuncInfo *finfo)
 	query = createPQExpBuffer();
 	q = createPQExpBuffer();
 	delqry = createPQExpBuffer();
+	labelq = createPQExpBuffer();
 	asPart = createPQExpBuffer();
 
 	/* Set proper schema search path so type references list correctly */
@@ -8529,6 +8658,11 @@ dumpFunc(Archive *fout, FuncInfo *finfo)
 
 	appendPQExpBuffer(q, "\n    %s;\n", asPart->data);
 
+	appendPQExpBuffer(labelq, "FUNCTION %s", funcsig);
+
+	if (binary_upgrade)
+		binary_upgrade_extension_member(q, &finfo->dobj, labelq->data);
+
 	ArchiveEntry(fout, finfo->dobj.catId, finfo->dobj.dumpId,
 				 funcsig_tag,
 				 finfo->dobj.namespace->dobj.name,
@@ -8540,12 +8674,10 @@ dumpFunc(Archive *fout, FuncInfo *finfo)
 				 NULL, NULL);
 
 	/* Dump Function Comments and Security Labels */
-	resetPQExpBuffer(q);
-	appendPQExpBuffer(q, "FUNCTION %s", funcsig);
-	dumpComment(fout, q->data,
+	dumpComment(fout, labelq->data,
 				finfo->dobj.namespace->dobj.name, finfo->rolname,
 				finfo->dobj.catId, 0, finfo->dobj.dumpId);
-	dumpSecLabel(fout, q->data,
+	dumpSecLabel(fout, labelq->data,
 				 finfo->dobj.namespace->dobj.name, finfo->rolname,
 				 finfo->dobj.catId, 0, finfo->dobj.dumpId);
 
@@ -8559,6 +8691,7 @@ dumpFunc(Archive *fout, FuncInfo *finfo)
 	destroyPQExpBuffer(query);
 	destroyPQExpBuffer(q);
 	destroyPQExpBuffer(delqry);
+	destroyPQExpBuffer(labelq);
 	destroyPQExpBuffer(asPart);
 	free(funcsig);
 	free(funcsig_tag);
@@ -8581,7 +8714,7 @@ dumpCast(Archive *fout, CastInfo *cast)
 {
 	PQExpBuffer defqry;
 	PQExpBuffer delqry;
-	PQExpBuffer castsig;
+	PQExpBuffer labelq;
 	FuncInfo   *funcInfo = NULL;
 	TypeInfo   *sourceInfo;
 	TypeInfo   *targetInfo;
@@ -8645,7 +8778,7 @@ dumpCast(Archive *fout, CastInfo *cast)
 
 	defqry = createPQExpBuffer();
 	delqry = createPQExpBuffer();
-	castsig = createPQExpBuffer();
+	labelq = createPQExpBuffer();
 
 	appendPQExpBuffer(delqry, "DROP CAST (%s AS %s);\n",
 					  getFormattedTypeName(cast->castsource, zeroAsNone),
@@ -8684,12 +8817,15 @@ dumpCast(Archive *fout, CastInfo *cast)
 		appendPQExpBuffer(defqry, " AS IMPLICIT");
 	appendPQExpBuffer(defqry, ";\n");
 
-	appendPQExpBuffer(castsig, "CAST (%s AS %s)",
+	appendPQExpBuffer(labelq, "CAST (%s AS %s)",
 					  getFormattedTypeName(cast->castsource, zeroAsNone),
 					  getFormattedTypeName(cast->casttarget, zeroAsNone));
 
+	if (binary_upgrade)
+		binary_upgrade_extension_member(defqry, &cast->dobj, labelq->data);
+
 	ArchiveEntry(fout, cast->dobj.catId, cast->dobj.dumpId,
-				 castsig->data,
+				 labelq->data,
 				 "pg_catalog", NULL, "",
 				 false, "CAST", SECTION_PRE_DATA,
 				 defqry->data, delqry->data, NULL,
@@ -8697,17 +8833,13 @@ dumpCast(Archive *fout, CastInfo *cast)
 				 NULL, NULL);
 
 	/* Dump Cast Comments */
-	resetPQExpBuffer(defqry);
-	appendPQExpBuffer(defqry, "CAST (%s AS %s)",
-					  getFormattedTypeName(cast->castsource, zeroAsNone),
-					  getFormattedTypeName(cast->casttarget, zeroAsNone));
-	dumpComment(fout, defqry->data,
+	dumpComment(fout, labelq->data,
 				NULL, "",
 				cast->dobj.catId, 0, cast->dobj.dumpId);
 
 	destroyPQExpBuffer(defqry);
 	destroyPQExpBuffer(delqry);
-	destroyPQExpBuffer(castsig);
+	destroyPQExpBuffer(labelq);
 }
 
 /*
@@ -8720,6 +8852,7 @@ dumpOpr(Archive *fout, OprInfo *oprinfo)
 	PQExpBuffer query;
 	PQExpBuffer q;
 	PQExpBuffer delq;
+	PQExpBuffer labelq;
 	PQExpBuffer oprid;
 	PQExpBuffer details;
 	const char *name;
@@ -8760,6 +8893,7 @@ dumpOpr(Archive *fout, OprInfo *oprinfo)
 	query = createPQExpBuffer();
 	q = createPQExpBuffer();
 	delq = createPQExpBuffer();
+	labelq = createPQExpBuffer();
 	oprid = createPQExpBuffer();
 	details = createPQExpBuffer();
 
@@ -8930,6 +9064,11 @@ dumpOpr(Archive *fout, OprInfo *oprinfo)
 	appendPQExpBuffer(q, "CREATE OPERATOR %s (\n%s\n);\n",
 					  oprinfo->dobj.name, details->data);
 
+	appendPQExpBuffer(labelq, "OPERATOR %s", oprid->data);
+
+	if (binary_upgrade)
+		binary_upgrade_extension_member(q, &oprinfo->dobj, labelq->data);
+
 	ArchiveEntry(fout, oprinfo->dobj.catId, oprinfo->dobj.dumpId,
 				 oprinfo->dobj.name,
 				 oprinfo->dobj.namespace->dobj.name,
@@ -8941,9 +9080,7 @@ dumpOpr(Archive *fout, OprInfo *oprinfo)
 				 NULL, NULL);
 
 	/* Dump Operator Comments */
-	resetPQExpBuffer(q);
-	appendPQExpBuffer(q, "OPERATOR %s", oprid->data);
-	dumpComment(fout, q->data,
+	dumpComment(fout, labelq->data,
 				oprinfo->dobj.namespace->dobj.name, oprinfo->rolname,
 				oprinfo->dobj.catId, 0, oprinfo->dobj.dumpId);
 
@@ -8952,6 +9089,7 @@ dumpOpr(Archive *fout, OprInfo *oprinfo)
 	destroyPQExpBuffer(query);
 	destroyPQExpBuffer(q);
 	destroyPQExpBuffer(delq);
+	destroyPQExpBuffer(labelq);
 	destroyPQExpBuffer(oprid);
 	destroyPQExpBuffer(details);
 }
@@ -9108,6 +9246,7 @@ dumpOpclass(Archive *fout, OpclassInfo *opcinfo)
 	PQExpBuffer query;
 	PQExpBuffer q;
 	PQExpBuffer delq;
+	PQExpBuffer labelq;
 	PGresult   *res;
 	int			ntups;
 	int			i_opcintype;
@@ -9156,6 +9295,7 @@ dumpOpclass(Archive *fout, OpclassInfo *opcinfo)
 	query = createPQExpBuffer();
 	q = createPQExpBuffer();
 	delq = createPQExpBuffer();
+	labelq = createPQExpBuffer();
 
 	/* Make sure we are in proper schema so regoperator works correctly */
 	selectSourceSchema(opcinfo->dobj.namespace->dobj.name);
@@ -9432,6 +9572,14 @@ dumpOpclass(Archive *fout, OpclassInfo *opcinfo)
 
 	appendPQExpBuffer(q, ";\n");
 
+	appendPQExpBuffer(labelq, "OPERATOR CLASS %s",
+					  fmtId(opcinfo->dobj.name));
+	appendPQExpBuffer(labelq, " USING %s",
+					  fmtId(amname));
+
+	if (binary_upgrade)
+		binary_upgrade_extension_member(q, &opcinfo->dobj, labelq->data);
+
 	ArchiveEntry(fout, opcinfo->dobj.catId, opcinfo->dobj.dumpId,
 				 opcinfo->dobj.name,
 				 opcinfo->dobj.namespace->dobj.name,
@@ -9443,12 +9591,7 @@ dumpOpclass(Archive *fout, OpclassInfo *opcinfo)
 				 NULL, NULL);
 
 	/* Dump Operator Class Comments */
-	resetPQExpBuffer(q);
-	appendPQExpBuffer(q, "OPERATOR CLASS %s",
-					  fmtId(opcinfo->dobj.name));
-	appendPQExpBuffer(q, " USING %s",
-					  fmtId(amname));
-	dumpComment(fout, q->data,
+	dumpComment(fout, labelq->data,
 				NULL, opcinfo->rolname,
 				opcinfo->dobj.catId, 0, opcinfo->dobj.dumpId);
 
@@ -9456,6 +9599,7 @@ dumpOpclass(Archive *fout, OpclassInfo *opcinfo)
 	destroyPQExpBuffer(query);
 	destroyPQExpBuffer(q);
 	destroyPQExpBuffer(delq);
+	destroyPQExpBuffer(labelq);
 }
 
 /*
@@ -9471,6 +9615,7 @@ dumpOpfamily(Archive *fout, OpfamilyInfo *opfinfo)
 	PQExpBuffer query;
 	PQExpBuffer q;
 	PQExpBuffer delq;
+	PQExpBuffer labelq;
 	PGresult   *res;
 	PGresult   *res_ops;
 	PGresult   *res_procs;
@@ -9514,6 +9659,7 @@ dumpOpfamily(Archive *fout, OpfamilyInfo *opfinfo)
 	query = createPQExpBuffer();
 	q = createPQExpBuffer();
 	delq = createPQExpBuffer();
+	labelq = createPQExpBuffer();
 
 	/* Make sure we are in proper schema so regoperator works correctly */
 	selectSourceSchema(opfinfo->dobj.namespace->dobj.name);
@@ -9622,6 +9768,7 @@ dumpOpfamily(Archive *fout, OpfamilyInfo *opfinfo)
 			destroyPQExpBuffer(query);
 			destroyPQExpBuffer(q);
 			destroyPQExpBuffer(delq);
+			destroyPQExpBuffer(labelq);
 			return;
 		}
 
@@ -9753,6 +9900,14 @@ dumpOpfamily(Archive *fout, OpfamilyInfo *opfinfo)
 		appendPQExpBuffer(q, ";\n");
 	}
 
+	appendPQExpBuffer(labelq, "OPERATOR FAMILY %s",
+					  fmtId(opfinfo->dobj.name));
+	appendPQExpBuffer(labelq, " USING %s",
+					  fmtId(amname));
+
+	if (binary_upgrade)
+		binary_upgrade_extension_member(q, &opfinfo->dobj, labelq->data);
+
 	ArchiveEntry(fout, opfinfo->dobj.catId, opfinfo->dobj.dumpId,
 				 opfinfo->dobj.name,
 				 opfinfo->dobj.namespace->dobj.name,
@@ -9764,12 +9919,7 @@ dumpOpfamily(Archive *fout, OpfamilyInfo *opfinfo)
 				 NULL, NULL);
 
 	/* Dump Operator Family Comments */
-	resetPQExpBuffer(q);
-	appendPQExpBuffer(q, "OPERATOR FAMILY %s",
-					  fmtId(opfinfo->dobj.name));
-	appendPQExpBuffer(q, " USING %s",
-					  fmtId(amname));
-	dumpComment(fout, q->data,
+	dumpComment(fout, labelq->data,
 				NULL, opfinfo->rolname,
 				opfinfo->dobj.catId, 0, opfinfo->dobj.dumpId);
 
@@ -9779,6 +9929,7 @@ dumpOpfamily(Archive *fout, OpfamilyInfo *opfinfo)
 	destroyPQExpBuffer(query);
 	destroyPQExpBuffer(q);
 	destroyPQExpBuffer(delq);
+	destroyPQExpBuffer(labelq);
 }
 
 /*
@@ -9791,7 +9942,7 @@ dumpConversion(Archive *fout, ConvInfo *convinfo)
 	PQExpBuffer query;
 	PQExpBuffer q;
 	PQExpBuffer delq;
-	PQExpBuffer details;
+	PQExpBuffer labelq;
 	PGresult   *res;
 	int			ntups;
 	int			i_conname;
@@ -9812,7 +9963,7 @@ dumpConversion(Archive *fout, ConvInfo *convinfo)
 	query = createPQExpBuffer();
 	q = createPQExpBuffer();
 	delq = createPQExpBuffer();
-	details = createPQExpBuffer();
+	labelq = createPQExpBuffer();
 
 	/* Make sure we are in proper schema */
 	selectSourceSchema(convinfo->dobj.namespace->dobj.name);
@@ -9869,6 +10020,11 @@ dumpConversion(Archive *fout, ConvInfo *convinfo)
 	/* regproc is automatically quoted in 7.3 and above */
 	appendPQExpBuffer(q, " FROM %s;\n", conproc);
 
+	appendPQExpBuffer(labelq, "CONVERSION %s", fmtId(convinfo->dobj.name));
+
+	if (binary_upgrade)
+		binary_upgrade_extension_member(q, &convinfo->dobj, labelq->data);
+
 	ArchiveEntry(fout, convinfo->dobj.catId, convinfo->dobj.dumpId,
 				 convinfo->dobj.name,
 				 convinfo->dobj.namespace->dobj.name,
@@ -9880,9 +10036,7 @@ dumpConversion(Archive *fout, ConvInfo *convinfo)
 				 NULL, NULL);
 
 	/* Dump Conversion Comments */
-	resetPQExpBuffer(q);
-	appendPQExpBuffer(q, "CONVERSION %s", fmtId(convinfo->dobj.name));
-	dumpComment(fout, q->data,
+	dumpComment(fout, labelq->data,
 				convinfo->dobj.namespace->dobj.name, convinfo->rolname,
 				convinfo->dobj.catId, 0, convinfo->dobj.dumpId);
 
@@ -9891,7 +10045,7 @@ dumpConversion(Archive *fout, ConvInfo *convinfo)
 	destroyPQExpBuffer(query);
 	destroyPQExpBuffer(q);
 	destroyPQExpBuffer(delq);
-	destroyPQExpBuffer(details);
+	destroyPQExpBuffer(labelq);
 }
 
 /*
@@ -9944,6 +10098,7 @@ dumpAgg(Archive *fout, AggInfo *agginfo)
 	PQExpBuffer query;
 	PQExpBuffer q;
 	PQExpBuffer delq;
+	PQExpBuffer labelq;
 	PQExpBuffer details;
 	char	   *aggsig;
 	char	   *aggsig_tag;
@@ -9969,6 +10124,7 @@ dumpAgg(Archive *fout, AggInfo *agginfo)
 	query = createPQExpBuffer();
 	q = createPQExpBuffer();
 	delq = createPQExpBuffer();
+	labelq = createPQExpBuffer();
 	details = createPQExpBuffer();
 
 	/* Make sure we are in proper schema */
@@ -10113,6 +10269,11 @@ dumpAgg(Archive *fout, AggInfo *agginfo)
 	appendPQExpBuffer(q, "CREATE AGGREGATE %s (\n%s\n);\n",
 					  aggsig, details->data);
 
+	appendPQExpBuffer(labelq, "AGGREGATE %s", aggsig);
+
+	if (binary_upgrade)
+		binary_upgrade_extension_member(q, &agginfo->aggfn.dobj, labelq->data);
+
 	ArchiveEntry(fout, agginfo->aggfn.dobj.catId, agginfo->aggfn.dobj.dumpId,
 				 aggsig_tag,
 				 agginfo->aggfn.dobj.namespace->dobj.name,
@@ -10124,12 +10285,10 @@ dumpAgg(Archive *fout, AggInfo *agginfo)
 				 NULL, NULL);
 
 	/* Dump Aggregate Comments */
-	resetPQExpBuffer(q);
-	appendPQExpBuffer(q, "AGGREGATE %s", aggsig);
-	dumpComment(fout, q->data,
+	dumpComment(fout, labelq->data,
 			agginfo->aggfn.dobj.namespace->dobj.name, agginfo->aggfn.rolname,
 				agginfo->aggfn.dobj.catId, 0, agginfo->aggfn.dobj.dumpId);
-	dumpSecLabel(fout, q->data,
+	dumpSecLabel(fout, labelq->data,
 			agginfo->aggfn.dobj.namespace->dobj.name, agginfo->aggfn.rolname,
 				 agginfo->aggfn.dobj.catId, 0, agginfo->aggfn.dobj.dumpId);
 
@@ -10158,6 +10317,7 @@ dumpAgg(Archive *fout, AggInfo *agginfo)
 	destroyPQExpBuffer(query);
 	destroyPQExpBuffer(q);
 	destroyPQExpBuffer(delq);
+	destroyPQExpBuffer(labelq);
 	destroyPQExpBuffer(details);
 }
 
@@ -10170,6 +10330,7 @@ dumpTSParser(Archive *fout, TSParserInfo *prsinfo)
 {
 	PQExpBuffer q;
 	PQExpBuffer delq;
+	PQExpBuffer labelq;
 
 	/* Skip if not to be dumped */
 	if (!prsinfo->dobj.dump || dataOnly)
@@ -10177,6 +10338,7 @@ dumpTSParser(Archive *fout, TSParserInfo *prsinfo)
 
 	q = createPQExpBuffer();
 	delq = createPQExpBuffer();
+	labelq = createPQExpBuffer();
 
 	/* Make sure we are in proper schema */
 	selectSourceSchema(prsinfo->dobj.namespace->dobj.name);
@@ -10204,6 +10366,12 @@ dumpTSParser(Archive *fout, TSParserInfo *prsinfo)
 	appendPQExpBuffer(delq, ".%s;\n",
 					  fmtId(prsinfo->dobj.name));
 
+	appendPQExpBuffer(labelq, "TEXT SEARCH PARSER %s",
+					  fmtId(prsinfo->dobj.name));
+
+	if (binary_upgrade)
+		binary_upgrade_extension_member(q, &prsinfo->dobj, labelq->data);
+
 	ArchiveEntry(fout, prsinfo->dobj.catId, prsinfo->dobj.dumpId,
 				 prsinfo->dobj.name,
 				 prsinfo->dobj.namespace->dobj.name,
@@ -10215,15 +10383,13 @@ dumpTSParser(Archive *fout, TSParserInfo *prsinfo)
 				 NULL, NULL);
 
 	/* Dump Parser Comments */
-	resetPQExpBuffer(q);
-	appendPQExpBuffer(q, "TEXT SEARCH PARSER %s",
-					  fmtId(prsinfo->dobj.name));
-	dumpComment(fout, q->data,
+	dumpComment(fout, labelq->data,
 				NULL, "",
 				prsinfo->dobj.catId, 0, prsinfo->dobj.dumpId);
 
 	destroyPQExpBuffer(q);
 	destroyPQExpBuffer(delq);
+	destroyPQExpBuffer(labelq);
 }
 
 /*
@@ -10235,6 +10401,7 @@ dumpTSDictionary(Archive *fout, TSDictInfo *dictinfo)
 {
 	PQExpBuffer q;
 	PQExpBuffer delq;
+	PQExpBuffer labelq;
 	PQExpBuffer query;
 	PGresult   *res;
 	int			ntups;
@@ -10247,6 +10414,7 @@ dumpTSDictionary(Archive *fout, TSDictInfo *dictinfo)
 
 	q = createPQExpBuffer();
 	delq = createPQExpBuffer();
+	labelq = createPQExpBuffer();
 	query = createPQExpBuffer();
 
 	/* Fetch name and namespace of the dictionary's template */
@@ -10296,6 +10464,12 @@ dumpTSDictionary(Archive *fout, TSDictInfo *dictinfo)
 	appendPQExpBuffer(delq, ".%s;\n",
 					  fmtId(dictinfo->dobj.name));
 
+	appendPQExpBuffer(labelq, "TEXT SEARCH DICTIONARY %s",
+					  fmtId(dictinfo->dobj.name));
+
+	if (binary_upgrade)
+		binary_upgrade_extension_member(q, &dictinfo->dobj, labelq->data);
+
 	ArchiveEntry(fout, dictinfo->dobj.catId, dictinfo->dobj.dumpId,
 				 dictinfo->dobj.name,
 				 dictinfo->dobj.namespace->dobj.name,
@@ -10307,15 +10481,13 @@ dumpTSDictionary(Archive *fout, TSDictInfo *dictinfo)
 				 NULL, NULL);
 
 	/* Dump Dictionary Comments */
-	resetPQExpBuffer(q);
-	appendPQExpBuffer(q, "TEXT SEARCH DICTIONARY %s",
-					  fmtId(dictinfo->dobj.name));
-	dumpComment(fout, q->data,
+	dumpComment(fout, labelq->data,
 				NULL, dictinfo->rolname,
 				dictinfo->dobj.catId, 0, dictinfo->dobj.dumpId);
 
 	destroyPQExpBuffer(q);
 	destroyPQExpBuffer(delq);
+	destroyPQExpBuffer(labelq);
 	destroyPQExpBuffer(query);
 }
 
@@ -10328,6 +10500,7 @@ dumpTSTemplate(Archive *fout, TSTemplateInfo *tmplinfo)
 {
 	PQExpBuffer q;
 	PQExpBuffer delq;
+	PQExpBuffer labelq;
 
 	/* Skip if not to be dumped */
 	if (!tmplinfo->dobj.dump || dataOnly)
@@ -10335,6 +10508,7 @@ dumpTSTemplate(Archive *fout, TSTemplateInfo *tmplinfo)
 
 	q = createPQExpBuffer();
 	delq = createPQExpBuffer();
+	labelq = createPQExpBuffer();
 
 	/* Make sure we are in proper schema */
 	selectSourceSchema(tmplinfo->dobj.namespace->dobj.name);
@@ -10356,6 +10530,12 @@ dumpTSTemplate(Archive *fout, TSTemplateInfo *tmplinfo)
 	appendPQExpBuffer(delq, ".%s;\n",
 					  fmtId(tmplinfo->dobj.name));
 
+	appendPQExpBuffer(labelq, "TEXT SEARCH TEMPLATE %s",
+					  fmtId(tmplinfo->dobj.name));
+
+	if (binary_upgrade)
+		binary_upgrade_extension_member(q, &tmplinfo->dobj, labelq->data);
+
 	ArchiveEntry(fout, tmplinfo->dobj.catId, tmplinfo->dobj.dumpId,
 				 tmplinfo->dobj.name,
 				 tmplinfo->dobj.namespace->dobj.name,
@@ -10367,15 +10547,13 @@ dumpTSTemplate(Archive *fout, TSTemplateInfo *tmplinfo)
 				 NULL, NULL);
 
 	/* Dump Template Comments */
-	resetPQExpBuffer(q);
-	appendPQExpBuffer(q, "TEXT SEARCH TEMPLATE %s",
-					  fmtId(tmplinfo->dobj.name));
-	dumpComment(fout, q->data,
+	dumpComment(fout, labelq->data,
 				NULL, "",
 				tmplinfo->dobj.catId, 0, tmplinfo->dobj.dumpId);
 
 	destroyPQExpBuffer(q);
 	destroyPQExpBuffer(delq);
+	destroyPQExpBuffer(labelq);
 }
 
 /*
@@ -10387,6 +10565,7 @@ dumpTSConfig(Archive *fout, TSConfigInfo *cfginfo)
 {
 	PQExpBuffer q;
 	PQExpBuffer delq;
+	PQExpBuffer labelq;
 	PQExpBuffer query;
 	PGresult   *res;
 	char	   *nspname;
@@ -10402,6 +10581,7 @@ dumpTSConfig(Archive *fout, TSConfigInfo *cfginfo)
 
 	q = createPQExpBuffer();
 	delq = createPQExpBuffer();
+	labelq = createPQExpBuffer();
 	query = createPQExpBuffer();
 
 	/* Fetch name and namespace of the config's parser */
@@ -10489,6 +10669,12 @@ dumpTSConfig(Archive *fout, TSConfigInfo *cfginfo)
 	appendPQExpBuffer(delq, ".%s;\n",
 					  fmtId(cfginfo->dobj.name));
 
+	appendPQExpBuffer(labelq, "TEXT SEARCH CONFIGURATION %s",
+					  fmtId(cfginfo->dobj.name));
+
+	if (binary_upgrade)
+		binary_upgrade_extension_member(q, &cfginfo->dobj, labelq->data);
+
 	ArchiveEntry(fout, cfginfo->dobj.catId, cfginfo->dobj.dumpId,
 				 cfginfo->dobj.name,
 				 cfginfo->dobj.namespace->dobj.name,
@@ -10500,15 +10686,13 @@ dumpTSConfig(Archive *fout, TSConfigInfo *cfginfo)
 				 NULL, NULL);
 
 	/* Dump Configuration Comments */
-	resetPQExpBuffer(q);
-	appendPQExpBuffer(q, "TEXT SEARCH CONFIGURATION %s",
-					  fmtId(cfginfo->dobj.name));
-	dumpComment(fout, q->data,
+	dumpComment(fout, labelq->data,
 				NULL, cfginfo->rolname,
 				cfginfo->dobj.catId, 0, cfginfo->dobj.dumpId);
 
 	destroyPQExpBuffer(q);
 	destroyPQExpBuffer(delq);
+	destroyPQExpBuffer(labelq);
 	destroyPQExpBuffer(query);
 }
 
@@ -10521,7 +10705,8 @@ dumpForeignDataWrapper(Archive *fout, FdwInfo *fdwinfo)
 {
 	PQExpBuffer q;
 	PQExpBuffer delq;
-	char	   *namecopy;
+	PQExpBuffer labelq;
+	char	   *qfdwname;
 
 	/* Skip if not to be dumped */
 	if (!fdwinfo->dobj.dump || dataOnly)
@@ -10529,9 +10714,12 @@ dumpForeignDataWrapper(Archive *fout, FdwInfo *fdwinfo)
 
 	q = createPQExpBuffer();
 	delq = createPQExpBuffer();
+	labelq = createPQExpBuffer();
+
+	qfdwname = strdup(fmtId(fdwinfo->dobj.name));
 
 	appendPQExpBuffer(q, "CREATE FOREIGN DATA WRAPPER %s",
-					  fmtId(fdwinfo->dobj.name));
+					  qfdwname);
 
 	if (fdwinfo->fdwvalidator && strcmp(fdwinfo->fdwvalidator, "-") != 0)
 		appendPQExpBuffer(q, " VALIDATOR %s",
@@ -10543,7 +10731,13 @@ dumpForeignDataWrapper(Archive *fout, FdwInfo *fdwinfo)
 	appendPQExpBuffer(q, ";\n");
 
 	appendPQExpBuffer(delq, "DROP FOREIGN DATA WRAPPER %s;\n",
-					  fmtId(fdwinfo->dobj.name));
+					  qfdwname);
+
+	appendPQExpBuffer(labelq, "FOREIGN DATA WRAPPER %s",
+					  qfdwname);
+
+	if (binary_upgrade)
+		binary_upgrade_extension_member(q, &fdwinfo->dobj, labelq->data);
 
 	ArchiveEntry(fout, fdwinfo->dobj.catId, fdwinfo->dobj.dumpId,
 				 fdwinfo->dobj.name,
@@ -10556,16 +10750,17 @@ dumpForeignDataWrapper(Archive *fout, FdwInfo *fdwinfo)
 				 NULL, NULL);
 
 	/* Handle the ACL */
-	namecopy = strdup(fmtId(fdwinfo->dobj.name));
 	dumpACL(fout, fdwinfo->dobj.catId, fdwinfo->dobj.dumpId,
 			"FOREIGN DATA WRAPPER",
-			namecopy, NULL, fdwinfo->dobj.name,
+			qfdwname, NULL, fdwinfo->dobj.name,
 			NULL, fdwinfo->rolname,
 			fdwinfo->fdwacl);
-	free(namecopy);
+
+	free(qfdwname);
 
 	destroyPQExpBuffer(q);
 	destroyPQExpBuffer(delq);
+	destroyPQExpBuffer(labelq);
 }
 
 /*
@@ -10577,10 +10772,11 @@ dumpForeignServer(Archive *fout, ForeignServerInfo *srvinfo)
 {
 	PQExpBuffer q;
 	PQExpBuffer delq;
+	PQExpBuffer labelq;
 	PQExpBuffer query;
 	PGresult   *res;
 	int			ntups;
-	char	   *namecopy;
+	char	   *qsrvname;
 	char	   *fdwname;
 
 	/* Skip if not to be dumped */
@@ -10589,8 +10785,11 @@ dumpForeignServer(Archive *fout, ForeignServerInfo *srvinfo)
 
 	q = createPQExpBuffer();
 	delq = createPQExpBuffer();
+	labelq = createPQExpBuffer();
 	query = createPQExpBuffer();
 
+	qsrvname = strdup(fmtId(srvinfo->dobj.name));
+
 	/* look up the foreign-data wrapper */
 	selectSourceSchema("pg_catalog");
 	appendPQExpBuffer(query, "SELECT fdwname "
@@ -10610,7 +10809,7 @@ dumpForeignServer(Archive *fout, ForeignServerInfo *srvinfo)
 	}
 	fdwname = PQgetvalue(res, 0, 0);
 
-	appendPQExpBuffer(q, "CREATE SERVER %s", fmtId(srvinfo->dobj.name));
+	appendPQExpBuffer(q, "CREATE SERVER %s", qsrvname);
 	if (srvinfo->srvtype && strlen(srvinfo->srvtype) > 0)
 	{
 		appendPQExpBuffer(q, " TYPE ");
@@ -10631,7 +10830,12 @@ dumpForeignServer(Archive *fout, ForeignServerInfo *srvinfo)
 	appendPQExpBuffer(q, ";\n");
 
 	appendPQExpBuffer(delq, "DROP SERVER %s;\n",
-					  fmtId(srvinfo->dobj.name));
+					  qsrvname);
+
+	appendPQExpBuffer(labelq, "SERVER %s", qsrvname);
+
+	if (binary_upgrade)
+		binary_upgrade_extension_member(q, &srvinfo->dobj, labelq->data);
 
 	ArchiveEntry(fout, srvinfo->dobj.catId, srvinfo->dobj.dumpId,
 				 srvinfo->dobj.name,
@@ -10644,13 +10848,11 @@ dumpForeignServer(Archive *fout, ForeignServerInfo *srvinfo)
 				 NULL, NULL);
 
 	/* Handle the ACL */
-	namecopy = strdup(fmtId(srvinfo->dobj.name));
 	dumpACL(fout, srvinfo->dobj.catId, srvinfo->dobj.dumpId,
 			"FOREIGN SERVER",
-			namecopy, NULL, srvinfo->dobj.name,
+			qsrvname, NULL, srvinfo->dobj.name,
 			NULL, srvinfo->rolname,
 			srvinfo->srvacl);
-	free(namecopy);
 
 	/* Dump user mappings */
 	dumpUserMappings(fout,
@@ -10658,8 +10860,11 @@ dumpForeignServer(Archive *fout, ForeignServerInfo *srvinfo)
 					 srvinfo->rolname,
 					 srvinfo->dobj.catId, srvinfo->dobj.dumpId);
 
+	free(qsrvname);
+
 	destroyPQExpBuffer(q);
 	destroyPQExpBuffer(delq);
+	destroyPQExpBuffer(labelq);
 }
 
 /*
@@ -11254,6 +11459,7 @@ dumpTableSchema(Archive *fout, TableInfo *tbinfo)
 	PQExpBuffer query = createPQExpBuffer();
 	PQExpBuffer q = createPQExpBuffer();
 	PQExpBuffer delq = createPQExpBuffer();
+	PQExpBuffer labelq = createPQExpBuffer();
 	PGresult   *res;
 	int			numParents;
 	TableInfo **parents;
@@ -11334,6 +11540,9 @@ dumpTableSchema(Archive *fout, TableInfo *tbinfo)
 		appendPQExpBuffer(q, "CREATE VIEW %s AS\n    %s\n",
 						  fmtId(tbinfo->dobj.name), viewdef);
 
+		appendPQExpBuffer(labelq, "VIEW %s",
+						  fmtId(tbinfo->dobj.name));
+
 		PQclear(res);
 	}
 	else
@@ -11379,6 +11588,9 @@ dumpTableSchema(Archive *fout, TableInfo *tbinfo)
 		appendPQExpBuffer(delq, "%s;\n",
 						  fmtId(tbinfo->dobj.name));
 
+		appendPQExpBuffer(labelq, "%s %s", reltypename,
+						  fmtId(tbinfo->dobj.name));
+
 		if (binary_upgrade)
 			binary_upgrade_set_pg_class_oids(q, tbinfo->dobj.catId.oid, false);
 
@@ -11716,6 +11928,9 @@ dumpTableSchema(Archive *fout, TableInfo *tbinfo)
 		}
 	}
 
+	if (binary_upgrade)
+		binary_upgrade_extension_member(q, &tbinfo->dobj, labelq->data);
+
 	ArchiveEntry(fout, tbinfo->dobj.catId, tbinfo->dobj.dumpId,
 				 tbinfo->dobj.name,
 				 tbinfo->dobj.namespace->dobj.name,
@@ -11748,6 +11963,7 @@ dumpTableSchema(Archive *fout, TableInfo *tbinfo)
 	destroyPQExpBuffer(query);
 	destroyPQExpBuffer(q);
 	destroyPQExpBuffer(delq);
+	destroyPQExpBuffer(labelq);
 }
 
 /*
@@ -11847,12 +12063,17 @@ dumpIndex(Archive *fout, IndxInfo *indxinfo)
 	TableInfo  *tbinfo = indxinfo->indextable;
 	PQExpBuffer q;
 	PQExpBuffer delq;
+	PQExpBuffer labelq;
 
 	if (dataOnly)
 		return;
 
 	q = createPQExpBuffer();
 	delq = createPQExpBuffer();
+	labelq = createPQExpBuffer();
+
+	appendPQExpBuffer(labelq, "INDEX %s",
+					  fmtId(indxinfo->dobj.name));
 
 	/*
 	 * If there's an associated constraint, don't dump the index per se, but
@@ -11897,16 +12118,14 @@ dumpIndex(Archive *fout, IndxInfo *indxinfo)
 	}
 
 	/* Dump Index Comments */
-	resetPQExpBuffer(q);
-	appendPQExpBuffer(q, "INDEX %s",
-					  fmtId(indxinfo->dobj.name));
-	dumpComment(fout, q->data,
+	dumpComment(fout, labelq->data,
 				tbinfo->dobj.namespace->dobj.name,
 				tbinfo->rolname,
 				indxinfo->dobj.catId, 0, indxinfo->dobj.dumpId);
 
 	destroyPQExpBuffer(q);
 	destroyPQExpBuffer(delq);
+	destroyPQExpBuffer(labelq);
 }
 
 /*
@@ -12150,19 +12369,19 @@ static void
 dumpTableConstraintComment(Archive *fout, ConstraintInfo *coninfo)
 {
 	TableInfo  *tbinfo = coninfo->contable;
-	PQExpBuffer q = createPQExpBuffer();
+	PQExpBuffer labelq = createPQExpBuffer();
 
-	appendPQExpBuffer(q, "CONSTRAINT %s ",
+	appendPQExpBuffer(labelq, "CONSTRAINT %s ",
 					  fmtId(coninfo->dobj.name));
-	appendPQExpBuffer(q, "ON %s",
+	appendPQExpBuffer(labelq, "ON %s",
 					  fmtId(tbinfo->dobj.name));
-	dumpComment(fout, q->data,
+	dumpComment(fout, labelq->data,
 				tbinfo->dobj.namespace->dobj.name,
 				tbinfo->rolname,
 				coninfo->dobj.catId, 0,
 			 coninfo->separate ? coninfo->dobj.dumpId : tbinfo->dobj.dumpId);
 
-	destroyPQExpBuffer(q);
+	destroyPQExpBuffer(labelq);
 }
 
 /*
@@ -12256,6 +12475,7 @@ dumpSequence(Archive *fout, TableInfo *tbinfo)
 				called;
 	PQExpBuffer query = createPQExpBuffer();
 	PQExpBuffer delqry = createPQExpBuffer();
+	PQExpBuffer labelq = createPQExpBuffer();
 
 	/* Make sure we are in proper schema */
 	selectSourceSchema(tbinfo->dobj.namespace->dobj.name);
@@ -12343,8 +12563,6 @@ dumpSequence(Archive *fout, TableInfo *tbinfo)
 	 */
 	if (!dataOnly)
 	{
-		resetPQExpBuffer(delqry);
-
 		/*
 		 * DROP must be fully qualified in case same name appears in
 		 * pg_catalog
@@ -12397,8 +12615,14 @@ dumpSequence(Archive *fout, TableInfo *tbinfo)
 
 		appendPQExpBuffer(query, ";\n");
 
+		appendPQExpBuffer(labelq, "SEQUENCE %s", fmtId(tbinfo->dobj.name));
+
 		/* binary_upgrade:	no need to clear TOAST table oid */
 
+		if (binary_upgrade)
+			binary_upgrade_extension_member(query, &tbinfo->dobj,
+											labelq->data);
+
 		ArchiveEntry(fout, tbinfo->dobj.catId, tbinfo->dobj.dumpId,
 					 tbinfo->dobj.name,
 					 tbinfo->dobj.namespace->dobj.name,
@@ -12448,12 +12672,10 @@ dumpSequence(Archive *fout, TableInfo *tbinfo)
 		}
 
 		/* Dump Sequence Comments and Security Labels */
-		resetPQExpBuffer(query);
-		appendPQExpBuffer(query, "SEQUENCE %s", fmtId(tbinfo->dobj.name));
-		dumpComment(fout, query->data,
+		dumpComment(fout, labelq->data,
 					tbinfo->dobj.namespace->dobj.name, tbinfo->rolname,
 					tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId);
-		dumpSecLabel(fout, query->data,
+		dumpSecLabel(fout, labelq->data,
 					 tbinfo->dobj.namespace->dobj.name, tbinfo->rolname,
 					 tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId);
 	}
@@ -12481,6 +12703,7 @@ dumpSequence(Archive *fout, TableInfo *tbinfo)
 
 	destroyPQExpBuffer(query);
 	destroyPQExpBuffer(delqry);
+	destroyPQExpBuffer(labelq);
 }
 
 static void
@@ -12489,6 +12712,7 @@ dumpTrigger(Archive *fout, TriggerInfo *tginfo)
 	TableInfo  *tbinfo = tginfo->tgtable;
 	PQExpBuffer query;
 	PQExpBuffer delqry;
+	PQExpBuffer labelq;
 	char	   *tgargs;
 	size_t		lentgargs;
 	const char *p;
@@ -12499,6 +12723,7 @@ dumpTrigger(Archive *fout, TriggerInfo *tginfo)
 
 	query = createPQExpBuffer();
 	delqry = createPQExpBuffer();
+	labelq = createPQExpBuffer();
 
 	/*
 	 * DROP must be fully qualified in case same name appears in pg_catalog
@@ -12659,6 +12884,11 @@ dumpTrigger(Archive *fout, TriggerInfo *tginfo)
 						  fmtId(tginfo->dobj.name));
 	}
 
+	appendPQExpBuffer(labelq, "TRIGGER %s ",
+					  fmtId(tginfo->dobj.name));
+	appendPQExpBuffer(labelq, "ON %s",
+					  fmtId(tbinfo->dobj.name));
+
 	ArchiveEntry(fout, tginfo->dobj.catId, tginfo->dobj.dumpId,
 				 tginfo->dobj.name,
 				 tbinfo->dobj.namespace->dobj.name,
@@ -12669,18 +12899,13 @@ dumpTrigger(Archive *fout, TriggerInfo *tginfo)
 				 tginfo->dobj.dependencies, tginfo->dobj.nDeps,
 				 NULL, NULL);
 
-	resetPQExpBuffer(query);
-	appendPQExpBuffer(query, "TRIGGER %s ",
-					  fmtId(tginfo->dobj.name));
-	appendPQExpBuffer(query, "ON %s",
-					  fmtId(tbinfo->dobj.name));
-
-	dumpComment(fout, query->data,
+	dumpComment(fout, labelq->data,
 				tbinfo->dobj.namespace->dobj.name, tbinfo->rolname,
 				tginfo->dobj.catId, 0, tginfo->dobj.dumpId);
 
 	destroyPQExpBuffer(query);
 	destroyPQExpBuffer(delqry);
+	destroyPQExpBuffer(labelq);
 }
 
 /*
@@ -12694,6 +12919,7 @@ dumpRule(Archive *fout, RuleInfo *rinfo)
 	PQExpBuffer query;
 	PQExpBuffer cmd;
 	PQExpBuffer delcmd;
+	PQExpBuffer labelq;
 	PGresult   *res;
 
 	/* Skip if not to be dumped */
@@ -12715,6 +12941,7 @@ dumpRule(Archive *fout, RuleInfo *rinfo)
 	query = createPQExpBuffer();
 	cmd = createPQExpBuffer();
 	delcmd = createPQExpBuffer();
+	labelq = createPQExpBuffer();
 
 	if (g_fout->remoteVersion >= 70300)
 	{
@@ -12779,6 +13006,11 @@ dumpRule(Archive *fout, RuleInfo *rinfo)
 	appendPQExpBuffer(delcmd, "%s;\n",
 					  fmtId(tbinfo->dobj.name));
 
+	appendPQExpBuffer(labelq, "RULE %s",
+					  fmtId(rinfo->dobj.name));
+	appendPQExpBuffer(labelq, " ON %s",
+					  fmtId(tbinfo->dobj.name));
+
 	ArchiveEntry(fout, rinfo->dobj.catId, rinfo->dobj.dumpId,
 				 rinfo->dobj.name,
 				 tbinfo->dobj.namespace->dobj.name,
@@ -12790,12 +13022,7 @@ dumpRule(Archive *fout, RuleInfo *rinfo)
 				 NULL, NULL);
 
 	/* Dump rule comments */
-	resetPQExpBuffer(query);
-	appendPQExpBuffer(query, "RULE %s",
-					  fmtId(rinfo->dobj.name));
-	appendPQExpBuffer(query, " ON %s",
-					  fmtId(tbinfo->dobj.name));
-	dumpComment(fout, query->data,
+	dumpComment(fout, labelq->data,
 				tbinfo->dobj.namespace->dobj.name,
 				tbinfo->rolname,
 				rinfo->dobj.catId, 0, rinfo->dobj.dumpId);
@@ -12805,6 +13032,7 @@ dumpRule(Archive *fout, RuleInfo *rinfo)
 	destroyPQExpBuffer(query);
 	destroyPQExpBuffer(cmd);
 	destroyPQExpBuffer(delcmd);
+	destroyPQExpBuffer(labelq);
 }
 
 /*
@@ -12900,11 +13128,16 @@ getExtensionMembership(ExtensionInfo extinfo[], int numExtensions)
 		/* Record dependency so that getDependencies needn't repeat this */
 		addObjectDependency(dobj, refdobj->dumpId);
 
+		dobj->ext_member = true;
+
 		/*
-		 * Mark the member object as not to be dumped.  We still need the
-		 * dependency link, to ensure that sorting is done correctly.
+		 * Normally, mark the member object as not to be dumped.  But in
+		 * binary upgrades, we still dump the members individually, since
+		 * the idea is to exactly reproduce the database contents rather
+		 * than replace the extension contents with something different.
 		 */
-		dobj->dump = false;
+		if (!binary_upgrade)
+			dobj->dump = false;
 	}
 
 	PQclear(res);
diff --git a/src/bin/pg_dump/pg_dump.h b/src/bin/pg_dump/pg_dump.h
index 140d02d1f8083890753cc57cece9b0b2247500b4..69668e9552043d7b1ccb64af336dc982267572e9 100644
--- a/src/bin/pg_dump/pg_dump.h
+++ b/src/bin/pg_dump/pg_dump.h
@@ -128,6 +128,7 @@ typedef struct _dumpableObject
 	char	   *name;			/* object name (should never be NULL) */
 	struct _namespaceInfo *namespace;	/* containing namespace, or NULL */
 	bool		dump;			/* true if we want to dump this object */
+	bool		ext_member;		/* true if object is member of extension */
 	DumpId	   *dependencies;	/* dumpIds of objects this one depends on */
 	int			nDeps;			/* number of valid dependencies */
 	int			allocDeps;		/* allocated size of dependencies[] */
@@ -144,6 +145,8 @@ typedef struct _extensionInfo
 {
 	DumpableObject dobj;
 	char       *namespace;		/* schema containing extension's objects */
+	bool		relocatable;
+	char	   *extversion;
 	char       *extconfig;		/* info about configuration tables */
 	char       *extcondition;
 } ExtensionInfo;
diff --git a/src/include/commands/extension.h b/src/include/commands/extension.h
index d0e94556f50380b92668a17c562c128d4acaf28d..8c07c3aaeffad931421a71e633cf8ec873bfc980 100644
--- a/src/include/commands/extension.h
+++ b/src/include/commands/extension.h
@@ -32,6 +32,11 @@ extern void CreateExtension(CreateExtensionStmt *stmt);
 extern void RemoveExtensions(DropStmt *stmt);
 extern void RemoveExtensionById(Oid extId);
 
+extern Oid	InsertExtensionTuple(const char *extName, Oid extOwner,
+					 Oid schemaOid, bool relocatable, const char *extVersion,
+					 Datum extConfig, Datum extCondition,
+					 List *requiredExtensions);
+
 extern void ExecAlterExtensionAddStmt(AlterExtensionAddStmt *stmt);
 
 extern Oid	get_extension_oid(const char *extname, bool missing_ok);