deparser: hash partition with REMAINDER 0 loses its entire FOR VALUES clause #350
Description
Summary
For a hash partition with REMAINDER 0, the deparser omits the whole FOR VALUES WITH (...) clause, producing invalid SQL. REMAINDER 1, 2, … are fine.
Every hash-partitioned table has exactly one remainder-0 partition, so this affects every hash partitioning scheme.
Versions
pgsql-deparser@18.3.6plpgsql-parser@18.5.8libpg-query@18.1.4- Node 24
Reproduction
import { parse } from 'plpgsql-parser'
import { deparse } from 'pgsql-deparser'
import { loadModule } from 'libpg-query'
await loadModule()
for (const r of [0, 1, 2]) {
const sql = `ALTER TABLE ONLY o ATTACH PARTITION o_p FOR VALUES WITH (MODULUS 4, REMAINDER ${r});`
console.log(await deparse((await parse(sql)).sql))
}Expected
ALTER TABLE ONLY o ATTACH PARTITION o_p FOR VALUES WITH (MODULUS 4, REMAINDER 0);Actual
REMAINDER 0 -> ALTER TABLE ONLY o ATTACH PARTITION o_p; <-- invalid
REMAINDER 1 -> ALTER TABLE ONLY o ATTACH PARTITION o_p FOR VALUES WITH (modulus 4, remainder 1);
REMAINDER 2 -> ALTER TABLE ONLY o ATTACH PARTITION o_p FOR VALUES WITH (modulus 4, remainder 2);
Cause
The AST loses the field, because protobuf JSON encoding omits zero-valued scalars:
REMAINDER 0 -> {"strategy":"h","modulus":4,"location":52}
REMAINDER 1 -> {"strategy":"h","modulus":4,"remainder":1,"location":52}
So remainder being absent is not distinguishable from remainder: 0 at the AST level — that part is arguably inherent to the encoding.
The actionable part is the deparser's response to it. Given strategy: "h", a missing remainder should be treated as 0 and rendered, rather than causing the entire FOR VALUES clause to be dropped. A hash bound is never valid without one, so the current behaviour cannot be correct in any case.
Aside
The clause is emitted in lower case (modulus / remainder). That is accepted by PostgreSQL, so it is cosmetic, but it differs from pg_dump's output if anyone is diffing rendered SQL as text.
Activity
Merge pull request #352 from constructive-io/fix/deparser-issues-292-…
pyramation commentedon Sep 17, 2026
thank you :)
pyramation commentedon Sep 17, 2026
thanks again!
#352 (comment)