Now that everyone is happy with how pg_upgrade_support uses global variables to set preserved oids (or at least has no better ideas), I think it is time to lock down this usage to prevent future breakage.
Specifically, the first attached patch causes pg_upgrade_support functions to throw errors when called by a backend that is not in binary upgrade mode. (This seems like a good safety measure.) Second, and more importantly, the patch prevents automatic oid assignment when in binary upgrade mode, except for temporary objects. This is to help guarantee that system-assigned oids do not conflict with preserved oids. I had to make an exception for temporary tables because pg_upgrade uses temporary tables to collect schema information. I tried writing the query to use CTEs (second patch), but I would then have to have one query for 8.3, which doesn't support CTEs, and another for 8.4+, plus the CTE query was more complex than I liked. Another idea would be to drop 8.3 support (and remove lots of code to support that), but the recent large increase in the number of people upgrading from 8.4 makes that unattractive. (8.3 did use a different timestamp storage format though.) (Of course, the assumption is that temporary tables will not exist at the time you are assigning preserved oids.) Barring objections, I plan to apply the first patch to head, and discard the second patch. FYI, I think the macro isTempOrToastNamespace() is misnamed --- it is testing for temporary tables or temporary toast tables, not for any toast table. Seems it should be called isTempOrToastTempNamespace(). Should I rename it in a separate commit? -- Bruce Momjian <br...@momjian.us> http://momjian.us EnterpriseDB http://enterprisedb.com + Everyone has their own god. +
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);
diff --git a/contrib/pg_upgrade/info.c b/contrib/pg_upgrade/info.c new file mode 100644 index 93ea266..3143160 *** a/contrib/pg_upgrade/info.c --- b/contrib/pg_upgrade/info.c *************** get_rel_infos(ClusterInfo *cluster, DbIn *** 319,394 **** * structures efficiently. */ ! snprintf(query, sizeof(query), ! "CREATE TEMPORARY TABLE info_rels (reloid) AS SELECT c.oid " ! "FROM pg_catalog.pg_class c JOIN pg_catalog.pg_namespace n " ! " ON c.relnamespace = n.oid " ! "LEFT OUTER JOIN pg_catalog.pg_index i " ! " ON c.oid = i.indexrelid " ! "WHERE relkind IN ('r', 'm', 'i'%s) AND " ! ! /* ! * pg_dump only dumps valid indexes; testing indisready is necessary in ! * 9.2, and harmless in earlier/later versions. ! */ ! " i.indisvalid IS DISTINCT FROM false AND " ! " i.indisready IS DISTINCT FROM false AND " ! /* exclude possible orphaned temp tables */ ! " ((n.nspname !~ '^pg_temp_' AND " ! " n.nspname !~ '^pg_toast_temp_' AND " ! /* skip pg_toast because toast index have relkind == 'i', not 't' */ ! " n.nspname NOT IN ('pg_catalog', 'information_schema', " ! " 'binary_upgrade', 'pg_toast') AND " ! " c.oid >= %u) " ! " OR (n.nspname = 'pg_catalog' AND " ! " relname IN ('pg_largeobject', 'pg_largeobject_loid_pn_index'%s) ));", ! /* see the comment at the top of old_8_3_create_sequence_script() */ ! (GET_MAJOR_VERSION(old_cluster.major_version) <= 803) ? ! "" : ", 'S'", ! FirstNormalObjectId, ! /* does pg_largeobject_metadata need to be migrated? */ ! (GET_MAJOR_VERSION(old_cluster.major_version) <= 804) ? ! "" : ", 'pg_largeobject_metadata', 'pg_largeobject_metadata_oid_index'"); ! ! PQclear(executeQueryOrDie(conn, "%s", query)); ! ! /* ! * Get TOAST tables and indexes; we have to gather the TOAST tables in ! * later steps because we can't schema-qualify TOAST tables. ! */ ! PQclear(executeQueryOrDie(conn, ! "INSERT INTO info_rels " ! "SELECT reltoastrelid " ! "FROM info_rels i JOIN pg_catalog.pg_class c " ! " ON i.reloid = c.oid " ! " AND c.reltoastrelid != %u", InvalidOid)); ! PQclear(executeQueryOrDie(conn, ! "INSERT INTO info_rels " ! "SELECT indexrelid " ! "FROM pg_index " ! "WHERE indisvalid " ! " AND indrelid IN (SELECT reltoastrelid " ! " FROM info_rels i " ! " JOIN pg_catalog.pg_class c " ! " ON i.reloid = c.oid " ! " AND c.reltoastrelid != %u)", ! InvalidOid)); ! ! snprintf(query, sizeof(query), ! "SELECT c.oid, n.nspname, c.relname, " ! " c.relfilenode, c.reltablespace, %s " ! "FROM info_rels i JOIN pg_catalog.pg_class c " ! " ON i.reloid = c.oid " ! " JOIN pg_catalog.pg_namespace n " ! " ON c.relnamespace = n.oid " ! " LEFT OUTER JOIN pg_catalog.pg_tablespace t " ! " ON c.reltablespace = t.oid " ! /* we preserve pg_class.oid so we sort by it to match old/new */ ! "ORDER BY 1;", ! /* 9.2 removed the spclocation column */ ! (GET_MAJOR_VERSION(cluster->major_version) <= 901) ? ! "t.spclocation" : "pg_catalog.pg_tablespace_location(t.oid) AS spclocation"); ! res = executeQueryOrDie(conn, "%s", query); ntups = PQntuples(res); --- 319,476 ---- * structures efficiently. */ ! if (GET_MAJOR_VERSION(cluster->major_version) >= 905) ! { ! snprintf(query, sizeof(query), ! /* get regular heap */ ! "WITH regular_heap (reloid) AS ( " ! " SELECT c.oid " ! " FROM pg_catalog.pg_class c JOIN pg_catalog.pg_namespace n " ! " ON c.relnamespace = n.oid " ! " LEFT OUTER JOIN pg_catalog.pg_index i " ! " ON c.oid = i.indexrelid " ! " WHERE relkind IN ('r', 'm', 'i'%s) AND " ! /* ! * pg_dump only dumps valid indexes; testing indisready is necessary in ! * 9.2, and harmless in earlier/later versions. ! */ ! " i.indisvalid IS DISTINCT FROM false AND " ! " i.indisready IS DISTINCT FROM false AND " ! /* exclude possible orphaned temp tables */ ! " ((n.nspname !~ '^pg_temp_' AND " ! " n.nspname !~ '^pg_toast_temp_' AND " ! /* skip pg_toast because toast index have relkind == 'i', not 't' */ ! " n.nspname NOT IN ('pg_catalog', 'information_schema', " ! " 'binary_upgrade', 'pg_toast') AND " ! " c.oid >= %u) " ! " OR (n.nspname = 'pg_catalog' AND " ! " relname IN ('pg_largeobject', 'pg_largeobject_loid_pn_index'%s) ))), " ! /* ! * We have to gather the TOAST tables in later steps because we ! * can't schema-qualify TOAST tables. ! */ ! /* get TOAST heap */ ! " toast_heap (reloid) AS ( " ! " SELECT reltoastrelid " ! " FROM regular_heap i JOIN pg_catalog.pg_class c " ! " ON i.reloid = c.oid " ! " AND c.reltoastrelid != %u), " ! /* get indexes on regular and TOAST heap */ ! " all_index (reloid) AS ( " ! " SELECT indexrelid " ! " FROM pg_index " ! " WHERE indisvalid " ! " AND indrelid IN (SELECT reltoastrelid " ! " FROM (SELECT reloid FROM regular_heap " ! " UNION ALL " ! " SELECT reloid FROM toast_heap) all_heap " ! " JOIN pg_catalog.pg_class c " ! " ON all_heap.reloid = c.oid " ! " AND c.reltoastrelid != %u)) " ! /* get all rels */ ! "SELECT c.oid, n.nspname, c.relname, " ! " c.relfilenode, c.reltablespace, %s " ! "FROM (SELECT reloid FROM regular_heap " ! " UNION ALL " ! " SELECT reloid FROM toast_heap " ! " UNION ALL " ! " SELECT reloid FROM all_index) all_rels " ! " JOIN pg_catalog.pg_class c " ! " ON all_rels.reloid = c.oid " ! " JOIN pg_catalog.pg_namespace n " ! " ON c.relnamespace = n.oid " ! " LEFT OUTER JOIN pg_catalog.pg_tablespace t " ! " ON c.reltablespace = t.oid " ! /* we preserve pg_class.oid so we sort by it to match old/new */ ! "ORDER BY 1;", ! /* see the comment at the top of old_8_3_create_sequence_script() */ ! (GET_MAJOR_VERSION(old_cluster.major_version) <= 803) ? ! "" : ", 'S'", ! FirstNormalObjectId, ! /* does pg_largeobject_metadata need to be migrated? */ ! (GET_MAJOR_VERSION(old_cluster.major_version) <= 804) ? ! "" : ", 'pg_largeobject_metadata', 'pg_largeobject_metadata_oid_index'", ! InvalidOid, InvalidOid, ! /* 9.2 removed the spclocation column */ ! (GET_MAJOR_VERSION(cluster->major_version) <= 901) ? ! "t.spclocation" : "pg_catalog.pg_tablespace_location(t.oid) AS spclocation"); ! } ! else ! { ! /* ! * This temporary table consumes OIDs, but they are discarded once ! * the session ends. ! */ ! snprintf(query, sizeof(query), ! "CREATE TEMPORARY TABLE info_rels (reloid) AS SELECT c.oid " ! "FROM pg_catalog.pg_class c JOIN pg_catalog.pg_namespace n " ! " ON c.relnamespace = n.oid " ! "LEFT OUTER JOIN pg_catalog.pg_index i " ! " ON c.oid = i.indexrelid " ! "WHERE relkind IN ('r', 'm', 'i'%s) AND " ! ! /* ! * pg_dump only dumps valid indexes; testing indisready is necessary in ! * 9.2, and harmless in earlier/later versions. ! */ ! " i.indisvalid IS DISTINCT FROM false AND " ! " i.indisready IS DISTINCT FROM false AND " ! /* exclude possible orphaned temp tables */ ! " ((n.nspname !~ '^pg_temp_' AND " ! " n.nspname !~ '^pg_toast_temp_' AND " ! /* skip pg_toast because toast index have relkind == 'i', not 't' */ ! " n.nspname NOT IN ('pg_catalog', 'information_schema', " ! " 'binary_upgrade', 'pg_toast') AND " ! " c.oid >= %u) " ! " OR (n.nspname = 'pg_catalog' AND " ! " relname IN ('pg_largeobject', 'pg_largeobject_loid_pn_index'%s) ));", ! /* see the comment at the top of old_8_3_create_sequence_script() */ ! (GET_MAJOR_VERSION(old_cluster.major_version) <= 803) ? ! "" : ", 'S'", ! FirstNormalObjectId, ! /* does pg_largeobject_metadata need to be migrated? */ ! (GET_MAJOR_VERSION(old_cluster.major_version) <= 804) ? ! "" : ", 'pg_largeobject_metadata', 'pg_largeobject_metadata_oid_index'"); ! ! PQclear(executeQueryOrDie(conn, "%s", query)); ! ! /* ! * Get TOAST tables and indexes; we have to gather the TOAST tables in ! * later steps because we can't schema-qualify TOAST tables. ! */ ! PQclear(executeQueryOrDie(conn, ! "INSERT INTO info_rels " ! "SELECT reltoastrelid " ! "FROM info_rels i JOIN pg_catalog.pg_class c " ! " ON i.reloid = c.oid " ! " AND c.reltoastrelid != %u", InvalidOid)); ! PQclear(executeQueryOrDie(conn, ! "INSERT INTO info_rels " ! "SELECT indexrelid " ! "FROM pg_index " ! "WHERE indisvalid " ! " AND indrelid IN (SELECT reltoastrelid " ! " FROM info_rels i " ! " JOIN pg_catalog.pg_class c " ! " ON i.reloid = c.oid " ! " AND c.reltoastrelid != %u)", ! InvalidOid)); ! ! snprintf(query, sizeof(query), ! "SELECT c.oid, n.nspname, c.relname, " ! " c.relfilenode, c.reltablespace, %s " ! "FROM info_rels i JOIN pg_catalog.pg_class c " ! " ON i.reloid = c.oid " ! " JOIN pg_catalog.pg_namespace n " ! " ON c.relnamespace = n.oid " ! " LEFT OUTER JOIN pg_catalog.pg_tablespace t " ! " ON c.reltablespace = t.oid " ! /* we preserve pg_class.oid so we sort by it to match old/new */ ! "ORDER BY 1;", ! /* 9.2 removed the spclocation column */ ! (GET_MAJOR_VERSION(cluster->major_version) <= 901) ? ! "t.spclocation" : "pg_catalog.pg_tablespace_location(t.oid) AS spclocation"); ! } res = executeQueryOrDie(conn, "%s", query); ntups = PQntuples(res);
-- Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-hackers