Skip to content

Commit 36baa59

Browse files
committed
fix(mssql): make _sqlx_test_databases creation race-safe
The `#[sqlx::test]` harness created the shared `_sqlx_test_databases` tracking table with `IF NOT EXISTS ... CREATE TABLE`, which is not atomic across connections. Under parallel test execution (CI default; masked locally by --test-threads=1) two tests could both pass the check and one then failed with error 2714 ("There is already an object named '_sqlx_test_databases'"). Guard the CREATE with TRY/CATCH that rethrows everything except 2714, so the losing side of the race proceeds. Author: Pablo Carrera <pabloce@poscye.com>
1 parent 4de1273 commit 36baa59

1 file changed

Lines changed: 15 additions & 7 deletions

File tree

sqlx-mssql/src/testing/mod.rs

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -131,15 +131,23 @@ async fn test_context(args: &TestArgs) -> Result<TestContext<Mssql>, Error> {
131131

132132
let mut conn = master_pool.acquire().await?;
133133

134-
// Create tracking table if it doesn't exist
134+
// Create the tracking table if it doesn't exist. `IF NOT EXISTS ... CREATE`
135+
// is not atomic across connections, so parallel `#[sqlx::test]`s can both
136+
// pass the check and one then fails with 2714 ("already an object named
137+
// '_sqlx_test_databases'"); swallow that race in TRY/CATCH.
135138
conn.execute(
136139
r#"
137-
IF NOT EXISTS (SELECT * FROM sys.tables WHERE name = '_sqlx_test_databases')
138-
CREATE TABLE _sqlx_test_databases (
139-
db_name NVARCHAR(200) NOT NULL PRIMARY KEY,
140-
test_path NVARCHAR(MAX) NOT NULL,
141-
created_at DATETIME2 NOT NULL DEFAULT SYSUTCDATETIME()
142-
);
140+
IF OBJECT_ID('_sqlx_test_databases', 'U') IS NULL
141+
BEGIN TRY
142+
CREATE TABLE _sqlx_test_databases (
143+
db_name NVARCHAR(200) NOT NULL PRIMARY KEY,
144+
test_path NVARCHAR(MAX) NOT NULL,
145+
created_at DATETIME2 NOT NULL DEFAULT SYSUTCDATETIME()
146+
);
147+
END TRY
148+
BEGIN CATCH
149+
IF ERROR_NUMBER() <> 2714 THROW;
150+
END CATCH;
143151
"#,
144152
)
145153
.await?;

0 commit comments

Comments
 (0)