Add backend and pg_dump code to allow preservation of pg_enum oids, for
authorBruce Momjian <[email protected]>
Sun, 27 Dec 2009 14:50:46 +0000 (14:50 +0000)
committerBruce Momjian <[email protected]>
Sun, 27 Dec 2009 14:50:46 +0000 (14:50 +0000)
use in binary upgrades.

Bump catalog version for detection by pg_migrator of new backend API.

src/backend/catalog/pg_enum.c
src/backend/commands/typecmds.c
src/bin/pg_dump/pg_dump.c
src/include/catalog/catversion.h
src/include/catalog/pg_enum.h

index 54c59445043329d97c44992261b8b97ce4f6ddf6..768b280c8d57025653449f4ada9f5106092669cb 100644 (file)
@@ -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));
 
index d45c29a6e42c4050ea62a47acd9101c21ff74f71..f03b1dd90f090364932ad1c7734b6b1d2efde70e 100644 (file)
@@ -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.
index c441553435dab8a3e88e0a3f7c469a504521f7ba..e50dd77d76d6e7d4c804b6857de49d25f121dc1c 100644 (file)
@@ -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,
index 717320f985bb22261fa2a7d797304fe507c07709..a591e67ab0b73ba181b9415645a6d01d104a3004 100644 (file)
@@ -53,6 +53,6 @@
  */
 
 /*                         yyyymmddN */
-#define CATALOG_VERSION_NO 200912181
+#define CATALOG_VERSION_NO 200912271
 
 #endif
index 9761a2ef5ac8dd54717968d14331cdef84f9286e..3f58cad62669ecc0508194b5d2c62e60d774f101 100644 (file)
@@ -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 */