Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion sqlx-sqlite/src/types/time.rs
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,7 @@ fn decode_datetime(value: SqliteValueRef<'_>) -> Result<PrimitiveDateTime, BoxDy
let dt = match value.type_info().0 {
DataType::Text => decode_datetime_from_text(value.text_borrowed()?),
DataType::Int4 | DataType::Integer => {
let parsed = OffsetDateTime::from_unix_timestamp(value.int64()?).unwrap();
let parsed = OffsetDateTime::from_unix_timestamp(value.int64()?)?;
Some(PrimitiveDateTime::new(parsed.date(), parsed.time()))
}

Expand Down
15 changes: 15 additions & 0 deletions tests/sqlite/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,21 @@ mod time_tests {
"'20:45:31.133'" == time!(20:45:31.133),
"'19:44'" == time!(19:44),
));

// An INTEGER holding a Unix timestamp that is out of range for `time` (for example a
// millisecond timestamp) must fail to decode instead of panicking.
#[sqlx_macros::test]
async fn it_errors_on_out_of_range_integer_primitive_date_time() -> anyhow::Result<()> {
let mut conn = new::<Sqlite>().await?;

let result = sqlx::query_scalar::<_, PrimitiveDateTime>("SELECT 1700000000000")
.fetch_one(&mut conn)
.await;

assert!(result.is_err(), "expected a decode error, got {result:?}");

Ok(())
}
}

#[cfg(feature = "bstr")]
Expand Down
Loading