You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
sqlx::migrate!("./migrations") bakes migration SQL + no_tx flags into the binary at compile time via a proc-macro. On stable Rust, changes to migration files do not cause cargo to recompile the calling crate, so the binary silently retains stale migration content.
Root cause
sqlx-macros-core/src/migrate.rs registers the migrations directory with cargo only under a nightly gate:
#[cfg(any(sqlx_macros_unstable, procmacro2_semver_exempt))]{
proc_macro::tracked_path::path(path);// <— never runs on stable}
The macro does emit include_str!(path) for each migration (which rustc tracks), but that tracking is bypassed when RUSTC_WRAPPER=sccache is in use: sccache hashes the source file (src/db.rs), sees it unchanged, and returns the cached object without re-running rustc or the proc-macro.
Even without sccache, cargo's fingerprint/incremental system can miss these deps in edge cases when the invoking source file is unchanged but a migration file has changed.
Impact
The no_tx flag / SQL content embedded in the binary does not update when a migration file is edited.
Workaround requires touch src/<file-containing-migrate!>.rs or cargo clean.
CI builds are unaffected if CARGO_INCREMENTAL=0 is set, so CI binaries are always correct. This is a local dev bug.
Concrete incident
During a post-merge hotfix: an -- no-transaction marker was added to a migration file to prevent DROP INDEX CONCURRENTLY from running inside a transaction. Despite cargo clean + disabling sccache, the compiled binary retained the old content. The hotfix had to rewrite the migration differently to force cargo to see a change. (upstream context)
Workaround (works today)
Add to build.rs:
ifletOk(entries) = std::fs::read_dir("migrations"){for entry in entries.flatten(){ifletSome(path) = entry.path().to_str(){println!("cargo:rerun-if-changed={path}");}}}println!("cargo:rerun-if-changed=migrations");
Good: Add a sqlx_build_support::watch_migrations!(dir) macro / function users can call from build.rs.
Minimal: Document the build.rs snippet above prominently in the migrate!() docs so users know they need it when sccache or incremental compilation is in play.
Version
sqlx 0.8.6, stable Rust (1.87), sccache in RUSTC_WRAPPER.
Summary
sqlx::migrate!("./migrations")bakes migration SQL +no_txflags into the binary at compile time via a proc-macro. On stable Rust, changes to migration files do not cause cargo to recompile the calling crate, so the binary silently retains stale migration content.Root cause
sqlx-macros-core/src/migrate.rsregisters the migrations directory with cargo only under a nightly gate:The macro does emit
include_str!(path)for each migration (which rustc tracks), but that tracking is bypassed whenRUSTC_WRAPPER=sccacheis in use: sccache hashes the source file (src/db.rs), sees it unchanged, and returns the cached object without re-running rustc or the proc-macro.Even without sccache, cargo's fingerprint/incremental system can miss these deps in edge cases when the invoking source file is unchanged but a migration file has changed.
Impact
no_txflag / SQL content embedded in the binary does not update when a migration file is edited.touch src/<file-containing-migrate!>.rsorcargo clean.CARGO_INCREMENTAL=0is set, so CI binaries are always correct. This is a local dev bug.Concrete incident
During a post-merge hotfix: an
-- no-transactionmarker was added to a migration file to preventDROP INDEX CONCURRENTLYfrom running inside a transaction. Despitecargo clean+ disabling sccache, the compiled binary retained the old content. The hotfix had to rewrite the migration differently to force cargo to see a change. (upstream context)Workaround (works today)
Add to
build.rs:Requested fix (any of these would help)
tracked_path::path()onceproc_macro::tracked_pathis stabilised (Tracking Issue for proc_macro::{tracked_env, tracked_path} rust-lang/rust#99515).sqlx_build_support::watch_migrations!(dir)macro / function users can call frombuild.rs.build.rssnippet above prominently in themigrate!()docs so users know they need it when sccache or incremental compilation is in play.Version
sqlx 0.8.6, stable Rust (1.87), sccache in
RUSTC_WRAPPER.