Skip to content

deparser: ON DELETE SET NULL (column_list) loses its column list #349

Description

@jasdeepkhalsa

Summary

pgsql-deparser drops the optional column list from ON DELETE SET NULL (...) and ON DELETE SET DEFAULT (...). The output is still valid SQL, but it means something different from the input — the referential action is silently widened from specific columns to all foreign key columns.

The column list on SET NULL / SET DEFAULT was added in PostgreSQL 15.

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 child ADD CONSTRAINT child_fk FOREIGN KEY (a, b) REFERENCES parent(a, b) ON DELETE SET NULL (b);`
console.log(await deparse((await parse(sql)).sql))

Expected

ALTER TABLE ONLY child ADD CONSTRAINT child_fk FOREIGN KEY (a, b) REFERENCES parent (a, b) ON DELETE SET NULL (b);

Actual

ALTER TABLE ONLY child ADD CONSTRAINT child_fk FOREIGN KEY(a, b) REFERENCES parent (a, b) ON DELETE SET NULL;

SET DEFAULT behaves the same way:

in : ... ON DELETE SET DEFAULT (b);
out: ... ON DELETE SET DEFAULT;

The parse tree is correct

Constraint keys: contype, conname, is_enforced, initially_valid, pktable,
                 fk_attrs, pk_attrs, fk_matchtype, fk_upd_action,
                 fk_del_action, fk_del_set_cols, location

fk_del_set_cols: [{"String":{"sval":"b"}}]
fk_del_action  : "n"

fk_del_set_cols is populated but does not appear to be consulted when rendering the ON DELETE clause.

Impact

This one is quiet — the output parses and applies cleanly, so nothing surfaces at apply time. The difference only shows up later, when a delete nulls more columns than the original schema intended.

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