Bug
File: sqlx-mssql/src/migrate.rs
The escape_table_name helper wraps the entire table_name in brackets:
fn escape_table_name(table_name: &str) -> String {
format!("[{}]", table_name.replace(']', "]]"))
}
When table_name is schema-qualified (e.g., dbo._sqlx_migrations), the result is [dbo._sqlx_migrations] — MSSQL treats this as a single identifier, not schema.table. The correct output should be [dbo].[_sqlx_migrations].
This is a pre-existing issue — the old unescaped code happened to work because the dot was unquoted. The bracket-wrapping fix for #4 preserves the same limitation.
Note: the other drivers (Postgres, MySQL, SQLite) have the same gap — they all interpolate table_name raw without schema-aware splitting.
Context
Suggested Fix
Split table_name on . and escape each segment individually:
fn escape_table_name(table_name: &str) -> String {
table_name
.split('.')
.map(|part| format!("[{}]", part.replace(']', "]]")))
.collect::<Vec<_>>()
.join(".")
}
This should also be considered for the other drivers using their respective quoting styles.
Bug
File:
sqlx-mssql/src/migrate.rsThe
escape_table_namehelper wraps the entiretable_namein brackets:When
table_nameis schema-qualified (e.g.,dbo._sqlx_migrations), the result is[dbo._sqlx_migrations]— MSSQL treats this as a single identifier, notschema.table. The correct output should be[dbo].[_sqlx_migrations].This is a pre-existing issue — the old unescaped code happened to work because the dot was unquoted. The bracket-wrapping fix for #4 preserves the same limitation.
Note: the other drivers (Postgres, MySQL, SQLite) have the same gap — they all interpolate
table_nameraw without schema-aware splitting.Context
dangerous_set_table_name()docs explicitly state the name "may be schema-qualified"Suggested Fix
Split
table_nameon.and escape each segment individually:This should also be considered for the other drivers using their respective quoting styles.