@@ -253,7 +253,9 @@ static void dumpDatabase(Archive *AH);
253253static void dumpEncoding(Archive *AH);
254254static void dumpStdStrings(Archive *AH);
255255static void binary_upgrade_set_type_oids_by_type_oid(Archive *fout,
256- PQExpBuffer upgrade_buffer, Oid pg_type_oid);
256+ PQExpBuffer upgrade_buffer,
257+ Oid pg_type_oid,
258+ bool force_array_type);
257259static bool binary_upgrade_set_type_oids_by_rel_oid(Archive *fout,
258260 PQExpBuffer upgrade_buffer, Oid pg_rel_oid);
259261static void binary_upgrade_set_pg_class_oids(Archive *fout,
@@ -3949,10 +3951,11 @@ dumpSubscription(Archive *fout, SubscriptionInfo *subinfo)
39493951static void
39503952binary_upgrade_set_type_oids_by_type_oid(Archive *fout,
39513953 PQExpBuffer upgrade_buffer,
3952- Oid pg_type_oid)
3954+ Oid pg_type_oid,
3955+ bool force_array_type)
39533956{
39543957 PQExpBuffer upgrade_query = createPQExpBuffer();
3955- PGresult *upgrade_res ;
3958+ PGresult *res ;
39563959 Oid pg_type_array_oid;
39573960
39583961 appendPQExpBufferStr(upgrade_buffer, "\n-- For binary upgrade, must preserve pg_type oid\n");
@@ -3964,12 +3967,43 @@ binary_upgrade_set_type_oids_by_type_oid(Archive *fout,
39643967 appendPQExpBuffer(upgrade_query,
39653968 "SELECT typarray "
39663969 "FROM pg_catalog.pg_type "
3967- "WHERE pg_type. oid = '%u'::pg_catalog.oid;",
3970+ "WHERE oid = '%u'::pg_catalog.oid;",
39683971 pg_type_oid);
39693972
3970- upgrade_res = ExecuteSqlQueryForSingleRow(fout, upgrade_query->data);
3973+ res = ExecuteSqlQueryForSingleRow(fout, upgrade_query->data);
3974+
3975+ pg_type_array_oid = atooid(PQgetvalue(res, 0, PQfnumber(res, "typarray")));
39713976
3972- pg_type_array_oid = atooid(PQgetvalue(upgrade_res, 0, PQfnumber(upgrade_res, "typarray")));
3977+ PQclear(res);
3978+
3979+ if (!OidIsValid(pg_type_array_oid) && force_array_type)
3980+ {
3981+ /*
3982+ * If the old version didn't assign an array type, but the new version
3983+ * does, we must select an unused type OID to assign. This currently
3984+ * only happens for domains, when upgrading pre-v11 to v11 and up.
3985+ *
3986+ * Note: local state here is kind of ugly, but we must have some,
3987+ * since we mustn't choose the same unused OID more than once.
3988+ */
3989+ static Oid next_possible_free_oid = FirstNormalObjectId;
3990+ bool is_dup;
3991+
3992+ do
3993+ {
3994+ ++next_possible_free_oid;
3995+ printfPQExpBuffer(upgrade_query,
3996+ "SELECT EXISTS(SELECT 1 "
3997+ "FROM pg_catalog.pg_type "
3998+ "WHERE oid = '%u'::pg_catalog.oid);",
3999+ next_possible_free_oid);
4000+ res = ExecuteSqlQueryForSingleRow(fout, upgrade_query->data);
4001+ is_dup = (PQgetvalue(res, 0, 0)[0] == 't');
4002+ PQclear(res);
4003+ } while (is_dup);
4004+
4005+ pg_type_array_oid = next_possible_free_oid;
4006+ }
39734007
39744008 if (OidIsValid(pg_type_array_oid))
39754009 {
@@ -3980,7 +4014,6 @@ binary_upgrade_set_type_oids_by_type_oid(Archive *fout,
39804014 pg_type_array_oid);
39814015 }
39824016
3983- PQclear(upgrade_res);
39844017 destroyPQExpBuffer(upgrade_query);
39854018}
39864019
@@ -4008,7 +4041,7 @@ binary_upgrade_set_type_oids_by_rel_oid(Archive *fout,
40084041 pg_type_oid = atooid(PQgetvalue(upgrade_res, 0, PQfnumber(upgrade_res, "crel")));
40094042
40104043 binary_upgrade_set_type_oids_by_type_oid(fout, upgrade_buffer,
4011- pg_type_oid);
4044+ pg_type_oid, false );
40124045
40134046 if (!PQgetisnull(upgrade_res, 0, PQfnumber(upgrade_res, "trel")))
40144047 {
@@ -9840,7 +9873,8 @@ dumpEnumType(Archive *fout, TypeInfo *tyinfo)
98409873
98419874 if (dopt->binary_upgrade)
98429875 binary_upgrade_set_type_oids_by_type_oid(fout, q,
9843- tyinfo->dobj.catId.oid);
9876+ tyinfo->dobj.catId.oid,
9877+ false);
98449878
98459879 appendPQExpBuffer(q, "CREATE TYPE %s AS ENUM (",
98469880 qtypname);
@@ -9976,8 +10010,9 @@ dumpRangeType(Archive *fout, TypeInfo *tyinfo)
997610010 qtypname);
997710011
997810012 if (dopt->binary_upgrade)
9979- binary_upgrade_set_type_oids_by_type_oid(fout,
9980- q, tyinfo->dobj.catId.oid);
10013+ binary_upgrade_set_type_oids_by_type_oid(fout, q,
10014+ tyinfo->dobj.catId.oid,
10015+ false);
998110016
998210017 appendPQExpBuffer(q, "CREATE TYPE %s AS RANGE (",
998310018 qtypname);
@@ -10091,8 +10126,9 @@ dumpUndefinedType(Archive *fout, TypeInfo *tyinfo)
1009110126 qtypname);
1009210127
1009310128 if (dopt->binary_upgrade)
10094- binary_upgrade_set_type_oids_by_type_oid(fout,
10095- q, tyinfo->dobj.catId.oid);
10129+ binary_upgrade_set_type_oids_by_type_oid(fout, q,
10130+ tyinfo->dobj.catId.oid,
10131+ false);
1009610132
1009710133 appendPQExpBuffer(q, "CREATE TYPE %s;\n",
1009810134 qtypname);
@@ -10296,10 +10332,14 @@ dumpBaseType(Archive *fout, TypeInfo *tyinfo)
1029610332 appendPQExpBuffer(delq, "%s CASCADE;\n",
1029710333 qtypname);
1029810334
10299- /* We might already have a shell type, but setting pg_type_oid is harmless */
10335+ /*
10336+ * We might already have a shell type, but setting pg_type_oid is
10337+ * harmless, and in any case we'd better set the array type OID.
10338+ */
1030010339 if (dopt->binary_upgrade)
1030110340 binary_upgrade_set_type_oids_by_type_oid(fout, q,
10302- tyinfo->dobj.catId.oid);
10341+ tyinfo->dobj.catId.oid,
10342+ false);
1030310343
1030410344 appendPQExpBuffer(q,
1030510345 "CREATE TYPE %s (\n"
@@ -10490,7 +10530,8 @@ dumpDomain(Archive *fout, TypeInfo *tyinfo)
1049010530
1049110531 if (dopt->binary_upgrade)
1049210532 binary_upgrade_set_type_oids_by_type_oid(fout, q,
10493- tyinfo->dobj.catId.oid);
10533+ tyinfo->dobj.catId.oid,
10534+ true); /* force array type */
1049410535
1049510536 qtypname = pg_strdup(fmtId(tyinfo->dobj.name));
1049610537
@@ -10692,7 +10733,8 @@ dumpCompositeType(Archive *fout, TypeInfo *tyinfo)
1069210733 if (dopt->binary_upgrade)
1069310734 {
1069410735 binary_upgrade_set_type_oids_by_type_oid(fout, q,
10695- tyinfo->dobj.catId.oid);
10736+ tyinfo->dobj.catId.oid,
10737+ false);
1069610738 binary_upgrade_set_pg_class_oids(fout, q, tyinfo->typrelid, false);
1069710739 }
1069810740
@@ -10967,7 +11009,8 @@ dumpShellType(Archive *fout, ShellTypeInfo *stinfo)
1096711009
1096811010 if (dopt->binary_upgrade)
1096911011 binary_upgrade_set_type_oids_by_type_oid(fout, q,
10970- stinfo->baseType->dobj.catId.oid);
11012+ stinfo->baseType->dobj.catId.oid,
11013+ false);
1097111014
1097211015 appendPQExpBuffer(q, "CREATE TYPE %s;\n",
1097311016 fmtId(stinfo->dobj.name));
0 commit comments