Commit e5b457c2 authored by Bruce Momjian's avatar Bruce Momjian

Add backend and pg_dump code to allow preservation of pg_enum oids, for

use in binary upgrades.

Bump catalog version for detection by pg_migrator of new backend API.
parent 1fd9883f
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* *
* *
* IDENTIFICATION * 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); ...@@ -33,7 +33,8 @@ static int oid_cmp(const void *p1, const void *p2);
* vals is a list of Value strings. * vals is a list of Value strings.
*/ */
void void
EnumValuesCreate(Oid enumTypeOid, List *vals) EnumValuesCreate(Oid enumTypeOid, List *vals,
Oid binary_upgrade_next_pg_enum_oid)
{ {
Relation pg_enum; Relation pg_enum;
TupleDesc tupDesc; TupleDesc tupDesc;
...@@ -58,13 +59,27 @@ EnumValuesCreate(Oid enumTypeOid, List *vals) ...@@ -58,13 +59,27 @@ EnumValuesCreate(Oid enumTypeOid, List *vals)
tupDesc = pg_enum->rd_att; tupDesc = pg_enum->rd_att;
/* /*
* Allocate oids. While this method does not absolutely guarantee that we * Allocate oids
* 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 = (Oid *) palloc(num_elems * sizeof(Oid)); oids = (Oid *) palloc(num_elems * sizeof(Oid));
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
{
/*
* 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.
*/
for (elemno = 0; elemno < num_elems; elemno++) for (elemno = 0; elemno < num_elems; elemno++)
{ {
/* /*
...@@ -73,9 +88,9 @@ EnumValuesCreate(Oid enumTypeOid, List *vals) ...@@ -73,9 +88,9 @@ EnumValuesCreate(Oid enumTypeOid, List *vals)
*/ */
oids[elemno] = GetNewOid(pg_enum); oids[elemno] = GetNewOid(pg_enum);
} }
/* sort them, just in case counter wrapped from high to low */ /* sort them, just in case counter wrapped from high to low */
qsort(oids, num_elems, sizeof(Oid), oid_cmp); qsort(oids, num_elems, sizeof(Oid), oid_cmp);
}
/* and make the entries */ /* and make the entries */
memset(nulls, false, sizeof(nulls)); memset(nulls, false, sizeof(nulls));
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * 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 * DESCRIPTION
* The "DefineFoo" routines take the parse tree and pick out the * The "DefineFoo" routines take the parse tree and pick out the
...@@ -1161,7 +1161,7 @@ DefineEnum(CreateEnumStmt *stmt) ...@@ -1161,7 +1161,7 @@ DefineEnum(CreateEnumStmt *stmt)
false); /* Type NOT NULL */ false); /* Type NOT NULL */
/* Enter the enum's values into pg_enum */ /* 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. * Create the array type that goes with it.
......
...@@ -12,7 +12,7 @@ ...@@ -12,7 +12,7 @@
* by PostgreSQL * by PostgreSQL
* *
* IDENTIFICATION * 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) ...@@ -6528,12 +6528,14 @@ dumpEnumType(Archive *fout, TypeInfo *tyinfo)
PGresult *res; PGresult *res;
int num, int num,
i; i;
Oid enum_oid;
char *label; char *label;
/* Set proper schema search path so regproc references list correctly */ /* Set proper schema search path so regproc references list correctly */
selectSourceSchema(tyinfo->dobj.namespace->dobj.name); 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'" "WHERE enumtypid = '%u'"
"ORDER BY oid", "ORDER BY oid",
tyinfo->dobj.catId.oid); tyinfo->dobj.catId.oid);
...@@ -6556,18 +6558,44 @@ dumpEnumType(Archive *fout, TypeInfo *tyinfo) ...@@ -6556,18 +6558,44 @@ dumpEnumType(Archive *fout, TypeInfo *tyinfo)
if (binary_upgrade) if (binary_upgrade)
binary_upgrade_set_type_oids_by_type_oid(q, tyinfo->dobj.catId.oid); 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)); fmtId(tyinfo->dobj.name));
if (!binary_upgrade)
{
/* Labels with server-assigned oids */
for (i = 0; i < num; i++) for (i = 0; i < num; i++)
{ {
label = PQgetvalue(res, i, 0); label = PQgetvalue(res, i, PQfnumber(res, "enumlabel"));
if (i > 0) if (i > 0)
appendPQExpBuffer(q, ",\n"); appendPQExpBuffer(q, ",");
appendPQExpBuffer(q, " "); appendPQExpBuffer(q, "\n ");
appendStringLiteralAH(q, label, fout); appendStringLiteralAH(q, label, fout);
} }
}
appendPQExpBuffer(q, "\n);\n"); 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, ArchiveEntry(fout, tyinfo->dobj.catId, tyinfo->dobj.dumpId,
tyinfo->dobj.name, tyinfo->dobj.name,
tyinfo->dobj.namespace->dobj.name, tyinfo->dobj.namespace->dobj.name,
......
...@@ -37,7 +37,7 @@ ...@@ -37,7 +37,7 @@
* Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * 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 @@ ...@@ -53,6 +53,6 @@
*/ */
/* yyyymmddN */ /* yyyymmddN */
#define CATALOG_VERSION_NO 200912181 #define CATALOG_VERSION_NO 200912271
#endif #endif
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* *
* Copyright (c) 2006-2009, PostgreSQL Global Development Group * 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 * NOTES
* the genbki.sh script reads this file and generates .bki * the genbki.sh script reads this file and generates .bki
...@@ -60,7 +60,8 @@ typedef FormData_pg_enum *Form_pg_enum; ...@@ -60,7 +60,8 @@ typedef FormData_pg_enum *Form_pg_enum;
/* /*
* prototypes for functions in pg_enum.c * 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); extern void EnumValuesDelete(Oid enumTypeOid);
#endif /* PG_ENUM_H */ #endif /* PG_ENUM_H */
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