Skip to content

Sort column definitions stably in order_column_definitions - #66

Open
lucasmazza wants to merge 1 commit into
lfittl:masterfrom
tremendous-rewards:lm/fix-unstable-column-definition-sort
Open

Sort column definitions stably in order_column_definitions#66
lucasmazza wants to merge 1 commit into
lfittl:masterfrom
tremendous-rewards:lm/fix-unstable-column-definition-sort

Conversation

@lucasmazza

@lucasmazza lucasmazza commented Aug 13, 2026

Copy link
Copy Markdown
Contributor

With order_column_definitions enabled, the same schema dump produces different structure.sql output depending on the platform. Running db:migrate on macOS reorders inline CHECK constraint lines; running it on Linux against the same database leaves them alone. The result is a schema file that churns whenever contributors migrate on different operating systems.

order_column_definitions keys each line inside a CREATE TABLE body on its first word. Column lines key on the column name, so their keys are unique, but every inline CHECK constraint keys on the literal word CONSTRAINT and they all tie. sort_by! isn't stable and delegates to the platform's qsort — glibc happens to preserve the input order of tied lines, BSD doesn't.

Breaking ties by the original index keeps pg_dump's own ordering (alphabetical by constraint name), which matches what the Linux output already produced, so existing schema files sort to exactly what they already contain.

One note on the regression test: it fails on macOS without the fix, but passes either way on glibc, where the unstable sort happens to land on the right answer. CI runs on ubuntu, so it guards the behavior rather than reproducing the failure there.

Rebased on top of #67, so this is now a single commit touching clean_dump.rb and its test.

@lfittl

lfittl commented Aug 13, 2026

Copy link
Copy Markdown
Owner

Huh, good catch on that stray gitlink - my bad!

Can you split this into a separate PR?

@lucasmazza

Copy link
Copy Markdown
Contributor Author

@lfittl done at #67. After you merge that one I'll rebase this branch and leave just the sorting fix here

Running `db:migrate` on macOS reordered CHECK constraint lines in
db/structure.sql, while the same migration in Docker left the file
untouched. Same gem version, same Ruby, same database — only the
platform differed.

`order_column_definitions` keys each line inside a CREATE TABLE body on
its first word. Column lines key on the column name, so they get unique
keys. Every inline CHECK constraint keys on the literal word
"CONSTRAINT", so they all tie. `sort_by!` is not stable and delegates to
the platform's qsort: glibc happens to preserve the input order of tied
lines, BSD shuffles them.

Breaking ties by the original index keeps pg_dump's own ordering, which
is what the Linux output already produced. Feeding a real 1558-constraint
structure.sql back through the sort now returns it byte for byte, so
existing schema files see no churn.

One caveat on the regression test: it fails on macOS without the fix, but
passes either way on glibc, where the unstable sort happens to do the
right thing. CI runs on ubuntu, so it guards the behavior rather than
reproducing the failure there.
@lucasmazza
lucasmazza force-pushed the lm/fix-unstable-column-definition-sort branch from 148fcc6 to a4d370a Compare August 13, 2026 21:29
@lucasmazza

Copy link
Copy Markdown
Contributor Author

@lfittl this PR now has only the original sorting fix and should be ready for merge :)

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.

2 participants