Skip to content

deparser: schema-qualified partition name is dropped from ATTACH/DETACH PARTITION #348

Description

@jasdeepkhalsa

Summary

pgsql-deparser drops the partition name entirely from ALTER TABLE ... ATTACH PARTITION and DETACH PARTITION when that name is schema-qualified. The resulting SQL is syntactically invalid. Unqualified names are handled correctly.

This matters in practice because pg_dump always emits schema-qualified names, so any parse → deparse round-trip of a dump containing partitioned tables produces broken SQL.

Versions

  • pgsql-deparser@18.3.6
  • plpgsql-parser@18.5.8
  • libpg-query@18.1.4
  • Node 24

Reproduction

import { parse } from 'plpgsql-parser'
import { deparse } from 'pgsql-deparser'
import { loadModule } from 'libpg-query'
await loadModule()

const sql = `ALTER TABLE ONLY public.measurement ATTACH PARTITION public.measurement_y2024 FOR VALUES FROM ('2024-01-01') TO ('2025-01-01');`
console.log(await deparse((await parse(sql)).sql))

Expected

ALTER TABLE ONLY public.measurement ATTACH PARTITION public.measurement_y2024 FOR VALUES FROM ('2024-01-01') TO ('2025-01-01');

Actual

ALTER TABLE ONLY public.measurement ATTACH PARTITION FOR VALUES FROM ('2024-01-01') TO ('2025-01-01');

The partition name is missing. DETACH is affected the same way:

in : ALTER TABLE ONLY public.measurement DETACH PARTITION public.measurement_y2024;
out: ALTER TABLE ONLY public.measurement DETACH PARTITION ;

Control — the unqualified form is correct:

in : ALTER TABLE ONLY measurement ATTACH PARTITION measurement_y2024 FOR VALUES FROM ('2024-01-01') TO ('2025-01-01');
out: ALTER TABLE ONLY measurement ATTACH PARTITION measurement_y2024 FOR VALUES FROM ('2024-01-01') TO ('2025-01-01');

The parse tree is correct

The name is present in the AST, so this looks like a deparser-side omission rather than a parser problem:

{"PartitionCmd":{"name":{"schemaname":"public","relname":"measurement_y2024","inh":true,"relpersistence":"p"},
 "bound":{"strategy":"r","lowerdatums":[...],"upperdatums":[...]}}}

PartitionCmd.name appears to be rendered by a path that reads relname but not schemaname.

Impact

Silent corruption rather than a loud failure: the statement is emitted, just without its target. In a migration pipeline this either fails to apply or, worse, is skipped as unparseable further downstream.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions