Skip to content

metadata-protocol's raw-SQL migrations quote identifiers with " on every dialect, but MySQL does not run with ANSI_QUOTES — the #8686 / #8629 / #5839 statements cannot parse there #9381

Description

@os-zhuang

Noticed while implementing #8928, which needed the same raw-SQL seam and had to decide its own quoting.

The claim

packages/metadata-protocol/src/migrations/seed-tenancy-backfill.ts quotes every identifier with double quotes, for every dialect:

functionquoteIdent(name: string): string{return`"${name}"`;}

Its module header explicitly names MySQL as a supported target — normalizeRows exists precisely to flatten "mysql2's [rows, fields]" beside pg's { rows } and better-sqlite3's bare array, and resolveSeedTenancyExec is built around driver.execute(sql, params).

Under MySQL's default sql_mode a double-quoted token is a string literal, not an identifier. ANSI_QUOTES is what would change that, and grepping packages/drivers/driver-sql/src/ finds no sql_mode / ANSI_QUOTES setting anywhere — the only MySQL session tweak withUtcSession applies is SET time_zone = '+00:00'. knex itself emits backticks for the mysql/mysql2 clients, so nothing upstream normalises this either.

So on MySQL these statements should fail to parse. Every call site swallows that into a warning by design (a migration must never fail a boot), which means the visible symptom is a log line saying the migration was skipped — not a wrong answer, but not the repair either.

Affected statements are all three migrations armed from the same assembly: seed-tenancy-backfill.ts (#8686 — split probe, collision probe, stamp, counter merge, global-counter delete), plus partial-index-probe.ts / sys-setting-identity-index.ts if they share the convention (worth checking in the same pass).

Verification status — stated exactly

Measured: the quoting is unconditional in source; no ANSI_QUOTES / sql_mode is set anywhere in driver-sql; the module's own header claims MySQL support.

NOT measured: this was not run against a live MySQL server. The repo has the machinery for that (live-dialect-matrix.testkit.ts, and the MySQL jobs that back sql-driver-datetime-mysql-storage.test.ts), so the confirming run is cheap for whoever picks this up — and it should be the first step, because if some layer does set ANSI_QUOTES this whole report is void.

Related

#8928 took the dialect-aware route for its own probes rather than inheriting this convention: os migrate duplicates reads the live driver.config.client and quotes with backticks for mysql/mysql2, double quotes otherwise (quoteIdent in packages/cli/src/commands/migrate/duplicates.ts, pinned in duplicates.probe-sql.test.ts). That is one small, already-tested implementation of the fix, if a shared helper is the direction taken.

Not fixed under #8928: packages/metadata-protocol/** was explicitly out of that card's file surface.

Metadata

Metadata

Assignees

Type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions