Skip to content

pg/catalog: pin four migration behaviors bytebase was testing for us - #407

Merged
rebelice merged 2 commits into
mainfrom
move-pg-sdl-migration-tests
Sep 4, 2026
Merged

pg/catalog: pin four migration behaviors bytebase was testing for us#407
rebelice merged 2 commits into
mainfrom
move-pg-sdl-migration-tests

Conversation

@d-bytebase

@d-bytebase d-bytebase commented Sep 3, 2026

Copy link
Copy Markdown
Contributor

What changed since the first push

This opened as a straight move of 24 test files out of bytebase's backend/plugin/schema/pg. Reading them against what pg/catalog already tests, that was the wrong shape, so the PR is now +106 lines across 3 existing files instead of +6,363 across 25 new ones.

Why

The 24 files called this package directly — LoadSDL, Diff, GenerateMigration — with no bytebase symbol in them, so they did belong here. But pg/catalog already tests nearly all of what they cover, with more cases and better assertions:

Their file Already covered by
column_sdl_diff, column_migration_integration diff_column_test.go (15 cases incl. identity, generated, collation), migration_column_test.go
comment_migration, get_sdl_diff_comment, procedure_sdl_diff diff_comment_test.go (13 cases), migration_comment_test.go (incl. "COMMENT ON VIEW uses VIEW not TABLE", "COMMENT ON PROCEDURE uses PROCEDURE not FUNCTION")
sequence_sdl_diff, sequence_migration_integration diff_sequence_test.go (incl. TestDiffSequenceSerialAbsorption), migration_sequence_test.go
view_sdl_diff, materialized_view_sdl_diff, view_migration_integration diff_view_test.go, migration_view_test.go (incl. "Matview indexes generated after matview creation")
standalone_index, camelcase_index migration_index_test.go, and TestContainerIdentifierQuoting/camelCase_in_index — which proves it against a real Postgres
trigger_sdl_diff, trigger_drop_dependency diff_trigger_test.go (12 cases), migration_ordering_test.go "2.2 drop table + dependent trigger → trigger dropped before table"
schema_implicit_creation migration_schema_test.go "schema operations ordered before table operations"
diff_audit (10 behaviors) migration_table_test.go "DROP TABLE CASCADE", migration_comment_test.go view/matview/procedure targets, diff_sequence_test.go absorption, migration_trigger_test.go "modified trigger as DROP plus CREATE"
parsing_migration extension_test.go, migration_extension_test.go, diff_column_test.go identity cases

They also assert differently from everything here: require.Contains(plan.SQL(), "…") against one concatenated blob, where pg/catalog inspects typed ops. That is what produced all four Codex findings on the first push, and two of the files were worse than duplicative — TestExcludeConstraintIndexNotDuplicated asserts the absence of an index name that appears nowhere in its fixture, which no code change can ever fail, and neither "exclude constraint" test has an EXCLUDE constraint in it at all.

What is actually new

Four behaviors were not covered anywhere here. Each goes into the file it belongs to, in that file's shape:

  • EXCLUDE backing index NOT generated (migration_index_test.go) — sits beside the PK/UNIQUE case that was already pinned. EXCLUDE carries an index the same way; a CREATE INDEX emitted next to the ADD CONSTRAINT fails on apply because the constraint already took the name.
  • Extension name does not become a schema (migration_extension_test.go) — a CREATE SCHEMA "pg_trgm" beside CREATE EXTENSION "pg_trgm" fails anywhere the extension is already installed.
  • Single quotes in a comment are doubled (migration_comment_test.go) — quoteLiteral has done this since it was written and nothing tested it. This is Codex's 4th finding, kept rather than dropped.
  • Dropping a procedure leaves a same-named function's comment alone (migration_comment_test.go) — procedures and functions share one catalog, so routine_x() the function and routine_x(integer) the procedure are separated only by their argument lists. A comment differ keyed on the bare name reports the dropped procedure's comment as a change to the surviving function.

Bug found on the way

Dropping any commented object emits COMMENT ON … IS NULL in PhaseMain, after the object's own DROP in PhasePre, and PostgreSQL has no COMMENT … IF EXISTS — so the migration fails on apply. Reproduced against postgres:16-alpine for tables, views and procedures alike. Filed as #408; the fix belongs in generateCommentDDL and wants a container test of its own, so it is not carried here.

Testing

Each new case carries a positive precondition so its negative assertion cannot pass vacuously, and each was checked by mutation — invert the expectation, confirm the test fails:

--- FAIL: TestMigrationIndex/EXCLUDE_backing_index_NOT_generated
--- FAIL: TestMigrationExtension/Extension_name_does_not_become_a_schema
--- FAIL: TestMigrationComment/single_quotes_in_a_comment_are_doubled
--- FAIL: TestMigrationComment/dropping_a_procedure_leaves_an_unrelated_function's_comment_alone
  • go build ./...
  • go test -count=1 ./pg/catalog/ — pass, 17.6 s
  • go test -short -count=1 ./pg/catalog/ — pass, 4.9 s
  • go test -tags=oracle -run '^$' -count=1 ./pg/catalog/ — compiles

