From a7ae1dcf4939cf643c5abe8dd673e4b87a6efd42 Mon Sep 17 00:00:00 2001 From: Bruce Momjian Date: Mon, 25 Aug 2014 22:19:05 -0400 Subject: [PATCH] pg_upgrade: prevent automatic oid assignment 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 | 17 +++++++++++++++++ src/backend/catalog/heap.c | 12 +++++++----- src/backend/catalog/index.c | 13 +++++++------ src/backend/catalog/pg_enum.c | 7 ++++++- src/backend/catalog/pg_type.c | 16 +++++++++++++--- src/backend/catalog/toasting.c | 6 +++++- src/backend/commands/typecmds.c | 9 +++++++-- src/backend/commands/user.c | 9 +++++++-- 8 files changed, 69 insertions(+), 20 deletions(-) diff --git a/contrib/pg_upgrade_support/pg_upgrade_support.c b/contrib/pg_upgrade_support/pg_upgrade_support.c index edd41d06ae..beaee7611d 100644 --- a/contrib/pg_upgrade_support/pg_upgrade_support.c +++ b/contrib/pg_upgrade_support/pg_upgrade_support.c @@ -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 diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c index 33eef9f1ca..c346edac93 100644 --- a/src/backend/catalog/heap.c +++ b/src/backend/catalog/heap.c @@ -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) diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index a5a204eb40..ee105940be 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -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; } diff --git a/src/backend/catalog/pg_enum.c b/src/backend/catalog/pg_enum.c index b4f2051749..086e80efcf 100644 --- a/src/backend/catalog/pg_enum.c +++ b/src/backend/catalog/pg_enum.c @@ -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 diff --git a/src/backend/catalog/pg_type.c b/src/backend/catalog/pg_type.c index f614915abf..f1329f87e1 100644 --- a/src/backend/catalog/pg_type.c +++ b/src/backend/catalog/pg_type.c @@ -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; } diff --git a/src/backend/catalog/toasting.c b/src/backend/catalog/toasting.c index c8e7ea852c..160f006ecd 100644 --- a/src/backend/catalog/toasting.c +++ b/src/backend/catalog/toasting.c @@ -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; diff --git a/src/backend/commands/typecmds.c b/src/backend/commands/typecmds.c index ec439fabd6..ad364efbcb 100644 --- a/src/backend/commands/typecmds.c +++ b/src/backend/commands/typecmds.c @@ -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; } diff --git a/src/backend/commands/user.c b/src/backend/commands/user.c index d3a2044191..91b6fa5c17 100644 --- a/src/backend/commands/user.c +++ b/src/backend/commands/user.c @@ -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; } -- 2.40.0