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.
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.tsquotes every identifier with double quotes, for every dialect:Its module header explicitly names MySQL as a supported target —
normalizeRowsexists precisely to flatten "mysql2's[rows, fields]" besidepg's{ rows }and better-sqlite3's bare array, andresolveSeedTenancyExecis built arounddriver.execute(sql, params).Under MySQL's default
sql_modea double-quoted token is a string literal, not an identifier.ANSI_QUOTESis what would change that, and greppingpackages/drivers/driver-sql/src/finds nosql_mode/ANSI_QUOTESsetting anywhere — the only MySQL session tweakwithUtcSessionapplies isSET time_zone = '+00:00'. knex itself emits backticks for themysql/mysql2clients, 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), pluspartial-index-probe.ts/sys-setting-identity-index.tsif 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_modeis set anywhere indriver-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 backsql-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 setANSI_QUOTESthis whole report is void.Related
#8928 took the dialect-aware route for its own probes rather than inheriting this convention:
os migrate duplicatesreads the livedriver.config.clientand quotes with backticks formysql/mysql2, double quotes otherwise (quoteIdentinpackages/cli/src/commands/migrate/duplicates.ts, pinned induplicates.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.