You are viewing a plain text version of this content. The canonical link for it is here.
Posted to github@arrow.apache.org by "izveigor (via GitHub)" <gi...@apache.org> on 2023/05/08 19:44:20 UTC

[GitHub] [arrow-rs] izveigor opened a new pull request, #4182: feat: cast between `Intervals`

izveigor opened a new pull request, #4182:
URL: https://github.com/apache/arrow-rs/pull/4182

   # Which issue does this PR close?
   
   <!--
   We generally require a GitHub issue to be filed for all bug fixes and enhancements and this helps us generate change logs for our releases. You can link an issue to this PR using the GitHub syntax. For example `Closes #123` indicates that this PR will close issue #123.
   -->
   
   Closes #4181
   
   # Rationale for this change
    
   <!--
   Why are you proposing this change? If this is already explained clearly in the issue then this section is not needed.
   Explaining clearly why changes are proposed helps reviewers understand your changes and offer better suggestions for fixes.
   -->
   
   # What changes are included in this PR?
   
   <!--
   There is no need to duplicate the description in the issue here but it is sometimes worth providing a summary of the individual changes in this PR.
   -->
   
   # Are there any user-facing changes?
   Yes
   
   <!--
   If there are user-facing changes then we may require documentation to be updated before approving the PR.
   -->
   
   <!---
   If there are any breaking changes to public APIs, please add the `breaking change` label.
   -->
   


-- 
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: github-unsubscribe@arrow.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [arrow-rs] tustvold commented on a diff in pull request #4182: feat: cast between `Intervals`

Posted by "tustvold (via GitHub)" <gi...@apache.org>.
tustvold commented on code in PR #4182:
URL: https://github.com/apache/arrow-rs/pull/4182#discussion_r1213013977


##########
arrow-cast/src/cast.rs:
##########
@@ -409,6 +413,125 @@ where
     }
 }
 
