abreis commented 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
`datum_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:
[email protected]