Include schema-qualified names in publication error messages.

First seen: 2026-04-28 11:03:34+00:00 · Messages: 34 · Participants: 6

Latest Update

2026-06-01 · claude-opus-4-6

Monthly Summary: Schema-Qualified Names in Publication Error Messages (May 2026)

Overview

This thread reached completion in May 2026, progressing from API design refinement through final commit and backpatch, with a minor post-commit quoting issue identified but accepted as pre-existing behavior.

Problem Statement

The function check_publication_add_relation() in pg_publication.c emitted error messages with only unqualified relation names (e.g., ERROR: "orders" is a system table), creating ambiguity in multi-schema databases — particularly problematic for logical replication setups referencing many relations across schemas.

Key Design Decisions

Two-Helper Architecture (Finalized)

The final committed design uses two helpers:

  1. get_qualified_objname in lsyscache.c — Oid-based, generalized for any namespace-qualified object (not just relations). Named generically after Shveta surveyed other call sites (getObjectIdentityParts(), generate_function_name(), etc.) that follow the same pattern.

  2. RelationGetQualifiedRelationName in rel.h/relcache.c — A thin Relation-based wrapper following the RelationGet* naming family. Placed with relcache APIs rather than lsyscache.c because the input is a Relation descriptor, not an Oid, following PostgreSQL's "input-type-dictates-module" convention.

Both use quote_qualified_identifier() at their core for proper double-quoting.

Two-Patch Split Strategy (Executed)

The rationale: changing long-standing error message text in stable branches breaks log-analysis tooling that matches on message shape, but freshly-introduced messages haven't calcified yet.

Backpatch Committed

Vignesh submitted the backpatch variant, accepting Euler's argument for keeping the local variable (since alignment with the already-committed HEAD patch was no longer a constraint). Amit Kapila pushed the backpatch after minor adjustments.

Post-Commit Issue: Nested Quoting

Peter Smith identified a quoting anomaly where errmsg() templates wrap %s in hardcoded double quotes, but quote_qualified_identifier() also quotes components, producing:

ERROR: cannot specify relation "public."my table"" in the publication EXCEPT clause

Vignesh demonstrated this is pre-existing behavior (same pattern in REFRESH MATERIALIZED VIEW CONCURRENTLY) and the issue was accepted as status quo with no follow-up patch proposed.

Thread Status

Closed. Both HEAD and backpatch commits are done. The nested-quoting concern is acknowledged but deferred as a broader pre-existing PostgreSQL design tension.

History (1 prior analysis)
2026-06-01 · claude-opus-4-6

Peter Smith Proposes Broader Scope: Schema-Qualify All Logical Replication Messages

Peter Smith has reopened the substantive discussion around the v5-0002 patch (targeting PG20), arguing it should be dramatically expanded in scope beyond check_publication_add_relation().

Key New Technical Argument: The Original Patch Is Too Narrow

Peter identifies dozens of additional call sites across logical replication code where relation/table/sequence names appear in error messages either unqualified or manually qualified (using inline "%s.%s" patterns) rather than using the new common helper (RelationGetQualifiedRelationName). He presents a comprehensive audit spanning:

  • publicationcmds.c — WHERE clause errors, column list errors, PublicationDropTables, OpenTableList conflicts
  • objectaddress.c — publication relation lookups
  • pg_publication.cpub_collist_validate, publication_add_relation
  • pg_subscription.cRemoveSubscriptionRel table sync state messages
  • subscriptioncmds.c — sequence removal/state messages (already using manual %s.%s)
  • sequencesync.c — sync completion messages (already using manual %s.%s)
  • tablecmds.cATPrepChangePersistence, ATExecAttachPartition
  • execReplication.cCheckCmdReplicaIdentity (multiple UPDATE/DELETE errors)
  • syncutils.c / worker.c — table sync worker start/finish messages

This transforms what was a 1-function fix into a cross-module consistency project.

Pushback on Euler's Stability Concern

Peter explicitly disagrees with Euler's earlier position about not changing existing messages. His argument: this isn't rewording for style — it's fixing substituted values to remove ambiguity while keeping message templates structurally the same. He concedes the point only if Euler's concern was specifically about backpatching (which Peter agrees shouldn't happen).

Code Review Nits on v5-0002

  1. Function name mismatch: Peter notes the committed function is RelationGetQualifiedRelationName but the v5-0002 patch still uses get_relation_qualified_name — the patch needs rebasing against the committed HEAD API.

  2. Repeated function calls: Peter reiterates that calling get_relation_qualified_name(targetrel) inline at every errmsg() site is less clean than assigning to a local variable up-front — echoing Euler's earlier argument but now in the context of the broader expansion.

Implications

If this broader scope is accepted, the v5-0002 patch for PG20 would grow from a handful of changes in one file to touching at least 8 source files across commands, catalog, executor, and replication subsystems. This significantly raises the review/testing burden and may require splitting into sub-patches by subsystem.