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

tustvold 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 a2c6647d4 `arrow::compute::kernels::temporal` should support 
nanoseconds  (#2996)
a2c6647d4 is described below

commit a2c6647d4790b64c538361d02bdbe34640ee75d2
Author: comphead <[email protected]>
AuthorDate: Wed Nov 2 18:24:13 2022 -0700

    `arrow::compute::kernels::temporal` should support nanoseconds  (#2996)
    
    * temporal nano seconds support
    
    * renamed functions
    
    * returned some public methods for downstream projects
    
    * moved tests parts
---
 arrow/src/compute/kernels/temporal.rs | 150 +++++++++++++++++++++-------------
 1 file changed, 92 insertions(+), 58 deletions(-)

diff --git a/arrow/src/compute/kernels/temporal.rs 
b/arrow/src/compute/kernels/temporal.rs
index 412adb9a9..8e42b04b9 100644
--- a/arrow/src/compute/kernels/temporal.rs
+++ b/arrow/src/compute/kernels/temporal.rs
@@ -621,50 +621,7 @@ where
     T: ArrowTemporalType + ArrowNumericType,
     i64: From<T::Native>,
 {
-    minute_generic::<T, _>(array)
-}
-
-/// Extracts the minutes of a given temporal array as an array of integers
-pub fn minute_generic<T, A: ArrayAccessor<Item = T::Native>>(
-    array: A,
-) -> Result<Int32Array>
-where
-    T: ArrowTemporalType + ArrowNumericType,
-    i64: From<T::Native>,
-{
-    match array.data_type().clone() {
-        DataType::Dictionary(_, value_type) => {
-            minute_internal::<T, A>(array, value_type.as_ref())
-        }
-        dt => minute_internal::<T, A>(array, &dt),
-    }
-}
-
-/// Extracts the minutes of a given temporal array as an array of integers
-fn minute_internal<T, A: ArrayAccessor<Item = T::Native>>(
-    array: A,
-    dt: &DataType,
-) -> Result<Int32Array>
-where
-    T: ArrowTemporalType + ArrowNumericType,
-    i64: From<T::Native>,
-{
-    let b = Int32Builder::with_capacity(array.len());
-    match dt {
-        DataType::Date64 | DataType::Timestamp(_, None) => {
-            let iter = ArrayIter::new(array);
-            Ok(as_datetime_with_op::<A, T, _>(iter, b, |t| {
-                t.minute() as i32
-            }))
-        }
-        DataType::Timestamp(_, Some(tz)) => {
-            let iter = ArrayIter::new(array);
-            extract_component_from_datetime_array::<A, T, _>(iter, b, tz, |t| {
-                t.minute() as i32
-            })
-        }
-        _ => return_compute_error_with!("minute does not support", 
array.data_type()),
-    }
+    time_fraction_generic::<T, _, _>(array, "minute", |t| t.minute() as i32)
 }
 
 /// Extracts the week of a given temporal primitive array as an array of 
integers
@@ -717,31 +674,46 @@ where
     T: ArrowTemporalType + ArrowNumericType,
     i64: From<T::Native>,
 {
-    second_generic::<T, _>(array)
+    time_fraction_generic::<T, _, _>(array, "second", |t| t.second() as i32)
 }
 
-/// Extracts the seconds of a given temporal array as an array of integers
-pub fn second_generic<T, A: ArrayAccessor<Item = T::Native>>(
+/// Extracts the nanoseconds of a given temporal primitive array as an array 
of integers
+pub fn nanosecond<T>(array: &PrimitiveArray<T>) -> Result<Int32Array>
+where
+    T: ArrowTemporalType + ArrowNumericType,
+    i64: From<T::Native>,
+{
+    time_fraction_generic::<T, _, _>(array, "nanosecond", |t| t.nanosecond() 
as i32)
+}
+
+/// Extracts the time fraction of a given temporal array as an array of 
integers
+fn time_fraction_generic<T, A: ArrayAccessor<Item = T::Native>, F>(
     array: A,
+    name: &str,
+    op: F,
 ) -> Result<Int32Array>
 where
+    F: Fn(NaiveDateTime) -> i32,
     T: ArrowTemporalType + ArrowNumericType,
     i64: From<T::Native>,
 {
     match array.data_type().clone() {
         DataType::Dictionary(_, value_type) => {
-            second_internal::<T, A>(array, value_type.as_ref())
+            time_fraction_internal::<T, A, _>(array, value_type.as_ref(), 
name, op)
         }
-        dt => second_internal::<T, A>(array, &dt),
+        dt => time_fraction_internal::<T, A, _>(array, &dt, name, op),
     }
 }
 
-/// Extracts the seconds of a given temporal array as an array of integers
-fn second_internal<T, A: ArrayAccessor<Item = T::Native>>(
+/// Extracts the time fraction of a given temporal array as an array of 
integers
+fn time_fraction_internal<T, A: ArrayAccessor<Item = T::Native>, F>(
     array: A,
     dt: &DataType,
+    name: &str,
+    op: F,
 ) -> Result<Int32Array>
 where
+    F: Fn(NaiveDateTime) -> i32,
     T: ArrowTemporalType + ArrowNumericType,
     i64: From<T::Native>,
 {
@@ -749,20 +721,41 @@ where
     match dt {
         DataType::Date64 | DataType::Timestamp(_, None) => {
             let iter = ArrayIter::new(array);
-            Ok(as_datetime_with_op::<A, T, _>(iter, b, |t| {
-                t.second() as i32
-            }))
+            Ok(as_datetime_with_op::<A, T, _>(iter, b, op))
         }
         DataType::Timestamp(_, Some(tz)) => {
             let iter = ArrayIter::new(array);
             extract_component_from_datetime_array::<A, T, _>(iter, b, tz, |t| {
-                t.second() as i32
+                op(t.naive_local())
             })
         }
-        _ => return_compute_error_with!("second does not support", 
array.data_type()),
+        _ => return_compute_error_with!(
+            format!("{} does not support", name),
+            array.data_type()
+        ),
     }
 }
 
+pub fn minute_generic<T, A: ArrayAccessor<Item = T::Native>>(
+    array: A,
+) -> Result<Int32Array>
+where
+    T: ArrowTemporalType + ArrowNumericType,
+    i64: From<T::Native>,
+{
+    time_fraction_generic::<T, _, _>(array, "minute", |t| t.minute() as i32)
+}
+
+pub fn second_generic<T, A: ArrayAccessor<Item = T::Native>>(
+    array: A,
+) -> Result<Int32Array>
+where
+    T: ArrowTemporalType + ArrowNumericType,
+    i64: From<T::Native>,
+{
+    time_fraction_generic::<T, _, _>(array, "second", |t| t.second() as i32)
+}
+
 #[cfg(test)]
 mod tests {
     use super::*;
@@ -1212,21 +1205,47 @@ mod tests {
         let expected = Int32Array::from(vec![11, 11, 21, 7, 21]);
         assert_eq!(expected, b);
 
-        let b = minute_generic::<TimestampSecondType, _>(
+        let b = time_fraction_generic::<TimestampSecondType, _, _>(
+            dict.downcast_dict::<TimestampSecondArray>().unwrap(),
+            "minute",
+            |t| t.minute() as i32,
+        )
+        .unwrap();
+
+        let b_old = minute_generic::<TimestampSecondType, _>(
             dict.downcast_dict::<TimestampSecondArray>().unwrap(),
         )
         .unwrap();
 
         let expected = Int32Array::from(vec![1, 1, 2, 3, 2]);
         assert_eq!(expected, b);
+        assert_eq!(expected, b_old);
 
-        let b = second_generic::<TimestampSecondType, _>(
+        let b = time_fraction_generic::<TimestampSecondType, _, _>(
+            dict.downcast_dict::<TimestampSecondArray>().unwrap(),
+            "second",
+            |t| t.second() as i32,
+        )
+        .unwrap();
+
+        let b_old = second_generic::<TimestampSecondType, _>(
             dict.downcast_dict::<TimestampSecondArray>().unwrap(),
         )
         .unwrap();
 
         let expected = Int32Array::from(vec![1, 1, 2, 3, 2]);
         assert_eq!(expected, b);
+        assert_eq!(expected, b_old);
+
+        let b = time_fraction_generic::<TimestampSecondType, _, _>(
+            dict.downcast_dict::<TimestampSecondArray>().unwrap(),
+            "nanosecond",
+            |t| t.nanosecond() as i32,
+        )
+        .unwrap();
+
+        let expected = Int32Array::from(vec![0, 0, 0, 0, 0]);
+        assert_eq!(expected, b);
     }
 
     #[test]
@@ -1313,4 +1332,19 @@ mod tests {
         let expected = Int32Array::from(vec![Some(1), Some(8), Some(8), 
Some(1), None]);
         assert_eq!(expected, b);
     }
+
+    #[test]
+    fn test_temporal_array_date64_nanosecond() {
+        // new Date(1667328721453)
+        // Tue Nov 01 2022 11:52:01 GMT-0700 (Pacific Daylight Time)
+        //
+        // new Date(1667328721453).getMilliseconds()
+        // 453
+
+        let a: PrimitiveArray<Date64Type> = vec![None, 
Some(1667328721453)].into();
+
+        let b = nanosecond(&a).unwrap();
+        assert!(!b.is_valid(0));
+        assert_eq!(453_000_000, b.value(1));
+    }
 }

Reply via email to