diff --git a/arrow-cast/src/cast.rs b/arrow-cast/src/cast.rs index 5bf8c19c5baf..e394426bd682 100644 --- a/arrow-cast/src/cast.rs +++ b/arrow-cast/src/cast.rs @@ -244,7 +244,7 @@ pub fn can_cast_types(from_type: &DataType, to_type: &DataType) -> bool { (Timestamp(_, _), Int64) => true, (Int64, Timestamp(_, _)) => true, (Timestamp(_, _), Timestamp(_, _) | Date32 | Date64) => true, - // date64 to timestamp might not make sense, + (Date64, Timestamp(_, None)) => true, (Int64, Duration(_)) => true, (Duration(_), Int64) => true, (Interval(from_type), Int64) => { @@ -1484,7 +1484,24 @@ pub fn cast_with_options( .unary::<_, Date64Type>(|x| x / (NANOSECONDS / MILLISECONDS)), )), - // date64 to timestamp might not make sense, + (Date64, Timestamp(TimeUnit::Second, None)) => Ok(Arc::new( + as_primitive_array::(array) + .unary::<_, TimestampSecondType>(|x| x / MILLISECONDS), + )), + (Date64, Timestamp(TimeUnit::Millisecond, None)) => { + cast_reinterpret_arrays::(array) + } + (Date64, Timestamp(TimeUnit::Microsecond, None)) => Ok(Arc::new( + as_primitive_array::(array).unary::<_, TimestampMicrosecondType>( + |x| x * (MICROSECONDS / MILLISECONDS), + ), + )), + (Date64, Timestamp(TimeUnit::Nanosecond, None)) => Ok(Arc::new( + as_primitive_array::(array).unary::<_, TimestampNanosecondType>( + |x| x * (NANOSECONDS / MILLISECONDS), + ), + )), + (Int64, Duration(TimeUnit::Second)) => { cast_reinterpret_arrays::(array) } @@ -4073,6 +4090,59 @@ mod tests { assert!(c.is_null(2)); } + #[test] + fn test_cast_date64_to_timestamp() { + let a = Date64Array::from(vec![Some(864000000005), Some(1545696000001), None]); + let array = Arc::new(a) as ArrayRef; + let b = cast(&array, &DataType::Timestamp(TimeUnit::Second, None)).unwrap(); + let c = b.as_any().downcast_ref::().unwrap(); + assert_eq!(864000000, c.value(0)); + assert_eq!(1545696000, c.value(1)); + assert!(c.is_null(2)); + } + + #[test] + fn test_cast_date64_to_timestamp_ms() { + let a = Date64Array::from(vec![Some(864000000005), Some(1545696000001), None]); + let array = Arc::new(a) as ArrayRef; + let b = cast(&array, &DataType::Timestamp(TimeUnit::Millisecond, None)).unwrap(); + let c = b + .as_any() + .downcast_ref::() + .unwrap(); + assert_eq!(864000000005, c.value(0)); + assert_eq!(1545696000001, c.value(1)); + assert!(c.is_null(2)); + } + + #[test] + fn test_cast_date64_to_timestamp_us() { + let a = Date64Array::from(vec![Some(864000000005), Some(1545696000001), None]); + let array = Arc::new(a) as ArrayRef; + let b = cast(&array, &DataType::Timestamp(TimeUnit::Microsecond, None)).unwrap(); + let c = b + .as_any() + .downcast_ref::() + .unwrap(); + assert_eq!(864000000005000, c.value(0)); + assert_eq!(1545696000001000, c.value(1)); + assert!(c.is_null(2)); + } + + #[test] + fn test_cast_date64_to_timestamp_ns() { + let a = Date64Array::from(vec![Some(864000000005), Some(1545696000001), None]); + let array = Arc::new(a) as ArrayRef; + let b = cast(&array, &DataType::Timestamp(TimeUnit::Nanosecond, None)).unwrap(); + let c = b + .as_any() + .downcast_ref::() + .unwrap(); + assert_eq!(864000000005000000, c.value(0)); + assert_eq!(1545696000001000000, c.value(1)); + assert!(c.is_null(2)); + } + #[test] fn test_cast_timestamp_to_i64() { let a = TimestampMillisecondArray::from(vec![