summaryrefslogtreecommitdiff
path: root/src/bin/pg_upgrade/version.c
diff options
context:
space:
mode:
authorTom Lane2021-04-29 19:24:37 +0000
committerTom Lane2021-04-29 19:24:37 +0000
commit57c081de0afcd01bf47c46f015bf8886b01c2c21 (patch)
tree5a4d8c3888224016b64641d5bfa4de30e5185859 /src/bin/pg_upgrade/version.c
parent94b9cb722552c37da78c8320bac1d5b55e34def6 (diff)
Fix some more omissions in pg_upgrade's tests for non-upgradable types.
Commits 29aeda6e4 et al closed up some oversights involving not checking for non-upgradable types within container types, such as arrays and ranges. However, I only looked at version.c, failing to notice that there were substantially-equivalent tests in check.c. (The division of responsibility between those files is less than clear...) In addition, because genbki.pl does not guarantee that auto-generated rowtype OIDs will hold still across versions, we need to consider that the composite type associated with a system catalog or view is non-upgradable. It seems unlikely that someone would have a user column declared that way, but if they did, trying to read it in another PG version would likely draw "no such pg_type OID" failures, thanks to the type OID embedded in composite Datums. To support the composite and reg*-type cases, extend the recursive query that does the search to allow any base query that returns a column of pg_type OIDs, rather than limiting it to exactly one starting type. As before, back-patch to all supported branches. Discussion: https://postgr.es/m/[email protected]
Diffstat (limited to 'src/bin/pg_upgrade/version.c')
-rw-r--r--src/bin/pg_upgrade/version.c53
1 files changed, 43 insertions, 10 deletions
diff --git a/src/bin/pg_upgrade/version.c b/src/bin/pg_upgrade/version.c
index a41247b33d2..4fd9b8749bc 100644
--- a/src/bin/pg_upgrade/version.c
+++ b/src/bin/pg_upgrade/version.c
@@ -97,17 +97,22 @@ new_9_0_populate_pg_largeobject_metadata(ClusterInfo *cluster, bool check_mode)
/*
- * check_for_data_type_usage
- * Detect whether there are any stored columns depending on the given type
+ * check_for_data_types_usage()
+ * Detect whether there are any stored columns depending on given type(s)
*
* If so, write a report to the given file name, and return true.
*
- * We check for the type in tables, matviews, and indexes, but not views;
+ * base_query should be a SELECT yielding a single column named "oid",
+ * containing the pg_type OIDs of one or more types that are known to have
+ * inconsistent on-disk representations across server versions.
+ *
+ * We check for the type(s) in tables, matviews, and indexes, but not views;
* there's no storage involved in a view.
*/
-static bool
-check_for_data_type_usage(ClusterInfo *cluster, const char *typename,
- char *output_path)
+bool
+check_for_data_types_usage(ClusterInfo *cluster,
+ const char *base_query,
+ const char *output_path)
{
bool found = false;
FILE *script = NULL;
@@ -127,7 +132,7 @@ check_for_data_type_usage(ClusterInfo *cluster, const char *typename,
i_attname;
/*
- * The type of interest might be wrapped in a domain, array,
+ * The type(s) of interest might be wrapped in a domain, array,
* composite, or range, and these container types can be nested (to
* varying extents depending on server version, but that's not of
* concern here). To handle all these cases we need a recursive CTE.
@@ -135,8 +140,8 @@ check_for_data_type_usage(ClusterInfo *cluster, const char *typename,
initPQExpBuffer(&querybuf);
appendPQExpBuffer(&querybuf,
"WITH RECURSIVE oids AS ( "
- /* the target type itself */
- " SELECT '%s'::pg_catalog.regtype AS oid "
+ /* start with the type(s) returned by base_query */
+ " %s "
" UNION ALL "
" SELECT * FROM ( "
/* inner WITH because we can only reference the CTE once */
@@ -154,7 +159,7 @@ check_for_data_type_usage(ClusterInfo *cluster, const char *typename,
" c.oid = a.attrelid AND "
" NOT a.attisdropped AND "
" a.atttypid = x.oid ",
- typename);
+ base_query);
/* Ranges were introduced in 9.2 */
if (GET_MAJOR_VERSION(cluster->major_version) >= 902)
@@ -222,6 +227,34 @@ check_for_data_type_usage(ClusterInfo *cluster, const char *typename,
return found;
}
+/*
+ * check_for_data_type_usage()
+ * Detect whether there are any stored columns depending on the given type
+ *
+ * If so, write a report to the given file name, and return true.
+ *
+ * typename should be a fully qualified type name. This is just a
+ * trivial wrapper around check_for_data_types_usage() to convert a
+ * type name into a base query.
+ */
+bool
+check_for_data_type_usage(ClusterInfo *cluster,
+ const char *typename,
+ const char *output_path)
+{
+ bool found;
+ char *base_query;
+
+ base_query = psprintf("SELECT '%s'::pg_catalog.regtype AS oid",
+ typename);
+
+ found = check_for_data_types_usage(cluster, base_query, output_path);
+
+ free(base_query);
+
+ return found;
+}
+
/*
* old_9_3_check_for_line_data_type_usage()