pg_upgrade: prevent automatic oid assignment
authorBruce Momjian <bruce@momjian.us>
Tue, 26 Aug 2014 02:19:05 +0000 (22:19 -0400)
committerBruce Momjian <bruce@momjian.us>
Tue, 26 Aug 2014 02:19:05 +0000 (22:19 -0400)
Prevent automatic oid assignment when in binary upgrade mode.  Also
throw an error when contrib/pg_upgrade_support functions are called when
not in binary upgrade mode.

This prevent automatically-assigned oids from conflicting with later
pre-assigned oids coming from the old cluster.  It also makes sure oids
are preserved in call important cases.

contrib/pg_upgrade_support/pg_upgrade_support.c
src/backend/catalog/heap.c
src/backend/catalog/index.c
src/backend/catalog/pg_enum.c
src/backend/catalog/pg_type.c
src/backend/catalog/toasting.c
src/backend/commands/typecmds.c
src/backend/commands/user.c

index edd41d06ae4ec7c47384f45071bc002e130ae08a..beaee7611df7b266794f8a42fd959e78957d2e19 100644 (file)
@@ -38,12 +38,20 @@ PG_FUNCTION_INFO_V1(set_next_pg_authid_oid);
 
 PG_FUNCTION_INFO_V1(create_empty_extension);
 
