Understanding ALTER TABLE Behavior on Partitioned Tables in PostgreSQL

Enterprise PostgreSQL Solutions

Comments are off

Understanding ALTER TABLE Behavior on Partitioned Tables in PostgreSQL

Partitioned tables are a core PostgreSQL feature, but one area still causes regular confusion—even for experienced users:

How exactly does ALTER TABLE behave when partitions are involved?

Does an operation propagate to partitions? Does it affect future partitions? Does ONLY do what it claims? Why do some commands work on parents but not on partitions—or vice versa?

Today, PostgreSQL documentation describes individual ALTER TABLE sub-commands well, but it rarely explains their interaction with partitioned tables as a whole. As a result, users often discover the real behavior only through trial and error.

This post summarizes a systematic investigation of ALTER TABLE behavior on partitioned tables, turning scattered rules into a consistent classification model.

The Problem: “Inconsistent” Is Not the Same as “Undocumented”

The PostgreSQL community often describes ALTER TABLE behavior on partitioned tables as inconsistent. In practice, the deeper problem is that:

  • The rules do exist, but

  • They are spread across code paths, error messages, and historical decisions, and

  • They are not documented in a way that lets users predict outcomes.

Without a mental model, even simple questions become hard to answer:

  • If I run this on the parent, what happens to existing partitions?

  • What about partitions created later?

  • Does ONLY prevent propagation—or is it ignored?

  • Can I override settings per partition?

How I Evaluated Each ALTER TABLE Sub-command

To make sense of this, I tested ALTER TABLE sub-commands against partitioned tables using the same set of questions each time.

Four evaluation criteria

For every sub-command, I asked:

  1. Propagation
    Does the action on a parent partitioned table propagate to existing partitions?
  2. Inheritance for new partitions
    If I create a new partition later, does it inherit the parent’s setting?
  3. Effect of ONLY
    Does ONLY parent_table actually prevent propagation, as the documentation suggests?
  4. Independence
    Can parent and child partitions have different values?

These four questions turn vague “inconsistency” into something concrete and testable.

Scope and version note

This analysis is based on PostgreSQL 18 development behavior (as of early 2026). All observations were verified against PostgreSQL 18, and some details may differ in earlier releases or change in future versions as partitioning support continues to evolve.

A Classification Model for ALTER TABLE on Partitioned Tables

Based on those criteria, ALTER TABLE sub-commands naturally fall into 15 categories. Each category represents a distinct behavioral pattern.

Think of these as reference buckets rather than value judgments.

C1 – Parent-only structural changes

These commands:

  • Can only be used on a partitioned table
  • Fail on partitions
  • Reject ONLY

They are:

  • ADD COLUMN
  • DROP COLUMN
  • SET DATA TYPE
  • DROP EXPRESSION
  • ADD GENERATED AS IDENTITY
  • ADD GENERATED
  • SET sequence_option
  • RESTART
  • ALTER CONSTRAINT

These commands define the shape of the partitioned table and must remain globally consistent.

C2 – Propagating changes with inheritance

These commands:

  • Propagate from parent to partitions
  • Respect ONLY
  • Are inherited by future partitions
  • Can be overridden per partition

They are:

  • SET DEFAULT
  • DROP DEFAULT
  • SET EXPRESSION AS
  • SET STORAGE
  • DROP CONSTRAINT
  • ENABLE/DISABLE TRIGGER

This is often what users expect ALTER TABLE to behave like.

C3 – Propagating, but not inherited by new partitions

Only one sub-command in this category:

  • SET STATISTICS

The behavior is the same as C2 except that, existing partitions are updated, but future ones are not—an important surprise if you assume inheritance is automatic.

C4 – Fully independent parent and partitions

These commands:

  • Do not propagate
  • Are not inherited
  • Allow different values per partition
  • Accept ONLY, but it has no effect

They are:

  • SET/RESET (attribute_option = value)
  • ENABLE/DISABLE [ REPLICA | ALWAYS ] RULE
  • ENABLE/DISABLE ROW LEVEL SECURITY
  • NO FORCE / FORCE ROW LEVEL SECURITY
  • OWNER TO
  • REPLICA IDENTITY
  • SET SCHEMA

From a user’s perspective, parent and partitions behave like unrelated tables.

C5 – Independent, but inherited by new partitions

Only one sub-command in this category:

  • SET COMPRESSION

The behavior is the same as C4 except that, existing partitions are untouched, but new partitions pick up the parent’s setting.

C6 – Mandatory propagation

Only one sub-command in this category:

  • ADD table_constraint

The behavior is the same as C2 except that, ONLY is rejected—the system enforces consistency across all partitions.

C7 – Leaf-partition-only commands

These commands:

  • Cannot be used on partitioned tables
  • Work only on leaf partitions

They are:

  • ADD table_constraint_with_index
  • ALTER CONSTRAINT ... INHERIT / NO INHERIT
  • CLUSTER ON
  • SET WITHOUT CLUSTER
  • SET LOGGED / UNLOGGED
  • SET (storage_parameter)

C8 – Parent-scoped, but partition-overridable

Only one sub-command in this category:

  • VALIDATE CONSTRAINT

The behavior is the same as C1 except that, validation is defined at the parent level, but partitions can differ in state.

C9 – Conditional inheritance

Only one sub-command in this category:

  • SET ACCESS METHOD

The behavior is the same C2 except that, if the parent has a value, new partitions inherit it. Otherwise, they fall back to the GUC default.

C10 – No propagation, but inherited by new partitions

Only one sub-command in this category:

  • SET TABLESPACE

Existing partitions remain unchanged, but future ones follow the parent. Accept ONLY, but it has no effect.

C11 – No-op on parents

Only one sub-command in this category:

  • RESET (storage_parameter)

These commands don’t fail on partitioned tables—but they don’t do anything either.

C12 – Unsupported for partitioned tables

These sub-commands are:

  • INHERIT
  • NO INHERIT

These are conceptually incompatible with declarative partitioning.

C13 – Parent-only metadata binding

These sub-commands are:

  • OF type
  • NOT OF

These apply only to the partitioned table itself. Accept ONLY, but it has no effect. They will fail on partitions.

C14 – Treated as normal tables

Only one sub-command in this category::

  • RENAME

No propagation, no inheritance, no partition-specific behavior.

C15 – Partition management commands

These sub-commands are:

  • ATTACH PARTITION
  • DETACH PARTITION

These commands operate on the partitioning structure rather than its properties.

Closing Notes

Until PostgreSQL documentation explicitly describes ALTER TABLE behavior on partitioned tables, this kind of reference remains essential.

If you work with partitioned tables regularly, I recommend bookmarking this mental model—and checking which category a command falls into before running it in production.