diff --git a/src/backend/catalog/pg_enum.c b/src/backend/catalog/pg_enum.c index 9a3d533c146aea26b7b76c60a5d03d065067e379..689ecd4830d99e8e08281dc76cc129d0a9c8f119 100644 --- a/src/backend/catalog/pg_enum.c +++ b/src/backend/catalog/pg_enum.c @@ -7,7 +7,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/catalog/pg_enum.c,v 1.11 2009/12/24 22:17:58 momjian Exp $ + * $PostgreSQL: pgsql/src/backend/catalog/pg_enum.c,v 1.12 2009/12/27 14:50:41 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -33,7 +33,8 @@ static int oid_cmp(const void *p1, const void *p2); * vals is a list of Value strings. */ void -EnumValuesCreate(Oid enumTypeOid, List *vals) +EnumValuesCreate(Oid enumTypeOid, List *vals, + Oid binary_upgrade_next_pg_enum_oid) { Relation pg_enum; TupleDesc tupDesc; @@ -58,25 +59,39 @@ EnumValuesCreate(Oid enumTypeOid, List *vals) tupDesc = pg_enum->rd_att; /* - * Allocate oids. While this method does not absolutely guarantee that we - * generate no duplicate oids (since we haven't entered each oid into the - * table before allocating the next), trouble could only occur if the oid - * counter wraps all the way around before we finish. Which seems - * unlikely. + * Allocate oids */ oids = (Oid *) palloc(num_elems * sizeof(Oid)); - for (elemno = 0; elemno < num_elems; elemno++) + if (OidIsValid(binary_upgrade_next_pg_enum_oid)) + { + if (num_elems != 1) + ereport(ERROR, + (errcode(ERRCODE_INVALID_PARAMETER_VALUE), + errmsg("EnumValuesCreate() can only set a single OID"))); + oids[0] = binary_upgrade_next_pg_enum_oid; + binary_upgrade_next_pg_enum_oid = InvalidOid; + } + else { /* - * The pg_enum.oid is stored in user tables. This oid must be - * preserved by binary upgrades. + * While this method does not absolutely guarantee that we generate + * no duplicate oids (since we haven't entered each oid into the + * table before allocating the next), trouble could only occur if + * the oid counter wraps all the way around before we finish. Which + * seems unlikely. */ - oids[elemno] = GetNewOid(pg_enum); + for (elemno = 0; elemno < num_elems; elemno++) + { + /* + * The pg_enum.oid is stored in user tables. This oid must be + * preserved by binary upgrades. + */ + oids[elemno] = GetNewOid(pg_enum); + } + /* sort them, just in case counter wrapped from high to low */ + qsort(oids, num_elems, sizeof(Oid), oid_cmp); } - /* sort them, just in case counter wrapped from high to low */ - qsort(oids, num_elems, sizeof(Oid), oid_cmp); - /* and make the entries */ memset(nulls, false, sizeof(nulls)); diff --git a/src/backend/commands/typecmds.c b/src/backend/commands/typecmds.c index 11990c0e106f7603fd8e9da22d4534f5b0aec6f6..a815752ecbbbecdbadee2aa8c15d737b0d7ec44c 100644 --- a/src/backend/commands/typecmds.c +++ b/src/backend/commands/typecmds.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/commands/typecmds.c,v 1.141 2009/12/24 22:09:23 momjian Exp $ + * $PostgreSQL: pgsql/src/backend/commands/typecmds.c,v 1.142 2009/12/27 14:50:43 momjian Exp $ * * DESCRIPTION * The "DefineFoo" routines take the parse tree and pick out the @@ -1161,7 +1161,7 @@ DefineEnum(CreateEnumStmt *stmt) false); /* Type NOT NULL */ /* Enter the enum's values into pg_enum */ - EnumValuesCreate(enumTypeOid, stmt->vals); + EnumValuesCreate(enumTypeOid, stmt->vals, InvalidOid); /* * Create the array type that goes with it. diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index 037c7045e50940384da13fcac47c13de159e38b6..16a912e19adf1152bc0486eea4a2d46c6050d414 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.562 2009/12/26 16:55:21 momjian Exp $ + * $PostgreSQL: pgsql/src/bin/pg_dump/pg_dump.c,v 1.563 2009/12/27 14:50:44 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -6528,12 +6528,14 @@ dumpEnumType(Archive *fout, TypeInfo *tyinfo) PGresult *res; int num, i; + Oid enum_oid; char *label; /* Set proper schema search path so regproc references list correctly */ selectSourceSchema(tyinfo->dobj.namespace->dobj.name); - appendPQExpBuffer(query, "SELECT enumlabel FROM pg_catalog.pg_enum " + appendPQExpBuffer(query, "SELECT oid, enumlabel " + "FROM pg_catalog.pg_enum " "WHERE enumtypid = '%u'" "ORDER BY oid", tyinfo->dobj.catId.oid); @@ -6556,18 +6558,44 @@ dumpEnumType(Archive *fout, TypeInfo *tyinfo) if (binary_upgrade) binary_upgrade_set_type_oids_by_type_oid(q, tyinfo->dobj.catId.oid); - appendPQExpBuffer(q, "CREATE TYPE %s AS ENUM (\n", + appendPQExpBuffer(q, "CREATE TYPE %s AS ENUM (", fmtId(tyinfo->dobj.name)); - for (i = 0; i < num; i++) + + if (!binary_upgrade) { - label = PQgetvalue(res, i, 0); - if (i > 0) - appendPQExpBuffer(q, ",\n"); - appendPQExpBuffer(q, " "); - appendStringLiteralAH(q, label, fout); + /* Labels with server-assigned oids */ + for (i = 0; i < num; i++) + { + label = PQgetvalue(res, i, PQfnumber(res, "enumlabel")); + if (i > 0) + appendPQExpBuffer(q, ","); + appendPQExpBuffer(q, "\n "); + appendStringLiteralAH(q, label, fout); + } } + appendPQExpBuffer(q, "\n);\n"); + if (binary_upgrade) + { + /* Labels with dump-assigned (preserved) oids */ + for (i = 0; i < num; i++) + { + enum_oid = atooid(PQgetvalue(res, i, PQfnumber(res, "oid"))); + label = PQgetvalue(res, i, PQfnumber(res, "enumlabel")); + + if (i == 0) + appendPQExpBuffer(q, "\n-- For binary upgrade, must preserve pg_enum oids\n"); + appendPQExpBuffer(q, + "SELECT binary_upgrade.add_pg_enum_label('%u'::pg_catalog.oid, " + "'%u'::pg_catalog.oid, ", + enum_oid, tyinfo->dobj.catId.oid); + appendStringLiteralAH(q, label, fout); + appendPQExpBuffer(q, ");\n"); + } + appendPQExpBuffer(q, "\n"); + } + ArchiveEntry(fout, tyinfo->dobj.catId, tyinfo->dobj.dumpId, tyinfo->dobj.name, tyinfo->dobj.namespace->dobj.name, diff --git a/src/include/catalog/catversion.h b/src/include/catalog/catversion.h index dde12c28673b1ffc124c3ae70b504b6a29f5735d..6ac2c6713d8bc6abf52fee17b8fca923f4853a62 100644 --- a/src/include/catalog/catversion.h +++ b/src/include/catalog/catversion.h @@ -37,7 +37,7 @@ * Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $PostgreSQL: pgsql/src/include/catalog/catversion.h,v 1.560 2009/12/19 04:08:32 tgl Exp $ + * $PostgreSQL: pgsql/src/include/catalog/catversion.h,v 1.561 2009/12/27 14:50:46 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -53,6 +53,6 @@ */ /* yyyymmddN */ -#define CATALOG_VERSION_NO 200912181 +#define CATALOG_VERSION_NO 200912271 #endif diff --git a/src/include/catalog/pg_enum.h b/src/include/catalog/pg_enum.h index c26e891f2fb6d6cba6970926bdeedf296a4e479e..cea056ae4c29bb9316d190564391923399bd792e 100644 --- a/src/include/catalog/pg_enum.h +++ b/src/include/catalog/pg_enum.h @@ -7,7 +7,7 @@ * * Copyright (c) 2006-2009, PostgreSQL Global Development Group * - * $PostgreSQL: pgsql/src/include/catalog/pg_enum.h,v 1.5 2009/01/01 17:23:57 momjian Exp $ + * $PostgreSQL: pgsql/src/include/catalog/pg_enum.h,v 1.6 2009/12/27 14:50:46 momjian Exp $ * * NOTES * the genbki.sh script reads this file and generates .bki @@ -60,7 +60,8 @@ typedef FormData_pg_enum *Form_pg_enum; /* * prototypes for functions in pg_enum.c */ -extern void EnumValuesCreate(Oid enumTypeOid, List *vals); +extern void EnumValuesCreate(Oid enumTypeOid, List *vals, + Oid binary_upgrade_next_pg_enum_oid); extern void EnumValuesDelete(Oid enumTypeOid); #endif /* PG_ENUM_H */