Skip to content

fix: emit per-child column overrides in PARTITION OF (#499)#500

Merged
tianzhou merged 4 commits into
mainfrom
fix/issue-499-partition-column-overrides
Jul 3, 2026
Merged

fix: emit per-child column overrides in PARTITION OF (#499)#500
tianzhou merged 4 commits into
mainfrom
fix/issue-499-partition-column-overrides

Conversation

@tianzhou

@tianzhou tianzhou commented Jul 3, 2026

Copy link
Copy Markdown
Contributor

Summary

  • When a partition child overrides DEFAULT or NOT NULL relative to its parent, the PARTITION OF statement now includes the column-element list (e.g. priority DEFAULT 10, notes NOT NULL).
  • Adds allTables map to generateTableSQL so it can compare child columns against the parent and detect overrides.
  • Adds test case issue_499_partition_column_overrides with full diff/plan fixtures.

Closes #499

Test plan

  • TestDiffFromFiles/create_table_issue_499_partition_column_overrides passes
  • All internal/diff tests pass
  • CI green

🤖 Generated with Claude Code

… OF (#499)

When a partition child overrides DEFAULT or NOT NULL relative to the
parent, generate the column-element list inside the PARTITION OF
statement so `pgschema plan` produces faithful DDL.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings July 3, 2026 09:45

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR extends the CREATE TABLE ... PARTITION OF ... emission path so that partition children can include a typed-table element list when they override DEFAULT and/or NOT NULL relative to the parent, aligning generated DDL with PostgreSQL’s supported grammar and addressing issue #499.

Changes:

  • Detect per-child column overrides for partition children and include them in the PARTITION OF (...) element list.
  • Thread an allTables lookup into generateTableSQL to compare child columns against the parent.
  • Add a new fixture-backed test case (issue_499_partition_column_overrides) validating the emitted plan/DDL.

Reviewed changes

Copilot reviewed 8 out of 8 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
internal/diff/table.go Adds partition-child column override detection and includes override elements in the PARTITION OF (...) list.
internal/diff/qualify_schema_test.go Updates test helper calls for the new generateTableSQL(..., allTables) signature.
testdata/diff/create_table/issue_499_partition_column_overrides/plan.txt New expected plan output for the added fixture.
testdata/diff/create_table/issue_499_partition_column_overrides/plan.sql New expected SQL plan output for the added fixture.
testdata/diff/create_table/issue_499_partition_column_overrides/plan.json New expected JSON plan output for the added fixture.
testdata/diff/create_table/issue_499_partition_column_overrides/old.sql New fixture: empty starting schema.
testdata/diff/create_table/issue_499_partition_column_overrides/new.sql New fixture: partitioned table + child overrides.
testdata/diff/create_table/issue_499_partition_column_overrides/diff.sql New expected diff SQL for the fixture.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread internal/diff/table.go Outdated
@greptile-apps

greptile-apps Bot commented Jul 3, 2026

Copy link
Copy Markdown

Greptile Summary

This PR fixes issue #499 by emitting per-child column overrides (DEFAULT, NOT NULL) in PARTITION OF DDL when a partition child diverges from its parent. It introduces an allTables lookup map inside generateCreateTablesSQL and threads it through to generateTableSQL, where parent–child column comparisons drive the new override emission.

  • internal/diff/table.go: builds an allTables map from the batch of tables being created and passes it to generateTableSQL; the function now compares each child column against its parent to detect DEFAULT and NOT NULL overrides and emits them in the PARTITION OF body.
  • testdata/diff/create_table/issue_499_partition_column_overrides/: adds a complete fixture set (old/new SQL, diff, plan) covering a list-partitioned orders table with orders_us having priority DEFAULT 10 and notes NOT NULL overrides.

Confidence Score: 3/5

The fix correctly handles the tested scenario but silently produces wrong DDL in two real migration paths, making it unsafe to merge as-is.

The allTables map is scoped to each call of generateCreateTablesSQL. Because diff.go calls that function twice with two disjoint table batches, a child in batch 2 cannot see a parent from batch 1. Separately, when a partition child is added to a pre-existing parent, the parent is absent from addedTables entirely. In both cases the override detection guard silently falls through, emitting bare PARTITION OF DDL without column overrides — and since PostgreSQL has no ALTER path to add them post-creation, the resulting schema is permanently wrong without any error or warning.

internal/diff/table.go — specifically the allTables construction and the parentKey lookup inside generateTableSQL

Important Files Changed

Filename Overview
internal/diff/table.go Core change: builds allTables from the current batch and threads it into generateTableSQL for parent–child column override detection; has gaps when parent and child land in different creation batches or when the parent already exists.
internal/diff/qualify_schema_test.go Trivially updated to pass nil as the new allTables argument; nil map reads are safe in Go.
testdata/diff/create_table/issue_499_partition_column_overrides/diff.sql Expected migration DDL fixture; matches the override logic being tested (priority DEFAULT 10, notes NOT NULL on orders_us).
testdata/diff/create_table/issue_499_partition_column_overrides/new.sql New schema fixture; correctly defines orders_us with priority DEFAULT 10 and notes NOT NULL overrides, and orders_eu with no overrides.
testdata/diff/create_table/issue_499_partition_column_overrides/plan.json Plan JSON fixture; captures expected SQL for all three tables including the override in orders_us.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[generateCreateTablesSQL\ncalled with batch of new tables] --> B[Build allTables map\nfrom batch only]
    B --> C[For each table in batch]
    C --> D{table.PartitionOf != ''}
    D -- No --> E[Emit standard CREATE TABLE]
    D -- Yes --> F{parentKey in allTables?}
    F -- No --> G[No override detection\n⚠ silent miss if parent\nin different batch or\nalready exists]
    F -- Yes --> H[For each child column\ncompare with parent column]
    H --> I{childDefault != parentDefault\nAND child has DEFAULT?}
    I -- Yes --> J[Append DEFAULT override]
    I -- No --> K{child NOT NULL\nAND parent nullable?}
    J --> K
    K -- Yes --> L[Append NOT NULL override]
    K -- No --> M[Next column]
    L --> M
    M --> N{More columns?}
    N -- Yes --> H
    N -- No --> O[Combine elementParts + constraintParts]
    O --> P{Any parts?}
    P -- Yes --> Q[Emit PARTITION OF with column element list]
    P -- No --> R[Emit bare PARTITION OF]
Loading
%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%%
flowchart TD
    A[generateCreateTablesSQL\ncalled with batch of new tables] --> B[Build allTables map\nfrom batch only]
    B --> C[For each table in batch]
    C --> D{table.PartitionOf != ''}
    D -- No --> E[Emit standard CREATE TABLE]
    D -- Yes --> F{parentKey in allTables?}
    F -- No --> G[No override detection\n⚠ silent miss if parent\nin different batch or\nalready exists]
    F -- Yes --> H[For each child column\ncompare with parent column]
    H --> I{childDefault != parentDefault\nAND child has DEFAULT?}
    I -- Yes --> J[Append DEFAULT override]
    I -- No --> K{child NOT NULL\nAND parent nullable?}
    J --> K
    K -- Yes --> L[Append NOT NULL override]
    K -- No --> M[Next column]
    L --> M
    M --> N{More columns?}
    N -- Yes --> H
    N -- No --> O[Combine elementParts + constraintParts]
    O --> P{Any parts?}
    P -- Yes --> Q[Emit PARTITION OF with column element list]
    P -- No --> R[Emit bare PARTITION OF]
Loading

Reviews (1): Last reviewed commit: "fix: emit per-child column overrides (DE..." | Re-trigger Greptile

Comment thread internal/diff/table.go Outdated
Comment thread internal/diff/table.go
Address review feedback from Copilot, Greptile, and @schema-codex:
the parent lookup for column-override detection was scoped to the
current add-table batch, silently missing existing parents and
cross-batch parents. Now uses allNewTables (all tables from the
target schema state) so override detection works regardless of
whether the parent is new or pre-existing.

Adds regression fixture for the incremental case (existing parent,
new child with overrides).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 15 out of 15 changed files in this pull request and generated 2 comments.

Comment thread internal/diff/table.go
@tianzhou

tianzhou commented Jul 3, 2026

Copy link
Copy Markdown
Contributor Author

Re-checked the latest head after 7decbf3 and 0c77576.

The earlier blocker was real, but it is now addressed: parent lookup for partition-column override comparison is sourced from the full target IR, and the incremental existing-parent case is covered by the new regression fixture. The remaining CI failure was only the stale plan fixture hash, which 0c77576 corrected.

Current CI is green on the latest head. Greptile's remaining summary is stale and refers to the older d775dc1 snapshot. No remaining findings from the reviewer pass; ready to merge.

Keep the existing-parent case (stronger test — covers the
review-flagged incremental scenario) and remove the redundant
empty-schema case.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@tianzhou tianzhou merged commit 7011b0a into main Jul 3, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

PARTITION OF create path: support child-specific column elements

2 participants