mirror of
https://github.com/postgres/postgres.git
synced 2025-05-05 09:19:17 +03:00
In binary-upgrade mode, dump dropped attributes of composite types.
Noah Misch
This commit is contained in:
parent
bcf63a51e3
commit
27c7875d95
@ -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)
|
|||||||
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)
|
|||||||
* 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)
|
|||||||
|
|
||||||
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)
|
|||||||
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;
|
||||||
|
|
||||||
/* Add collation if not default for the column type */
|
/* Format properly if not first attr */
|
||||||
if (OidIsValid(attcollation))
|
if (actual_atts++ > 0)
|
||||||
|
appendPQExpBuffer(q, ",");
|
||||||
|
appendPQExpBuffer(q, "\n\t");
|
||||||
|
|
||||||
|
if (!attisdropped)
|
||||||
{
|
{
|
||||||
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
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* 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));
|
||||||
|
|
||||||
if (i < ntups - 1)
|
/* stash separately for insertion after the CREATE TYPE */
|
||||||
appendPQExpBuffer(q, ",");
|
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)
|
|||||||
|
|
||||||
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"
|
|||||||
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;
|
|||||||
|
|
||||||
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;
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user