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]