From sqlx-knowledge-patch
Patches Claude's knowledge with SQLx 0.8.3–0.9.0-alpha.1 updates: SqlSafeStr, owned Arguments, sqlx.toml config, begin_with transactions, SQLite hooks, PgBindIter, and breaking changes. Load before SQLx tasks.
npx claudepluginhub nevaberry/nevaberry-plugins --plugin sqlx-knowledge-patchThis skill uses the workspace's default tool permissions.
Designs and optimizes AI agent action spaces, tool definitions, observation formats, error recovery, and context for higher task completion rates.
Implements structured self-debugging workflow for AI agent failures: capture errors, diagnose patterns like loops or context overflow, apply contained recoveries, and generate introspection reports.
Compares coding agents like Claude Code and Aider on custom YAML-defined codebase tasks using git worktrees, measuring pass rate, cost, time, and consistency.
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.
| 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 |
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) { ... }
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 StructsHandle 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
}
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.
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.
| 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) |
| 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 |