From f8ca6b8b5d0d34143bfdbbd526f76fa6c0da4588 Mon Sep 17 00:00:00 2001 From: lovasoa Date: Mon, 28 Sep 2026 00:55:16 +0200 Subject: [PATCH] fix(sqlite): return an error for out-of-range timestamps --- sqlx-core/src/sqlite/types/time.rs | 2 +- tests/sqlite/types.rs | 31 ++++++++++++++++++++++++++++++ 2 files changed, 32 insertions(+), 1 deletion(-) diff --git a/sqlx-core/src/sqlite/types/time.rs b/sqlx-core/src/sqlite/types/time.rs index bac568c671..a6eea0ab95 100644 --- a/sqlx-core/src/sqlite/types/time.rs +++ b/sqlx-core/src/sqlite/types/time.rs @@ -151,7 +151,7 @@ fn decode_datetime(value: SqliteValueRef<'_>) -> Result decode_datetime_from_text(value.text()?), DataType::Int | DataType::Int64 => { - let parsed = OffsetDateTime::from_unix_timestamp(value.int64()).unwrap(); + let parsed = OffsetDateTime::from_unix_timestamp(value.int64())?; Some(PrimitiveDateTime::new(parsed.date(), parsed.time())) } diff --git a/tests/sqlite/types.rs b/tests/sqlite/types.rs index 962823d894..595d1c4c30 100644 --- a/tests/sqlite/types.rs +++ b/tests/sqlite/types.rs @@ -136,6 +136,37 @@ mod time_tests { use sqlx_oldapi::types::time::{Date, OffsetDateTime, PrimitiveDateTime, Time}; use time::macros::{date, datetime, time}; + #[sqlx_macros::test] + async fn out_of_range_unix_timestamps_return_decode_errors() -> anyhow::Result<()> { + use sqlx_oldapi::Connection; + + let mut conn = sqlx_oldapi::SqliteConnection::connect("sqlite::memory:").await?; + for timestamp in [i64::MIN, i64::MAX] { + let result = sqlx_oldapi::query_scalar::<_, PrimitiveDateTime>("SELECT ?") + .bind(timestamp) + .fetch_one(&mut conn) + .await; + + match result { + Err(sqlx_oldapi::Error::ColumnDecode { source, .. }) => { + assert!(source.is::()); + } + other => panic!("expected a timestamp range error for {timestamp}, got {other:?}"), + } + } + + // A rejected value must not prevent subsequent queries on the connection. + for timestamp in [-1, 0, 1] { + let decoded = sqlx_oldapi::query_scalar::<_, PrimitiveDateTime>("SELECT ?") + .bind(timestamp) + .fetch_one(&mut conn) + .await?; + assert_eq!(decoded.assume_utc().unix_timestamp(), timestamp); + } + + Ok(()) + } + test_type!(time_offset_date_time( Sqlite, "SELECT datetime({0}) is datetime(?), {0}, ?",