waitingkuo commented on code in PR #3016:
URL: https://github.com/apache/arrow-rs/pull/3016#discussion_r1013603939


##########
arrow/src/compute/kernels/cast.rs:
##########
@@ -1413,6 +1422,71 @@ pub fn cast_with_options(
             as_primitive_array::<TimestampNanosecondType>(array)
                 .unary::<_, Date64Type>(|x| x / (NANOSECONDS / MILLISECONDS)),
         )),
+        (Timestamp(TimeUnit::Second, _), Time64(TimeUnit::Microsecond)) => 
Ok(Arc::new(
+            as_primitive_array::<TimestampSecondType>(array)
+                .unary::<_, Time64MicrosecondType>(|x| {
+                    x * MICROSECONDS % MICROSECONDS_IN_DAY
+                }),
+        )),
+        (Timestamp(TimeUnit::Second, _), Time64(TimeUnit::Nanosecond)) => 
Ok(Arc::new(
+            as_primitive_array::<TimestampSecondType>(array)
+                .unary::<_, Time64NanosecondType>(|x| {
+                    x * NANOSECONDS % NANOSECONDS_IN_DAY
+                }),
+        )),
+        (Timestamp(TimeUnit::Millisecond, _), Time64(TimeUnit::Microsecond)) 
=> {
+            Ok(Arc::new(
+                as_primitive_array::<TimestampSecondType>(array)
+                    .unary::<_, Time64MicrosecondType>(|x| {
+                        x / MILLISECONDS % MICROSECONDS_IN_DAY
+                    }),
+            ))
+        }
+        (Timestamp(TimeUnit::Millisecond, _), Time64(TimeUnit::Nanosecond)) => 
{
+            Ok(Arc::new(
+                as_primitive_array::<TimestampSecondType>(array)
+                    .unary::<_, Time64NanosecondType>(|x| {
+                        x / MILLISECONDS % NANOSECONDS_IN_DAY
+                    }),
+            ))
+        }
+        (Timestamp(TimeUnit::Microsecond, _), Time64(TimeUnit::Microsecond)) 
=> {
+            Ok(Arc::new(
+                as_primitive_array::<TimestampSecondType>(array)
+                    .unary::<_, Time64MicrosecondType>(|x| {
+                        x / MICROSECONDS % MICROSECONDS_IN_DAY
+                    }),
+            ))
+        }
+        (Timestamp(TimeUnit::Microsecond, _), Time64(TimeUnit::Nanosecond)) => 
{
+            Ok(Arc::new(
+                as_primitive_array::<TimestampSecondType>(array)
+                    .unary::<_, Time64NanosecondType>(|x| {
+                        x / MICROSECONDS % NANOSECONDS_IN_DAY
+                    }),
+            ))
+        }
+        (Timestamp(TimeUnit::Nanosecond, _), Time64(TimeUnit::Microsecond)) => 
{
+            Ok(Arc::new(
+                as_primitive_array::<TimestampSecondType>(array)
+                    .unary::<_, Time64MicrosecondType>(|x| {
+                        x / NANOSECONDS % MICROSECONDS_IN_DAY
+                    }),
+            ))
+        }
+        (Timestamp(TimeUnit::Nanosecond, _), Time64(TimeUnit::Nanosecond)) => {
+            Ok(Arc::new(
+                as_primitive_array::<TimestampSecondType>(array)
+                    .unary::<_, Time64NanosecondType>(|x| {
+                        x / NANOSECONDS % NANOSECONDS_IN_DAY
+                    }),
+            ))
+        }

Review Comment:
   @tustvold  is it recommended? it's not that consistent in `cast`
   sometimes it's separated by TimeUnit, sometimes it's merged into one



##########
arrow/src/compute/kernels/cast.rs:
##########
@@ -1413,6 +1422,71 @@ pub fn cast_with_options(
             as_primitive_array::<TimestampNanosecondType>(array)
                 .unary::<_, Date64Type>(|x| x / (NANOSECONDS / MILLISECONDS)),
         )),
