abreis edited a comment on pull request #9454:
URL: https://github.com/apache/arrow/pull/9454#issuecomment-778208765


   > @abreis , I am not convinced that that is sufficient, unfortunately, 
because it excludes all types that are not Numeric (i.e. all dates and times 
for primitives, as well as all other logical types).
   > 
   > We could of course offer a `DatumTemporal` and a `DatumList` and so one 
and so forth, but IMO that is introducing more complexity, as we now start 
having `struct`s for all kinds of logical types.
   
   I agree. I just realized that `ArrowPrimitiveType` exists though, so Datum 
can be generic over that instead.
   
   Here is a more fleshed-out mock of a Datum type. The signature of 
`math_divide` enforces a consistent `T` over array/array and array/scalar 
combinations, and the method's output.
   
   Base type:
   ```rust
   #[derive(Debug)]
   pub enum Datum<'a, T>
   where
       T: ArrowPrimitiveType,
   {
       Array(&'a PrimitiveArray<T>),
       Scalar(Option<T::Native>),
   }
   ```
   
   `From` impls for both arrays and nullable scalars:
   ```rust
   impl<'a, T> From<&'a PrimitiveArray<T>> for Datum<'a, T>
   where
       T: ArrowPrimitiveType,
   {
       fn from(array: &'a PrimitiveArray<T>) -> Self {
           Datum::Array(array)
       }
   }
   
   impl<'a, T> From<Option<T::Native>> for Datum<'a, T>
   where
       T: ArrowPrimitiveType,
   {
       fn from(scalar: Option<T::Native>) -> Self {
           Datum::Scalar(scalar)
       }
   }
   ```
   
   A (user-facing) method for math division:
   ```rust
   pub fn math_divide<'a1, 'a2, T, DL, DR>(
       left: DL,
       right: DR,
   ) -> Result<PrimitiveArray<T>>
   where
       T: ArrowNumericType,
       T::Native: Div<Output = T::Native> + Zero,
       DL: Into<Datum<'a1, T>>, // left and right may have different lifetimes
       DR: Into<Datum<'a2, T>>, // but `T` must be the same
   {
       use Datum::*;
       match (left.into(), right.into()) {
           (Array(left), Array(right)) => todo!(), // array/array
           (Array(array), Scalar(divisor)) => todo!(), // array/scalar
           _ => todo!(),
       }
   }
   ```
   
   Test code:
   ```rust
   fn test_datum_divide() {
       let array1 = Int32Array::from(vec![15, 15, 8, 1, 9]);
       let array2 = Int32Array::from(vec![5, 6, 8, 9, 1]);
       let scalar = Some(8i32);
   
       let a_over_a = math_divide(&array1, &array2).unwrap(); // works
       let a_over_s = math_divide(&array1, scalar).unwrap(); // also works
   }
   ```
   
   @jorgecarleitao I'm aware this doesn't address the second half of your 
comment. I'm just exploring this idea for the current version of arrow.


----------------------------------------------------------------
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.

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


Reply via email to