sqlx-knowledge-patch
SQLx Knowledge Patch
Covers SQLx 0.8.3–0.9.0-alpha.1 (2025-01-03 through 2025-10-14). Claude Opus 4.6 knows SQLx through 0.7.x. It is unaware of the 0.8+ features and 0.9 breaking changes below.
Index
| Topic | Reference | Key features |
|---|---|---|
| Transactions | references/transactions.md | begin_with, per-DB option types, is_in_transaction, type aliases |
| Type system & macros | references/type-system.md | SqlSafeStr, Arguments lifetime removal, smart pointer Encode/Decode, PgBindIter, PgHasArrayType auto-derive, json(nullable), transparent named structs |
| SQLite | references/sqlite.md | Commit/rollback/preupdate hooks, feature flags (sqlite-deserialize, sqlite-load-extension, sqlite-unlock-notify), sqlite-unbundled, no_tx migrations |
| Postgres & MySQL | references/postgres-and-mysql.md | Geometry types, ipnet support, PgConnectOptions auto-escaping, MySQL collation inference, PgListener improvements |
| Configuration & runtime | references/configuration.md | sqlx.toml, MSRV 1.86, runtime feature changes, Migrator::with_migrations, RawSql type parameter |
0.8 → 0.9 Migration — Breaking Changes
Note: 0.9.0-alpha.1 is the current alpha. Many breaking changes from 0.8.x.
| What changed | Before (0.8) | After (0.9) |
|---|---|---|
| Query string safety | query("...") accepts &str |
Accepts impl SqlSafeStr — only &'static str or AssertSqlSafe |
Arguments lifetime |
Arguments<'q>, SqliteArguments<'q> |
Arguments (no lifetime) — values are owned |
| Runtime features | runtime-tokio-native-tls combos |
Separate runtime-tokio + native-tls; combos removed |
| MSRV | 1.75 | 1.86 |
RawSql |
No type parameter | RawSql methods require DB type parameter |
RawSql::fetch_optional |
Returns Result<DB::Row> |
Returns Result<Option<DB::Row>> |
Cow decoding |
Could be Cow::Borrowed |
Always Cow::Owned |
| SQLite extension loading | extension() safe method |
unsafe; requires sqlite-load-extension feature |
SqliteValue |
Sync |
!Sync; SqliteValueRef is !Send |
| MySQL text columns | Inferred as Vec<u8> |
Inferred as String |
PgConnectOptions::options() |
Manual escaping needed | Auto-escaped — remove manual escaping |
#[derive(sqlx::Type)] newtype |
No auto PgHasArrayType |
Auto-generates PgHasArrayType; add #[sqlx(no_pg_array)] if manual impl exists |
Also note: 0.8.4 was yanked — use 0.8.5+ instead. All 0.8.4 features are available in 0.8.5.
SqlSafeStr — Query String Safety (0.9)
The most impactful breaking change. All query*() functions now take impl SqlSafeStr instead of &str. Only &'static str and AssertSqlSafe implement it.
use sqlx::AssertSqlSafe;
// Static strings work as before
sqlx::query("SELECT * FROM users WHERE id = $1")
.bind(user_id)
.fetch_one(&pool).await?;
// Dynamic queries must be wrapped
let table = "users";
let q = format!("SELECT * FROM {table}");
sqlx::query(AssertSqlSafe(q)).fetch_all(&pool).await?;
This also enables returning owned queries as Query<'static, DB>.
begin_with — Transaction Options (0.8.4+)
Start transactions with database-specific options:
use sqlx::postgres::{PgIsolationLevel, PgTransactionOptions};
let tx = conn
.begin_with(
PgTransactionOptions::new()
.isolation_level(PgIsolationLevel::Serializable)
.read_only(true),
)
.await?;
Each database has its own options type: PgTransactionOptions, MySqlTransactionOptions, SqliteTransactionOptions.
See references/transactions.md for is_in_transaction and type aliases.
Arguments Lifetime Removal (0.9)
Arguments<'q> is now just Arguments (no lifetime). SqliteArguments and AnyArguments similarly lost their lifetime parameter. Bound values are now owned.
// Before (0.8)
fn build_query<'q>(args: &mut PgArguments<'q>) { ... }
// After (0.9)
fn build_query(args: &mut PgArguments) { ... }
Smart Pointer Encode/Decode/Type (0.9)
Box<T>, Arc<T>, Rc<T>, and Cow<'_, T> now implement Encode, Decode, and Type when T does. Breaking: Cow always decodes as Cow::Owned.
PgBindIter — Bind Iterators as Arrays (0.9)
Bind iterators directly as Postgres arrays without collecting to Vec:
use sqlx::postgres::PgBindIter;
let ids = [1i32, 2, 3];
sqlx::query("SELECT * FROM users WHERE id = ANY($1)")
.bind(PgBindIter(ids.iter()))
.fetch_all(&pool).await?;
#[derive(sqlx::Type)] Auto-Generates PgHasArrayType (0.9)
Newtype structs deriving sqlx::Type now automatically get a PgHasArrayType impl. Add #[sqlx(no_pg_array)] to opt out:
#[derive(sqlx::Type)]
#[sqlx(no_pg_array)] // needed if you had a manual PgHasArrayType impl
struct MyId(i32);
json(nullable) and Transparent Named Structs
Handle nullable JSON columns in FromRow derives (0.8.4+):
#[derive(sqlx::FromRow)]
struct MyRow {
#[sqlx(json(nullable))]
metadata: Option<MyJsonType>,
}
Single-field named structs can now use #[sqlx(transparent)] (0.9):
#[derive(sqlx::Type)]
#[sqlx(transparent)]
struct UserId {
id: i32, // single named field — now supported
}
Runtime Feature Migration (0.9)
Deprecated combination features removed. Use separate features:
# Before (0.8)
sqlx = { version = "0.8", features = ["runtime-tokio-native-tls"] }
# After (0.9)
sqlx = { version = "0.9", features = ["runtime-tokio", "native-tls"] }
New runtime options: runtime-smol and runtime-async-global-executor (replacing deprecated async-std).
sqlx.toml Configuration (0.9)
Per-crate configuration (requires sqlx-toml feature). Supports renaming DATABASE_URL, global type overrides for macros, renaming the _sqlx_migrations table, and SQLite extension loading in macros/CLI.
Guide: sqlx::_config module docs. See references/configuration.md for details.
SQLite Feature Flag Changes (0.9)
New non-default features for conditional SQLite APIs:
| Feature | Enables |
|---|---|
sqlite-deserialize |
SqliteConnection::serialize() / deserialize() |
sqlite-load-extension |
SqliteConnectOptions::extension() (now unsafe) |
sqlite-unlock-notify |
Internal sqlite3_unlock_notify() usage |
sqlite-preupdate-hook |
conn.on_preupdate() callback (added in 0.8.4) |
See references/sqlite.md for commit/rollback hooks and no_tx migrations.
New APIs Summary
| API | Version | Description |
|---|---|---|
conn.on_commit() / on_rollback() |
0.8.3 | SQLite commit/rollback hook callbacks |
PgListener: Acquire + next_buffered() |
0.8.3 | Use PgListener as connection; batch notifications |
PgPoint, PgLine |
0.8.3 | Postgres geometry types |
| Transaction type aliases | 0.8.3 | PgTransaction<'c>, MySqlTransaction<'c>, SqliteTransaction<'c> |
sqlite-unbundled feature |
0.8.3 | Dynamically link system libsqlite3.so |
AnyQueryResult for SQLite/MySQL |
0.8.3 | Previously Postgres-only |
begin_with + per-DB options |
0.8.4 | Custom transaction isolation, read-only, etc. |
Connection::is_in_transaction |
0.8.4 | Check if inside a transaction |
conn.on_preupdate() |
0.8.4 | SQLite preupdate hook (requires feature) |
#[sqlx(json(nullable))] |
0.8.4 | Handle nullable JSON columns in FromRow |
PgLineSegment, PgBox, PgPath, PgPolygon, PgCircle |
0.8.4 | Additional Postgres geometry types |
ipnet::IpNet mapping |
0.8.4 | Maps to Postgres INET/CIDR (requires ipnet feature) |
SqlSafeStr / AssertSqlSafe |
0.9 | Query string safety wrapper |
PgBindIter |
0.9 | Bind iterators as Postgres arrays |
Encode/Decode for Box<T>, Arc<T>, Rc<T>, Cow<T> |
0.9 | Smart pointer support |
#[sqlx(no_pg_array)] |
0.9 | Opt out of auto PgHasArrayType |
#[sqlx(transparent)] on named structs |
0.9 | Single-field named structs (not just tuple structs) |
no_tx SQLite migrations |
0.9 | Opt out of transaction wrapping |
Migrator::with_migrations() |
0.9 | Build Migrator from collection programmatically |
sqlx.toml configuration |
0.9 | Per-crate config (requires sqlx-toml feature) |
Reference Files
| File | Contents |
|---|---|
| transactions.md | begin_with options, isolation levels, is_in_transaction, type aliases |
| type-system.md | SqlSafeStr, Arguments lifetime, smart pointers, PgBindIter, PgHasArrayType, json(nullable), transparent structs |
| sqlite.md | Commit/rollback/preupdate hooks, feature flags, sqlite-unbundled, no_tx migrations |
| postgres-and-mysql.md | Geometry types, ipnet, PgConnectOptions escaping, MySQL collation, PgListener |
| configuration.md | sqlx.toml, MSRV/runtime changes, Migrator::with_migrations, RawSql type parameter |
More from nevaberry/nevaberry-plugins
dioxus-knowledge-patch
Dioxus changes since training cutoff (latest: 0.7.4) — Signals replacing use_state, RSX macro overhaul, server functions, asset!() system, dx CLI, Element-as-Result. Load before working with Dioxus.
46rust-knowledge-patch
Rust changes since training cutoff (latest: 1.94.0) \u2014 Rust 2024 Edition, async closures, trait upcasting, new std APIs, cargo resolver v3. Load before working with Rust.
20postgresql-knowledge-patch
PostgreSQL changes since training cutoff (latest: 18.1) — JSON_TABLE, SQL/JSON functions, MERGE RETURNING, virtual generated columns, UUIDv7, temporal PRIMARY KEY. Load before working with PostgreSQL.
16bun-knowledge-patch
Bun changes since training cutoff (latest: 1.3.10) \u2014 S3 client, built-in SQL/Redis, route-based HTTP server, CSS bundler, V8 compatibility. Load before working with Bun.
14nextjs-knowledge-patch
Next.js changes since training cutoff (latest: 16.1) — proxy.ts, \"use cache\", Cache Components, navigation hooks, typed routes, auto PageProps, React 19.2. Load before working with Next.js.
14postgis-knowledge-patch
PostGIS changes since training cutoff (latest: 3.6.1) — SFCGAL CG_* rename, ST_CoverageClean, ST_AsRasterAgg, topology bigint IDs, viewport simplification, 3D SFCGAL ops. Load before working with PostGIS.
13