This is an automated email from the ASF dual-hosted git repository.
Jefffrey pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/arrow-rs.git
The following commit(s) were added to refs/heads/main by this push:
new fd86c75c60 fix(arrow-cast): fix incorrect conversion (#9852)
fd86c75c60 is described below
commit fd86c75c609c664e8d24c780a8a6654729879c0c
Author: bboissin <[email protected]>
AuthorDate: Fri May 1 07:16:28 2026 +0200
fix(arrow-cast): fix incorrect conversion (#9852)
MICROSECONDS / NANOSECONDS = 0, this should be NANOSECONDS /
MILLISECONDS.
Found with claude code audit.
# Which issue does this PR close?
- Closes #9851
# Rationale for this change
Bugfix, instead of multiplying by 0 we multiply by the correct factor.
---
arrow-cast/src/cast/mod.rs | 48 +++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 47 insertions(+), 1 deletion(-)
diff --git a/arrow-cast/src/cast/mod.rs b/arrow-cast/src/cast/mod.rs
index 5f08dcbfc1..2d9923c9a2 100644
--- a/arrow-cast/src/cast/mod.rs
+++ b/arrow-cast/src/cast/mod.rs
@@ -1729,7 +1729,7 @@ pub fn cast_with_options(
(Time32(TimeUnit::Millisecond), Time64(TimeUnit::Nanosecond)) =>
Ok(Arc::new(
array
.as_primitive::<Time32MillisecondType>()
- .unary::<_, Time64NanosecondType>(|x| x as i64 * (MICROSECONDS
/ NANOSECONDS)),
+ .unary::<_, Time64NanosecondType>(|x| x as i64 * (NANOSECONDS
/ MILLISECONDS)),
)),
(Time64(TimeUnit::Microsecond), Time32(TimeUnit::Second)) =>
Ok(Arc::new(
@@ -13277,6 +13277,52 @@ mod tests {
assert_eq!(cast_array.value(2), 3000);
}
+ #[test]
+ fn test_cast_time32_millisecond_to_time64_nanosecond() {
+ let array =
+ Time32MillisecondArray::from(vec![Some(1_000), Some(2_000), None,
Some(43_200_000)]);
+ let b = cast(&array, &DataType::Time64(TimeUnit::Nanosecond)).unwrap();
+ let c = b.as_primitive::<Time64NanosecondType>();
+ assert_eq!(c.value(0), 1_000_000_000);
+ assert_eq!(c.value(1), 2_000_000_000);
+ assert!(c.is_null(2));
+ assert_eq!(c.value(3), 43_200_000_000_000);
+ }
+
+ #[test]
+ fn test_cast_time32_millisecond_to_time64_microsecond() {
+ let array =
+ Time32MillisecondArray::from(vec![Some(1_000), Some(2_000), None,
Some(43_200_000)]);
+ let b = cast(&array,
&DataType::Time64(TimeUnit::Microsecond)).unwrap();
+ let c = b.as_primitive::<Time64MicrosecondType>();
+ assert_eq!(c.value(0), 1_000_000);
+ assert_eq!(c.value(1), 2_000_000);
+ assert!(c.is_null(2));
+ assert_eq!(c.value(3), 43_200_000_000);
+ }
+
+ #[test]
+ fn test_cast_time32_second_to_time64_nanosecond() {
+ let array = Time32SecondArray::from(vec![Some(1), Some(60), None,
Some(43_200)]);
+ let b = cast(&array, &DataType::Time64(TimeUnit::Nanosecond)).unwrap();
+ let c = b.as_primitive::<Time64NanosecondType>();
+ assert_eq!(c.value(0), 1_000_000_000);
+ assert_eq!(c.value(1), 60_000_000_000);
+ assert!(c.is_null(2));
+ assert_eq!(c.value(3), 43_200_000_000_000);
+ }
+
+ #[test]
+ fn test_cast_time32_second_to_time64_microsecond() {
+ let array = Time32SecondArray::from(vec![Some(1), Some(60), None,
Some(43_200)]);
+ let b = cast(&array,
&DataType::Time64(TimeUnit::Microsecond)).unwrap();
+ let c = b.as_primitive::<Time64MicrosecondType>();
+ assert_eq!(c.value(0), 1_000_000);
+ assert_eq!(c.value(1), 60_000_000);
+ assert!(c.is_null(2));
+ assert_eq!(c.value(3), 43_200_000_000);
+ }
+
#[test]
fn test_cast_string_to_time32_second_to_int64() {
// Mimic: select arrow_cast('03:12:44'::time,
'Time32(Second)')::bigint;