Adjust error message to reflect the inheritance relationship

First seen: 2026-05-09 02:51:44+00:00 · Messages: 1 · Participants: 1

Latest Update

2026-05-11 · opus 4.7

Thread Analysis: Adjust error message to reflect the inheritance relationship

Core Problem

The thread raises a minor but legitimate user-experience issue in PostgreSQL's DDL error reporting for inheritance hierarchies. The reporter demonstrates the following scenario:

CREATE TABLE t0(c0 boolean);
CREATE TABLE t3(c0 boolean) INHERITS(t0);
ALTER TABLE ONLY t0 ADD CONSTRAINT Z PRIMARY KEY(c0);
-- ERROR:  column "c0" of table "t3" is not marked NOT NULL

The user issues ALTER TABLE ONLY t0 ... intending to operate only on the parent, yet the error message references the child table t3. At first glance this is confusing: why is PostgreSQL complaining about t3 when the user explicitly said ONLY t0?

Why This Behavior Is Architecturally Correct

The reporter correctly traces the logic into ATPrepAddPrimaryKey() in src/backend/commands/tablecmds.c. The comment there explains the design rationale:

For the case where we're asked not to recurse, we verify that a not-null constraint exists on each column of each (direct) child table, throwing an error if not. Not throwing an error would also work, because a not-null constraint would be created anyway, but it'd cause a silent scan of the child table to verify absence of nulls.

This reflects a deliberate PostgreSQL design decision about inheritance + primary keys:

  1. A PRIMARY KEY implies NOT NULL on each key column.
  2. In PostgreSQL's inheritance model, NOT NULL constraints on a parent must also be enforced on all descendants — a tuple in the child is conceptually visible through the parent, so a NULL in the child would violate the parent's PK semantics when queried via the parent.
  3. Therefore, even when the user says ONLY t0, the system must verify that every child column is already NOT NULL. If it isn't, PostgreSQL refuses rather than silently doing an expensive full-table scan of each child to prove null-absence.

So the error is not a bug — it's intentional defensive behavior to avoid hidden O(N) work across an inheritance tree.

Proposed Change

The reporter proposes a pure wording/clarity patch to the error message in tablecmds.c:

Justification: the phrase "child table" already appears elsewhere in tablecmds.c for analogous situations, so this aligns the diagnostic vocabulary across the file and immediately tells the user why a table they didn't name is appearing in the error.

Technical Assessment of the Patch

Strengths

Considerations / Tradeoffs

Key Technical Insights

The deeper lesson buried in this small thread is about NOT NULL propagation in inheritance and why ALTER TABLE ONLY ... ADD PRIMARY KEY isn't fully "only". Since work by Alvaro Herrera (pg16/17 era) to make NOT NULL a proper catalogued constraint (pg_constraint rows with contype = 'n'), the interplay between PK addition and child NOT NULL state has become more visible. The ATPrepAddPrimaryKey validation exists precisely because:

The error is the correct resolution of that trilemma, and improving its wording is exactly the kind of polish that helps users understand this non-obvious design.

Status

As of the posted message, this is a single-message proposal seeking feedback ("Any thoughts?"). No patch file was attached in-thread, no reviewers have weighed in, and no committer has responded yet. The change is small enough that it would likely be handled as a trivial cleanup patch if a committer picks it up; the main gating question is simply whether the improved clarity is judged worth the translation re-work.