+        (Timestamp(TimeUnit::Second, _), Time64(TimeUnit::Microsecond)) => 
Ok(Arc::new(
+            as_primitive_array::<TimestampSecondType>(array)
+                .unary::<_, Time64MicrosecondType>(|x| {
+                    x * MICROSECONDS % MICROSECONDS_IN_DAY
+                }),
+        )),
+        (Timestamp(TimeUnit::Second, _), Time64(TimeUnit::Nanosecond)) => 
Ok(Arc::new(
+            as_primitive_array::<TimestampSecondType>(array)
+                .unary::<_, Time64NanosecondType>(|x| {
+                    x * NANOSECONDS % NANOSECONDS_IN_DAY
+                }),
+        )),
+        (Timestamp(TimeUnit::Millisecond, _), Time64(TimeUnit::Microsecond)) 
=> {
+            Ok(Arc::new(
+                as_primitive_array::<TimestampSecondType>(array)
+                    .unary::<_, Time64MicrosecondType>(|x| {
+                        x / MILLISECONDS % MICROSECONDS_IN_DAY
+                    }),
+            ))
+        }
+        (Timestamp(TimeUnit::Millisecond, _), Time64(TimeUnit::Nanosecond)) => 
{
+            Ok(Arc::new(
+                as_primitive_array::<TimestampSecondType>(array)
+                    .unary::<_, Time64NanosecondType>(|x| {
+                        x / MILLISECONDS % NANOSECONDS_IN_DAY
+                    }),
+            ))
+        }
+        (Timestamp(TimeUnit::Microsecond, _), Time64(TimeUnit::Microsecond)) 
=> {
+            Ok(Arc::new(
+                as_primitive_array::<TimestampSecondType>(array)
+                    .unary::<_, Time64MicrosecondType>(|x| {
+                        x / MICROSECONDS % MICROSECONDS_IN_DAY
+                    }),
+            ))
+        }
+        (Timestamp(TimeUnit::Microsecond, _), Time64(TimeUnit::Nanosecond)) => 
{
+            Ok(Arc::new(
+                as_primitive_array::<TimestampSecondType>(array)
+                    .unary::<_, Time64NanosecondType>(|x| {
+                        x / MICROSECONDS % NANOSECONDS_IN_DAY
+                    }),
+            ))
+        }
+        (Timestamp(TimeUnit::Nanosecond, _), Time64(TimeUnit::Microsecond)) => 
{
+            Ok(Arc::new(
+                as_primitive_array::<TimestampSecondType>(array)
+                    .unary::<_, Time64MicrosecondType>(|x| {
+                        x / NANOSECONDS % MICROSECONDS_IN_DAY
+                    }),
+            ))
+        }
+        (Timestamp(TimeUnit::Nanosecond, _), Time64(TimeUnit::Nanosecond)) => {
+            Ok(Arc::new(
+                as_primitive_array::<TimestampSecondType>(array)
+                    .unary::<_, Time64NanosecondType>(|x| {
+                        x / NANOSECONDS % NANOSECONDS_IN_DAY
+                    }),
+            ))
+        }

Review Comment:
   I think we could merge them into
   
   ```rust
   (Timestamp(from_unit: &TimeUnit, _), Time64(to_unit: &TimeUnit)
   and 
   (Timestamp(from_unit: &TimeUnit, _), Time32(to_unit: &TimeUnit)
   ```
   
   
   you can try to follow the logic for 
   ```rust
   (Timestamp(from_unit, _), Timestamp(to_unit, to_tz))
   ```
   



##########
arrow/src/compute/kernels/cast.rs:
##########
@@ -1413,6 +1422,71 @@ pub fn cast_with_options(
             as_primitive_array::<TimestampNanosecondType>(array)
                 .unary::<_, Date64Type>(|x| x / (NANOSECONDS / MILLISECONDS)),
         )),
