diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index c2f6180..1c6205b 100644 *** a/src/bin/pg_dump/pg_dump.c --- b/src/bin/pg_dump/pg_dump.c *************** *** 7937,7942 **** static void --- 7937,7943 ---- dumpCompositeType(Archive *fout, TypeInfo *tyinfo) { PQExpBuffer q = createPQExpBuffer(); + PQExpBuffer dropped = createPQExpBuffer(); PQExpBuffer delq = createPQExpBuffer(); PQExpBuffer labelq = createPQExpBuffer(); PQExpBuffer query = createPQExpBuffer(); *************** *** 7944,7952 **** dumpCompositeType(Archive *fout, TypeInfo *tyinfo) --- 7945,7957 ---- int ntups; int i_attname; int i_atttypdefn; + int i_attlen; + int i_attalign; + int i_attisdropped; int i_attcollation; int i_typrelid; int i; + int actual_atts; /* Set proper schema search path so type references list correctly */ selectSourceSchema(tyinfo->dobj.namespace->dobj.name); *************** *** 7962,7967 **** dumpCompositeType(Archive *fout, TypeInfo *tyinfo) --- 7967,7973 ---- */ appendPQExpBuffer(query, "SELECT a.attname, " "pg_catalog.format_type(a.atttypid, a.atttypmod) AS atttypdefn, " + "a.attlen, a.attalign, a.attisdropped, " "CASE WHEN a.attcollation <> at.typcollation " "THEN a.attcollation ELSE 0 END AS attcollation, " "ct.typrelid " *************** *** 7979,7984 **** dumpCompositeType(Archive *fout, TypeInfo *tyinfo) --- 7985,7991 ---- /* We assume here that remoteVersion must be at least 70300 */ appendPQExpBuffer(query, "SELECT a.attname, " "pg_catalog.format_type(a.atttypid, a.atttypmod) AS atttypdefn, " + "a.attlen, a.attalign, a.attisdropped, " "0 AS attcollation, " "ct.typrelid " "FROM pg_catalog.pg_type ct, pg_catalog.pg_attribute a " *************** *** 7996,8001 **** dumpCompositeType(Archive *fout, TypeInfo *tyinfo) --- 8003,8011 ---- i_attname = PQfnumber(res, "attname"); i_atttypdefn = PQfnumber(res, "atttypdefn"); + i_attlen = PQfnumber(res, "attlen"); + i_attalign = PQfnumber(res, "attalign"); + i_attisdropped = PQfnumber(res, "attisdropped"); i_attcollation = PQfnumber(res, "attcollation"); i_typrelid = PQfnumber(res, "typrelid"); *************** *** 8010,8047 **** dumpCompositeType(Archive *fout, TypeInfo *tyinfo) appendPQExpBuffer(q, "CREATE TYPE %s AS (", fmtId(tyinfo->dobj.name)); for (i = 0; i < ntups; i++) { char *attname; char *atttypdefn; Oid attcollation; attname = PQgetvalue(res, i, i_attname); atttypdefn = PQgetvalue(res, i, i_atttypdefn); attcollation = atooid(PQgetvalue(res, i, i_attcollation)); ! appendPQExpBuffer(q, "\n\t%s %s", fmtId(attname), atttypdefn); ! /* Add collation if not default for the column type */ ! if (OidIsValid(attcollation)) { ! CollInfo *coll; ! coll = findCollationByOid(attcollation); ! if (coll) { ! /* always schema-qualify, don't try to be smart */ ! appendPQExpBuffer(q, " COLLATE %s.", ! fmtId(coll->dobj.namespace->dobj.name)); ! appendPQExpBuffer(q, "%s", ! fmtId(coll->dobj.name)); } } ! ! if (i < ntups - 1) ! appendPQExpBuffer(q, ","); } appendPQExpBuffer(q, "\n);\n"); /* * DROP must be fully qualified in case same name appears in pg_catalog --- 8020,8094 ---- appendPQExpBuffer(q, "CREATE TYPE %s AS (", fmtId(tyinfo->dobj.name)); + actual_atts = 0; for (i = 0; i < ntups; i++) { char *attname; char *atttypdefn; + char *attlen; + char *attalign; + bool attisdropped; Oid attcollation; attname = PQgetvalue(res, i, i_attname); atttypdefn = PQgetvalue(res, i, i_atttypdefn); + attlen = PQgetvalue(res, i, i_attlen); + attalign = PQgetvalue(res, i, i_attalign); + attisdropped = (PQgetvalue(res, i, i_attisdropped)[0] == 't'); attcollation = atooid(PQgetvalue(res, i, i_attcollation)); ! if (attisdropped && !binary_upgrade) ! continue; ! ! /* Format properly if not first attr */ ! if (actual_atts++ > 0) ! appendPQExpBuffer(q, ","); ! appendPQExpBuffer(q, "\n\t"); ! if (!attisdropped) { ! appendPQExpBuffer(q, "%s %s", fmtId(attname), atttypdefn); ! /* Add collation if not default for the column type */ ! if (OidIsValid(attcollation)) { ! CollInfo *coll; ! ! coll = findCollationByOid(attcollation); ! if (coll) ! { ! /* always schema-qualify, don't try to be smart */ ! appendPQExpBuffer(q, " COLLATE %s.", ! fmtId(coll->dobj.namespace->dobj.name)); ! appendPQExpBuffer(q, "%s", ! fmtId(coll->dobj.name)); ! } } } ! else /* binary_upgrade - see under dumpTableSchema() */ ! { ! appendPQExpBuffer(q, "%s INTEGER /* dummy */", fmtId(attname)); ! ! /* stash separately for insertion after the CREATE TYPE */ ! appendPQExpBuffer(dropped, ! "\n-- For binary upgrade, recreate dropped column.\n"); ! appendPQExpBuffer(dropped, "UPDATE pg_catalog.pg_attribute\n" ! "SET attlen = %s, " ! "attalign = '%s', attbyval = false\n" ! "WHERE attname = ", attlen, attalign); ! appendStringLiteralAH(dropped, attname, fout); ! appendPQExpBuffer(dropped, "\n AND attrelid = "); ! appendStringLiteralAH(dropped, fmtId(tyinfo->dobj.name), fout); ! appendPQExpBuffer(dropped, "::pg_catalog.regclass;\n"); ! ! appendPQExpBuffer(dropped, "ALTER TYPE %s ", ! fmtId(tyinfo->dobj.name)); ! appendPQExpBuffer(dropped, "DROP ATTRIBUTE %s;\n", ! fmtId(attname)); ! } } appendPQExpBuffer(q, "\n);\n"); + appendPQExpBufferStr(q, dropped->data); /* * DROP must be fully qualified in case same name appears in pg_catalog *************** *** 8077,8082 **** dumpCompositeType(Archive *fout, TypeInfo *tyinfo) --- 8124,8130 ---- PQclear(res); destroyPQExpBuffer(q); + destroyPQExpBuffer(dropped); destroyPQExpBuffer(delq); destroyPQExpBuffer(labelq); destroyPQExpBuffer(query); *************** *** 12004,12010 **** dumpTableSchema(Archive *fout, TableInfo *tbinfo) "UNLOGGED " : "", reltypename, fmtId(tbinfo->dobj.name)); ! if (tbinfo->reloftype) appendPQExpBuffer(q, " OF %s", tbinfo->reloftype); actual_atts = 0; for (j = 0; j < tbinfo->numatts; j++) --- 12052,12058 ---- "UNLOGGED " : "", reltypename, fmtId(tbinfo->dobj.name)); ! if (tbinfo->reloftype && !binary_upgrade) appendPQExpBuffer(q, " OF %s", tbinfo->reloftype); actual_atts = 0; for (j = 0; j < tbinfo->numatts; j++) *************** *** 12032,12038 **** dumpTableSchema(Archive *fout, TableInfo *tbinfo) bool has_notnull = (tbinfo->notnull[j] && (!tbinfo->inhNotNull[j] || binary_upgrade)); ! if (tbinfo->reloftype && !has_default && !has_notnull) continue; /* Format properly if not first attr */ --- 12080,12087 ---- bool has_notnull = (tbinfo->notnull[j] && (!tbinfo->inhNotNull[j] || binary_upgrade)); ! if (tbinfo->reloftype && !binary_upgrade && ! !has_default && !has_notnull) continue; /* Format properly if not first attr */ *************** *** 12060,12066 **** dumpTableSchema(Archive *fout, TableInfo *tbinfo) } /* Attribute type */ ! if (tbinfo->reloftype) { appendPQExpBuffer(q, "WITH OPTIONS"); } --- 12109,12115 ---- } /* Attribute type */ ! if (tbinfo->reloftype && !binary_upgrade) { appendPQExpBuffer(q, "WITH OPTIONS"); } *************** *** 12126,12132 **** dumpTableSchema(Archive *fout, TableInfo *tbinfo) if (actual_atts) appendPQExpBuffer(q, "\n)"); ! else if (!tbinfo->reloftype) { /* * We must have a parenthesized attribute list, even though empty, --- 12175,12181 ---- if (actual_atts) appendPQExpBuffer(q, "\n)"); ! else if (!(tbinfo->reloftype && !binary_upgrade)) { /* * We must have a parenthesized attribute list, even though empty, *************** *** 12268,12273 **** dumpTableSchema(Archive *fout, TableInfo *tbinfo) --- 12317,12329 ---- } } + if (tbinfo->reloftype) + { + appendPQExpBuffer(q, "\n-- For binary upgrade, set up typed tables this way.\n"); + appendPQExpBuffer(q, "ALTER TABLE ONLY %s OF %s;\n", + fmtId(tbinfo->dobj.name), tbinfo->reloftype); + } + appendPQExpBuffer(q, "\n-- For binary upgrade, set heap's relfrozenxid\n"); appendPQExpBuffer(q, "UPDATE pg_catalog.pg_class\n" "SET relfrozenxid = '%u'\n"