alamb commented on pull request #984:
URL: https://github.com/apache/arrow-rs/pull/984#issuecomment-992692480


   So I messed around with this some more. The key thing I kept hitting was 
that the comparisons to the dictionary values effectively needed to be "dynamic"
   
    Here is one approach that we might be able to use (and skip the specialized 
`eq_dict_scalar` entirely).
   
   ```rust
   
   /// Perform `left == right` operation on an array and a numeric scalar
   /// value. Supports PrimtiveArrays, and DictionaryArrays that have primitive 
values
   pub fn eq_dyn_scalar<T>(
       left: &dyn Array,
       right: T::Native,
   ) -> Result<BooleanArray>
   where
       T: ArrowNumericType,
   {
       #[cfg(not(feature = "simd"))]
       println!("{}", std::any::type_name::<T>());
       match left.data_type() {
           DataType::UInt8 => {
               // horrible (?) way to get a u8
               let right: u8 = right.to_usize()
                   .and_then(|right| right.try_into().ok())
                   .ok_or_else(|| ArrowError::ComputeError(format!("Can not 
convert {:?} to u8 for comparison with UInt8Array", right)))?;
               eq_scalar::<UInt8Type>(as_primitive::<UInt8Type>(left), right)
           }
           DataType::UInt16 => {
               // horrible (?) way to get a u16
               let right: u16 = right.to_usize()
                   .and_then(|right| right.try_into().ok())
                   .ok_or_else(|| ArrowError::ComputeError(format!("Can not 
convert {:?} to u16 for comparison with UInt16Array", right)))?;
               eq_scalar::<UInt16Type>(as_primitive::<UInt16Type>(left), right)
           }
           // TODO other primitive array types
           DataType::Dictionary(key_type, value_type) => {
               match key_type.as_ref() {
                   DataType::UInt8 => {
                       let left = as_dictionary::<UInt8Type>(left);
                       unpack_dict_comparison(left, 
eq_dyn_scalar::<T>(left.values().as_ref(), right)?)
                   }
                   // TODO fill out the rest of the key types here
                   _ => todo!()
               }
           }
           // TODO macroize / fill out rest of primitive dispatch
           _ => todo!()
       }
   }
   ```
   
   The downside is you still need type annotations at the callsite:
   
   ```rust
   
       #[test]
       fn test_dict_eq_scalar() {
   ...
           let array = builder.finish();
           // still need the UInt8Type annotations
           let a_eq = eq_dyn_scalar::<UInt8Type>(&array, 123u8).unwrap();
           assert_eq!(
               a_eq,
               BooleanArray::from(vec![Some(true), None, Some(false)])
           );
       }
   ```
   


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