Skip to content

Error on .sql migration files that don't match the expected filename format - #4367

Open
teddytennant wants to merge 1 commit into
transact-rs:mainfrom
teddytennant:fix/migrate-error-on-unparseable-sql-filename
Open

Error on .sql migration files that don't match the expected filename format#4367
teddytennant wants to merge 1 commit into
transact-rs:mainfrom
teddytennant:fix/migrate-error-on-unparseable-sql-filename

Conversation

@teddytennant

Copy link
Copy Markdown

Closes #4362.

The bug

resolve_blocking_with_config() splits a migration filename on the first _ and continues if it
doesn't get two parts. A .sql file with no underscore — schema.sql — is therefore dropped from
the migration set with no error and no warning: the migration runner reports success and the
schema never reaches the database.

The failure mode depends on whether the name happens to contain an underscore. a_schema.sql
already hard-errors on the version parse; schema.sql is silently ignored. That inconsistency is
the surprising part.

The fix

When a filename fails to parse but ends in .sql, return a ResolveError naming the offending file
and the expected <VERSION>_<DESCRIPTION>.sql format. Files that don't end in .sql (README,
.gitkeep) are still ignored silently, exactly as before — that behaviour is intentional and is
pinned by a second test.

Also updated the MigrationSource doc comment, which claimed "Files that don't match this format are
silently ignored" and is no longer accurate for .sql files.

Verification

Fail-before (test present, source fix reverted):

running 6 tests
test migrate::source::resolve_errors_on_sql_file_without_version_prefix ... FAILED
test migrate::source::resolve_ignores_files_not_ending_in_sql ... ok
---- migrate::source::resolve_errors_on_sql_file_without_version_prefix stdout ----
thread '...' panicked at sqlx-core/src/migrate/source.rs:307:10:
expected an error for a `.sql` file with no version prefix: []
test result: FAILED. 5 passed; 1 failed

Pass-after:

test result: ok. 6 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out

Baseline before any edit was 4 passed / 0 failed — no pre-existing failures.

cargo test --test migrate-macro --no-default-features --features runtime-tokio,tls-none,macros,migrate,sqlite
passes, exercising both the migrate! compile-time path and the runtime path over the repo's three
fixture migration directories.

cargo fmt --all -- --check clean. cargo clippy -p sqlx-core --all-targets -- -D warnings clean.

I also swept every migrations*/ directory in the repo, including examples and sqlx-cli fixtures:
zero files that the new error would reject.

Is this a breaking change?

Behaviourally, yes — a .sql file that previously resolved to nothing now errors. The issue asks for
"an error (or warning)", and the consistency argument is strong since a_schema.sql already errors.
If you'd rather this were a tracing::warn! for a 0.9.x patch release, say the word and I'll switch
it.

Deliberately not done

The other option in the issue — actually supporting version-less migrations — is a feature decision
with ordering and checksum implications, not a bug fix, so I left it alone.

…PTION>.sql`

`resolve_blocking_with_config()` skipped any filename that didn't split into
two parts on `_`, so a migration named `schema.sql` (no version prefix) was
dropped from the migration set without any diagnostic. `a_schema.sql` already
errors on the version parse, so the failure mode depended on whether the file
happened to contain an underscore.

Return a `ResolveError` naming the file and the expected format when the name
ends in `.sql` but doesn't parse. Files that don't end in `.sql` (README,
.gitkeep, editor backups) are still ignored silently.
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.

migrate! silently ignores *.sql files with no prefix

1 participant