diff --git a/contrib/pg_upgrade_support/pg_upgrade_support.c b/contrib/pg_upgrade_support/pg_upgrade_support.c new file mode 100644 index edd41d0..beaee76 *** a/contrib/pg_upgrade_support/pg_upgrade_support.c --- b/contrib/pg_upgrade_support/pg_upgrade_support.c *************** PG_FUNCTION_INFO_V1(set_next_pg_authid_o *** 38,49 **** --- 38,57 ---- 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(); *************** set_next_array_pg_type_oid(PG_FUNCTION_A *** 54,59 **** --- 62,68 ---- { Oid typoid = PG_GETARG_OID(0); + CHECK_IS_BINARY_UPGRADE; binary_upgrade_next_array_pg_type_oid = typoid; PG_RETURN_VOID(); *************** set_next_toast_pg_type_oid(PG_FUNCTION_A *** 64,69 **** --- 73,79 ---- { Oid typoid = PG_GETARG_OID(0); + CHECK_IS_BINARY_UPGRADE; binary_upgrade_next_toast_pg_type_oid = typoid; PG_RETURN_VOID(); *************** set_next_heap_pg_class_oid(PG_FUNCTION_A *** 74,79 **** --- 84,90 ---- { Oid reloid = PG_GETARG_OID(0); + CHECK_IS_BINARY_UPGRADE; binary_upgrade_next_heap_pg_class_oid = reloid; PG_RETURN_VOID(); *************** set_next_index_pg_class_oid(PG_FUNCTION_ *** 84,89 **** --- 95,101 ---- { Oid reloid = PG_GETARG_OID(0); + CHECK_IS_BINARY_UPGRADE; binary_upgrade_next_index_pg_class_oid = reloid; PG_RETURN_VOID(); *************** set_next_toast_pg_class_oid(PG_FUNCTION_ *** 94,99 **** --- 106,112 ---- { Oid reloid = PG_GETARG_OID(0); + CHECK_IS_BINARY_UPGRADE; binary_upgrade_next_toast_pg_class_oid = reloid; PG_RETURN_VOID(); *************** set_next_pg_enum_oid(PG_FUNCTION_ARGS) *** 104,109 **** --- 117,123 ---- { Oid enumoid = PG_GETARG_OID(0); + CHECK_IS_BINARY_UPGRADE; binary_upgrade_next_pg_enum_oid = enumoid; PG_RETURN_VOID(); *************** set_next_pg_authid_oid(PG_FUNCTION_ARGS) *** 114,119 **** --- 128,134 ---- { Oid authoid = PG_GETARG_OID(0); + CHECK_IS_BINARY_UPGRADE; binary_upgrade_next_pg_authid_oid = authoid; PG_RETURN_VOID(); } *************** create_empty_extension(PG_FUNCTION_ARGS) *** 129,134 **** --- 144,151 ---- 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 new file mode 100644 index 33eef9f..d810fe9 *** a/src/backend/catalog/heap.c --- b/src/backend/catalog/heap.c *************** *** 39,44 **** --- 39,45 ---- #include "catalog/dependency.h" #include "catalog/heap.h" #include "catalog/index.h" + #include "catalog/namespace.h" #include "catalog/objectaccess.h" #include "catalog/pg_attrdef.h" #include "catalog/pg_collation.h" *************** heap_create_with_catalog(const char *rel *** 1088,1107 **** */ if (!OidIsValid(relid)) { ! /* ! * Use binary-upgrade override for pg_class.oid/relfilenode, if ! * supplied. ! */ 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)) { relid = binary_upgrade_next_heap_pg_class_oid; binary_upgrade_next_heap_pg_class_oid = InvalidOid; } else if (IsBinaryUpgrade && OidIsValid(binary_upgrade_next_toast_pg_class_oid) && relkind == RELKIND_TOASTVALUE) { --- 1089,1112 ---- */ if (!OidIsValid(relid)) { ! /* Use binary-upgrade override for pg_class.oid/relfilenode? */ if (IsBinaryUpgrade && ! !isTempOrToastNamespace(relnamespace) && (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 */ else if (IsBinaryUpgrade && + !isTempOrToastNamespace(relnamespace) && OidIsValid(binary_upgrade_next_toast_pg_class_oid) && relkind == RELKIND_TOASTVALUE) { *************** heap_create_with_catalog(const char *rel *** 1169,1175 **** relkind == RELKIND_MATVIEW || relkind == RELKIND_FOREIGN_TABLE || relkind == RELKIND_COMPOSITE_TYPE)) ! new_array_oid = AssignTypeArrayOid(); /* * Since defining a relation also defines a complex type, we add a new --- 1174,1180 ---- relkind == RELKIND_MATVIEW || relkind == RELKIND_FOREIGN_TABLE || relkind == RELKIND_COMPOSITE_TYPE)) ! new_array_oid = AssignTypeArrayOid(relnamespace); /* * Since defining a relation also defines a complex type, we add a new diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c new file mode 100644 index a5a204e..8719cb8 *** a/src/backend/catalog/index.c --- b/src/backend/catalog/index.c *************** *** 35,40 **** --- 35,41 ---- #include "catalog/dependency.h" #include "catalog/heap.h" #include "catalog/index.h" + #include "catalog/namespace.h" #include "catalog/objectaccess.h" #include "catalog/pg_collation.h" #include "catalog/pg_constraint.h" *************** index_create(Relation heapRelation, *** 796,808 **** */ if (!OidIsValid(indexRelationId)) { ! /* ! * Use binary-upgrade override for pg_class.oid/relfilenode, if ! * supplied. ! */ ! if (IsBinaryUpgrade && ! OidIsValid(binary_upgrade_next_index_pg_class_oid)) { indexRelationId = binary_upgrade_next_index_pg_class_oid; binary_upgrade_next_index_pg_class_oid = InvalidOid; } --- 797,810 ---- */ if (!OidIsValid(indexRelationId)) { ! /* Use binary-upgrade override for pg_class.oid/relfilenode? */ ! if (IsBinaryUpgrade && !isTempOrToastNamespace(namespaceId)) { + 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 new file mode 100644 index b4f2051..e2566a8 *** a/src/backend/catalog/pg_enum.c --- b/src/backend/catalog/pg_enum.c *************** restart: *** 341,349 **** } /* Get a new OID for the new label */ ! if (IsBinaryUpgrade && OidIsValid(binary_upgrade_next_pg_enum_oid)) { /* * 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 * guaranteed to be consistent. --- 341,359 ---- } /* Get a new OID for the new label */ ! if (IsBinaryUpgrade) { /* + * We can't easily check here if this is a temporary name space, + * so the creation of temporary tables using ENUM values are not supported + * in upgrade mode. + */ + 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 * guaranteed to be consistent. diff --git a/src/backend/catalog/pg_type.c b/src/backend/catalog/pg_type.c new file mode 100644 index f614915..88099b3 *** a/src/backend/catalog/pg_type.c --- b/src/backend/catalog/pg_type.c *************** *** 20,25 **** --- 20,26 ---- #include "catalog/binary_upgrade.h" #include "catalog/dependency.h" #include "catalog/indexing.h" + #include "catalog/namespace.h" #include "catalog/objectaccess.h" #include "catalog/pg_collation.h" #include "catalog/pg_namespace.h" *************** TypeShellMake(const char *typeName, Oid *** 126,134 **** */ 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)) { HeapTupleSetOid(tup, binary_upgrade_next_pg_type_oid); binary_upgrade_next_pg_type_oid = InvalidOid; } --- 127,140 ---- */ tup = heap_form_tuple(tupDesc, values, nulls); ! /* Use binary-upgrade override for pg_type.oid? */ ! if (IsBinaryUpgrade && !isTempOrToastNamespace(typeNamespace)) { + 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; } *************** TypeCreate(Oid newTypeOid, *** 437,444 **** 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)) { HeapTupleSetOid(tup, binary_upgrade_next_pg_type_oid); binary_upgrade_next_pg_type_oid = InvalidOid; } --- 443,455 ---- if (OidIsValid(newTypeOid)) HeapTupleSetOid(tup, newTypeOid); /* Use binary-upgrade override for pg_type.oid, if supplied. */ ! else if (IsBinaryUpgrade && !isTempOrToastNamespace(typeNamespace)) { + 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 new file mode 100644 index 94543e1..8469867 *** a/src/backend/catalog/toasting.c --- b/src/backend/catalog/toasting.c *************** create_toast_table(Relation rel, Oid toa *** 170,176 **** if (!needs_toast_table(rel)) return false; } ! else { /* * Check to see whether the table needs a TOAST table. --- 170,176 ---- if (!needs_toast_table(rel)) return false; } ! else if (!isTempOrToastNamespace(rel->rd_rel->relnamespace)) { /* * Check to see whether the table needs a TOAST table. *************** create_toast_table(Relation rel, Oid toa *** 259,266 **** else namespaceid = PG_TOAST_NAMESPACE; ! /* Use binary-upgrade override for pg_type.oid, if supplied. */ ! if (IsBinaryUpgrade && OidIsValid(binary_upgrade_next_toast_pg_type_oid)) { toast_typid = binary_upgrade_next_toast_pg_type_oid; binary_upgrade_next_toast_pg_type_oid = InvalidOid; --- 259,271 ---- else namespaceid = PG_TOAST_NAMESPACE; ! /* ! * 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) && ! !isTempOrToastNamespace(rel->rd_rel->relnamespace)) { toast_typid = binary_upgrade_next_toast_pg_type_oid; binary_upgrade_next_toast_pg_type_oid = InvalidOid; diff --git a/src/backend/commands/typecmds.c b/src/backend/commands/typecmds.c new file mode 100644 index f377c19..0657f73 *** a/src/backend/commands/typecmds.c --- b/src/backend/commands/typecmds.c *************** DefineType(List *names, List *parameters *** 546,552 **** NameListToString(analyzeName)); #endif ! array_oid = AssignTypeArrayOid(); /* * now have TypeCreate do all the real work. --- 546,552 ---- NameListToString(analyzeName)); #endif ! array_oid = AssignTypeArrayOid(typeNamespace); /* * now have TypeCreate do all the real work. *************** DefineEnum(CreateEnumStmt *stmt) *** 1090,1096 **** errmsg("type \"%s\" already exists", enumName))); } ! enumArrayOid = AssignTypeArrayOid(); /* Create the pg_type entry */ enumTypeOid = --- 1090,1096 ---- errmsg("type \"%s\" already exists", enumName))); } ! enumArrayOid = AssignTypeArrayOid(enumNamespace); /* Create the pg_type entry */ enumTypeOid = *************** DefineRange(CreateRangeStmt *stmt) *** 1424,1430 **** alignment = (subtypalign == 'd') ? 'd' : 'i'; /* Allocate OID for array type */ ! rangeArrayOid = AssignTypeArrayOid(); /* Create the pg_type entry */ typoid = --- 1424,1430 ---- alignment = (subtypalign == 'd') ? 'd' : 'i'; /* Allocate OID for array type */ ! rangeArrayOid = AssignTypeArrayOid(typeNamespace); /* Create the pg_type entry */ typoid = *************** findRangeSubtypeDiffFunction(List *procn *** 1982,1994 **** * Pre-assign the type's array OID for use in pg_type.typarray */ Oid ! 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)) { type_array_oid = binary_upgrade_next_array_pg_type_oid; binary_upgrade_next_array_pg_type_oid = InvalidOid; } --- 1982,1999 ---- * Pre-assign the type's array OID for use in pg_type.typarray */ Oid ! AssignTypeArrayOid(Oid namespace_oid) { Oid type_array_oid; ! /* Use binary-upgrade override for pg_type.typarray? */ ! if (IsBinaryUpgrade && !isTempOrToastNamespace(namespace_oid)) { + 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 new file mode 100644 index d3a2044..91b6fa5 *** a/src/backend/commands/user.c --- b/src/backend/commands/user.c *************** CreateRole(CreateRoleStmt *stmt) *** 379,388 **** /* * pg_largeobject_metadata contains pg_authid.oid's, so we use the ! * binary-upgrade override, if specified. */ ! if (IsBinaryUpgrade && OidIsValid(binary_upgrade_next_pg_authid_oid)) { HeapTupleSetOid(tuple, binary_upgrade_next_pg_authid_oid); binary_upgrade_next_pg_authid_oid = InvalidOid; } --- 379,393 ---- /* * pg_largeobject_metadata contains pg_authid.oid's, so we use the ! * binary-upgrade override. */ ! 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; } diff --git a/src/include/commands/typecmds.h b/src/include/commands/typecmds.h new file mode 100644 index 792c178..e49a62d *** a/src/include/commands/typecmds.h --- b/src/include/commands/typecmds.h *************** extern Oid DefineEnum(CreateEnumStmt *st *** 28,34 **** extern Oid DefineRange(CreateRangeStmt *stmt); extern Oid AlterEnum(AlterEnumStmt *stmt, bool isTopLevel); extern Oid DefineCompositeType(RangeVar *typevar, List *coldeflist); ! extern Oid AssignTypeArrayOid(void); extern Oid AlterDomainDefault(List *names, Node *defaultRaw); extern Oid AlterDomainNotNull(List *names, bool notNull); --- 28,34 ---- extern Oid DefineRange(CreateRangeStmt *stmt); extern Oid AlterEnum(AlterEnumStmt *stmt, bool isTopLevel); extern Oid DefineCompositeType(RangeVar *typevar, List *coldeflist); ! extern Oid AssignTypeArrayOid(Oid namespace_oid); extern Oid AlterDomainDefault(List *names, Node *defaultRaw); extern Oid AlterDomainNotNull(List *names, bool notNull);