Commit 27c7875d authored by Heikki Linnakangas's avatar Heikki Linnakangas

In binary-upgrade mode, dump dropped attributes of composite types.

Noah Misch
parent bcf63a51
...@@ -7937,6 +7937,7 @@ static void ...@@ -7937,6 +7937,7 @@ static void
dumpCompositeType(Archive *fout, TypeInfo *tyinfo) dumpCompositeType(Archive *fout, TypeInfo *tyinfo)
{ {
PQExpBuffer q = createPQExpBuffer(); PQExpBuffer q = createPQExpBuffer();
PQExpBuffer dropped = createPQExpBuffer();
PQExpBuffer delq = createPQExpBuffer(); PQExpBuffer delq = createPQExpBuffer();
PQExpBuffer labelq = createPQExpBuffer(); PQExpBuffer labelq = createPQExpBuffer();
PQExpBuffer query = createPQExpBuffer(); PQExpBuffer query = createPQExpBuffer();
...@@ -7944,9 +7945,13 @@ dumpCompositeType(Archive *fout, TypeInfo *tyinfo) ...@@ -7944,9 +7945,13 @@ dumpCompositeType(Archive *fout, TypeInfo *tyinfo)
int ntups; int ntups;
int i_attname; int i_attname;
int i_atttypdefn; int i_atttypdefn;
int i_attlen;
int i_attalign;
int i_attisdropped;
int i_attcollation; int i_attcollation;
int i_typrelid; int i_typrelid;
int i; int i;
int actual_atts;
/* Set proper schema search path so type references list correctly */ /* Set proper schema search path so type references list correctly */
selectSourceSchema(tyinfo->dobj.namespace->dobj.name); selectSourceSchema(tyinfo->dobj.namespace->dobj.name);
...@@ -7958,33 +7963,37 @@ dumpCompositeType(Archive *fout, TypeInfo *tyinfo) ...@@ -7958,33 +7963,37 @@ dumpCompositeType(Archive *fout, TypeInfo *tyinfo)
* attcollation is new in 9.1. Since we only want to dump COLLATE * attcollation is new in 9.1. Since we only want to dump COLLATE
* clauses for attributes whose collation is different from their * clauses for attributes whose collation is different from their
* type's default, we use a CASE here to suppress uninteresting * type's default, we use a CASE here to suppress uninteresting
* attcollations cheaply. * attcollations cheaply. atttypid will be 0 for dropped columns;
* collation does not matter for those.
*/ */
appendPQExpBuffer(query, "SELECT a.attname, " appendPQExpBuffer(query, "SELECT a.attname, "
"pg_catalog.format_type(a.atttypid, a.atttypmod) AS atttypdefn, " "pg_catalog.format_type(a.atttypid, a.atttypmod) AS atttypdefn, "
"a.attlen, a.attalign, a.attisdropped, "
"CASE WHEN a.attcollation <> at.typcollation " "CASE WHEN a.attcollation <> at.typcollation "
"THEN a.attcollation ELSE 0 END AS attcollation, " "THEN a.attcollation ELSE 0 END AS attcollation, "
"ct.typrelid " "ct.typrelid "
"FROM pg_catalog.pg_type ct, pg_catalog.pg_attribute a, " "FROM pg_catalog.pg_type ct "
"pg_catalog.pg_type at " "JOIN pg_catalog.pg_attribute a ON a.attrelid = ct.typrelid "
"LEFT JOIN pg_catalog.pg_type at ON at.oid = a.atttypid "
"WHERE ct.oid = '%u'::pg_catalog.oid " "WHERE ct.oid = '%u'::pg_catalog.oid "
"AND a.attrelid = ct.typrelid "
"AND a.atttypid = at.oid "
"AND NOT a.attisdropped "
"ORDER BY a.attnum ", "ORDER BY a.attnum ",
tyinfo->dobj.catId.oid); tyinfo->dobj.catId.oid);
} }
else else
{ {
/* We assume here that remoteVersion must be at least 70300 */ /*
* We assume here that remoteVersion must be at least 70300. Since
* ALTER TYPE could not drop columns until 9.1, attisdropped should
* always be false.
*/
appendPQExpBuffer(query, "SELECT a.attname, " appendPQExpBuffer(query, "SELECT a.attname, "
"pg_catalog.format_type(a.atttypid, a.atttypmod) AS atttypdefn, " "pg_catalog.format_type(a.atttypid, a.atttypmod) AS atttypdefn, "
"a.attlen, a.attalign, a.attisdropped, "
"0 AS attcollation, " "0 AS attcollation, "
"ct.typrelid " "ct.typrelid "
"FROM pg_catalog.pg_type ct, pg_catalog.pg_attribute a " "FROM pg_catalog.pg_type ct, pg_catalog.pg_attribute a "
"WHERE ct.oid = '%u'::pg_catalog.oid " "WHERE ct.oid = '%u'::pg_catalog.oid "
"AND a.attrelid = ct.typrelid " "AND a.attrelid = ct.typrelid "
"AND NOT a.attisdropped "
"ORDER BY a.attnum ", "ORDER BY a.attnum ",
tyinfo->dobj.catId.oid); tyinfo->dobj.catId.oid);
} }
...@@ -7996,6 +8005,9 @@ dumpCompositeType(Archive *fout, TypeInfo *tyinfo) ...@@ -7996,6 +8005,9 @@ dumpCompositeType(Archive *fout, TypeInfo *tyinfo)
i_attname = PQfnumber(res, "attname"); i_attname = PQfnumber(res, "attname");
i_atttypdefn = PQfnumber(res, "atttypdefn"); 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_attcollation = PQfnumber(res, "attcollation");
i_typrelid = PQfnumber(res, "typrelid"); i_typrelid = PQfnumber(res, "typrelid");
...@@ -8010,38 +8022,81 @@ dumpCompositeType(Archive *fout, TypeInfo *tyinfo) ...@@ -8010,38 +8022,81 @@ dumpCompositeType(Archive *fout, TypeInfo *tyinfo)
appendPQExpBuffer(q, "CREATE TYPE %s AS (", appendPQExpBuffer(q, "CREATE TYPE %s AS (",
fmtId(tyinfo->dobj.name)); fmtId(tyinfo->dobj.name));
actual_atts = 0;
for (i = 0; i < ntups; i++) for (i = 0; i < ntups; i++)
{ {
char *attname; char *attname;
char *atttypdefn; char *atttypdefn;
char *attlen;
char *attalign;
bool attisdropped;
Oid attcollation; Oid attcollation;
attname = PQgetvalue(res, i, i_attname); attname = PQgetvalue(res, i, i_attname);
atttypdefn = PQgetvalue(res, i, i_atttypdefn); 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)); attcollation = atooid(PQgetvalue(res, i, i_attcollation));
appendPQExpBuffer(q, "\n\t%s %s", fmtId(attname), atttypdefn); if (attisdropped && !binary_upgrade)
continue;
/* Format properly if not first attr */
if (actual_atts++ > 0)
appendPQExpBuffer(q, ",");
appendPQExpBuffer(q, "\n\t");
/* Add collation if not default for the column type */ if (!attisdropped)
if (OidIsValid(attcollation))
{ {
CollInfo *coll; appendPQExpBuffer(q, "%s %s", fmtId(attname), atttypdefn);
coll = findCollationByOid(attcollation); /* Add collation if not default for the column type */
if (coll) if (OidIsValid(attcollation))
{ {
/* always schema-qualify, don't try to be smart */ CollInfo *coll;
appendPQExpBuffer(q, " COLLATE %s.",
fmtId(coll->dobj.namespace->dobj.name)); coll = findCollationByOid(attcollation);
appendPQExpBuffer(q, "%s", if (coll)
fmtId(coll->dobj.name)); {
/* 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
if (i < ntups - 1) {
appendPQExpBuffer(q, ","); /*
* This is a dropped attribute and we're in binary_upgrade mode.
* Insert a placeholder for it in the CREATE TYPE command, and
* set length and alignment with direct UPDATE to the catalogs
* afterwards. See similar code in 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"); appendPQExpBuffer(q, "\n);\n");
appendPQExpBufferStr(q, dropped->data);
/* /*
* DROP must be fully qualified in case same name appears in pg_catalog * DROP must be fully qualified in case same name appears in pg_catalog
...@@ -8077,6 +8132,7 @@ dumpCompositeType(Archive *fout, TypeInfo *tyinfo) ...@@ -8077,6 +8132,7 @@ dumpCompositeType(Archive *fout, TypeInfo *tyinfo)
PQclear(res); PQclear(res);
destroyPQExpBuffer(q); destroyPQExpBuffer(q);
destroyPQExpBuffer(dropped);
destroyPQExpBuffer(delq); destroyPQExpBuffer(delq);
destroyPQExpBuffer(labelq); destroyPQExpBuffer(labelq);
destroyPQExpBuffer(query); destroyPQExpBuffer(query);
......
...@@ -1955,6 +1955,12 @@ Table "public.test_tbl2_subclass" ...@@ -1955,6 +1955,12 @@ Table "public.test_tbl2_subclass"
Inherits: test_tbl2 Inherits: test_tbl2
DROP TABLE test_tbl2_subclass; DROP TABLE test_tbl2_subclass;
-- This test isn't that interesting on its own, but the purpose is to leave
-- behind a table to test pg_upgrade with. The table has a composite type
-- column in it, and the composite type has a dropped attribute.
CREATE TYPE test_type3 AS (a int);
CREATE TABLE test_tbl3 (c) AS SELECT '(1)'::test_type3;
ALTER TYPE test_type3 DROP ATTRIBUTE a, ADD ATTRIBUTE b int;
CREATE TYPE test_type_empty AS (); CREATE TYPE test_type_empty AS ();
DROP TYPE test_type_empty; DROP TYPE test_type_empty;
-- --
......
...@@ -1371,6 +1371,13 @@ ALTER TYPE test_type2 RENAME ATTRIBUTE a TO aa CASCADE; ...@@ -1371,6 +1371,13 @@ ALTER TYPE test_type2 RENAME ATTRIBUTE a TO aa CASCADE;
DROP TABLE test_tbl2_subclass; DROP TABLE test_tbl2_subclass;
-- This test isn't that interesting on its own, but the purpose is to leave
-- behind a table to test pg_upgrade with. The table has a composite type
-- column in it, and the composite type has a dropped attribute.
CREATE TYPE test_type3 AS (a int);
CREATE TABLE test_tbl3 (c) AS SELECT '(1)'::test_type3;
ALTER TYPE test_type3 DROP ATTRIBUTE a, ADD ATTRIBUTE b int;
CREATE TYPE test_type_empty AS (); CREATE TYPE test_type_empty AS ();
DROP TYPE test_type_empty; DROP TYPE test_type_empty;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment