Skip to content

feat: prep db identifiers for cross-platform (Postgres) portability#444

Draft
turegjorup wants to merge 2 commits into
mainfrom
feature/portability-prep-rename
Draft

feat: prep db identifiers for cross-platform (Postgres) portability#444
turegjorup wants to merge 2 commits into
mainfrom
feature/portability-prep-rename

Conversation

@turegjorup
Copy link
Copy Markdown
Contributor

Note

Targets release/2.7.0. Lands here so the consolidated 3.0 migration in #441 / #442 can be regenerated against the portable entity shape and migrations:rollup stays honest for 2.x → 3.0 upgraders.

Why

Two things in the current schema are MariaDB-only and block fresh Postgres installs:

  1. changed_idx index name reused on 15 tables. MariaDB scopes index names per-table; Postgres scopes them schema-wide, so the second CREATE INDEX changed_idx collides with relation "changed_idx" already exists.
  2. user table is reserved in standard SQL and in Postgres. Doctrine doesn't auto-quote it, so generated DML like INSERT INTO user (...) is a syntax error on Postgres.

Without resolving these on 2.7, the consolidated 3.0 migration can't emit a Postgres-portable shape — it has to match what 2.x → 3.0 upgraders' MariaDB already has, or migrations:rollup lies. Fixing the divergence on 2.7 first means upgraders converge to the portable shape before they ever touch 3.0.

What

  • Migration Version20260507120000RENAME INDEX changed_idx TO <table>_changed_idx on the 15 affected tables (feed, feed_source, media, playlist, playlist_screen_region, playlist_slide, screen, screen_campaign, screen_group, screen_group_campaign, screen_layout, screen_layout_regions, slide, template, theme). Reversible. No-op for MariaDB at runtime.
  • Entity metadata — 15 #[ORM\Index(name: 'changed_idx')] updated to <table>_changed_idx; User entity gets #[ORM\Table(name: '\user`')]` so Doctrine emits the platform-native quoted identifier on every reference.
  • CI gate — new validate-doctrine-schema-postgres job in pr.yaml spins up a Postgres 16 service container, applies entity metadata via doctrine:schema:update --force --complete, then runs doctrine:schema:validate. Catches future entity changes that break Postgres compatibility.

Why backtick-quote user instead of renaming it

A rename (userapp_user) was the first approach considered but it requires touching every table that FKs into user, plus realigning Doctrine's auto-derived hash-based index names (UNIQ_8D93D649…UNIQ_88BDF3E9…). Backtick-quoting the identifier in the entity attribute is the standard Doctrine mechanism for reserved words: zero schema change, Doctrine emits `user` on MariaDB and "user" on Postgres from the same metadata. Trade-off accepted: any raw SQL outside Doctrine that hardcodes user would still need quoting on Postgres — but the only known instances (MultiTenantRepositoryTrait, RelationsChecksumCalculator) are deferred MariaDB-only paths called out in #442's "Out of scope" section anyway.

Test plan

  • MariaDB: doctrine:migrations:migrate applies all 26 migrations cleanly; doctrine:schema:validate is in sync; full PHPUnit suite green (133 tests / 516 assertions, byte-identical to pristine release/2.7.0).
  • MariaDB: down/up cycle of the new migration verified.
  • Postgres 16: doctrine:schema:update --force --complete applies entity metadata in 265 queries; doctrine:schema:validate is in sync; user table is created, no changed_idx collision.
  • CI green on this PR (the new Postgres job is the proof point).

Follow-ups (not in this PR)

🤖 Generated with Claude Code

turegjorup and others added 2 commits May 7, 2026 02:07
- Rename 15 `changed_idx` indexes to `<table>_changed_idx` (Postgres
  scopes index names schema-wide; MariaDB scopes per-table — the shared
  name collides on Postgres).
- Quote `user` table identifier in entity metadata
  (`#[ORM\Table(name: '`user`')]`). Doctrine emits the platform-native
  quote on every reference (`` `user` `` on MariaDB, `"user"` on
  Postgres), so no table rename is needed.
- Add `validate-doctrine-schema-postgres` CI job that applies entity
  metadata to a Postgres 16 service container via
  `doctrine:schema:update --force --complete` and then runs
  `doctrine:schema:validate`. Gates against future entity-level
  Postgres regressions.

Lands on 2.7 so the consolidated 3.0 migration (#441 / #442) can emit
the portable shape from the start, keeping `migrations:rollup` honest
for 2.x → 3.0 upgraders.

Verified locally on MariaDB: migration applies cleanly,
`doctrine:schema:validate` in sync, full PHPUnit suite green
(133 tests / 516 assertions, identical to pristine release/2.7.0).
Verified on Postgres 16: `doctrine:schema:update --force --complete`
applies the metadata in 265 queries, `doctrine:schema:validate` in
sync. down/up cycle of the new migration also verified.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@turegjorup turegjorup requested a review from tuj May 7, 2026 00:08
@turegjorup turegjorup self-assigned this May 7, 2026
Base automatically changed from release/2.7.0 to main May 12, 2026 08:32
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.

1 participant