diff options
author | Tom Lane | 2021-04-29 19:24:37 +0000 |
---|---|---|
committer | Tom Lane | 2021-04-29 19:24:37 +0000 |
commit | 57c081de0afcd01bf47c46f015bf8886b01c2c21 (patch) | |
tree | 5a4d8c3888224016b64641d5bfa4de30e5185859 /src/bin/pg_upgrade/version.c | |
parent | 94b9cb722552c37da78c8320bac1d5b55e34def6 (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.c | 53 |
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() |