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: [email protected]

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

Reply via email to