+        (Timestamp(TimeUnit::Second, _), Time64(TimeUnit::Microsecond)) => 
Ok(Arc::new(
+            as_primitive_array::<TimestampSecondType>(array)
+                .unary::<_, Time64MicrosecondType>(|x| {
+                    x * MICROSECONDS % MICROSECONDS_IN_DAY
+                }),
+        )),
+        (Timestamp(TimeUnit::Second, _), Time64(TimeUnit::Nanosecond)) => 
Ok(Arc::new(
+            as_primitive_array::<TimestampSecondType>(array)
+                .unary::<_, Time64NanosecondType>(|x| {
+                    x * NANOSECONDS % NANOSECONDS_IN_DAY
+                }),
+        )),
+        (Timestamp(TimeUnit::Millisecond, _), Time64(TimeUnit::Microsecond)) 
=> {
+            Ok(Arc::new(
+                as_primitive_array::<TimestampSecondType>(array)
+                    .unary::<_, Time64MicrosecondType>(|x| {
+                        x / MILLISECONDS % MICROSECONDS_IN_DAY
+                    }),
+            ))
+        }
+        (Timestamp(TimeUnit::Millisecond, _), Time64(TimeUnit::Nanosecond)) => 
{
+            Ok(Arc::new(
+                as_primitive_array::<TimestampSecondType>(array)
+                    .unary::<_, Time64NanosecondType>(|x| {
+                        x / MILLISECONDS % NANOSECONDS_IN_DAY
+                    }),
+            ))
+        }
+        (Timestamp(TimeUnit::Microsecond, _), Time64(TimeUnit::Microsecond)) 
=> {
+            Ok(Arc::new(
+                as_primitive_array::<TimestampSecondType>(array)
+                    .unary::<_, Time64MicrosecondType>(|x| {
+                        x / MICROSECONDS % MICROSECONDS_IN_DAY
+                    }),
+            ))
+        }
+        (Timestamp(TimeUnit::Microsecond, _), Time64(TimeUnit::Nanosecond)) => 
{
+            Ok(Arc::new(
+                as_primitive_array::<TimestampSecondType>(array)
+                    .unary::<_, Time64NanosecondType>(|x| {
+                        x / MICROSECONDS % NANOSECONDS_IN_DAY
+                    }),
+            ))
+        }
+        (Timestamp(TimeUnit::Nanosecond, _), Time64(TimeUnit::Microsecond)) => 
{
+            Ok(Arc::new(
+                as_primitive_array::<TimestampSecondType>(array)
+                    .unary::<_, Time64MicrosecondType>(|x| {
+                        x / NANOSECONDS % MICROSECONDS_IN_DAY
+                    }),
+            ))
+        }
+        (Timestamp(TimeUnit::Nanosecond, _), Time64(TimeUnit::Nanosecond)) => {
+            Ok(Arc::new(
+                as_primitive_array::<TimestampSecondType>(array)
+                    .unary::<_, Time64NanosecondType>(|x| {
+                        x / NANOSECONDS % NANOSECONDS_IN_DAY
+                    }),
+            ))
+        }
+        (Timestamp(_, _), Time32(_)) => cast_with_options(
+            &cast_with_options(array, &Time64(TimeUnit::Microsecond), 
cast_options)?,
+            to_type,
+            cast_options,
+        ),

Review Comment:
   perhaps we could implement it like the way casting to TIme64. I'm now sure 
casting twice here is a good idea or now. @tustvold do you have any comments?



##########
arrow/src/compute/kernels/cast.rs:
##########
@@ -3990,6 +4064,40 @@ mod tests {
         assert!(c.is_null(2));
     }
 
+    #[test]
+    fn test_cast_timestamp_to_time64() {
+        let a = TimestampSecondArray::from(vec![Some(86405), Some(1), None])
+            .with_timezone("UTC".to_string());
+        let array = Arc::new(a) as ArrayRef;
+        let b = cast(&array, 
&DataType::Time64(TimeUnit::Microsecond)).unwrap();
+        let c = b.as_any().downcast_ref::<Time64MicrosecondArray>().unwrap();
+        assert_eq!(5000000, c.value(0));
+        assert_eq!(1000000, c.value(1));
+        assert!(c.is_null(2));
+        let b = cast(&array, &DataType::Time64(TimeUnit::Nanosecond)).unwrap();
+        let c = b.as_any().downcast_ref::<Time64NanosecondArray>().unwrap();
+        assert_eq!(5000000000, c.value(0));
+        assert_eq!(1000000000, c.value(1));
+        assert!(c.is_null(2));
+    }
+
+    #[test]
+    fn test_cast_timestamp_to_time32() {
+        let a = TimestampSecondArray::from(vec![Some(86405), Some(1), None])
+            .with_timezone("UTC".to_string());
+        let array = Arc::new(a) as ArrayRef;
+        let b = cast(&array, &DataType::Time32(TimeUnit::Second)).unwrap();
+        let c = b.as_any().downcast_ref::<Time32SecondArray>().unwrap();
+        assert_eq!(5, c.value(0));
+        assert_eq!(1, c.value(1));
+        assert!(c.is_null(2));
+        let b = cast(&array, 
&DataType::Time32(TimeUnit::Millisecond)).unwrap();
+        let c = b.as_any().downcast_ref::<Time32MillisecondArray>().unwrap();
+        assert_eq!(5000, c.value(0));
+        assert_eq!(1000, c.value(1));
+        assert!(c.is_null(2));
+    }
+

Review Comment:
   👍 
   i would be great if we have some test cases covers casting from 
millis/micros/nanos



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to