Logical Replication - revisit `is_table_publication` function implementation

First seen: 2026-04-07 07:02:23+00:00 · Messages: 8 · Participants: 3

Latest Update

2026-05-18 · claude-opus-4-6

Logical Replication: Revisiting is_table_publication and is_schema_publication Implementation

Core Problem

In PostgreSQL's logical replication subsystem, two internal functions — is_table_publication() and is_schema_publication() — determine the "type" of a publication by scanning system catalogs. Specifically:

These functions are called during ALTER PUBLICATION operations, particularly when adding EXCEPT clauses or modifying publication membership. The existing implementations unconditionally perform catalog scans (via SysScanDesc) even in cases where the answer can be trivially derived from the publication's Form_pg_publication metadata — specifically the puballtables and puballsequences boolean flags.

The key architectural invariant being exploited is that FOR ALL TABLES, FOR ALL SEQUENCES, FOR TABLE ..., and FOR TABLES IN SCHEMA ... are mutually exclusive publication modes. This means:

Therefore, both functions can short-circuit and return false immediately when either of these flags is set, avoiding unnecessary catalog scans entirely.

Proposed Solution

Patch v1

The initial patch adds an early-return check at the top of both is_table_publication() and is_schema_publication():

/* FOR TABLE / FOR TABLES IN SCHEMA cannot coexist with FOR ALL TABLES. */
if (pubform->puballtables)
    return false;

Additional cleanup includes:

Patch v2

After Shveta Malik pointed out that FOR ALL SEQUENCES is also mutually exclusive with FOR TABLE and FOR TABLES IN SCHEMA (a constraint the patch author initially missed), v2 adds an analogous short-circuit:

if (pubform->puballsequences)
    return false;

This ensures completeness: all three "global" publication modes (puballtables, puballsequences, and potentially future ones) are handled before falling through to the catalog scan path.

Where the Optimization Actually Helps

Shveta Malik's analysis in her April 9 message is the most architecturally precise in the thread. She identifies the specific code path where the optimization provides real benefit:

  1. Adding EXCEPT to an ALL TABLES publication: This is a valid, non-erroneous operation. Before this patch, is_table_publication() and is_schema_publication() would scan pg_publication_rel and pg_publication_namespace respectively, only to find no rows. With the patch, they return false immediately.

  2. Adding tables/schemas to an ALL TABLES publication: This errors out in CheckAlterPublication() before these functions are called, so the optimization doesn't help here.

  3. Adding tables/schemas to a normal (non-ALL) publication: The catalog scan is still needed to determine the publication's actual membership, so the optimization doesn't help here either.

  4. Error paths (e.g., adding EXCEPT to a FOR TABLE publication): The scan is still required to distinguish between a publication with actual table entries vs. an empty publication.

The optimization is therefore narrowly targeted but hits a valid production code path — specifically the EXCEPT clause workflow on ALL TABLES publications.

Technical Tradeoffs

Open Questions and Status

The patch received generally positive feedback but stalled without a committer picking it up. As of the last message (May 18, 2026), the author is seeking guidance on how to advance it. The patch lacks:

  1. Committer review: No committer has weighed in on the thread.
  2. Deep analysis of the prexcept removal: The simplification of is_table_publication() to no longer check prexcept deserves more scrutiny.
  3. Regression test coverage: No discussion of whether existing tests cover the optimized paths or whether new tests are needed.

This is a minor optimization/cleanup patch — the kind that often languishes without a champion among committers, particularly during busy development cycles.