+#define CHECK_IS_BINARY_UPGRADE                                \
+do {                                                           \
+   if (!IsBinaryUpgrade)                                       \
+       ereport(ERROR,                                          \
+               (errcode(ERRCODE_CANT_CHANGE_RUNTIME_PARAM),    \
+                (errmsg("function can only be called when server is in binary upgrade mode")))); \
+} while (0)
 
 Datum
 set_next_pg_type_oid(PG_FUNCTION_ARGS)
 {
    Oid         typoid = PG_GETARG_OID(0);
 
+   CHECK_IS_BINARY_UPGRADE;
    binary_upgrade_next_pg_type_oid = typoid;
 
    PG_RETURN_VOID();
@@ -54,6 +62,7 @@ set_next_array_pg_type_oid(PG_FUNCTION_ARGS)
 {
    Oid         typoid = PG_GETARG_OID(0);
 
+   CHECK_IS_BINARY_UPGRADE;
    binary_upgrade_next_array_pg_type_oid = typoid;
 
    PG_RETURN_VOID();
@@ -64,6 +73,7 @@ set_next_toast_pg_type_oid(PG_FUNCTION_ARGS)
 {
    Oid         typoid = PG_GETARG_OID(0);
 
+   CHECK_IS_BINARY_UPGRADE;
    binary_upgrade_next_toast_pg_type_oid = typoid;
 
    PG_RETURN_VOID();
@@ -74,6 +84,7 @@ set_next_heap_pg_class_oid(PG_FUNCTION_ARGS)
 {
    Oid         reloid = PG_GETARG_OID(0);
 
+   CHECK_IS_BINARY_UPGRADE;
    binary_upgrade_next_heap_pg_class_oid = reloid;
 
    PG_RETURN_VOID();
@@ -84,6 +95,7 @@ set_next_index_pg_class_oid(PG_FUNCTION_ARGS)
 {
    Oid         reloid = PG_GETARG_OID(0);
 
+   CHECK_IS_BINARY_UPGRADE;
    binary_upgrade_next_index_pg_class_oid = reloid;
 
    PG_RETURN_VOID();
@@ -94,6 +106,7 @@ set_next_toast_pg_class_oid(PG_FUNCTION_ARGS)
 {
    Oid         reloid = PG_GETARG_OID(0);
 
+   CHECK_IS_BINARY_UPGRADE;
    binary_upgrade_next_toast_pg_class_oid = reloid;
 
    PG_RETURN_VOID();
@@ -104,6 +117,7 @@ set_next_pg_enum_oid(PG_FUNCTION_ARGS)
 {
    Oid         enumoid = PG_GETARG_OID(0);
 
+   CHECK_IS_BINARY_UPGRADE;
    binary_upgrade_next_pg_enum_oid = enumoid;
 
    PG_RETURN_VOID();
@@ -114,6 +128,7 @@ set_next_pg_authid_oid(PG_FUNCTION_ARGS)
 {
    Oid         authoid = PG_GETARG_OID(0);
 
+   CHECK_IS_BINARY_UPGRADE;
    binary_upgrade_next_pg_authid_oid = authoid;
    PG_RETURN_VOID();
 }
@@ -129,6 +144,8 @@ create_empty_extension(PG_FUNCTION_ARGS)
    Datum       extCondition;
    List       *requiredExtensions;
 
+   CHECK_IS_BINARY_UPGRADE;
+
    if (PG_ARGISNULL(4))
        extConfig = PointerGetDatum(NULL);
    else
index 33eef9f1caffcfbcd178140047d1ef64abb5145c..c346edac93be55889e8fe18398579be551ce0f5f 100644 (file)
@@ -1088,19 +1088,21 @@ heap_create_with_catalog(const char *relname,
     */
    if (!OidIsValid(relid))
    {
-       /*
-        * Use binary-upgrade override for pg_class.oid/relfilenode, if
-        * supplied.
-        */
+        /* Use binary-upgrade override for pg_class.oid/relfilenode? */
        if (IsBinaryUpgrade &&
-           OidIsValid(binary_upgrade_next_heap_pg_class_oid) &&
            (relkind == RELKIND_RELATION || relkind == RELKIND_SEQUENCE ||
             relkind == RELKIND_VIEW || relkind == RELKIND_MATVIEW ||
             relkind == RELKIND_COMPOSITE_TYPE || relkind == RELKIND_FOREIGN_TABLE))
        {
+           if (!OidIsValid(binary_upgrade_next_heap_pg_class_oid))
+               ereport(ERROR,
+                       (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
+                        errmsg("pg_class heap OID value not set when in binary upgrade mode")));
+
            relid = binary_upgrade_next_heap_pg_class_oid;
            binary_upgrade_next_heap_pg_class_oid = InvalidOid;
        }
+       /* There might be no TOAST table, so we have to test for it. */
        else if (IsBinaryUpgrade &&
                 OidIsValid(binary_upgrade_next_toast_pg_class_oid) &&
                 relkind == RELKIND_TOASTVALUE)
index a5a204eb40b20185a5b465abaf13ade1f5de460a..ee105940be03760152b24434e5ec34b6e266f16b 100644 (file)
@@ -796,13 +796,14 @@ index_create(Relation heapRelation,
     */
    if (!OidIsValid(indexRelationId))
    {
-       /*
-        * Use binary-upgrade override for pg_class.oid/relfilenode, if
-        * supplied.
-        */
-       if (IsBinaryUpgrade &&
-           OidIsValid(binary_upgrade_next_index_pg_class_oid))
+       /* Use binary-upgrade override for pg_class.oid/relfilenode? */
+       if (IsBinaryUpgrade)
        {
+           if (!OidIsValid(binary_upgrade_next_index_pg_class_oid))
+               ereport(ERROR,
+                       (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
+                        errmsg("pg_class index OID value not set when in binary upgrade mode")));
+
            indexRelationId = binary_upgrade_next_index_pg_class_oid;
            binary_upgrade_next_index_pg_class_oid = InvalidOid;
        }
index b4f2051749d352f3b73813472c1e98c915ca229a..086e80efcfbd168ede2d3cb7044b12722e997555 100644 (file)
@@ -341,8 +341,13 @@ restart:
    }
 
    /* Get a new OID for the new label */
-   if (IsBinaryUpgrade && OidIsValid(binary_upgrade_next_pg_enum_oid))
+   if (IsBinaryUpgrade)
    {
+       if (!OidIsValid(binary_upgrade_next_pg_enum_oid))
+           ereport(ERROR,
+                   (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
+                    errmsg("pg_enum OID value not set when in binary upgrade mode")));
+
        /*
         * Use binary-upgrade override for pg_enum.oid, if supplied. During
         * binary upgrade, all pg_enum.oid's are set this way so they are
index f614915abfb84ee9cb544e71370dd0df9420bcb8..f1329f87e10da2f0b43a10f8919b662d3a46b7af 100644 (file)
@@ -126,9 +126,14 @@ TypeShellMake(const char *typeName, Oid typeNamespace, Oid ownerId)
     */
    tup = heap_form_tuple(tupDesc, values, nulls);
 
-   /* Use binary-upgrade override for pg_type.oid, if supplied. */
-   if (IsBinaryUpgrade && OidIsValid(binary_upgrade_next_pg_type_oid))
+   /* Use binary-upgrade override for pg_type.oid? */
+   if (IsBinaryUpgrade)
    {
+       if (!OidIsValid(binary_upgrade_next_pg_type_oid))
+           ereport(ERROR,
+                   (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
+                    errmsg("pg_type OID value not set when in binary upgrade mode")));
+
        HeapTupleSetOid(tup, binary_upgrade_next_pg_type_oid);
        binary_upgrade_next_pg_type_oid = InvalidOid;
    }
@@ -437,8 +442,13 @@ TypeCreate(Oid newTypeOid,
        if (OidIsValid(newTypeOid))
            HeapTupleSetOid(tup, newTypeOid);
        /* Use binary-upgrade override for pg_type.oid, if supplied. */
-       else if (IsBinaryUpgrade && OidIsValid(binary_upgrade_next_pg_type_oid))
+       else if (IsBinaryUpgrade)
        {
+           if (!OidIsValid(binary_upgrade_next_pg_type_oid))
+               ereport(ERROR,
+                       (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
+                        errmsg("pg_type OID value not set when in binary upgrade mode")));
+
            HeapTupleSetOid(tup, binary_upgrade_next_pg_type_oid);
            binary_upgrade_next_pg_type_oid = InvalidOid;
        }
index c8e7ea852cb4e9056ba82ba499262732d5ff2409..160f006ecdf1e3c3578abf6bc122b47d4a0fea70 100644 (file)
@@ -259,7 +259,11 @@ create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid,
    else
        namespaceid = PG_TOAST_NAMESPACE;
 
-   /* Use binary-upgrade override for pg_type.oid, if supplied. */
+   /*
+    * Use binary-upgrade override for pg_type.oid, if supplied.  We might
+    * be in the post-schema-restore phase where we are doing ALTER TABLE
+    * to create TOAST tables that didn't exist in the old cluster.
+    */
    if (IsBinaryUpgrade && OidIsValid(binary_upgrade_next_toast_pg_type_oid))
    {
        toast_typid = binary_upgrade_next_toast_pg_type_oid;
index ec439fabd633ef1dc20b1792f393a6d9c7ae78e7..ad364efbcbd5e15654308142a25185e2fe4d1d47 100644 (file)
@@ -1986,9 +1986,14 @@ AssignTypeArrayOid(void)
 {
    Oid         type_array_oid;
 
-   /* Use binary-upgrade override for pg_type.typarray, if supplied. */
-   if (IsBinaryUpgrade && OidIsValid(binary_upgrade_next_array_pg_type_oid))
+   /* Use binary-upgrade override for pg_type.typarray? */
+   if (IsBinaryUpgrade)
    {
+       if (!OidIsValid(binary_upgrade_next_array_pg_type_oid))
+           ereport(ERROR,
+                   (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
+                    errmsg("pg_type array OID value not set when in binary upgrade mode")));
+
        type_array_oid = binary_upgrade_next_array_pg_type_oid;
        binary_upgrade_next_array_pg_type_oid = InvalidOid;
    }
index d3a2044191b5ca029c0883d01c219d63c8075012..91b6fa5c17d5c04bcaab3bc58fa3ba467efc3968 100644 (file)
@@ -379,10 +379,15 @@ CreateRole(CreateRoleStmt *stmt)
 
    /*
     * pg_largeobject_metadata contains pg_authid.oid's, so we use the
-    * binary-upgrade override, if specified.
+    * binary-upgrade override.
     */
-   if (IsBinaryUpgrade && OidIsValid(binary_upgrade_next_pg_authid_oid))
+   if (IsBinaryUpgrade)
    {
+       if (!OidIsValid(binary_upgrade_next_pg_authid_oid))
+           ereport(ERROR,
+                   (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
+                    errmsg("pg_authid OID value not set when in binary upgrade mode")));
+
        HeapTupleSetOid(tuple, binary_upgrade_next_pg_authid_oid);
        binary_upgrade_next_pg_authid_oid = InvalidOid;
    }