From b82f60ca9cc79b4f6d0b0c059d1885f23b636ca9 Mon Sep 17 00:00:00 2001 From: Dilip Kumar Date: Mon, 13 Jul 2026 16:19:00 +0530 Subject: [PATCH v1] Do not reassign subscriptions belonging to other databases in REASSIGN OWNED. Subscription objects are fundamentally database-local in scope. Subscription DDL commands already operate on a per-database basis: CREATE SUBSCRIPTION stores subdbid = MyDatabaseId, and ALTER/DROP SUBSCRIPTION commands (including ALTER SUBSCRIPTION ... OWNER TO) look subscriptions up by (MyDatabaseId, subname) via the unique index on (subdbid, subname), acting strictly on subscriptions in the current database. Furthermore, subscription fields like subserver (commit 8185bb5) and subconflictlogrelid (commit a5918fd) reference database-local objects (!relisshared) in that database. However, because pg_subscription is stored as a shared catalog table (relisshared == true), shared dependency entries for subscriptions in pg_shdepend have dbid = InvalidOid. As a result, REASSIGN OWNED attempted to reassign subscriptions belonging to any database in the cluster. When executed in a database other than subdbid, this caused AlterSubscriptionOwner_internal() to resolve database-local references (such as subserver and subconflictlogrelid) against the current database (MyDatabaseId), resulting in errors or wrongly altering unrelated objects. Fix this by skipping subscription ownership reassignment in AlterSubscriptionOwner_internal() if form->subdbid != MyDatabaseId. Like other database-local objects, subscriptions will now be reassigned when REASSIGN OWNED is executed in the database to which they belong. --- doc/src/sgml/ref/reassign_owned.sgml | 5 ++++- doc/src/sgml/user-manag.sgml | 4 +++- src/backend/commands/subscriptioncmds.c | 9 +++++++++ 3 files changed, 16 insertions(+), 2 deletions(-) diff --git a/doc/src/sgml/ref/reassign_owned.sgml b/doc/src/sgml/ref/reassign_owned.sgml index ab692bd0690..5fca2329de2 100644 --- a/doc/src/sgml/ref/reassign_owned.sgml +++ b/doc/src/sgml/ref/reassign_owned.sgml @@ -48,7 +48,10 @@ REASSIGN OWNED BY { old_role | CURR The name of a role. The ownership of all the objects within the current database, and of all shared objects (databases, tablespaces), owned by this role will be reassigned to - new_role. + new_role. Subscriptions, + although stored in a shared catalog, belong to a specific database + and are reassigned only when REASSIGN OWNED is executed + in that database. diff --git a/doc/src/sgml/user-manag.sgml b/doc/src/sgml/user-manag.sgml index 0ec32700bd4..c7e0b11706e 100644 --- a/doc/src/sgml/user-manag.sgml +++ b/doc/src/sgml/user-manag.sgml @@ -530,7 +530,9 @@ ALTER TABLE bobs_table OWNER TO alice; that contains objects owned by the role. (Note that the first such REASSIGN OWNED will change the ownership of any shared-across-databases objects, that is databases or tablespaces, that - are owned by the role-to-be-dropped.) + are owned by the role-to-be-dropped. Subscriptions, while stored in a + shared catalog, belong to a specific database and are reassigned when + REASSIGN OWNED is executed in that database.) diff --git a/src/backend/commands/subscriptioncmds.c b/src/backend/commands/subscriptioncmds.c index 4292e7fb8f4..cd37885222a 100644 --- a/src/backend/commands/subscriptioncmds.c +++ b/src/backend/commands/subscriptioncmds.c @@ -2868,6 +2868,15 @@ AlterSubscriptionOwner_internal(Relation rel, HeapTuple tup, Oid newOwnerId) form = (Form_pg_subscription) GETSTRUCT(tup); + /* + * Don't process subscriptions belonging to other databases. While + * pg_subscription is a shared catalog, subscriptions refer to db-local + * objects like subserver and subconflictlogrelid which exist only in the + * database identified by subdbid. + */ + if (form->subdbid != MyDatabaseId) + return; + if (form->subowner == newOwnerId) return; -- 2.49.0