fix(deps): update rust crate sqlx to 0.9#74
Conversation
|
There was a problem hiding this comment.
Summary
This PR updates the sqlx dependency from version 0.8 to 0.9, a major version upgrade released on May 6, 2026. The change is minimal (single line in Cargo.toml) but carries significant implications due to breaking changes in the sqlx ecosystem.
Verdict: Needs verification before approval - while the code changes are minimal, several breaking changes in sqlx 0.9 could affect this crate.
Research notes
Key findings from sqlx 0.9.0 CHANGELOG:
Breaking Changes Relevant to This Crate:
- MSRV increased to Rust 1.94.0 (from 1.86) - may require toolchain update
- Migrator trait changes (#3383) - significant changes to
Migratetrait, affectsmigrator()function exported by this crate Migrator::set_ignore_missingandset_lockingreturn&mut Selfinstead of&Self(#3526)- Lifetime parameter removed from
Argumentstrait (#3960) - affects query building - All
query*()functions now takeimpl SqlSafeStr(#3723) - only implemented for&'static strandAssertSqlSafe - PostgreSQL options escaping (#3800) - options passed to
PgConnectOptions::options()are now automatically escaped - Removed deprecated runtime+TLS features (#3821) - e.g.,
runtime-tokio-native-tls libsqlite3-sysversioning policy changed - uses semver range, max version may increase in minor releases
Non-Breaking but Notable:
- New
sqlx.tomlconfiguration file support (requiressqlx-tomlfeature) - GitHub organization transfer pending (moving to
transact-rs) Cargo.lockremoved from tracking in sqlx repo
Code Impact Analysis
Safe Areas (No Breaking Changes Expected):
-
Basic query execution (
sqlx::query(),.bind(),.execute()): The core usage pattern insrc/lib.rslines 478-498, 537-549, 617-637, 697-709 uses standard query API with&strliterals which satisfySqlSafeStr -
Pool operations (
PgPool::connect,PoolProvider): No breaking changes affecting pool creation or thePoolProvidertrait fromsqlx-pool-router -
Type derives (
Type,Encode,Decode): The crate doesn't use custom#[derive(sqlx::Type)]for newtype structs that would conflict with auto-generatedPgHasArrayType
Potentially Affected Areas:
-
Migration system (
src/lib.rs:129-132):pub fn migrator() -> sqlx::migrate::Migrator { sqlx::migrate!("./migrations") }
The
Migratetrait has significant changes (#3383). Whilesqlx::migrate!()macro should still work, the public API exposesMigratorwhich consumers might interact with differently. -
QueryBuilder usage (
src/repository.rs:69-239):
UsesQueryBuilder<'_, sqlx::Postgres>with.push_bind(). The lifetime removal fromArgumentstrait (#3960) shouldn't affect this since it's using concrete types, but verification needed. -
Test fixtures (
#[sqlx::test]attributes throughout tests):
The#[sqlx::test]macro behavior may have changed, particularly around database cleanup and test isolation.
Suggested next steps
-
Run full test suite:
cargo testmust pass with sqlx 0.9. Pay special attention to:- Migration-related tests
- Tests using
TestDbPoolsfor read/write separation - QueryBuilder-based queries in repository tests
-
Verify MSRV compatibility: Ensure CI toolchain supports Rust 1.94.0+
-
Check dependent crates: If other crates in the
outletecosystem depend on this, verify they compile against sqlx 0.9 -
Review migration docs: Check if any migration workflow changes are needed based on #3383
-
Update lockfile: Run
cargo updateto ensureCargo.lockreflects compatible transitive dependencies
General findings
Non-blocking: The single-line version bump is appropriate for a dependency update PR. However, major version upgrades should ideally include:
- A note in the commit message about verified compatibility
- Mention of any required downstream changes (e.g., MSRV bump)
- Confirmation that all tests pass locally before merge
The PR description "fix(deps): update rust crate sqlx to 0.9" follows conventional commits but doesn't capture the scope of a major version upgrade. Consider amending to note any breaking changes or verification steps taken.
This PR contains the following updates:
0.8→0.9Release Notes
launchbadge/sqlx (sqlx)
v0.9.0Compare Source
Important Announcements
New Github Organization
Shortly after this release is published, the SQLx repository will be transferred to a new GitHub organization:
https://github.com/transact-rs/
This is because SQLx has not been owned or maintained by LaunchBadge, LLC. for a few years now, and has since been
informally transferred to the collective ownership of its principal authors. Moving the repository to a new
organization makes this change more clear, and also allows for potentially inviting outside collaborators.
Cargo.lockRemoved from TrackingThe
Cargo.lockhas been removed from tracking in Git. CI should now always test with the latest versions ofall dependencies by default, alongside our pass that checks with
cargo generate-lockfile -Z minimal-versions.This should eliminate the need for any PRs that update dependencies to also update
Cargo.lockorcontend with an endless stream of merge conflicts against it.
N.B.
cargo install --locked sqlx-cliwill no longer work. However,cargo install sqlx-clihas alwaysused the latest dependencies by default, ignoring the lockfile, so most users should not be affected. For users
requiring reproducible builds, consider maintaining your own lockfile instead; historically, we only ran
cargo updatesporadically, so relying on SQLx's lockfile offered few guarantees anyway.
See the manual page for
cargo installfor details.Breaking
As per our MSRV policy, the supported Rust version for this release cycle is
1.94.0.sqlx.tomlformat [[@abonander]]sqlx-clinow support per-crate configuration files (sqlx.toml)DATABASE_URLfor a crate (for multi-database workspaces)_sqlx_migrationstable (for multiple crates using the same database)sqlx-tomlto use.sqlx-clihas it enabled by default, butsqlxdoes not.so it's better to keep the default feature set as limited as possible.
This is something we learned the hard way.
sqlx::_configmodule in documentation.DATABASE_URLrenaming and global type overrides: [Link]_sqlx_migrationsrenaming and multiple schemas: [Link]chronowhentimeis enabled (e.g. when usingtower-sessions-sqlx-store): [Link]bigdecimalwhenrust_decimalis enabled is also shown, but problems withchrono/timeare more common.Migratetraitsqlx::migrate::resolve_blocking()is now#[doc(hidden)]and thus SemVer-exempt.tracinglogs from SQLx will need to update the spelling.PgAdvisoryLockGuard[[@bonsairobo]]Migrator::set_ignore_missingandset_lockingnow return&mut Selfinstead of&Selfwhich may break code in rare circumstances.
query!()macros for certain queries in Postgres.RawSqllifetime issues [[@abonander]]DBtype parameter to all methods ofRawSqlDecode,EncodeandTypeforBox,Arc,CowandRc[[@joeydewaal]]impl Decode for Cownow always decodesCow::Owned, lifetime is unlinkedquery*()functions now takeimpl SqlSafeStrwhich is only implemented for
&'static strandAssertSqlSafe.For all others, wrap in
AssertSqlSafe(<query>).Query<'static, DB>.SqlSafeStrtrait is deliberately similar tostd::panic::UnwindSafe,serving as a speedbump to warn users about naïvely building queries with
format!()while allowing a workaround for advanced usage that is easy to spot on code review.
PgConnectOptions::options()are now automatically escaped.Manual escaping of options is no longer necessary and may cause incorrect behavior.
runtime-tokio-native-tls)TransactionManagertrait insqlx.#[doc(hidden)],but it will break SeaORM if not proactively fixed.
str[[@abonander]]Vec<u8>will be inferred to beString(this should ultimately fix more code than it breaks).
SET NAMES utf8mb4 COLLATE utf8_general_ciis no longer sent by default; instead,SET NAMES utf8mb4is sent toallow the server to select the appropriate default collation (since this is version- and configuration-dependent).
MySqlConnectOptions::charset()and::collation()now imply::set_names(true)because they don't do anything otherwise.charsetdoesn't change what's sent in theProtocol::HandshakeResponse41packet as that normally onlymatters for error messages before
SET NAMESis sent.The default collation if
set_names = falseisutf8mb4_general_ci.RawSql::fetch_optional()now returnssqlx::Result<Option<DB::Row>>instead of
sqlx::Result<DB::Row>. Whoops.libsqlite3-sysversioning, feature flags, safety changes [[@abonander]]libsqlite3-sysversion is now specified using a range.The maximum of the range may now be increased in any backwards-compatible release.
The minimum of the range may only be increased in major releases.
If you have
libsqlite3-sysin your dependencies, Cargo should choose a compatible version automatically.If otherwise unconstrained, Cargo should choose the latest version supported.
sqlx-tomlfeature) is nowunsafe.sqlite-deserializeenablingSqliteConnection::serialize()andSqliteConnection::deserialize()sqlite-load-extensionenablingSqliteConnectOptions::extension()and::extension_with_entrypoint()sqlite-unlock-notifyenables internal use ofsqlite3_unlock_notify()SqliteValueandSqliteValueRefchanges:sqlite3_value*interface reserves the right to be stateful.Without protection, any call could theoretically invalidate values previously returned, leading to dangling pointers.
SqliteValueis now!SyncandSqliteValueRefis!Sendto prevent data races from concurrent accesses.SqliteValueinMutex, or convert theSqliteValueRefto an owned value.SqliteValueand any derivedSqliteValueRefs now internally track if that value has been used to decode aborrowed
&[u8]or&strand errors if it's used to decode any other type.per
SqliteValue/SqliteValueRef.SqliteValuefor details.PgLTree::fromtoFrom<Vec<PgLTreeLabel>>implementation [[@JerryQ17]]SqliteArguments[[@iamjpotts]].pgpassfile handling did not process backslash-escapes in the password part.Now it does, which may change what password is sent to the server.
#[derive(sqlx::Type)]automatically generateimpl PgHasArrayTypeby default for newtype structs [[@papaj-na-wrotkach]]Delete the manual impl or add
#[sqlx(no_pg_array)]where conflicts occur.offlineoptional to allow building withoutserde[[@CathalMullan]]mysql-rsafeatureor an error will be generated at runtime. RSA encryption is only used for plaintext (non-TLS) connections.
AnyTypeInfo[[@abonander]]Added
Arc<str>andArc<[u8]>(andRcequivalents) [[@joeydewaal]]runtime-smolandruntime-async-global-executorfeatures to replace usages of the deprecatedasync-stdcrate.no_txmigration support [[@AlexTMjugador]]Migrator::with_migrations()constructor [[@xb284524239]]sqlx.toml, update SQLite extension example [[@supleed2]]Json::into_inner()[[@chrxn1c]]SqlStr[[@joeydewaal]]PgNotificationstruct clone [[@michaelvanstraten]]Changed
OnceCell/Lazywith stdOnceLock/LazyLock[[@paolobarbolini]]Debugimplementations acrossPgRow,MySqlRowandSqliteRow[[@davidcornu]]QueryLoggerback [[@joeydewaal]].bind()inREADME.md[[@sobolevn]]randetceterato0.11.0libsqlite3-sysversion range to<0.38.0Fixed
futuresandfutures-util[[@paolobarbolini]]Pool.close: close all connections before returning [[@jpmelos]]ROLLBACKtransaction when dropped duringBEGIN. [[@kevincox]].envloading, caching, and invalidation [[@abonander]]which served as a useful comparison.
Command::cargo_bin()[[@abonander]]SASLprep[[@var4yn]]from_utf8_uncheckedwithfrom_utf8in SQLite column name handling [[@barry3406]]StdSocket::poll_ready()[[@abonander]]Configuration
📅 Schedule: (UTC)
🚦 Automerge: Disabled by config. Please merge this manually once you are satisfied.
♻ Rebasing: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.
🔕 Ignore: Close this PR and you won't be reminded about this update again.
This PR was generated by Mend Renovate. View the repository job log.