summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMasahiko Sawada2026-08-26 19:03:58 +0000
committerMasahiko Sawada2026-08-26 19:03:58 +0000
commitec074c41efbd93ddc4b882c142c15c8d5b2ae6f8 (patch)
treeb3a7b8376c8a531d4ff9f54be3a24f056eac8ab3
parent715d8397195c6435bae837446c3ae9b1dcd4221a (diff)
Fix crash in subscription refresh on concurrent relation drop.
Commit 46b4f5c11b0 made the logical replication origin checks quote the schema and relation names they interpolate into the query sent to the publisher. Those names can be NULL, which that commit overlooked. AlterSubscription_refresh() collects the OIDs of the relations already present in pg_subscription_rel and hands them to check_publications_origin_tables() and check_publications_origin_sequences(), which append the schema-qualified name of each one to the query so that already-subscribed relations are excluded from the check. The relations are never locked, so one of them can be dropped concurrently before its name is read, and get_rel_name() and get_namespace_name() return NULL. quote_literal_cstr() dereferences it and crashes the backend. This commit fixes this by skipping a relation whose name is no longer available. A dropped relation is not synchronized anyway, and the appended clauses only exclude relations from a check whose sole effect is a WARNING, so omitting one can at most produce a spurious WARNING. The window is reachable from ALTER SUBSCRIPTION ... REFRESH PUBLICATION and from SET, ADD and DROP PUBLICATION, which refresh by default, but only when copy_data is true and origin is none. Backpatch to v16 as commit 46b4f5c11b0 was back-patched that far. The sequence path exists only in v19 and later. The test is applied to v19 and later only. Adding it to v17 and v18 would require enabling injection point support in src/test/subscription there, and v16 predates injection points entirely. That is more test infrastructure churn on stable branches than this fix warrants. Reported-by: SATYANARAYANA NARLAPURAM <satyanarlapuram@gmail.com> Author: SATYANARAYANA NARLAPURAM <satyanarlapuram@gmail.com> Co-authored-by: Bharath Rupireddy <bharath.rupireddyforpostgres@gmail.com> Reviewed-by: Ajin Cherian <itsajin@gmail.com> Reviewed-by: Masahiko Sawada <sawada.mshk@gmail.com> Discussion: https://postgr.es/m/CAHg+QDcd_o3707Ey8c8b7HkE-t14g8c0tk8ME3ctywDsh3ut8g@mail.gmail.com Backpatch-through: 16
-rw-r--r--src/backend/commands/subscriptioncmds.c20
1 files changed, 16 insertions, 4 deletions
diff --git a/src/backend/commands/subscriptioncmds.c b/src/backend/commands/subscriptioncmds.c
index 395dcc678c2..88b71187b7d 100644
--- a/src/backend/commands/subscriptioncmds.c
+++ b/src/backend/commands/subscriptioncmds.c
@@ -2164,10 +2164,22 @@ check_publications_origin(WalReceiverConn *wrconn, List *publications,
for (i = 0; i < subrel_count; i++)
{
Oid relid = subrel_local_oids[i];
- char *schemaname = get_namespace_name(get_rel_namespace(relid));
- char *tablename = get_rel_name(relid);
- char *schemaname_lit = quote_literal_cstr(schemaname);
- char *tablename_lit = quote_literal_cstr(tablename);
+ char *schemaname;
+ char *tablename;
+ char *schemaname_lit;
+ char *tablename_lit;
+
+ /* The table may have been dropped concurrently; skip if gone. */
+ tablename = get_rel_name(relid);
+ if (tablename == NULL)
+ continue;
+
+ schemaname = get_namespace_name(get_rel_namespace(relid));
+ if (schemaname == NULL)
+ continue;
+
+ schemaname_lit = quote_literal_cstr(schemaname);
+ tablename_lit = quote_literal_cstr(tablename);
appendStringInfo(&cmd, "AND NOT (N.nspname = %s AND C.relname = %s)\n",
schemaname_lit, tablename_lit);