Upgrade SQLx to ship fixed SQLite

This commit is contained in:
Brent Traut
2026-05-26 17:30:54 -07:00
parent cd934c8bcb
commit ad306b67dd
11 changed files with 624 additions and 385 deletions
+1 -1
View File
@@ -163,7 +163,7 @@ use_repo(nightly_rust, "rust_toolchains")
toolchains = use_extension("@rules_rs//rs/experimental/toolchains:module_extension.bzl", "toolchains")
toolchains.toolchain(
edition = "2024",
version = "1.93.0",
version = "1.94.0",
)
use_repo(toolchains, "default_rust_toolchains")
+136 -131
View File
File diff suppressed because one or more lines are too long
+438 -235
View File
File diff suppressed because it is too large Load Diff
+4 -3
View File
@@ -366,13 +366,14 @@ sha2 = "0.10"
shlex = "1.3.0"
similar = "2.7.0"
socket2 = "0.6.1"
sqlx = { version = "0.8.6", default-features = false, features = [
sqlx = { version = "0.9.0", default-features = false, features = [
"chrono",
"json",
"macros",
"migrate",
"runtime-tokio-rustls",
"sqlite",
"runtime-tokio",
"sqlite-bundled",
"tls-rustls-ring",
"time",
"uuid",
] }
+1 -1
View File
@@ -1,3 +1,3 @@
[toolchain]
channel = "1.93.0"
channel = "1.94.0"
components = ["clippy", "rustfmt", "rust-src"]
+1 -1
View File
@@ -179,7 +179,7 @@ if (-not (Ensure-Command 'cargo')) {
Write-Host "==> Configuring Rust toolchain per rust-toolchain.toml" -ForegroundColor Cyan
# Pin to the workspace toolchain and install components
$toolchain = '1.93.0'
$toolchain = '1.94.0'
& rustup toolchain install $toolchain --profile minimal | Out-Host
& rustup default $toolchain | Out-Host
& rustup component add clippy rustfmt rust-src --toolchain $toolchain | Out-Host
+2
View File
@@ -19,6 +19,8 @@ fn runtime_migrator(base: &'static Migrator) -> Migrator {
ignore_missing: true,
locking: base.locking,
no_tx: base.no_tx,
table_name: base.table_name.clone(),
create_schemas: base.create_schemas.clone(),
}
}
+30
View File
@@ -569,6 +569,36 @@ mod tests {
let _ = tokio::fs::remove_dir_all(codex_home).await;
}
#[tokio::test]
async fn linked_sqlite_has_wal_reset_bug_fix() {
let pool = SqlitePool::connect("sqlite::memory:")
.await
.expect("open in-memory sqlite db");
let sqlite_version: String = sqlx::query_scalar("SELECT sqlite_version()")
.fetch_one(&pool)
.await
.expect("query linked sqlite version");
pool.close().await;
let version = sqlite_version
.split('.')
.map(|part| part.parse::<u32>().expect("numeric sqlite version"))
.collect::<Vec<_>>();
assert_eq!(
version.len(),
3,
"unexpected SQLite version: {sqlite_version}"
);
let version = (version[0], version[1], version[2]);
let includes_wal_reset_fix = version >= (3, 51, 3)
|| (version.0 == 3 && version.1 == 50 && version.2 >= 7)
|| (version.0 == 3 && version.1 == 44 && version.2 >= 6);
assert!(
includes_wal_reset_fix,
"linked SQLite {sqlite_version} is vulnerable to the WAL-reset corruption bug"
);
}
#[tokio::test]
async fn open_state_sqlite_tolerates_newer_applied_migrations() {
let codex_home = unique_temp_dir();
+1 -1
View File
@@ -450,7 +450,7 @@ RETURNING
"#,
);
let mut query = sqlx::query(&query)
let mut query = sqlx::query(sqlx::AssertSqlSafe(query))
.bind(time_delta_seconds)
.bind(token_delta)
.bind(token_delta)
+5 -7
View File
@@ -392,7 +392,7 @@ WHERE cumulative_estimated_bytes <= ?
ORDER BY ts DESC, ts_nanos DESC, id DESC
"#
);
let mut sql = sqlx::query_as::<_, FeedbackLogRow>(query.as_str());
let mut sql = sqlx::query_as::<_, FeedbackLogRow>(sqlx::AssertSqlSafe(query));
for thread_id in thread_ids {
sql = sql.bind(thread_id);
}
@@ -463,7 +463,7 @@ fn format_feedback_log_line(
line
}
fn push_log_filters<'a>(builder: &mut QueryBuilder<'a, Sqlite>, query: &'a LogQuery) {
fn push_log_filters(builder: &mut QueryBuilder<Sqlite>, query: &LogQuery) {
if !query.levels_upper.is_empty() {
builder.push(" AND UPPER(level) IN (");
{
@@ -511,11 +511,7 @@ fn push_log_filters<'a>(builder: &mut QueryBuilder<'a, Sqlite>, query: &'a LogQu
}
}
fn push_like_filters<'a>(
builder: &mut QueryBuilder<'a, Sqlite>,
column: &str,
filters: &'a [String],
) {
fn push_like_filters(builder: &mut QueryBuilder<Sqlite>, column: &str, filters: &[String]) {
if filters.is_empty() {
return;
}
@@ -613,6 +609,8 @@ mod tests {
ignore_missing: false,
locking: true,
no_tx: false,
table_name: Cow::Borrowed("_sqlx_migrations"),
create_schemas: Cow::Borrowed(&[]),
};
let pool = SqlitePool::connect_with(
SqliteConnectOptions::new()
+5 -5
View File
@@ -260,7 +260,7 @@ LIMIT 2
}
query.push_str(" ORDER BY child_thread_id");
let mut sql = sqlx::query(query.as_str()).bind(parent_thread_id.to_string());
let mut sql = sqlx::query(sqlx::AssertSqlSafe(query)).bind(parent_thread_id.to_string());
if let Some(status) = status {
sql = sql.bind(status.to_string());
}
@@ -301,7 +301,7 @@ ORDER BY depth ASC, child_thread_id ASC
"#
);
let mut sql = sqlx::query(query.as_str()).bind(root_thread_id.to_string());
let mut sql = sqlx::query(sqlx::AssertSqlSafe(query)).bind(root_thread_id.to_string());
if let Some(status) = status {
let status = status.to_string();
sql = sql.bind(status.clone()).bind(status);
@@ -999,7 +999,7 @@ fn one_thread_id_from_rows(
}
}
pub(super) fn push_thread_select_columns(builder: &mut QueryBuilder<'_, Sqlite>) {
pub(super) fn push_thread_select_columns(builder: &mut QueryBuilder<Sqlite>) {
builder.push(
r#"
SELECT
@@ -1076,7 +1076,7 @@ pub struct ThreadFilterOptions<'a> {
}
pub(super) fn push_thread_filters<'a>(
builder: &mut QueryBuilder<'a, Sqlite>,
builder: &mut QueryBuilder<Sqlite>,
options: ThreadFilterOptions<'a>,
) {
let ThreadFilterOptions {
@@ -1156,7 +1156,7 @@ pub(super) fn push_thread_filters<'a>(
}
pub(super) fn push_thread_order_and_limit(
builder: &mut QueryBuilder<'_, Sqlite>,
builder: &mut QueryBuilder<Sqlite>,
sort_key: SortKey,
sort_direction: SortDirection,
limit: usize,