The companion bytebase PR still deletes the 24 files there: bytebase/bytebase#21337.

🤖 Generated with Claude Code

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: e177d698dd

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread pg/catalog/diff_audit_test.go Outdated
Comment thread pg/catalog/standalone_index_test.go Outdated
Comment thread pg/catalog/materialized_view_sdl_diff_test.go Outdated
Comment thread pg/catalog/comment_migration_test.go Outdated
@d-bytebase
d-bytebase force-pushed the move-pg-sdl-migration-tests branch from e177d69 to 6d6ba1b Compare September 3, 2026 17:11
bytebase's backend/plugin/schema/pg held 24 test files that called this package
directly — LoadSDL, Diff, GenerateMigration — with no bytebase symbol in them.
Read against what pg/catalog already tests, all but four of their behaviors are
covered here, usually by more cases and always with better assertions: they
string-matched plan.SQL() where these files inspect typed ops. So this takes the
four that were not covered, in the shape of the file each belongs to, rather
than the 6,300 lines.

- EXCLUDE backing index NOT generated (migration_index_test.go). The PK/UNIQUE
  case beside it was already pinned; EXCLUDE carries an index the same way and
  was not. A CREATE INDEX emitted next to the ADD CONSTRAINT fails on apply.
- Extension name does not become a schema (migration_extension_test.go). A
  CREATE SCHEMA "pg_trgm" beside CREATE EXTENSION "pg_trgm" fails anywhere the
  extension is already installed.
- Single quotes in a comment are doubled (migration_comment_test.go).
  quoteLiteral has been doubling them since it was written and nothing tested
  it; a bare quote closes the literal early and the statement stops parsing.
- Dropping a procedure leaves an unrelated function's comment alone
  (migration_comment_test.go). Procedures and functions share one catalog, so a
  comment differ keying on the bare name reports the dropped procedure's comment
  as a change to a surviving function.

Each carries a positive precondition so the negative assertion cannot pass
vacuously, and each was checked by mutation: invert the expectation and the test
fails.

go build ./..., go test ./pg/catalog/, go test -short ./pg/catalog/ and the
-tags=oracle compile all pass.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@d-bytebase
d-bytebase force-pushed the move-pg-sdl-migration-tests branch from 6d6ba1b to 0a2c14b Compare September 3, 2026 17:12
@d-bytebase d-bytebase changed the title pg/catalog: take over the SDL migration tests that lived in bytebase pg/catalog: pin four migration behaviors bytebase was testing for us Sep 3, 2026
d-bytebase added a commit to bytebase/bytebase that referenced this pull request Sep 3, 2026
Effort 7 of docs/design/backend-test-execution-time.md says engine conformance
belongs in omni. 24 files in backend/plugin/schema/pg were already omni's in
substance: they call omni/pg/catalog's LoadSDL, Diff and GenerateMigration
directly and name no bytebase symbol at all. Migration-era leftovers from when
we swapped the ANTLR SDL engine for omni's.

They do not move as they are. Read against omni's own pg/catalog suite, all but
four of their behaviors are covered there already, by more cases and with
better assertions — they match substrings of the rendered SQL where omni
inspects typed migration ops. Two of them cannot fail at all: neither test named
for EXCLUDE constraints has an EXCLUDE constraint in its fixture, and one
asserts the absence of an index name that appears nowhere. The four genuine gaps
went to omni beside the cases they belong with, in that suite's shape —
bytebase/omni#407. The rest are deleted here.

The package goes from 15.1 s to 12.0 s.

Looking for the rest of effort 7 found that the metadata proto is not the near
blocker it is written up as. omni has no Oracle or MSSQL engine to move to —
only a parser and AST, which those packages already use for their own
extractors — and schema/tidb uses none of the TiDB catalog omni does have. Every
container test in plugin/schema/* calls a bytebase-owned entry point, so the
272 s of Oracle and 51 s of MSSQL stay until the implementations move. Section 7
now records that per engine.

omniSDLMigration and diffPostgresSDL stay: omni_filter_test.go and
sdl_migration_omni_test.go still use them.

go vet, golangci-lint and go test ./backend/plugin/schema/... all pass.

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

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 0a2c14b5c3

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread pg/catalog/migration_comment_test.go Outdated
Comment thread pg/catalog/migration_comment_test.go
The function and the procedure had different names, so a comment differ keyed on
the bare name rather than the full signature would still have kept them apart
and the test would still have passed. They now share the name routine_x and
differ only in arguments, which is the shape that gets it wrong, and the
assertion matches on routine_x() so the survivor is distinguishable from the
routine_x(integer) being dropped.

Checked by mutation: relax the match to the bare name and the case fails on
`COMMENT ON PROCEDURE public.routine_x(integer) IS NULL`.

That op is itself invalid — it runs in PhaseMain, after the procedure's own DROP
in PhasePre, and PostgreSQL has no COMMENT ... IF EXISTS. It is not specific to
procedures; dropping any commented table or view produces the same unapplyable
plan. Filed as #408 rather than fixed here, since the fix belongs in
generateCommentDDL and wants a container test of its own.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@rebelice
rebelice merged commit c0a6ff1 into main Sep 4, 2026
23 checks 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.

2 participants