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

viirya 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 f8254e7f0 Replace complicated temporal macro with generic functions 
(#2850)
f8254e7f0 is described below

commit f8254e7f01ad8ccb4b86c33ad429a04e9ffc6737
Author: Liang-Chi Hsieh <[email protected]>
AuthorDate: Wed Oct 12 16:30:13 2022 -0700

    Replace complicated temporal macro with generic functions (#2850)
    
    * Remove complicated macro
    
    * Fix clippy
    
    * Add doc.
---
 arrow/src/compute/kernels/cast.rs     | 117 +++++++--
 arrow/src/compute/kernels/temporal.rs | 472 +++++++++++++---------------------
 2 files changed, 280 insertions(+), 309 deletions(-)

diff --git a/arrow/src/compute/kernels/cast.rs 
b/arrow/src/compute/kernels/cast.rs
index 912ea2883..b573c65d0 100644
--- a/arrow/src/compute/kernels/cast.rs
+++ b/arrow/src/compute/kernels/cast.rs
@@ -37,14 +37,13 @@
 
 use chrono::format::strftime::StrftimeItems;
 use chrono::format::{parse, Parsed};
-use chrono::Timelike;
+use chrono::{NaiveDateTime, Timelike};
 use std::ops::{Div, Mul};
 use std::str;
 use std::sync::Arc;
 
 use crate::buffer::MutableBuffer;
 use crate::compute::kernels::cast_utils::string_to_timestamp_nanos;
-use crate::compute::kernels::temporal::extract_component_from_array;
 use crate::compute::kernels::temporal::return_compute_error_with;
 use crate::compute::{divide_scalar, multiply_scalar};
 use crate::compute::{try_unary, using_chrono_tz_and_utc_naive_date_time};
@@ -1638,6 +1637,98 @@ where
     unsafe { PrimitiveArray::<R>::from_trusted_len_iter(iter) }
 }
 
+fn as_time_with_string_op<
+    A: ArrayAccessor<Item = T::Native>,
+    OffsetSize,
+    T: ArrowTemporalType,
+    F,
+>(
+    iter: ArrayIter<A>,
+    mut builder: GenericStringBuilder<OffsetSize>,
+    op: F,
+) -> ArrayRef
+where
+    OffsetSize: OffsetSizeTrait,
+    F: Fn(NaiveDateTime) -> String,
+    i64: From<T::Native>,
+{
+    iter.into_iter().for_each(|value| {
+        if let Some(value) = value {
+            match as_datetime::<T>(<i64 as From<_>>::from(value)) {
+                Some(dt) => builder.append_value(op(dt)),
+                None => builder.append_null(),
+            }
+        } else {
+            builder.append_null();
+        }
+    });
+
+    Arc::new(builder.finish())
+}
+
+fn extract_component_from_datatime_array<
+    A: ArrayAccessor<Item = T::Native>,
+    OffsetSize,
+    T: ArrowTemporalType,
+    F,
+>(
+    iter: ArrayIter<A>,
+    mut builder: GenericStringBuilder<OffsetSize>,
+    tz: &str,
+    mut parsed: Parsed,
+    op: F,
+) -> Result<ArrayRef>
+where
+    OffsetSize: OffsetSizeTrait,
+    F: Fn(NaiveDateTime) -> String,
+    i64: From<T::Native>,
+{
+    if (tz.starts_with('+') || tz.starts_with('-')) && !tz.contains(':') {
+        return_compute_error_with!(
+            "Invalid timezone",
+            "Expected format [+-]XX:XX".to_string()
+        )
+    } else {
+        let tz_parse_result = parse(&mut parsed, tz, StrftimeItems::new("%z"));
+        let fixed_offset_from_parsed = match tz_parse_result {
+            Ok(_) => match parsed.to_fixed_offset() {
+                Ok(fo) => Some(fo),
+                err => return_compute_error_with!("Invalid timezone", err),
+            },
+            _ => None,
+        };
+
+        for value in iter {
+            if let Some(value) = value {
+                match as_datetime::<T>(<i64 as From<_>>::from(value)) {
+                    Some(utc) => {
+                        let fixed_offset = match fixed_offset_from_parsed {
+                            Some(fo) => fo,
+                            None => {
+                                match 
using_chrono_tz_and_utc_naive_date_time(tz, utc) {
+                                    Some(fo) => fo,
+                                    err => return_compute_error_with!(
+                                        "Unable to parse timezone",
+                                        err
+                                    ),
+                                }
+                            }
+                        };
+                        builder.append_value(op(utc + fixed_offset));
+                    }
+                    err => return_compute_error_with!(
+                        "Unable to read value as datetime",
+                        err
+                    ),
+                }
+            } else {
+                builder.append_null();
+            }
+        }
+    }
+    Ok(Arc::new(builder.finish()))
+}
+
 /// Cast timestamp types to Utf8/LargeUtf8
 fn cast_timestamp_to_string<T, OffsetSize>(
     array: &ArrayRef,
@@ -1650,38 +1741,30 @@ where
 {
     let array = array.as_any().downcast_ref::<PrimitiveArray<T>>().unwrap();
 
-    let mut builder = GenericStringBuilder::<OffsetSize>::new();
+    let builder = GenericStringBuilder::<OffsetSize>::new();
 
     if let Some(tz) = tz {
-        let mut scratch = Parsed::new();
+        let scratch = Parsed::new();
         // The macro calls `as_datetime` on timestamp values of the array.
         // After applying timezone offset on the datatime, calling `to_string` 
to get
         // the strings.
         let iter = ArrayIter::new(array);
-        extract_component_from_array!(
+        extract_component_from_datatime_array::<_, OffsetSize, T, _>(
             iter,
             builder,
-            to_string,
-            |value, tz| as_datetime::<T>(<i64 as From<_>>::from(value))
-                .map(|datetime| datetime + tz),
             tz,
             scratch,
-            |value| as_datetime::<T>(<i64 as From<_>>::from(value)),
-            |h| h
+            |t| t.to_string(),
         )
     } else {
         // No timezone available. Calling `to_string` on the datatime value 
simply.
         let iter = ArrayIter::new(array);
-        extract_component_from_array!(
+        Ok(as_time_with_string_op::<_, OffsetSize, T, _>(
             iter,
             builder,
-            to_string,
-            |value| as_datetime::<T>(<i64 as From<_>>::from(value)),
-            |h| h
-        )
+            |t| t.to_string(),
+        ))
     }
-
-    Ok(Arc::new(builder.finish()) as ArrayRef)
 }
 
 /// Cast date32 types to Utf8/LargeUtf8
diff --git a/arrow/src/compute/kernels/temporal.rs 
b/arrow/src/compute/kernels/temporal.rs
index e61fec999..220b7dadc 100644
--- a/arrow/src/compute/kernels/temporal.rs
+++ b/arrow/src/compute/kernels/temporal.rs
@@ -17,7 +17,7 @@
 
 //! Defines temporal kernels for time and date related functions.
 
-use chrono::{Datelike, Timelike};
+use chrono::{Datelike, NaiveDateTime, NaiveTime, Timelike};
 
 use crate::array::*;
 use crate::datatypes::*;
@@ -28,83 +28,124 @@ use chrono::format::strftime::StrftimeItems;
 use chrono::format::{parse, Parsed};
 use chrono::FixedOffset;
 
-macro_rules! extract_component_from_array {
-    ($iter:ident, $builder:ident, $extract_fn:ident, $using:expr, 
$convert:expr) => {
-        $iter.into_iter().for_each(|value| {
-            if let Some(value) = value {
-                match $using(value) {
-                    Some(dt) => 
$builder.append_value($convert(dt.$extract_fn())),
-                    None => $builder.append_null(),
-                }
-            } else {
-                $builder.append_null();
+/// This function takes an `ArrayIter` of input array and an extractor `op` 
which takes
+/// an input `NaiveTime` and returns time component (e.g. hour) as `i32` value.
+/// The extracted values are built by the given `builder` to be an 
`Int32Array`.
+fn as_time_with_op<A: ArrayAccessor<Item = T::Native>, T: ArrowTemporalType, 
F>(
+    iter: ArrayIter<A>,
+    mut builder: PrimitiveBuilder<Int32Type>,
+    op: F,
+) -> Int32Array
+where
+    F: Fn(NaiveTime) -> i32,
+    i64: From<T::Native>,
+{
+    iter.into_iter().for_each(|value| {
+        if let Some(value) = value {
+            match as_time::<T>(i64::from(value)) {
+                Some(dt) => builder.append_value(op(dt)),
+                None => builder.append_null(),
             }
-        })
-    };
-    ($iter:ident, $builder:ident, $extract_fn1:ident, $extract_fn2:ident, 
$using:expr, $convert:expr) => {
-        $iter.into_iter().for_each(|value| {
-            if let Some(value) = value {
-                match $using(value) {
-                    Some(dt) => {
-                        
$builder.append_value($convert(dt.$extract_fn1().$extract_fn2()));
-                    }
-                    None => $builder.append_null(),
-                }
-            } else {
-                $builder.append_null();
+        } else {
+            builder.append_null();
+        }
+    });
+
+    builder.finish()
+}
+
+/// This function takes an `ArrayIter` of input array and an extractor `op` 
which takes
+/// an input `NaiveDateTime` and returns data time component (e.g. hour) as 
`i32` value.
+/// The extracted values are built by the given `builder` to be an 
`Int32Array`.
+fn as_datetime_with_op<A: ArrayAccessor<Item = T::Native>, T: 
ArrowTemporalType, F>(
+    iter: ArrayIter<A>,
+    mut builder: PrimitiveBuilder<Int32Type>,
+    op: F,
+) -> Int32Array
+where
+    F: Fn(NaiveDateTime) -> i32,
+    i64: From<T::Native>,
+{
+    iter.into_iter().for_each(|value| {
+        if let Some(value) = value {
+            match as_datetime::<T>(i64::from(value)) {
+                Some(dt) => builder.append_value(op(dt)),
+                None => builder.append_null(),
             }
-        })
-    };
-    ($iter:ident, $builder:ident, $extract_fn:ident, $using:expr, $tz:ident, 
$parsed:ident, $value_as_datetime:expr, $convert:expr) => {
-        if ($tz.starts_with('+') || $tz.starts_with('-')) && 
!$tz.contains(':') {
-            return_compute_error_with!(
-                "Invalid timezone",
-                "Expected format [+-]XX:XX".to_string()
-            )
         } else {
-            let tz_parse_result = parse(&mut $parsed, &$tz, 
StrftimeItems::new("%z"));
-            let fixed_offset_from_parsed = match tz_parse_result {
-                Ok(_) => match $parsed.to_fixed_offset() {
-                    Ok(fo) => Some(fo),
-                    err => return_compute_error_with!("Invalid timezone", err),
-                },
-                _ => None,
-            };
-
-            for value in $iter.into_iter() {
-                if let Some(value) = value {
-                    match $value_as_datetime(value) {
-                        Some(utc) => {
-                            let fixed_offset = match fixed_offset_from_parsed {
-                                Some(fo) => fo,
-                                None => match 
using_chrono_tz_and_utc_naive_date_time(
-                                    &$tz, utc,
-                                ) {
+            builder.append_null();
+        }
+    });
+
+    builder.finish()
+}
+
+/// This function extracts date time component (e.g. hour) from an array of 
datatime.
+/// `iter` is the `ArrayIter` of input datatime array. `builder` is used to 
build the
+/// returned `Int32Array` containing the extracted components. `tz` is 
timezone string
+/// which will be added to datetime values in the input array. `parsed` is a 
`Parsed`
+/// object used to parse timezone string. `op` is the extractor closure which 
takes
+/// data time object of `NaiveDateTime` type and returns `i32` value of 
extracted
+/// component.
+fn extract_component_from_datatime_array<
+    A: ArrayAccessor<Item = T::Native>,
+    T: ArrowTemporalType,
+    F,
+>(
+    iter: ArrayIter<A>,
+    mut builder: PrimitiveBuilder<Int32Type>,
+    tz: &str,
+    mut parsed: Parsed,
+    op: F,
+) -> Result<Int32Array>
+where
+    F: Fn(NaiveDateTime) -> i32,
+    i64: From<T::Native>,
+{
+    if (tz.starts_with('+') || tz.starts_with('-')) && !tz.contains(':') {
+        return_compute_error_with!(
+            "Invalid timezone",
+            "Expected format [+-]XX:XX".to_string()
+        )
+    } else {
+        let tz_parse_result = parse(&mut parsed, tz, StrftimeItems::new("%z"));
+        let fixed_offset_from_parsed = match tz_parse_result {
+            Ok(_) => match parsed.to_fixed_offset() {
+                Ok(fo) => Some(fo),
+                err => return_compute_error_with!("Invalid timezone", err),
+            },
+            _ => None,
+        };
+
+        for value in iter {
+            if let Some(value) = value {
+                match as_datetime::<T>(i64::from(value)) {
+                    Some(utc) => {
+                        let fixed_offset = match fixed_offset_from_parsed {
+                            Some(fo) => fo,
+                            None => {
+                                match 
using_chrono_tz_and_utc_naive_date_time(tz, utc) {
                                     Some(fo) => fo,
                                     err => return_compute_error_with!(
                                         "Unable to parse timezone",
                                         err
                                     ),
-                                },
-                            };
-                            match $using(value, fixed_offset) {
-                                Some(dt) => {
-                                    
$builder.append_value($convert(dt.$extract_fn()));
                                 }
-                                None => $builder.append_null(),
                             }
-                        }
-                        err => return_compute_error_with!(
-                            "Unable to read value as datetime",
-                            err
-                        ),
+                        };
+                        builder.append_value(op(utc + fixed_offset));
                     }
-                } else {
-                    $builder.append_null();
+                    err => return_compute_error_with!(
+                        "Unable to read value as datetime",
+                        err
+                    ),
                 }
+            } else {
+                builder.append_null();
             }
         }
-    };
+    }
+    Ok(builder.finish())
 }
 
 macro_rules! return_compute_error_with {
@@ -113,7 +154,6 @@ macro_rules! return_compute_error_with {
     };
 }
 
-pub(crate) use extract_component_from_array;
 pub(crate) use return_compute_error_with;
 
 // Internal trait, which is used for mapping values from DateLike structures
@@ -206,47 +246,25 @@ where
     T: ArrowTemporalType + ArrowNumericType,
     i64: std::convert::From<T::Native>,
 {
-    let mut b = Int32Builder::with_capacity(array.len());
+    let b = Int32Builder::with_capacity(array.len());
     match dt {
         DataType::Time32(_) | DataType::Time64(_) => {
             let iter = ArrayIter::new(array);
-            extract_component_from_array!(
-                iter,
-                b,
-                hour,
-                |value| as_time::<T>(i64::from(value)),
-                |h| h as i32
-            );
+            Ok(as_time_with_op::<A, T, _>(iter, b, |t| t.hour() as i32))
         }
         DataType::Date32 | DataType::Date64 | DataType::Timestamp(_, None) => {
             let iter = ArrayIter::new(array);
-            extract_component_from_array!(
-                iter,
-                b,
-                hour,
-                |value| as_datetime::<T>(i64::from(value)),
-                |h| h as i32
-            )
+            Ok(as_datetime_with_op::<A, T, _>(iter, b, |t| t.hour() as i32))
         }
         DataType::Timestamp(_, Some(tz)) => {
-            let mut scratch = Parsed::new();
+            let scratch = Parsed::new();
             let iter = ArrayIter::new(array);
-            extract_component_from_array!(
-                iter,
-                b,
-                hour,
-                |value, tz| as_datetime::<T>(i64::from(value))
-                    .map(|datetime| datetime + tz),
-                tz,
-                scratch,
-                |value| as_datetime::<T>(i64::from(value)),
-                |h| h as i32
-            )
+            extract_component_from_datatime_array::<A, T, _>(iter, b, tz, 
scratch, |t| {
+                t.hour() as i32
+            })
         }
         _ => return_compute_error_with!("hour does not support", 
array.data_type()),
     }
-
-    Ok(b.finish())
 }
 
 /// Extracts the years of a given temporal primitive array as an array of 
integers
@@ -281,22 +299,14 @@ where
     T: ArrowTemporalType + ArrowNumericType,
     i64: std::convert::From<T::Native>,
 {
-    let mut b = Int32Builder::with_capacity(array.len());
     match dt {
         DataType::Date32 | DataType::Date64 | DataType::Timestamp(_, _) => {
+            let b = Int32Builder::with_capacity(array.len());
             let iter = ArrayIter::new(array);
-            extract_component_from_array!(
-                iter,
-                b,
-                year,
-                |value| as_datetime::<T>(i64::from(value)),
-                |h| h as i32
-            )
+            Ok(as_datetime_with_op::<A, T, _>(iter, b, |t| t.year()))
         }
         _t => return_compute_error_with!("year does not support", 
array.data_type()),
     }
-
-    Ok(b.finish())
 }
 
 /// Extracts the quarter of a given temporal primitive array as an array of 
integers within
@@ -335,37 +345,23 @@ where
     T: ArrowTemporalType + ArrowNumericType,
     i64: std::convert::From<T::Native>,
 {
-    let mut b = Int32Builder::with_capacity(array.len());
+    let b = Int32Builder::with_capacity(array.len());
     match dt {
         DataType::Date32 | DataType::Date64 | DataType::Timestamp(_, None) => {
             let iter = ArrayIter::new(array);
-            extract_component_from_array!(
-                iter,
-                b,
-                quarter,
-                |value| as_datetime::<T>(i64::from(value)),
-                |h| h as i32
-            )
+            Ok(as_datetime_with_op::<A, T, _>(iter, b, |t| {
+                t.quarter() as i32
+            }))
         }
         DataType::Timestamp(_, Some(tz)) => {
-            let mut scratch = Parsed::new();
+            let scratch = Parsed::new();
             let iter = ArrayIter::new(array);
-            extract_component_from_array!(
-                iter,
-                b,
-                quarter,
-                |value, tz| as_datetime::<T>(i64::from(value))
-                    .map(|datetime| datetime + tz),
-                tz,
-                scratch,
-                |value| as_datetime::<T>(i64::from(value)),
-                |h| h as i32
-            )
+            extract_component_from_datatime_array::<A, T, _>(iter, b, tz, 
scratch, |t| {
+                t.quarter() as i32
+            })
         }
         _ => return_compute_error_with!("quarter does not support", 
array.data_type()),
     }
-
-    Ok(b.finish())
 }
 
 /// Extracts the month of a given temporal primitive array as an array of 
integers within
@@ -403,37 +399,23 @@ where
     T: ArrowTemporalType + ArrowNumericType,
     i64: std::convert::From<T::Native>,
 {
-    let mut b = Int32Builder::with_capacity(array.len());
+    let b = Int32Builder::with_capacity(array.len());
     match dt {
         DataType::Date32 | DataType::Date64 | DataType::Timestamp(_, None) => {
             let iter = ArrayIter::new(array);
-            extract_component_from_array!(
-                iter,
-                b,
-                month,
-                |value| as_datetime::<T>(i64::from(value)),
-                |h| h as i32
-            )
+            Ok(as_datetime_with_op::<A, T, _>(iter, b, |t| {
+                t.month() as i32
+            }))
         }
         DataType::Timestamp(_, Some(tz)) => {
-            let mut scratch = Parsed::new();
+            let scratch = Parsed::new();
             let iter = ArrayIter::new(array);
-            extract_component_from_array!(
-                iter,
-                b,
-                month,
-                |value, tz| as_datetime::<T>(i64::from(value))
-                    .map(|datetime| datetime + tz),
-                tz,
-                scratch,
-                |value| as_datetime::<T>(i64::from(value)),
-                |h| h as i32
-            )
+            extract_component_from_datatime_array::<A, T, _>(iter, b, tz, 
scratch, |t| {
+                t.month() as i32
+            })
         }
         _ => return_compute_error_with!("month does not support", 
array.data_type()),
     }
-
-    Ok(b.finish())
 }
 
 /// Extracts the day of week of a given temporal primitive array as an array of
@@ -485,37 +467,23 @@ where
     T: ArrowTemporalType + ArrowNumericType,
     i64: std::convert::From<T::Native>,
 {
-    let mut b = Int32Builder::with_capacity(array.len());
+    let b = Int32Builder::with_capacity(array.len());
     match dt {
         DataType::Date32 | DataType::Date64 | DataType::Timestamp(_, None) => {
             let iter = ArrayIter::new(array);
-            extract_component_from_array!(
-                iter,
-                b,
-                num_days_from_monday,
-                |value| { as_datetime::<T>(i64::from(value)) },
-                |h| h as i32
-            )
+            Ok(as_datetime_with_op::<A, T, _>(iter, b, |t| {
+                t.num_days_from_monday()
+            }))
         }
         DataType::Timestamp(_, Some(tz)) => {
-            let mut scratch = Parsed::new();
+            let scratch = Parsed::new();
             let iter = ArrayIter::new(array);
-            extract_component_from_array!(
-                iter,
-                b,
-                num_days_from_monday,
-                |value, tz| as_datetime::<T>(i64::from(value))
-                    .map(|datetime| datetime + tz),
-                tz,
-                scratch,
-                |value| as_datetime::<T>(i64::from(value)),
-                |h| h as i32
-            )
+            extract_component_from_datatime_array::<A, T, _>(iter, b, tz, 
scratch, |t| {
+                t.num_days_from_monday()
+            })
         }
         _ => return_compute_error_with!("weekday does not support", 
array.data_type()),
     }
-
-    Ok(b.finish())
 }
 
 /// Extracts the day of week of a given temporal primitive array as an array of
@@ -567,40 +535,26 @@ where
     T: ArrowTemporalType + ArrowNumericType,
     i64: std::convert::From<T::Native>,
 {
-    let mut b = Int32Builder::with_capacity(array.len());
+    let b = Int32Builder::with_capacity(array.len());
     match dt {
         DataType::Date32 | DataType::Date64 | DataType::Timestamp(_, None) => {
             let iter = ArrayIter::new(array);
-            extract_component_from_array!(
-                iter,
-                b,
-                num_days_from_sunday,
-                |value| { as_datetime::<T>(i64::from(value)) },
-                |h| h as i32
-            )
+            Ok(as_datetime_with_op::<A, T, _>(iter, b, |t| {
+                t.num_days_from_sunday()
+            }))
         }
         DataType::Timestamp(_, Some(tz)) => {
-            let mut scratch = Parsed::new();
+            let scratch = Parsed::new();
             let iter = ArrayIter::new(array);
-            extract_component_from_array!(
-                iter,
-                b,
-                num_days_from_sunday,
-                |value, tz| as_datetime::<T>(i64::from(value))
-                    .map(|datetime| datetime + tz),
-                tz,
-                scratch,
-                |value| as_datetime::<T>(i64::from(value)),
-                |h| h as i32
-            )
+            extract_component_from_datatime_array::<A, T, _>(iter, b, tz, 
scratch, |t| {
+                t.num_days_from_sunday()
+            })
         }
         _ => return_compute_error_with!(
             "num_days_from_sunday does not support",
             array.data_type()
         ),
     }
-
-    Ok(b.finish())
 }
 
 /// Extracts the day of a given temporal primitive array as an array of 
integers
@@ -635,37 +589,21 @@ where
     T: ArrowTemporalType + ArrowNumericType,
     i64: std::convert::From<T::Native>,
 {
-    let mut b = Int32Builder::with_capacity(array.len());
+    let b = Int32Builder::with_capacity(array.len());
     match dt {
         DataType::Date32 | DataType::Date64 | DataType::Timestamp(_, None) => {
             let iter = ArrayIter::new(array);
-            extract_component_from_array!(
-                iter,
-                b,
-                day,
-                |value| { as_datetime::<T>(i64::from(value)) },
-                |h| h as i32
-            )
+            Ok(as_datetime_with_op::<A, T, _>(iter, b, |t| t.day() as i32))
         }
         DataType::Timestamp(_, Some(ref tz)) => {
-            let mut scratch = Parsed::new();
+            let scratch = Parsed::new();
             let iter = ArrayIter::new(array);
-            extract_component_from_array!(
-                iter,
-                b,
-                day,
-                |value, tz| as_datetime::<T>(i64::from(value))
-                    .map(|datetime| datetime + tz),
-                tz,
-                scratch,
-                |value| as_datetime::<T>(i64::from(value)),
-                |h| h as i32
-            )
+            extract_component_from_datatime_array::<A, T, _>(iter, b, tz, 
scratch, |t| {
+                t.day() as i32
+            })
         }
         _ => return_compute_error_with!("day does not support", 
array.data_type()),
     }
-
-    Ok(b.finish())
 }
 
 /// Extracts the day of year of a given temporal primitive array as an array 
of integers
@@ -704,37 +642,23 @@ where
     T::Native: ArrowNativeType,
     i64: std::convert::From<T::Native>,
 {
-    let mut b = Int32Builder::with_capacity(array.len());
+    let b = Int32Builder::with_capacity(array.len());
     match dt {
         DataType::Date32 | DataType::Date64 | DataType::Timestamp(_, None) => {
             let iter = ArrayIter::new(array);
-            extract_component_from_array!(
-                iter,
-                b,
-                ordinal,
-                |value| { as_datetime::<T>(i64::from(value)) },
-                |h| h as i32
-            )
+            Ok(as_datetime_with_op::<A, T, _>(iter, b, |t| {
+                t.ordinal() as i32
+            }))
         }
         DataType::Timestamp(_, Some(ref tz)) => {
-            let mut scratch = Parsed::new();
+            let scratch = Parsed::new();
             let iter = ArrayIter::new(array);
-            extract_component_from_array!(
-                iter,
-                b,
-                ordinal,
-                |value, tz| as_datetime::<T>(i64::from(value))
-                    .map(|datetime| datetime + tz),
-                tz,
-                scratch,
-                |value| as_datetime::<T>(i64::from(value)),
-                |h| h as i32
-            )
+            extract_component_from_datatime_array::<A, T, _>(iter, b, tz, 
scratch, |t| {
+                t.ordinal() as i32
+            })
         }
         _ => return_compute_error_with!("doy does not support", 
array.data_type()),
     }
-
-    Ok(b.finish())
 }
 
 /// Extracts the minutes of a given temporal primitive array as an array of 
integers
@@ -771,37 +695,23 @@ where
     T: ArrowTemporalType + ArrowNumericType,
     i64: std::convert::From<T::Native>,
 {
-    let mut b = Int32Builder::with_capacity(array.len());
+    let b = Int32Builder::with_capacity(array.len());
     match dt {
         DataType::Date64 | DataType::Timestamp(_, None) => {
             let iter = ArrayIter::new(array);
-            extract_component_from_array!(
-                iter,
-                b,
-                minute,
-                |value| { as_datetime::<T>(i64::from(value)) },
-                |h| h as i32
-            )
+            Ok(as_datetime_with_op::<A, T, _>(iter, b, |t| {
+                t.minute() as i32
+            }))
         }
         DataType::Timestamp(_, Some(tz)) => {
-            let mut scratch = Parsed::new();
+            let scratch = Parsed::new();
             let iter = ArrayIter::new(array);
-            extract_component_from_array!(
-                iter,
-                b,
-                minute,
-                |value, tz| as_datetime::<T>(i64::from(value))
-                    .map(|datetime| datetime + tz),
-                tz,
-                scratch,
-                |value| as_datetime::<T>(i64::from(value)),
-                |h| h as i32
-            )
+            extract_component_from_datatime_array::<A, T, _>(iter, b, tz, 
scratch, |t| {
+                t.minute() as i32
+            })
         }
         _ => return_compute_error_with!("minute does not support", 
array.data_type()),
     }
-
-    Ok(b.finish())
 }
 
 /// Extracts the week of a given temporal primitive array as an array of 
integers
@@ -836,24 +746,16 @@ where
     T: ArrowTemporalType + ArrowNumericType,
     i64: std::convert::From<T::Native>,
 {
-    let mut b = Int32Builder::with_capacity(array.len());
-
     match dt {
         DataType::Date32 | DataType::Date64 | DataType::Timestamp(_, None) => {
+            let b = Int32Builder::with_capacity(array.len());
             let iter = ArrayIter::new(array);
-            extract_component_from_array!(
-                iter,
-                b,
-                iso_week,
-                week,
-                |value| { as_datetime::<T>(i64::from(value)) },
-                |h| h as i32
-            )
+            Ok(as_datetime_with_op::<A, T, _>(iter, b, |t| {
+                t.iso_week().week() as i32
+            }))
         }
         _ => return_compute_error_with!("week does not support", 
array.data_type()),
     }
-
-    Ok(b.finish())
 }
 
 /// Extracts the seconds of a given temporal primitive array as an array of 
integers
@@ -890,37 +792,23 @@ where
     T: ArrowTemporalType + ArrowNumericType,
     i64: std::convert::From<T::Native>,
 {
-    let mut b = Int32Builder::with_capacity(array.len());
+    let b = Int32Builder::with_capacity(array.len());
     match dt {
         DataType::Date64 | DataType::Timestamp(_, None) => {
             let iter = ArrayIter::new(array);
-            extract_component_from_array!(
-                iter,
-                b,
-                second,
-                |value| { as_datetime::<T>(i64::from(value)) },
-                |h| h as i32
-            )
+            Ok(as_datetime_with_op::<A, T, _>(iter, b, |t| {
+                t.second() as i32
+            }))
         }
         DataType::Timestamp(_, Some(tz)) => {
-            let mut scratch = Parsed::new();
+            let scratch = Parsed::new();
             let iter = ArrayIter::new(array);
-            extract_component_from_array!(
-                iter,
-                b,
-                second,
-                |value, tz| as_datetime::<T>(i64::from(value))
-                    .map(|datetime| datetime + tz),
-                tz,
-                scratch,
-                |value| as_datetime::<T>(i64::from(value)),
-                |h| h as i32
-            )
+            extract_component_from_datatime_array::<A, T, _>(iter, b, tz, 
scratch, |t| {
+                t.second() as i32
+            })
         }
         _ => return_compute_error_with!("second does not support", 
array.data_type()),
     }
-
-    Ok(b.finish())
 }
 
 #[cfg(test)]

Reply via email to