+/// Cast the array from interval year month to month day nano
+fn cast_interval_year_month_to_interval_month_day_nano(
+    array: &dyn Array,
+    cast_options: &CastOptions,
+) -> Result<ArrayRef, ArrowError> {
+    let array = array.as_primitive::<IntervalYearMonthType>();
+
+    if cast_options.safe {
+        Ok(Arc::new(array.unary_opt::<_, IntervalMonthDayNanoType>(
+            |v| {
+                let months = IntervalYearMonthType::to_months(v);
+                Some(IntervalMonthDayNanoType::make_value(months, 0, 0))
+            },
+        )))
+    } else {
+        Ok(Arc::new(
+            array.try_unary::<_, IntervalMonthDayNanoType, ArrowError>(|v| {
+                let months = IntervalYearMonthType::to_months(v);
+                Ok(IntervalMonthDayNanoType::make_value(months, 0, 0))
+            })?,
+        ))
+    }
+}
+
+/// Cast the array from interval day time to month day nano
+fn cast_interval_day_time_to_interval_month_day_nano(
+    array: &dyn Array,
+    cast_options: &CastOptions,
+) -> Result<ArrayRef, ArrowError> {
+    let array = array.as_primitive::<IntervalDayTimeType>();
+    let mul = 10_i32.pow(6);
+
+    if cast_options.safe {
+        Ok(Arc::new(array.unary_opt::<_, IntervalMonthDayNanoType>(
+            |v| {
+                let (days, ms) = IntervalDayTimeType::to_parts(v);
+                Some(IntervalMonthDayNanoType::make_value(
+                    0,
+                    days,
+                    (ms * mul).into(),

Review Comment:
   ```suggestion
                       ms as i64 * mil,
   ```



##########
arrow-cast/src/cast.rs:
##########
@@ -409,6 +413,125 @@ where
     }
 }
 
+/// Cast the array from interval year month to month day nano
+fn cast_interval_year_month_to_interval_month_day_nano(
+    array: &dyn Array,
+    cast_options: &CastOptions,
+) -> Result<ArrayRef, ArrowError> {
+    let array = array.as_primitive::<IntervalYearMonthType>();
+
+    if cast_options.safe {
+        Ok(Arc::new(array.unary_opt::<_, IntervalMonthDayNanoType>(
+            |v| {
+                let months = IntervalYearMonthType::to_months(v);
+                Some(IntervalMonthDayNanoType::make_value(months, 0, 0))
+            },
+        )))
+    } else {
+        Ok(Arc::new(
+            array.try_unary::<_, IntervalMonthDayNanoType, ArrowError>(|v| {
+                let months = IntervalYearMonthType::to_months(v);
+                Ok(IntervalMonthDayNanoType::make_value(months, 0, 0))
+            })?,
+        ))
+    }
+}
+
+/// Cast the array from interval day time to month day nano
+fn cast_interval_day_time_to_interval_month_day_nano(
+    array: &dyn Array,
+    cast_options: &CastOptions,
+) -> Result<ArrayRef, ArrowError> {
+    let array = array.as_primitive::<IntervalDayTimeType>();
+    let mul = 10_i32.pow(6);
+
+    if cast_options.safe {

Review Comment:
   It occurs to me that this actually cannot overflow, and so can just use `unary`.
   
   It is performing a widening multiplication of i32 milliseconds to i64 nanoseconds



##########
arrow-cast/src/cast.rs:
##########
@@ -409,6 +413,125 @@ where
     }
 }
 
+/// Cast the array from interval year month to month day nano
+fn cast_interval_year_month_to_interval_month_day_nano(
+    array: &dyn Array,
+    cast_options: &CastOptions,
+) -> Result<ArrayRef, ArrowError> {
+    let array = array.as_primitive::<IntervalYearMonthType>();
+
+    if cast_options.safe {
+        Ok(Arc::new(array.unary_opt::<_, IntervalMonthDayNanoType>(
+            |v| {
+                let months = IntervalYearMonthType::to_months(v);
+                Some(IntervalMonthDayNanoType::make_value(months, 0, 0))
+            },
+        )))
+    } else {
+        Ok(Arc::new(
+            array.try_unary::<_, IntervalMonthDayNanoType, ArrowError>(|v| {
+                let months = IntervalYearMonthType::to_months(v);
+                Ok(IntervalMonthDayNanoType::make_value(months, 0, 0))
+            })?,
+        ))
+    }
+}
+
+/// Cast the array from interval day time to month day nano
+fn cast_interval_day_time_to_interval_month_day_nano(
+    array: &dyn Array,
+    cast_options: &CastOptions,
+) -> Result<ArrayRef, ArrowError> {
+    let array = array.as_primitive::<IntervalDayTimeType>();
+    let mul = 10_i32.pow(6);

Review Comment:
   ```suggestion
       let mul = 1_000_000;
   ```



##########
arrow-cast/src/cast.rs:
##########
@@ -409,6 +413,125 @@ where
     }
 }
 
+/// Cast the array from interval year month to month day nano
+fn cast_interval_year_month_to_interval_month_day_nano(
+    array: &dyn Array,
+    cast_options: &CastOptions,
+) -> Result<ArrayRef, ArrowError> {
+    let array = array.as_primitive::<IntervalYearMonthType>();
+
+    if cast_options.safe {
+        Ok(Arc::new(array.unary_opt::<_, IntervalMonthDayNanoType>(
+            |v| {
+                let months = IntervalYearMonthType::to_months(v);
+                Some(IntervalMonthDayNanoType::make_value(months, 0, 0))
+            },
+        )))
+    } else {
+        Ok(Arc::new(
+            array.try_unary::<_, IntervalMonthDayNanoType, ArrowError>(|v| {
+                let months = IntervalYearMonthType::to_months(v);
+                Ok(IntervalMonthDayNanoType::make_value(months, 0, 0))
+            })?,
+        ))
+    }
+}
+
+/// Cast the array from interval day time to month day nano
+fn cast_interval_day_time_to_interval_month_day_nano(
+    array: &dyn Array,
+    cast_options: &CastOptions,
+) -> Result<ArrayRef, ArrowError> {
+    let array = array.as_primitive::<IntervalDayTimeType>();
+    let mul = 10_i32.pow(6);
+
+    if cast_options.safe {
+        Ok(Arc::new(array.unary_opt::<_, IntervalMonthDayNanoType>(
+            |v| {
+                let (days, ms) = IntervalDayTimeType::to_parts(v);
+                Some(IntervalMonthDayNanoType::make_value(
+                    0,
+                    days,
+                    (ms * mul).into(),
+                ))
+            },
+        )))
+    } else {
+        Ok(Arc::new(
+            array.try_unary::<_, IntervalMonthDayNanoType, ArrowError>(|v| {
+                let (days, ms) = IntervalDayTimeType::to_parts(v);
+                let nanos = ms.mul_checked(mul).map_err(|_| {
+                    ArrowError::CastError(format!(
+                        "Cannot cast to IntervalDayTimeType. Overflowing on {:?}",
+                        v
+                    ))
+                })?;
+                Ok(IntervalMonthDayNanoType::make_value(0, days, nanos.into()))
+            })?,
+        ))
+    }
+}
+
+/// Cast the array from interval month day nano to year month
+fn cast_interval_month_day_nano_to_interval_year_month(
+    array: &dyn Array,
+    cast_options: &CastOptions,
+) -> Result<ArrayRef, ArrowError> {
+    let array = array.as_primitive::<IntervalMonthDayNanoType>();
+
+    if cast_options.safe {
+        Ok(Arc::new(array.unary_opt::<_, IntervalYearMonthType>(|v| {
+            let (months, _, _) = IntervalMonthDayNanoType::to_parts(v);
+            Some(IntervalYearMonthType::make_value(0, months))
+        })))
+    } else {
+        Ok(Arc::new(
+            array.try_unary::<_, IntervalYearMonthType, ArrowError>(|v| {
+                let (months, _, _) = IntervalMonthDayNanoType::to_parts(v);
+                Ok(IntervalYearMonthType::make_value(0, months))
+            })?,
+        ))
+    }
+}
+
+/// Cast the array from interval month day nano to day time
+fn cast_interval_month_day_nano_to_interval_day_time(
+    array: &dyn Array,
+    cast_options: &CastOptions,
+) -> Result<ArrayRef, ArrowError> {
+    let array = array.as_primitive::<IntervalMonthDayNanoType>();
+    let mul = 10_i64.pow(6);
+
+    if cast_options.safe {
+        Ok(Arc::new(array.unary_opt::<_, IntervalDayTimeType>(|v| {
+            let (_, days, nanos) = IntervalMonthDayNanoType::to_parts(v);

Review Comment:
   This appears to discard the months component?



##########
arrow-cast/src/cast.rs:
##########
@@ -409,6 +413,125 @@ where
     }
 }
 
+/// Cast the array from interval year month to month day nano
+fn cast_interval_year_month_to_interval_month_day_nano(
+    array: &dyn Array,
+    cast_options: &CastOptions,
+) -> Result<ArrayRef, ArrowError> {
+    let array = array.as_primitive::<IntervalYearMonthType>();
+
+    if cast_options.safe {
+        Ok(Arc::new(array.unary_opt::<_, IntervalMonthDayNanoType>(
+            |v| {
+                let months = IntervalYearMonthType::to_months(v);
+                Some(IntervalMonthDayNanoType::make_value(months, 0, 0))
+            },
+        )))
+    } else {
+        Ok(Arc::new(
+            array.try_unary::<_, IntervalMonthDayNanoType, ArrowError>(|v| {
+                let months = IntervalYearMonthType::to_months(v);
+                Ok(IntervalMonthDayNanoType::make_value(months, 0, 0))
+            })?,
+        ))
+    }
+}
+
+/// Cast the array from interval day time to month day nano
+fn cast_interval_day_time_to_interval_month_day_nano(
+    array: &dyn Array,
+    cast_options: &CastOptions,
+) -> Result<ArrayRef, ArrowError> {
+    let array = array.as_primitive::<IntervalDayTimeType>();
+    let mul = 10_i32.pow(6);
+
+    if cast_options.safe {
+        Ok(Arc::new(array.unary_opt::<_, IntervalMonthDayNanoType>(
+            |v| {
+                let (days, ms) = IntervalDayTimeType::to_parts(v);
+                Some(IntervalMonthDayNanoType::make_value(
+                    0,
+                    days,
+                    (ms * mul).into(),
+                ))
+            },
+        )))
+    } else {
+        Ok(Arc::new(
+            array.try_unary::<_, IntervalMonthDayNanoType, ArrowError>(|v| {
+                let (days, ms) = IntervalDayTimeType::to_parts(v);
+                let nanos = ms.mul_checked(mul).map_err(|_| {
+                    ArrowError::CastError(format!(
+                        "Cannot cast to IntervalDayTimeType. Overflowing on {:?}",
+                        v
+                    ))
+                })?;
+                Ok(IntervalMonthDayNanoType::make_value(0, days, nanos.into()))
+            })?,
+        ))
+    }
+}
+
+/// Cast the array from interval month day nano to year month
+fn cast_interval_month_day_nano_to_interval_year_month(
+    array: &dyn Array,
+    cast_options: &CastOptions,
+) -> Result<ArrayRef, ArrowError> {
+    let array = array.as_primitive::<IntervalMonthDayNanoType>();

Review Comment:
   I think people would find it surprising that this discards any days or nanoseconds. I suspect we either need to error if they are anything other than 0, or make an approximation about the number of hours in a day and the number of days in a month...



##########
arrow-cast/src/cast.rs:
##########
@@ -409,6 +413,125 @@ where
     }
 }
 
+/// Cast the array from interval year month to month day nano
+fn cast_interval_year_month_to_interval_month_day_nano(
+    array: &dyn Array,
+    cast_options: &CastOptions,
+) -> Result<ArrayRef, ArrowError> {
+    let array = array.as_primitive::<IntervalYearMonthType>();
+
+    if cast_options.safe {
+        Ok(Arc::new(array.unary_opt::<_, IntervalMonthDayNanoType>(
+            |v| {
+                let months = IntervalYearMonthType::to_months(v);
+                Some(IntervalMonthDayNanoType::make_value(months, 0, 0))
+            },
+        )))
+    } else {
+        Ok(Arc::new(
+            array.try_unary::<_, IntervalMonthDayNanoType, ArrowError>(|v| {
+                let months = IntervalYearMonthType::to_months(v);
+                Ok(IntervalMonthDayNanoType::make_value(months, 0, 0))
+            })?,
+        ))
+    }
+}
+
+/// Cast the array from interval day time to month day nano
+fn cast_interval_day_time_to_interval_month_day_nano(
+    array: &dyn Array,
+    cast_options: &CastOptions,
+) -> Result<ArrayRef, ArrowError> {
+    let array = array.as_primitive::<IntervalDayTimeType>();
+    let mul = 10_i32.pow(6);
+
+    if cast_options.safe {
+        Ok(Arc::new(array.unary_opt::<_, IntervalMonthDayNanoType>(
+            |v| {
+                let (days, ms) = IntervalDayTimeType::to_parts(v);
+                Some(IntervalMonthDayNanoType::make_value(
+                    0,
+                    days,
+                    (ms * mul).into(),
+                ))
+            },
+        )))
+    } else {
+        Ok(Arc::new(
+            array.try_unary::<_, IntervalMonthDayNanoType, ArrowError>(|v| {
+                let (days, ms) = IntervalDayTimeType::to_parts(v);
+                let nanos = ms.mul_checked(mul).map_err(|_| {
+                    ArrowError::CastError(format!(
+                        "Cannot cast to IntervalDayTimeType. Overflowing on {:?}",
+                        v
+                    ))
+                })?;
+                Ok(IntervalMonthDayNanoType::make_value(0, days, nanos.into()))
+            })?,
+        ))
+    }
+}
+
+/// Cast the array from interval month day nano to year month
+fn cast_interval_month_day_nano_to_interval_year_month(
+    array: &dyn Array,
+    cast_options: &CastOptions,
+) -> Result<ArrayRef, ArrowError> {
+    let array = array.as_primitive::<IntervalMonthDayNanoType>();
+
+    if cast_options.safe {
+        Ok(Arc::new(array.unary_opt::<_, IntervalYearMonthType>(|v| {
+            let (months, _, _) = IntervalMonthDayNanoType::to_parts(v);
+            Some(IntervalYearMonthType::make_value(0, months))
+        })))
+    } else {
+        Ok(Arc::new(
+            array.try_unary::<_, IntervalYearMonthType, ArrowError>(|v| {
+                let (months, _, _) = IntervalMonthDayNanoType::to_parts(v);
+                Ok(IntervalYearMonthType::make_value(0, months))
+            })?,
+        ))
+    }
+}
+
+/// Cast the array from interval month day nano to day time
+fn cast_interval_month_day_nano_to_interval_day_time(
+    array: &dyn Array,
+    cast_options: &CastOptions,
+) -> Result<ArrayRef, ArrowError> {
+    let array = array.as_primitive::<IntervalMonthDayNanoType>();
+    let mul = 10_i64.pow(6);
+
+    if cast_options.safe {
+        Ok(Arc::new(array.unary_opt::<_, IntervalDayTimeType>(|v| {
+            let (_, days, nanos) = IntervalMonthDayNanoType::to_parts(v);
+            Some(IntervalDayTimeType::make_value(
+                days,
+                (nanos / mul).try_into().unwrap(),

Review Comment:
   ```suggestion
                   (nanos / mul).try_into().ok()?,
   ```



-- 
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: github-unsubscribe@arrow.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [arrow-rs] tustvold commented on a diff in pull request #4182: feat: cast between `Intervals`

Posted by "tustvold (via GitHub)" <gi...@apache.org>.
tustvold commented on code in PR #4182:
URL: https://github.com/apache/arrow-rs/pull/4182#discussion_r1188826227


##########
arrow-cast/src/cast.rs:
##########
@@ -460,6 +462,56 @@ where
     }
 }
 
+/// Cast the array from interval year month to month day nano
+fn cast_interval_year_month_to_interval_month_day_nano(
+    array: &dyn Array,
+    _cast_options: &CastOptions,
+) -> Result<ArrayRef, ArrowError> {
+    let array = array
+        .as_any()
+        .downcast_ref::<PrimitiveArray<IntervalYearMonthType>>()
+        .ok_or_else(|| {
+            ArrowError::ComputeError(
+                "Internal Error: Cannot cast interval to IntervalArray of expected type"
+                    .to_string(),
+            )
+        })?;
+
+    let iter = array
+        .iter()
+        .map(|v| v.and_then(|v| Some(IntervalMonthDayNanoType::make_value(v, 0, 0))));
+    Ok(Arc::new(unsafe {
+        PrimitiveArray::<IntervalMonthDayNanoType>::from_trusted_len_iter(iter)
+    }))
+}
+
+/// Cast the array from interval day time to month day nano
+fn cast_interval_day_time_to_interval_month_day_nano(
+    array: &dyn Array,
+    _cast_options: &CastOptions,
+) -> Result<ArrayRef, ArrowError> {
+    let array = array
+        .as_any()
+        .downcast_ref::<PrimitiveArray<IntervalDayTimeType>>()
+        .ok_or_else(|| {
+            ArrowError::ComputeError(
+                "Internal Error: Cannot cast interval to IntervalArray of expected type"
+                    .to_string(),
+            )
+        })?;

Review Comment:
   ```suggestion
           let array = array.as_primitive::<IntervalDayTimeType>();
   ```
   



##########
arrow-cast/src/cast.rs:
##########
@@ -460,6 +462,56 @@ where
     }
 }
 
+/// Cast the array from interval year month to month day nano
+fn cast_interval_year_month_to_interval_month_day_nano(
+    array: &dyn Array,
+    _cast_options: &CastOptions,
+) -> Result<ArrayRef, ArrowError> {
+    let array = array
+        .as_any()
+        .downcast_ref::<PrimitiveArray<IntervalYearMonthType>>()
+        .ok_or_else(|| {
+            ArrowError::ComputeError(
+                "Internal Error: Cannot cast interval to IntervalArray of expected type"
+                    .to_string(),
+            )
+        })?;

Review Comment:
   ```suggestion
       let array = array.as_primitive::<IntervalYearMonthType>();
   ```



##########
arrow-cast/src/cast.rs:
##########
@@ -8761,4 +8819,98 @@ mod tests {
         );
         assert!(casted_array.is_err());
     }
+
+    /// helper function to test casting from interval year month to interval month day nano
+    fn cast_from_interval_year_month_to_interval_month_day_nano(
+        array: Vec<i32>,
+        cast_options: &CastOptions,
+    ) -> Result<PrimitiveArray<IntervalMonthDayNanoType>, ArrowError> {
+        let array = PrimitiveArray::<IntervalYearMonthType>::from(array);
+        let array = Arc::new(array) as ArrayRef;
+        let casted_array = cast_with_options(
+            &array,
+            &DataType::Interval(IntervalUnit::MonthDayNano),
+            cast_options,
+        )?;
+        casted_array
+            .as_any()
+            .downcast_ref::<IntervalMonthDayNanoArray>()
+            .ok_or_else(|| {
+                ArrowError::ComputeError(
+                    "Failed to downcast to IntervalMonthDayNanoArray".to_string(),
+                )
+            })
+            .cloned()

Review Comment:
   ```suggestion
           Ok(casted_array.as_primitive::<IntervalMonthDayNanoType>().clone())
   ```



##########
arrow-cast/src/cast.rs:
##########
@@ -460,6 +462,56 @@ where
     }
 }
 
+/// Cast the array from interval year month to month day nano
+fn cast_interval_year_month_to_interval_month_day_nano(
+    array: &dyn Array,
+    _cast_options: &CastOptions,
+) -> Result<ArrayRef, ArrowError> {
+    let array = array
+        .as_any()
+        .downcast_ref::<PrimitiveArray<IntervalYearMonthType>>()
+        .ok_or_else(|| {
+            ArrowError::ComputeError(
+                "Internal Error: Cannot cast interval to IntervalArray of expected type"
+                    .to_string(),
+            )
+        })?;
+
+    let iter = array
+        .iter()
+        .map(|v| v.and_then(|v| Some(IntervalMonthDayNanoType::make_value(v, 0, 0))));
+    Ok(Arc::new(unsafe {
+        PrimitiveArray::<IntervalMonthDayNanoType>::from_trusted_len_iter(iter)
+    }))
+}
+
+/// Cast the array from interval day time to month day nano
+fn cast_interval_day_time_to_interval_month_day_nano(
+    array: &dyn Array,
+    _cast_options: &CastOptions,
+) -> Result<ArrayRef, ArrowError> {
+    let array = array
+        .as_any()
+        .downcast_ref::<PrimitiveArray<IntervalDayTimeType>>()
+        .ok_or_else(|| {
+            ArrowError::ComputeError(
+                "Internal Error: Cannot cast interval to IntervalArray of expected type"
+                    .to_string(),
+            )
+        })?;
+
+    let iter = array.iter().map(|v| {

Review Comment:
   I think this needs to perform checked conversion, and can make use of unary_opt and try_unary to achieve this based on the cast options



##########
arrow-cast/src/cast.rs:
##########
@@ -8761,4 +8819,98 @@ mod tests {
         );
         assert!(casted_array.is_err());
     }
+
+    /// helper function to test casting from interval year month to interval month day nano
+    fn cast_from_interval_year_month_to_interval_month_day_nano(
+        array: Vec<i32>,
+        cast_options: &CastOptions,
+    ) -> Result<PrimitiveArray<IntervalMonthDayNanoType>, ArrowError> {
+        let array = PrimitiveArray::<IntervalYearMonthType>::from(array);
+        let array = Arc::new(array) as ArrayRef;
+        let casted_array = cast_with_options(
+            &array,
+            &DataType::Interval(IntervalUnit::MonthDayNano),
+            cast_options,
+        )?;
+        casted_array
+            .as_any()
+            .downcast_ref::<IntervalMonthDayNanoArray>()
+            .ok_or_else(|| {
+                ArrowError::ComputeError(
+                    "Failed to downcast to IntervalMonthDayNanoArray".to_string(),
+                )
+            })
+            .cloned()
+    }
+
+    #[test]
+    fn test_cast_from_interval_year_month_to_interval_month_day_nano() {
+        // from interval year month to interval month day nano
+        let array = vec![1234567];
+        let casted_array = cast_from_interval_year_month_to_interval_month_day_nano(
+            array,
+            &DEFAULT_CAST_OPTIONS,
+        )
+        .unwrap();
+        assert_eq!(
+            casted_array.data_type(),
+            &DataType::Interval(IntervalUnit::MonthDayNano)
+        );
+        assert_eq!(casted_array.value(0), 97812474910747780469848774134464512);
+
+        let array = vec![i32::MAX];
+        let casted_array = cast_from_interval_year_month_to_interval_month_day_nano(
+            array.clone(),
+            &DEFAULT_CAST_OPTIONS,
+        )
+        .unwrap();
+        assert!(casted_array.is_valid(0));
+    }
+
+    /// helper function to test casting from interval day time to interval month day nano
+    fn cast_from_interval_day_time_to_interval_month_day_nano(
+        array: Vec<i64>,
+        cast_options: &CastOptions,
+    ) -> Result<PrimitiveArray<IntervalMonthDayNanoType>, ArrowError> {
+        let array = PrimitiveArray::<IntervalDayTimeType>::from(array);
+        let array = Arc::new(array) as ArrayRef;
+        let casted_array = cast_with_options(
+            &array,
+            &DataType::Interval(IntervalUnit::MonthDayNano),
+            cast_options,
+        )?;
+        casted_array
+            .as_any()
+            .downcast_ref::<IntervalMonthDayNanoArray>()
+            .ok_or_else(|| {
+                ArrowError::ComputeError(
+                    "Failed to downcast to IntervalMonthDayNanoArray".to_string(),
+                )
+            })

Review Comment:
   ```suggestion
           Ok(casted_array.as_primitive::<IntervalMonthDataNanoType>().clone())
   ```



-- 
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: github-unsubscribe@arrow.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [arrow-rs] tustvold merged pull request #4182: feat: cast between `Intervals`

Posted by "tustvold (via GitHub)" <gi...@apache.org>.
tustvold merged PR #4182:
URL: https://github.com/apache/arrow-rs/pull/4182


-- 
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: github-unsubscribe@arrow.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [arrow-rs] izveigor commented on a diff in pull request #4182: feat: cast between `Intervals`

Posted by "izveigor (via GitHub)" <gi...@apache.org>.
izveigor commented on code in PR #4182:
URL: https://github.com/apache/arrow-rs/pull/4182#discussion_r1210787386


##########
arrow-cast/src/cast.rs:
##########
@@ -409,6 +413,125 @@ where
     }
 }
 
+/// Cast the array from interval year month to month day nano
+fn cast_interval_year_month_to_interval_month_day_nano(
+    array: &dyn Array,
+    cast_options: &CastOptions,
+) -> Result<ArrayRef, ArrowError> {
+    let array = array.as_primitive::<IntervalYearMonthType>();
+
+    if cast_options.safe {
+        Ok(Arc::new(array.unary_opt::<_, IntervalMonthDayNanoType>(
+            |v| {
+                let months = IntervalYearMonthType::to_months(v);
+                Some(IntervalMonthDayNanoType::make_value(months, 0, 0))
+            },
+        )))
+    } else {
+        Ok(Arc::new(
+            array.try_unary::<_, IntervalMonthDayNanoType, ArrowError>(|v| {

Review Comment:
   Is an unsafe way needed in this case, if the overflow never happens?



-- 
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: github-unsubscribe@arrow.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [arrow-rs] alamb commented on pull request #4182: feat: cast between `Intervals`

Posted by "alamb (via GitHub)" <gi...@apache.org>.
alamb commented on PR #4182:
URL: https://github.com/apache/arrow-rs/pull/4182#issuecomment-1572683822

   I wonder if this PR will make the next release (so we can use it in datafusion) 🤔 


-- 
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: github-unsubscribe@arrow.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [arrow-rs] tustvold commented on a diff in pull request #4182: feat: cast between `Intervals`

Posted by "tustvold (via GitHub)" <gi...@apache.org>.
tustvold commented on code in PR #4182:
URL: https://github.com/apache/arrow-rs/pull/4182#discussion_r1213012070


##########
arrow-cast/src/cast.rs:
##########
@@ -409,6 +413,125 @@ where
     }
 }
 
+/// Cast the array from interval year month to month day nano
+fn cast_interval_year_month_to_interval_month_day_nano(
+    array: &dyn Array,
+    cast_options: &CastOptions,
+) -> Result<ArrayRef, ArrowError> {
+    let array = array.as_primitive::<IntervalYearMonthType>();
+
+    if cast_options.safe {
+        Ok(Arc::new(array.unary_opt::<_, IntervalMonthDayNanoType>(
+            |v| {
+                let months = IntervalYearMonthType::to_months(v);
+                Some(IntervalMonthDayNanoType::make_value(months, 0, 0))
+            },
+        )))
+    } else {
+        Ok(Arc::new(
+            array.try_unary::<_, IntervalMonthDayNanoType, ArrowError>(|v| {

Review Comment:
   If the method is infallible you can just use `unary` without needing to use either `unary_opt` or `try_unary`



-- 
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: github-unsubscribe@arrow.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [arrow-rs] tustvold commented on a diff in pull request #4182: feat: cast between `Intervals`

Posted by "tustvold (via GitHub)" <gi...@apache.org>.
tustvold commented on code in PR #4182:
URL: https://github.com/apache/arrow-rs/pull/4182#discussion_r1213012070


##########
arrow-cast/src/cast.rs:
##########
@@ -409,6 +413,125 @@ where
     }
 }
 
+/// Cast the array from interval year month to month day nano
+fn cast_interval_year_month_to_interval_month_day_nano(
+    array: &dyn Array,
+    cast_options: &CastOptions,
+) -> Result<ArrayRef, ArrowError> {
+    let array = array.as_primitive::<IntervalYearMonthType>();
+
+    if cast_options.safe {
+        Ok(Arc::new(array.unary_opt::<_, IntervalMonthDayNanoType>(
+            |v| {
+                let months = IntervalYearMonthType::to_months(v);
+                Some(IntervalMonthDayNanoType::make_value(months, 0, 0))
+            },
+        )))
+    } else {
+        Ok(Arc::new(
+            array.try_unary::<_, IntervalMonthDayNanoType, ArrowError>(|v| {

Review Comment:
   If the method is infallible you can just use `unary`



-- 
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: github-unsubscribe@arrow.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [arrow-rs] izveigor commented on pull request #4182: feat: cast between `Intervals`

Posted by "izveigor (via GitHub)" <gi...@apache.org>.
izveigor commented on PR #4182:
URL: https://github.com/apache/arrow-rs/pull/4182#issuecomment-1569048340

   @tustvold Sorry for the long delay. I left a few questions on this PR. Can you pay attention to them if you have time.


-- 
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: github-unsubscribe@arrow.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [arrow-rs] alamb commented on pull request #4182: feat: cast between `Intervals`

Posted by "alamb (via GitHub)" <gi...@apache.org>.
alamb commented on PR #4182:
URL: https://github.com/apache/arrow-rs/pull/4182#issuecomment-1540517012

   Thank you for taking this on @izveigor 


-- 
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: github-unsubscribe@arrow.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [arrow-rs] izveigor commented on a diff in pull request #4182: feat: cast between `Intervals`

Posted by "izveigor (via GitHub)" <gi...@apache.org>.
izveigor commented on code in PR #4182:
URL: https://github.com/apache/arrow-rs/pull/4182#discussion_r1210788541


##########
arrow-cast/src/cast.rs:
##########
@@ -409,6 +413,125 @@ where
     }
 }
 
+/// Cast the array from interval year month to month day nano
+fn cast_interval_year_month_to_interval_month_day_nano(
+    array: &dyn Array,
+    cast_options: &CastOptions,
+) -> Result<ArrayRef, ArrowError> {
+    let array = array.as_primitive::<IntervalYearMonthType>();
+
+    if cast_options.safe {
+        Ok(Arc::new(array.unary_opt::<_, IntervalMonthDayNanoType>(
+            |v| {
+                let months = IntervalYearMonthType::to_months(v);
+                Some(IntervalMonthDayNanoType::make_value(months, 0, 0))
+            },
+        )))
+    } else {
+        Ok(Arc::new(
+            array.try_unary::<_, IntervalMonthDayNanoType, ArrowError>(|v| {
+                let months = IntervalYearMonthType::to_months(v);
+                Ok(IntervalMonthDayNanoType::make_value(months, 0, 0))
+            })?,
+        ))
+    }
+}
+
+/// Cast the array from interval day time to month day nano
+fn cast_interval_day_time_to_interval_month_day_nano(
+    array: &dyn Array,
+    cast_options: &CastOptions,
+) -> Result<ArrayRef, ArrowError> {
+    let array = array.as_primitive::<IntervalDayTimeType>();
+    let mul = 10_i32.pow(6);
+
+    if cast_options.safe {
+        Ok(Arc::new(array.unary_opt::<_, IntervalMonthDayNanoType>(
+            |v| {
+                let (days, ms) = IntervalDayTimeType::to_parts(v);
+                Some(IntervalMonthDayNanoType::make_value(
+                    0,

Review Comment:
   I think the method: `months = days * 30` is not entirely accurate?



-- 
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: github-unsubscribe@arrow.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [arrow-rs] tustvold commented on pull request #4182: feat: cast between `Intervals`

Posted by "tustvold (via GitHub)" <gi...@apache.org>.
tustvold commented on PR #4182:
URL: https://github.com/apache/arrow-rs/pull/4182#issuecomment-1573741442

   Thank you


-- 
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: github-unsubscribe@arrow.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org