From 182c4b5d8a3e4299a8ac1ac7b2d4c6bf864db55d Mon Sep 17 00:00:00 2001 From: Vignesh C Date: Wed, 22 Apr 2026 16:35:57 +0530 Subject: [PATCH v28 4/4] Preserve conflict log destination and subscription OID for subscriptions Support pg_dump to dump and restore the conflict_log_destination setting for subscriptions. During a normal CREATE SUBSCRIPTION, a conflict log table is created automatically when required. However, during binary upgrade, the conflict log table will already exist and must be reused rather than recreated, and the subscription must retain its original OID to correctly re-establish catalog relationships. To ensure correct behavior, pg_dump now emits an ALTER SUBSCRIPTION command after subscription creation to restore the conflict_log_destination setting. --- src/backend/catalog/heap.c | 4 +- src/backend/commands/subscriptioncmds.c | 144 +++++++++++++----- src/backend/utils/adt/pg_upgrade_support.c | 10 ++ src/bin/pg_dump/pg_dump.c | 110 ++++++++++++- src/bin/pg_dump/pg_dump.h | 2 + src/bin/pg_dump/pg_dump_sort.c | 31 ++++ src/bin/pg_dump/t/002_pg_dump.pl | 5 +- src/bin/pg_upgrade/pg_upgrade.c | 4 + src/bin/pg_upgrade/t/004_subscription.pl | 14 +- src/include/catalog/binary_upgrade.h | 1 + src/include/catalog/pg_proc.dat | 4 + .../expected/spgist_name_ops.out | 6 +- 12 files changed, 288 insertions(+), 47 deletions(-) diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c index ad284ac09ca..a7f9094d44a 100644 --- a/src/backend/catalog/heap.c +++ b/src/backend/catalog/heap.c @@ -311,11 +311,13 @@ heap_create(const char *relname, * But allow creating indexes on relations in pg_catalog even if * allow_system_table_mods = off, upper layers already guarantee it's on a * user defined relation, not a system one. + * + * Allow creation of conflict table in binary-upgrade mode. */ if (!allow_system_table_mods && ((IsCatalogNamespace(relnamespace) && relkind != RELKIND_INDEX) || IsToastNamespace(relnamespace) || - IsConflictNamespace(relnamespace)) && + (!IsBinaryUpgrade && IsConflictNamespace(relnamespace))) && IsNormalProcessingMode()) ereport(ERROR, (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), diff --git a/src/backend/commands/subscriptioncmds.c b/src/backend/commands/subscriptioncmds.c index c36df63a13e..09de9223246 100644 --- a/src/backend/commands/subscriptioncmds.c +++ b/src/backend/commands/subscriptioncmds.c @@ -88,6 +88,12 @@ /* check if the 'val' has 'bits' set */ #define IsSet(val, bits) (((val) & (bits)) == (bits)) +/* + * This will be set by the pg_upgrade_support function -- + * binary_upgrade_set_next_pg_subscription_oid(). + */ +Oid binary_upgrade_next_pg_subscription_oid = InvalidOid; + /* * Structure to hold a bitmap representing the user-provided CREATE/ALTER * SUBSCRIPTION command options and the parsed/default values of each of them. @@ -794,8 +800,21 @@ CreateSubscription(ParseState *pstate, CreateSubscriptionStmt *stmt, memset(values, 0, sizeof(values)); memset(nulls, false, sizeof(nulls)); - subid = GetNewOidWithIndex(rel, SubscriptionObjectIndexId, - Anum_pg_subscription_oid); + /* Use binary-upgrade override for pg_subscription.oid? */ + if (IsBinaryUpgrade) + { + if (!OidIsValid(binary_upgrade_next_pg_subscription_oid)) + ereport(ERROR, + (errcode(ERRCODE_INVALID_PARAMETER_VALUE), + errmsg("pg_subscription OID value not set when in binary upgrade mode"))); + + subid = binary_upgrade_next_pg_subscription_oid; + binary_upgrade_next_pg_subscription_oid = InvalidOid; + } + else + subid = GetNewOidWithIndex(rel, SubscriptionObjectIndexId, + Anum_pg_subscription_oid); + values[Anum_pg_subscription_oid - 1] = ObjectIdGetDatum(subid); values[Anum_pg_subscription_subdbid - 1] = ObjectIdGetDatum(MyDatabaseId); values[Anum_pg_subscription_subskiplsn - 1] = LSNGetDatum(InvalidXLogRecPtr); @@ -1440,6 +1459,85 @@ CheckAlterSubOption(Subscription *sub, const char *option, } } +/* + * AlterSubscriptionConflictLogDestination + * + * Update the conflict log table associated with a subscription when its + * conflict log destination is changed. + * + * If the new destination requires a conflict log table and none was previously + * required, this function validates an existing conflict log table identified + * by the subscription specific naming convention or creates a new one. + * + * If the new destination no longer requires a conflict log table, the existing + * conflict log table associated with the subscription is removed via internal + * dependency cleanup to prevent orphaned relations. + * + * The function enforces that any conflict log table used is a permanent + * relation in a permanent schema, matches the expected structure, and is not + * already associated with another subscription. + * + * On success, *conflicttablerelid is set to the OID of the conflict log table + * that was created or validated, or to InvalidOid if no table is required. + * + * Returns true if the subscription's conflict log table reference must be + * updated as a result of the destination change; false otherwise. + */ +static bool +AlterSubscriptionConflictLogDestination(Subscription *sub, + ConflictLogDest logdest, + Oid *conflicttablerelid) +{ + ConflictLogDest old_dest = GetLogDestination(sub->conflictlogdest); + bool want_table; + bool has_oldtable; + bool update_relid = false; + Oid relid = InvalidOid; + + want_table = IsSet(logdest, CONFLICT_LOG_DEST_TABLE); + has_oldtable = IsSet(old_dest, CONFLICT_LOG_DEST_TABLE); + + if (want_table && !has_oldtable) + { + char relname[NAMEDATALEN]; + + snprintf(relname, NAMEDATALEN, "pg_conflict_%u", sub->oid); + + /* + * In upgrade scenarios, the conflict log table already exists. Update + * the catalog to record the association. + */ + relid = get_relname_relid(relname, PG_CONFLICT_NAMESPACE); + if (!OidIsValid(relid)) + relid = create_conflict_log_table(sub->oid, sub->name); + + update_relid = true; + } + else if (!want_table && has_oldtable) + { + ObjectAddress object; + + /* + * Conflict log tables are recorded as internal dependencies of the + * subscription. Drop the table if it is not required anymore to + * avoid stale or orphaned relations. + * + * XXX: At present, only conflict log tables are managed this way. In + * future if we introduce additional internal dependencies, we may + * need a targeted deletion to avoid deletion of any other objects. + */ + ObjectAddressSet(object, SubscriptionRelationId, sub->oid); + performDeletion(&object, DROP_CASCADE, + PERFORM_DELETION_INTERNAL | + PERFORM_DELETION_SKIP_ORIGINAL); + + update_relid = true; + } + + *conflicttablerelid = relid; + return update_relid; +} + /* * Alter the existing subscription. */ @@ -1804,53 +1902,23 @@ AlterSubscription(ParseState *pstate, AlterSubscriptionStmt *stmt, if (opts.conflictlogdest != old_dest) { - bool want_table = IsSet(opts.conflictlogdest, - CONFLICT_LOG_DEST_TABLE); - bool has_oldtable = - IsSet(old_dest, CONFLICT_LOG_DEST_TABLE); + bool update_relid; + Oid relid = InvalidOid; values[Anum_pg_subscription_subconflictlogdest - 1] = CStringGetTextDatum(ConflictLogDestNames[opts.conflictlogdest]); replaces[Anum_pg_subscription_subconflictlogdest - 1] = true; - if (want_table && !has_oldtable) + update_relid = AlterSubscriptionConflictLogDestination(sub, + opts.conflictlogdest, + &relid); + if (update_relid) { - Oid relid; - - relid = create_conflict_log_table(subid, sub->name); - values[Anum_pg_subscription_subconflictlogrelid - 1] = ObjectIdGetDatum(relid); replaces[Anum_pg_subscription_subconflictlogrelid - 1] = true; } - else if (!want_table && has_oldtable) - { - ObjectAddress object; - - /* - * Conflict log tables are recorded as internal - * dependencies of the subscription. Drop the - * table if it is not required anymore to avoid - * stale or orphaned relations. - * - * XXX: At present, only conflict log tables are - * managed this way. In future if we introduce - * additional internal dependencies, we may need - * a targeted deletion to avoid deletion of any - * other objects. - */ - ObjectAddressSet(object, SubscriptionRelationId, - subid); - performDeletion(&object, DROP_CASCADE, - PERFORM_DELETION_INTERNAL | - PERFORM_DELETION_SKIP_ORIGINAL); - - values[Anum_pg_subscription_subconflictlogrelid - 1] = - ObjectIdGetDatum(InvalidOid); - replaces[Anum_pg_subscription_subconflictlogrelid - 1] = - true; - } } } diff --git a/src/backend/utils/adt/pg_upgrade_support.c b/src/backend/utils/adt/pg_upgrade_support.c index b505a6b4fee..59c3e7f0146 100644 --- a/src/backend/utils/adt/pg_upgrade_support.c +++ b/src/backend/utils/adt/pg_upgrade_support.c @@ -181,6 +181,16 @@ binary_upgrade_set_next_pg_authid_oid(PG_FUNCTION_ARGS) PG_RETURN_VOID(); } +Datum +binary_upgrade_set_next_pg_subscription_oid(PG_FUNCTION_ARGS) +{ + Oid subid = PG_GETARG_OID(0); + + CHECK_IS_BINARY_UPGRADE; + binary_upgrade_next_pg_subscription_oid = subid; + PG_RETURN_VOID(); +} + Datum binary_upgrade_create_empty_extension(PG_FUNCTION_ARGS) { diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index d56dcc701ce..c3dcc9543d1 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -1981,6 +1981,8 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) static void selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) { + DumpOptions *dopt = fout->dopt; + /* * DUMP_COMPONENT_DEFINITION typically implies a CREATE SCHEMA statement * and (for --clean) a DROP SCHEMA statement. (In the absence of @@ -2010,6 +2012,32 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) */ nsinfo->dobj.dump_contains = nsinfo->dobj.dump = DUMP_COMPONENT_ACL; } + else if (strcmp(nsinfo->dobj.name, "pg_conflict") == 0) + { + if (dopt->binary_upgrade) + { + /* + * The pg_conflict schema is a strange beast that sits in a sort + * of no-mans-land between being a system object and a user + * object. CREATE SCHEMA would fail, so its + * DUMP_COMPONENT_DEFINITION is just a comment. + */ + nsinfo->create = false; + nsinfo->dobj.dump = DUMP_COMPONENT_ALL; + nsinfo->dobj.dump &= ~DUMP_COMPONENT_DEFINITION; + nsinfo->dobj.dump_contains = DUMP_COMPONENT_ALL; + + /* + * Also, make like it has a comment even if it doesn't; this is so + * that we'll emit a command to drop the comment, if appropriate. + * (Without this, we'd not call dumpCommentExtended for it.) + */ + nsinfo->dobj.components |= DUMP_COMPONENT_COMMENT; + } + else + nsinfo->dobj.dump_contains = nsinfo->dobj.dump = + DUMP_COMPONENT_NONE; + } else if (strncmp(nsinfo->dobj.name, "pg_", 3) == 0 || strcmp(nsinfo->dobj.name, "information_schema") == 0) { @@ -2067,9 +2095,31 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) static void selectDumpableTable(TableInfo *tbinfo, Archive *fout) { + DumpOptions *dopt = fout->dopt; + if (checkExtensionMembership(&tbinfo->dobj, fout)) return; /* extension membership overrides all else */ + if (strcmp(tbinfo->dobj.namespace->dobj.name, "pg_conflict") == 0) + { + if (dopt->binary_upgrade) + { + /* + * Dump pg_conflict tables only during binary upgrade. The schema + * is assumed to already exist. + */ + tbinfo->dobj.dump = DUMP_COMPONENT_DEFINITION; + + /* + * Suppress the "ALTER TABLE ... OWNER TO ..." command for this + * table. This prevents pg_dump from outputting the owner change. + */ + tbinfo->rolname = NULL; + } + else + tbinfo->dobj.dump = DUMP_COMPONENT_NONE; + } + /* * If specific tables are being dumped, dump just those tables; else, dump * according to the parent namespace's dump flag. @@ -5184,6 +5234,8 @@ getSubscriptions(Archive *fout) int i_subfailover; int i_subretaindeadtuples; int i_submaxretention; + int i_subconflictlogrelid; + int i_sublogdestination; int i, ntups; @@ -5282,9 +5334,16 @@ getSubscriptions(Archive *fout) " '-1' AS subwalrcvtimeout,\n"); if (fout->remoteVersion >= 190000) - appendPQExpBufferStr(query, " fs.srvname AS subservername\n"); + appendPQExpBufferStr(query, " fs.srvname AS subservername,\n"); else - appendPQExpBufferStr(query, " NULL AS subservername\n"); + appendPQExpBufferStr(query, " NULL AS subservername,\n"); + + if (fout->remoteVersion >= 190000) + appendPQExpBufferStr(query, + " s.subconflictlogrelid, s.subconflictlogdest\n"); + else + appendPQExpBufferStr(query, + " NULL AS subconflictlogrelid, NULL AS subconflictlogdest\n"); appendPQExpBufferStr(query, "FROM pg_subscription s\n"); @@ -5333,6 +5392,8 @@ getSubscriptions(Archive *fout) i_subpublications = PQfnumber(res, "subpublications"); i_suborigin = PQfnumber(res, "suborigin"); i_suboriginremotelsn = PQfnumber(res, "suboriginremotelsn"); + i_subconflictlogrelid = PQfnumber(res, "subconflictlogrelid"); + i_sublogdestination = PQfnumber(res, "subconflictlogdest"); subinfo = pg_malloc_array(SubscriptionInfo, ntups); @@ -5391,6 +5452,38 @@ getSubscriptions(Archive *fout) subinfo[i].suboriginremotelsn = pg_strdup(PQgetvalue(res, i, i_suboriginremotelsn)); + if (PQgetisnull(res, i, i_subconflictlogrelid)) + subinfo[i].subconflictlogrelid = InvalidOid; + else + { + TableInfo *tableInfo; + + subinfo[i].subconflictlogrelid = + atooid(PQgetvalue(res, i, i_subconflictlogrelid)); + + if (subinfo[i].subconflictlogrelid) + { + tableInfo = findTableByOid(subinfo[i].subconflictlogrelid); + if (!tableInfo) + pg_fatal("could not find conflict log table with OID %u", + subinfo[i].subconflictlogrelid); + + addObjectDependency(&subinfo[i].dobj, tableInfo->dobj.dumpId); + } + } + + if (PQgetisnull(res, i, i_sublogdestination)) + subinfo[i].subconflictlogdest = NULL; + else + subinfo[i].subconflictlogdest = + pg_strdup(PQgetvalue(res, i, i_sublogdestination)); + + if (PQgetisnull(res, i, i_sublogdestination)) + subinfo[i].subconflictlogdest = NULL; + else + subinfo[i].subconflictlogdest = + pg_strdup(PQgetvalue(res, i, i_sublogdestination)); + /* Decide whether we want to dump it */ selectDumpableObject(&(subinfo[i].dobj), fout); } @@ -5583,6 +5676,14 @@ dumpSubscription(Archive *fout, const SubscriptionInfo *subinfo) appendPQExpBuffer(delq, "DROP SUBSCRIPTION %s;\n", qsubname); + if (dopt->binary_upgrade) + { + appendPQExpBufferStr(query, "\n-- For binary upgrade, must preserve pg_subscription.oid\n"); + appendPQExpBuffer(query, + "SELECT pg_catalog.binary_upgrade_set_next_pg_subscription_oid('%u'::pg_catalog.oid);\n\n", + subinfo->dobj.catId.oid); + } + appendPQExpBuffer(query, "CREATE SUBSCRIPTION %s ", qsubname); if (subinfo->subservername) @@ -5656,6 +5757,11 @@ dumpSubscription(Archive *fout, const SubscriptionInfo *subinfo) appendPQExpBufferStr(query, ");\n"); + appendPQExpBuffer(query, + "\n\nALTER SUBSCRIPTION %s SET (conflict_log_destination = %s);\n", + qsubname, + subinfo->subconflictlogdest); + /* * In binary-upgrade mode, we allow the replication to continue after the * upgrade. diff --git a/src/bin/pg_dump/pg_dump.h b/src/bin/pg_dump/pg_dump.h index 5a6726d8b12..0c203767012 100644 --- a/src/bin/pg_dump/pg_dump.h +++ b/src/bin/pg_dump/pg_dump.h @@ -722,6 +722,7 @@ typedef struct _SubscriptionInfo bool subfailover; bool subretaindeadtuples; int submaxretention; + Oid subconflictlogrelid; char *subservername; char *subconninfo; char *subslotname; @@ -730,6 +731,7 @@ typedef struct _SubscriptionInfo char *subpublications; char *suborigin; char *suboriginremotelsn; + char *subconflictlogdest; } SubscriptionInfo; /* diff --git a/src/bin/pg_dump/pg_dump_sort.c b/src/bin/pg_dump/pg_dump_sort.c index 03e5c1c1116..c27b232e799 100644 --- a/src/bin/pg_dump/pg_dump_sort.c +++ b/src/bin/pg_dump/pg_dump_sort.c @@ -1131,6 +1131,19 @@ repairTableAttrDefMultiLoop(DumpableObject *tableobj, addObjectDependency(attrdefobj, tableobj->dumpId); } +/* + * Because we make subscriptions depend on their conflict log tables, while + * there is an automatic dependency in the other direction, we need to break + * the loop. Remove the automatic dependency, allowing the table to be created + * first. + */ +static void +repairSubscriptionTableLoop(DumpableObject *subobj, DumpableObject *tableobj) +{ + /* Remove table's dependency on subscription */ + removeObjectDependency(tableobj, subobj->dumpId); +} + /* * CHECK, NOT NULL constraints on domains work just like those on tables ... */ @@ -1361,6 +1374,24 @@ repairDependencyLoop(DumpableObject **loop, return; } + /* + * Subscription and its Conflict Log Table + */ + if (nLoop == 2 && + loop[0]->objType == DO_TABLE && + loop[1]->objType == DO_SUBSCRIPTION) + { + repairSubscriptionTableLoop(loop[1], loop[0]); + return; + } + if (nLoop == 2 && + loop[0]->objType == DO_SUBSCRIPTION && + loop[1]->objType == DO_TABLE) + { + repairSubscriptionTableLoop(loop[0], loop[1]); + return; + } + /* index on partitioned table and corresponding index on partition */ if (nLoop == 2 && loop[0]->objType == DO_INDEX && diff --git a/src/bin/pg_dump/t/002_pg_dump.pl b/src/bin/pg_dump/t/002_pg_dump.pl index 3bc8e51561d..81998e2f96e 100644 --- a/src/bin/pg_dump/t/002_pg_dump.pl +++ b/src/bin/pg_dump/t/002_pg_dump.pl @@ -3276,9 +3276,10 @@ my %tests = ( create_order => 50, create_sql => 'CREATE SUBSCRIPTION sub3 CONNECTION \'dbname=doesnotexist\' PUBLICATION pub1 - WITH (connect = false, origin = any, streaming = on);', + WITH (connect = false, origin = any, streaming = on, conflict_log_destination= table);', regexp => qr/^ - \QCREATE SUBSCRIPTION sub3 CONNECTION 'dbname=doesnotexist' PUBLICATION pub1 WITH (connect = false, slot_name = 'sub3', streaming = on);\E + \QCREATE SUBSCRIPTION sub3 CONNECTION 'dbname=doesnotexist' PUBLICATION pub1 WITH (connect = false, slot_name = 'sub3', streaming = on);\E\n\n\n + \QALTER SUBSCRIPTION sub3 SET (conflict_log_destination = table);\E /xm, like => { %full_runs, section_post_data => 1, }, unlike => { diff --git a/src/bin/pg_upgrade/pg_upgrade.c b/src/bin/pg_upgrade/pg_upgrade.c index 2127d297bfe..135ef658c2c 100644 --- a/src/bin/pg_upgrade/pg_upgrade.c +++ b/src/bin/pg_upgrade/pg_upgrade.c @@ -35,6 +35,10 @@ * * We control all assignments of pg_database.oid because we want the directory * names to match between the old and new cluster. + * + * We control assignment of pg_subscription.oid because we want the oid to + * match between the old and new cluster to make use of subscription's + * conflict log table which is named using the subscription oid. */ diff --git a/src/bin/pg_upgrade/t/004_subscription.pl b/src/bin/pg_upgrade/t/004_subscription.pl index f68821df2a3..81956964ede 100644 --- a/src/bin/pg_upgrade/t/004_subscription.pl +++ b/src/bin/pg_upgrade/t/004_subscription.pl @@ -290,7 +290,7 @@ $publisher->safe_psql( $old_sub->safe_psql( 'postgres', qq[ CREATE TABLE tab_upgraded2(id int); - CREATE SUBSCRIPTION regress_sub5 CONNECTION '$connstr' PUBLICATION regress_pub5; + CREATE SUBSCRIPTION regress_sub5 CONNECTION '$connstr' PUBLICATION regress_pub5 with (conflict_log_destination = 'table'); ]); # The table tab_upgraded2 will be in the init state as the subscriber's @@ -312,7 +312,10 @@ my $tab_upgraded1_oid = $old_sub->safe_psql('postgres', "SELECT oid FROM pg_class WHERE relname = 'tab_upgraded1'"); my $tab_upgraded2_oid = $old_sub->safe_psql('postgres', "SELECT oid FROM pg_class WHERE relname = 'tab_upgraded2'"); - +my $sub5_oid = $old_sub->safe_psql('postgres', + "SELECT oid FROM pg_subscription where subname = 'regress_sub5'"); +my $sub_clt_relid = $old_sub->safe_psql('postgres', + "SELECT subconflictlogrelid FROM pg_subscription WHERE subname = 'regress_sub5'"); $old_sub->stop; # Change configuration so that initial table sync does not get started @@ -393,6 +396,13 @@ $result = $new_sub->safe_psql('postgres', "SELECT xmin IS NOT NULL from pg_replication_slots WHERE slot_name = 'pg_conflict_detection'"); is($result, qq(t), "conflict detection slot exists"); +# The subscription oid and the subscription conflict log table relid should be preserved +$result = $new_sub->safe_psql('postgres', "SELECT oid FROM pg_subscription WHERE subname = 'regress_sub5'"); +is($result, qq($sub5_oid), "subscription oid should have been preserved"); + +$result = $new_sub->safe_psql('postgres', "SELECT subconflictlogrelid FROM pg_subscription WHERE subname = 'regress_sub5'"); +is($result, qq($sub_clt_relid), "subscription conflict log table relid should have been preserved"); + # Resume the initial sync and wait until all tables of subscription # 'regress_sub5' are synchronized $new_sub->append_conf('postgresql.conf', diff --git a/src/include/catalog/binary_upgrade.h b/src/include/catalog/binary_upgrade.h index 7bf7ae44385..b15b18e7dc9 100644 --- a/src/include/catalog/binary_upgrade.h +++ b/src/include/catalog/binary_upgrade.h @@ -32,6 +32,7 @@ extern PGDLLIMPORT RelFileNumber binary_upgrade_next_toast_pg_class_relfilenumbe extern PGDLLIMPORT Oid binary_upgrade_next_pg_enum_oid; extern PGDLLIMPORT Oid binary_upgrade_next_pg_authid_oid; +extern PGDLLIMPORT Oid binary_upgrade_next_pg_subscription_oid; extern PGDLLIMPORT bool binary_upgrade_record_init_privs; diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat index fa9ae79082b..c9293df27aa 100644 --- a/src/include/catalog/pg_proc.dat +++ b/src/include/catalog/pg_proc.dat @@ -12024,6 +12024,10 @@ proname => 'binary_upgrade_create_conflict_detection_slot', proisstrict => 'f', provolatile => 'v', proparallel => 'u', prorettype => 'void', proargtypes => '', prosrc => 'binary_upgrade_create_conflict_detection_slot' }, +{ oid => '8407', descr => 'for use by pg_upgrade', + proname => 'binary_upgrade_set_next_pg_subscription_oid', provolatile => 'v', + proparallel => 'r', prorettype => 'void', proargtypes => 'oid', + prosrc => 'binary_upgrade_set_next_pg_subscription_oid' }, # conversion functions { oid => '4310', descr => 'internal conversion function for KOI8R to WIN1251', diff --git a/src/test/modules/spgist_name_ops/expected/spgist_name_ops.out b/src/test/modules/spgist_name_ops/expected/spgist_name_ops.out index 1ee65ede243..39d43368c42 100644 --- a/src/test/modules/spgist_name_ops/expected/spgist_name_ops.out +++ b/src/test/modules/spgist_name_ops/expected/spgist_name_ops.out @@ -59,11 +59,12 @@ select * from t binary_upgrade_set_next_multirange_pg_type_oid | 1 | binary_upgrade_set_next_multirange_pg_type_oid binary_upgrade_set_next_pg_authid_oid | | binary_upgrade_set_next_pg_authid_oid binary_upgrade_set_next_pg_enum_oid | | binary_upgrade_set_next_pg_enum_oid + binary_upgrade_set_next_pg_subscription_oid | | binary_upgrade_set_next_pg_subscription_oid binary_upgrade_set_next_pg_tablespace_oid | | binary_upgrade_set_next_pg_tablespace_oid binary_upgrade_set_next_pg_type_oid | | binary_upgrade_set_next_pg_type_oid binary_upgrade_set_next_toast_pg_class_oid | 1 | binary_upgrade_set_next_toast_pg_class_oid binary_upgrade_set_next_toast_relfilenode | | binary_upgrade_set_next_toast_relfilenode -(13 rows) +(14 rows) -- Verify clean failure when INCLUDE'd columns result in overlength tuple -- The error message details are platform-dependent, so show only SQLSTATE @@ -108,11 +109,12 @@ select * from t binary_upgrade_set_next_multirange_pg_type_oid | 1 | binary_upgrade_set_next_multirange_pg_type_oid binary_upgrade_set_next_pg_authid_oid | | binary_upgrade_set_next_pg_authid_oid binary_upgrade_set_next_pg_enum_oid | | binary_upgrade_set_next_pg_enum_oid + binary_upgrade_set_next_pg_subscription_oid | | binary_upgrade_set_next_pg_subscription_oid binary_upgrade_set_next_pg_tablespace_oid | | binary_upgrade_set_next_pg_tablespace_oid binary_upgrade_set_next_pg_type_oid | | binary_upgrade_set_next_pg_type_oid binary_upgrade_set_next_toast_pg_class_oid | 1 | binary_upgrade_set_next_toast_pg_class_oid binary_upgrade_set_next_toast_relfilenode | | binary_upgrade_set_next_toast_relfilenode -(13 rows) +(14 rows) \set VERBOSITY sqlstate insert into t values(repeat('xyzzy', 12), 42, repeat('xyzzy', 4000)); -- 2.43.0