You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@arrow.apache.org by tu...@apache.org on 2022/11/07 19:12:14 UTC

[arrow-rs] branch master updated: Enable casting from Date64 to Timestamp (#3038)

This is an automated email from the ASF dual-hosted git repository.

tustvold pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/arrow-rs.git


The following commit(s) were added to refs/heads/master by this push:
     new 951caed78 Enable casting from Date64 to Timestamp (#3038)
951caed78 is described below

commit 951caed784876d15a9e712a5981de31cee4e3085
Author: Marko Grujic <ma...@gmail.com>
AuthorDate: Mon Nov 7 20:12:08 2022 +0100

    Enable casting from Date64 to Timestamp (#3038)
---
 arrow-cast/src/cast.rs | 74 ++++++++++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 72 insertions(+), 2 deletions(-)

diff --git a/arrow-cast/src/cast.rs b/arrow-cast/src/cast.rs
index 5bf8c19c5..e394426bd 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::<Date64Type>(array)
+                .unary::<_, TimestampSecondType>(|x| x / MILLISECONDS),
+        )),
+        (Date64, Timestamp(TimeUnit::Millisecond, None)) => {
+            cast_reinterpret_arrays::<Date64Type, TimestampMillisecondType>(array)
+        }
+        (Date64, Timestamp(TimeUnit::Microsecond, None)) => Ok(Arc::new(
+            as_primitive_array::<Date64Type>(array).unary::<_, TimestampMicrosecondType>(
+                |x| x * (MICROSECONDS / MILLISECONDS),
+            ),
+        )),
+        (Date64, Timestamp(TimeUnit::Nanosecond, None)) => Ok(Arc::new(
+            as_primitive_array::<Date64Type>(array).unary::<_, TimestampNanosecondType>(
+                |x| x * (NANOSECONDS / MILLISECONDS),
+            ),
+        )),
+
         (Int64, Duration(TimeUnit::Second)) => {
             cast_reinterpret_arrays::<Int64Type, DurationSecondType>(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::<TimestampSecondArray>().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::<TimestampMillisecondArray>()
+            .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::<TimestampMicrosecondArray>()
+            .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::<TimestampNanosecondArray>()
+            .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![