From 05397f87d3b7f0fa619fb32294694151a0f67865 Mon Sep 17 00:00:00 2001 From: CairoLee Date: Tue, 24 Feb 2026 20:00:46 +0800 Subject: [PATCH] fix: use `From` impl for SQLite `AnyQueryResult` to preserve `last_insert_id` The `map_result()` function in `sqlx-sqlite/src/any.rs` was hardcoding `last_insert_id: None`, discarding the actual `last_insert_rowid` from `SqliteQueryResult`. Meanwhile, a correct `From` implementation already existed in `query_result.rs` (added in #3608) but was never used by the actual query execution path. This commit replaces the manual construction in `map_result()` with a delegation to `AnyQueryResult::from()`, which properly maps the SQLite `last_insert_rowid` value. A regression test is added to verify that `AnyQueryResult::last_insert_id()` returns the correct value after INSERT operations on SQLite. Closes #2982 --- sqlx-sqlite/src/any.rs | 5 +---- tests/sqlite/any.rs | 39 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 40 insertions(+), 4 deletions(-) diff --git a/sqlx-sqlite/src/any.rs b/sqlx-sqlite/src/any.rs index b3a5af5543..19debe5039 100644 --- a/sqlx-sqlite/src/any.rs +++ b/sqlx-sqlite/src/any.rs @@ -235,8 +235,5 @@ fn map_arguments(args: AnyArguments) -> SqliteArguments { } fn map_result(res: SqliteQueryResult) -> AnyQueryResult { - AnyQueryResult { - rows_affected: res.rows_affected(), - last_insert_id: None, - } + AnyQueryResult::from(res) } diff --git a/tests/sqlite/any.rs b/tests/sqlite/any.rs index b71c3ba43d..84f6971b9c 100644 --- a/tests/sqlite/any.rs +++ b/tests/sqlite/any.rs @@ -1,6 +1,45 @@ use sqlx::Any; use sqlx_test::new; +// Regression test for https://github.com/launchbadge/sqlx/issues/2982 +// `map_result()` in sqlx-sqlite/src/any.rs was discarding `last_insert_rowid`, +// always returning `last_insert_id: None` in `AnyQueryResult`. +#[sqlx_macros::test] +async fn any_query_result_has_last_insert_id() -> anyhow::Result<()> { + sqlx::any::install_default_drivers(); + let mut conn = new::().await?; + + sqlx::query( + "CREATE TEMPORARY TABLE any_last_id_test (id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT NOT NULL)", + ) + .execute(&mut conn) + .await?; + + let result = sqlx::query("INSERT INTO any_last_id_test (name) VALUES (?)") + .bind("Alice") + .execute(&mut conn) + .await?; + + assert_eq!( + result.last_insert_id(), + Some(1), + "first insert should return id 1" + ); + + let result = sqlx::query("INSERT INTO any_last_id_test (name) VALUES (?)") + .bind("Bob") + .execute(&mut conn) + .await?; + + assert_eq!( + result.last_insert_id(), + Some(2), + "second insert should return id 2" + ); + + Ok(()) +} + #[sqlx_macros::test] async fn it_encodes_bool_with_any() -> anyhow::Result<()> { sqlx::any::install_default_drivers();