diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c
index ad1086d169a5ec20a284fa2353b102ca9bc321cb..c1ab56283654af9a86ef07f29add9fffa00b659e 100644
--- a/src/bin/pg_dump/pg_dump.c
+++ b/src/bin/pg_dump/pg_dump.c
@@ -12,7 +12,7 @@
  *	by PostgreSQL
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/bin/pg_dump/pg_dump.c,v 1.539 2009/06/11 14:49:07 momjian Exp $
+ *	  $PostgreSQL: pgsql/src/bin/pg_dump/pg_dump.c,v 1.540 2009/07/02 21:34:32 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -233,7 +233,7 @@ main(int argc, char **argv)
 	static int	outputNoTablespaces = 0;
 	static int	use_setsessauth = 0;
 
-	struct option long_options[] = {
+	static struct option long_options[] = {
 		{"data-only", no_argument, NULL, 'a'},
 		{"blobs", no_argument, NULL, 'b'},
 		{"clean", no_argument, NULL, 'c'},
@@ -1733,7 +1733,7 @@ dumpDatabase(Archive *AH)
 	if (binary_upgrade)
 	{
 		appendPQExpBuffer(creaQry, "\n-- For binary upgrade, set datfrozenxid.\n");
-		appendPQExpBuffer(creaQry, "UPDATE pg_database\n"
+		appendPQExpBuffer(creaQry, "UPDATE pg_catalog.pg_database\n"
 						  "SET datfrozenxid = '%u'\n"
 						  "WHERE	datname = ",
 						  frozenxid);
@@ -4712,8 +4712,8 @@ getTableAttrs(TableInfo *tblinfo, int numTables)
 			appendPQExpBuffer(q, "SELECT a.attnum, a.attname, "
 						   "a.atttypmod, -1 AS attstattarget, a.attstorage, "
 							  "t.typstorage, a.attnotnull, a.atthasdef, "
-							  "false AS attisdropped, 0 AS attlen, "
-							  "' ' AS attalign, false AS attislocal, "
+							  "false AS attisdropped, a.attlen, "
+							  "a.attalign, false AS attislocal, "
 							  "format_type(t.oid,a.atttypmod) AS atttypname "
 							  "FROM pg_attribute a LEFT JOIN pg_type t "
 							  "ON a.atttypid = t.oid "
@@ -4729,7 +4729,7 @@ getTableAttrs(TableInfo *tblinfo, int numTables)
 							  "-1 AS attstattarget, attstorage, "
 							  "attstorage AS typstorage, "
 							  "attnotnull, atthasdef, false AS attisdropped, "
-							  "0 AS attlen, ' ' AS attalign, "
+							  "attlen, attalign, "
 							  "false AS attislocal, "
 							  "(SELECT typname FROM pg_type WHERE oid = atttypid) AS atttypname "
 							  "FROM pg_attribute a "
@@ -4806,20 +4806,6 @@ getTableAttrs(TableInfo *tblinfo, int numTables)
 
 		PQclear(res);
 
-
-		/*
-		 * ALTER TABLE DROP COLUMN clears pg_attribute.atttypid, so we set the
-		 * column data type to 'TEXT;  we will later drop the column.
-		 */
-		if (binary_upgrade)
-		{
-			for (j = 0; j < ntups; j++)
-			{
-				if (tbinfo->attisdropped[j])
-					tbinfo->atttypnames[j] = strdup("TEXT");
-			}
-		}
-
 		/*
 		 * Get info about column defaults
 		 */
@@ -9783,19 +9769,35 @@ dumpTableSchema(Archive *fout, TableInfo *tbinfo)
 		actual_atts = 0;
 		for (j = 0; j < tbinfo->numatts; j++)
 		{
-			/* Is this one of the table's own attrs, and not dropped ? */
-			if (!tbinfo->inhAttrs[j] &&
-				(!tbinfo->attisdropped[j] || binary_upgrade))
+			/*
+			 * Normally, dump if it's one of the table's own attrs, and not
+			 * dropped.  But for binary upgrade, dump all the columns.
+			 */
+			if ((!tbinfo->inhAttrs[j] && !tbinfo->attisdropped[j]) ||
+				binary_upgrade)
 			{
 				/* Format properly if not first attr */
 				if (actual_atts > 0)
 					appendPQExpBuffer(q, ",");
 				appendPQExpBuffer(q, "\n    ");
+				actual_atts++;
 
 				/* Attribute name */
 				appendPQExpBuffer(q, "%s ",
 								  fmtId(tbinfo->attnames[j]));
 
+				if (tbinfo->attisdropped[j])
+				{
+					/*
+					 * ALTER TABLE DROP COLUMN clears pg_attribute.atttypid,
+					 * so we will not have gotten a valid type name; insert
+					 * INTEGER as a stopgap.  We'll clean things up later.
+					 */
+					appendPQExpBuffer(q, "INTEGER /* dummy */");
+					/* Skip all the rest, too */
+					continue;
+				}
+
 				/* Attribute type */
 				if (g_fout->remoteVersion >= 70100)
 				{
@@ -9811,22 +9813,23 @@ dumpTableSchema(Archive *fout, TableInfo *tbinfo)
 				}
 
 				/*
-				 * Default value --- suppress if inherited or to be printed
-				 * separately.
+				 * Default value --- suppress if inherited (except in
+				 * binary-upgrade case, where we're not doing normal
+				 * inheritance) or if it's to be printed separately.
 				 */
 				if (tbinfo->attrdefs[j] != NULL &&
-					!tbinfo->inhAttrDef[j] &&
+					(!tbinfo->inhAttrDef[j] || binary_upgrade) &&
 					!tbinfo->attrdefs[j]->separate)
 					appendPQExpBuffer(q, " DEFAULT %s",
 									  tbinfo->attrdefs[j]->adef_expr);
 
 				/*
-				 * Not Null constraint --- suppress if inherited
+				 * Not Null constraint --- suppress if inherited, except
+				 * in binary-upgrade case.
 				 */
-				if (tbinfo->notnull[j] && !tbinfo->inhNotNull[j])
+				if (tbinfo->notnull[j] &&
+					(!tbinfo->inhNotNull[j] || binary_upgrade))
 					appendPQExpBuffer(q, " NOT NULL");
-
-				actual_atts++;
 			}
 		}
 
@@ -9852,7 +9855,7 @@ dumpTableSchema(Archive *fout, TableInfo *tbinfo)
 
 		appendPQExpBuffer(q, "\n)");
 
-		if (numParents > 0)
+		if (numParents > 0 && !binary_upgrade)
 		{
 			appendPQExpBuffer(q, "\nINHERITS (");
 			for (k = 0; k < numParents; k++)
@@ -9892,8 +9895,16 @@ dumpTableSchema(Archive *fout, TableInfo *tbinfo)
 		appendPQExpBuffer(q, ";\n");
 
 		/*
-		 * For binary-compatible heap files, we create dropped columns above
-		 * and drop them here.
+		 * To create binary-compatible heap files, we have to ensure the
+		 * same physical column order, including dropped columns, as in the
+		 * original.  Therefore, we create dropped columns above and drop
+		 * them here, also updating their attlen/attalign values so that
+		 * the dropped column can be skipped properly.  (We do not bother
+		 * with restoring the original attbyval setting.)  Also, inheritance
+		 * relationships are set up by doing ALTER INHERIT rather than using
+		 * an INHERITS clause --- the latter would possibly mess up the
+		 * column order.  That also means we have to take care about setting
+		 * attislocal correctly, plus fix up any inherited CHECK constraints.
 		 */
 		if (binary_upgrade)
 		{
@@ -9901,50 +9912,82 @@ dumpTableSchema(Archive *fout, TableInfo *tbinfo)
 			{
 				if (tbinfo->attisdropped[j])
 				{
+					appendPQExpBuffer(q, "\n-- For binary upgrade, recreate dropped column.\n");
+					appendPQExpBuffer(q, "UPDATE pg_catalog.pg_attribute\n"
+									  "SET attlen = %d, "
+									  "attalign = '%c', attbyval = false\n"
+									  "WHERE attname = ",
+									  tbinfo->attlen[j],
+									  tbinfo->attalign[j]);
+					appendStringLiteralAH(q, tbinfo->attnames[j], fout);
+					appendPQExpBuffer(q, "\n  AND attrelid = ");
+					appendStringLiteralAH(q, fmtId(tbinfo->dobj.name), fout);
+					appendPQExpBuffer(q, "::pg_catalog.regclass;\n");
+
 					appendPQExpBuffer(q, "ALTER TABLE ONLY %s ",
 									  fmtId(tbinfo->dobj.name));
 					appendPQExpBuffer(q, "DROP COLUMN %s;\n",
 									  fmtId(tbinfo->attnames[j]));
+				}
+				else if (!tbinfo->attislocal[j])
+				{
+					appendPQExpBuffer(q, "\n-- For binary upgrade, recreate inherited column.\n");
+					appendPQExpBuffer(q, "UPDATE pg_catalog.pg_attribute\n"
+									  "SET attislocal = false\n"
+									  "WHERE attname = ");
+					appendStringLiteralAH(q, tbinfo->attnames[j], fout);
+					appendPQExpBuffer(q, "\n  AND attrelid = ");
+					appendStringLiteralAH(q, fmtId(tbinfo->dobj.name), fout);
+					appendPQExpBuffer(q, "::pg_catalog.regclass;\n");
+				}
+			}
 
-					/*
-					 * ALTER TABLE DROP COLUMN clears pg_attribute.atttypid,
-					 * so we have to set pg_attribute.attlen and
-					 * pg_attribute.attalign values because that is what is
-					 * used to skip over dropped columns in the heap tuples.
-					 * We have atttypmod, but it seems impossible to know the
-					 * correct data type that will yield pg_attribute values
-					 * that match the old installation. See comment in
-					 * backend/catalog/heap.c::RemoveAttributeById()
-					 */
-					appendPQExpBuffer(q, "\n-- For binary upgrade, recreate dropped column's length and alignment.\n");
-					appendPQExpBuffer(q, "UPDATE pg_attribute\n"
-									  "SET attlen = %d, "
-									  "attalign = '%c'\n"
-									  "WHERE	attname = '%s'\n"
-									  "	AND attrelid = \n"
-									  "	(\n"
-									  "		SELECT oid\n"
-									  "		FROM pg_class\n"
-									  "		WHERE	relnamespace = "
-									  "(SELECT oid FROM pg_namespace "
-									  "WHERE nspname = CURRENT_SCHEMA)\n"
-									  "			AND relname = ",
-									  tbinfo->attlen[j],
-									  tbinfo->attalign[j],
-									  tbinfo->attnames[j]);
-					appendStringLiteralAH(q, tbinfo->dobj.name, fout);
-					appendPQExpBuffer(q, "\n	);\n");
+			for (k = 0; k < tbinfo->ncheck; k++)
+			{
+				ConstraintInfo *constr = &(tbinfo->checkexprs[k]);
+
+				if (constr->separate || constr->conislocal)
+					continue;
+
+				appendPQExpBuffer(q, "\n-- For binary upgrade, set up inherited constraint.\n");
+				appendPQExpBuffer(q, "ALTER TABLE ONLY %s ",
+								  fmtId(tbinfo->dobj.name));
+				appendPQExpBuffer(q, " ADD CONSTRAINT %s ",
+								  fmtId(constr->dobj.name));
+				appendPQExpBuffer(q, "%s;\n", constr->condef);
+				appendPQExpBuffer(q, "UPDATE pg_catalog.pg_constraint\n"
+								  "SET conislocal = false\n"
+								  "WHERE contype = 'c' AND conname = ");
+				appendStringLiteralAH(q, constr->dobj.name, fout);
+				appendPQExpBuffer(q, "\n  AND conrelid = ");
+				appendStringLiteralAH(q, fmtId(tbinfo->dobj.name), fout);
+				appendPQExpBuffer(q, "::pg_catalog.regclass;\n");
+			}
+
+			if (numParents > 0)
+			{
+				appendPQExpBuffer(q, "\n-- For binary upgrade, set up inheritance this way.\n");
+				for (k = 0; k < numParents; k++)
+				{
+					TableInfo  *parentRel = parents[k];
+
+					appendPQExpBuffer(q, "ALTER TABLE ONLY %s INHERIT ",
+									  fmtId(tbinfo->dobj.name));
+					if (parentRel->dobj.namespace != tbinfo->dobj.namespace)
+						appendPQExpBuffer(q, "%s.",
+										  fmtId(parentRel->dobj.namespace->dobj.name));
+					appendPQExpBuffer(q, "%s;\n",
+									  fmtId(parentRel->dobj.name));
 				}
 			}
+
 			appendPQExpBuffer(q, "\n-- For binary upgrade, set relfrozenxid.\n");
-			appendPQExpBuffer(q, "UPDATE pg_class\n"
+			appendPQExpBuffer(q, "UPDATE pg_catalog.pg_class\n"
 							  "SET relfrozenxid = '%u'\n"
-							  "WHERE	relname = ",
+							  "WHERE oid = ",
 							  tbinfo->frozenxid);
-			appendStringLiteralAH(q, tbinfo->dobj.name, fout);
-			appendPQExpBuffer(q, "\n	AND relnamespace = "
-							  "(SELECT oid FROM pg_namespace "
-							  "WHERE nspname = CURRENT_SCHEMA);\n");
+			appendStringLiteralAH(q, fmtId(tbinfo->dobj.name), fout);
+			appendPQExpBuffer(q, "::pg_catalog.regclass;\n");
 		}
 
 		/* Loop dumping statistics and storage statements */
@@ -10051,8 +10094,8 @@ dumpAttrDef(Archive *fout, AttrDefInfo *adinfo)
 	if (!tbinfo->dobj.dump || !adinfo->separate || dataOnly)
 		return;
 
-	/* Don't print inherited defaults, either */
-	if (tbinfo->inhAttrDef[adnum - 1])
+	/* Don't print inherited defaults, either, except for binary upgrade */
+	if (tbinfo->inhAttrDef[adnum - 1] && !binary_upgrade)
 		return;
 
 	q = createPQExpBuffer();