From 037a99de9541ddc73099cfe021294b91ae3055c9 Mon Sep 17 00:00:00 2001 From: Liang-Chi Hsieh Date: Sun, 24 Jul 2022 15:36:28 -0700 Subject: [PATCH 1/3] Use ArrayAccessor --- arrow/src/compute/kernels/comparison.rs | 533 +++++++++++++----------- 1 file changed, 298 insertions(+), 235 deletions(-) diff --git a/arrow/src/compute/kernels/comparison.rs b/arrow/src/compute/kernels/comparison.rs index 5344e160c09..a95c849e8eb 100644 --- a/arrow/src/compute/kernels/comparison.rs +++ b/arrow/src/compute/kernels/comparison.rs @@ -24,8 +24,7 @@ //! use crate::array::*; -use crate::buffer::{bitwise_bin_op_helper, buffer_unary_not, Buffer, MutableBuffer}; -use crate::compute::binary_boolean_kernel; +use crate::buffer::{buffer_unary_not, Buffer, MutableBuffer}; use crate::compute::util::combine_option_bitmap; use crate::datatypes::{ ArrowNativeType, ArrowNumericType, DataType, Date32Type, Date64Type, Float32Type, @@ -40,168 +39,72 @@ use regex::{escape, Regex}; use std::any::type_name; use std::collections::HashMap; -/// Helper function to perform boolean lambda function on values from two arrays, this +/// Helper function to perform boolean lambda function on values from two array accessors, this /// version does not attempt to use SIMD. -macro_rules! compare_op { - ($left: expr, $right:expr, $op:expr) => {{ - if $left.len() != $right.len() { - return Err(ArrowError::ComputeError( - "Cannot perform comparison operation on arrays of different length" - .to_string(), - )); - } - - let null_bit_buffer = - combine_option_bitmap(&[$left.data_ref(), $right.data_ref()], $left.len())?; - - // Safety: - // `i < $left.len()` and $left.len() == $right.len() - let comparison = (0..$left.len()) - .map(|i| unsafe { $op($left.value_unchecked(i), $right.value_unchecked(i)) }); - // same size as $left.len() and $right.len() - let buffer = unsafe { MutableBuffer::from_trusted_len_iter_bool(comparison) }; - - let data = unsafe { - ArrayData::new_unchecked( - DataType::Boolean, - $left.len(), - None, - null_bit_buffer, - 0, - vec![Buffer::from(buffer)], - vec![], - ) - }; - Ok(BooleanArray::from(data)) - }}; -} +fn compare_op(left: T, right: T, op: F) -> Result +where + F: Fn(T::Item, T::Item) -> bool, +{ + if left.len() != right.len() { + return Err(ArrowError::ComputeError( + "Cannot perform comparison operation on arrays of different length" + .to_string(), + )); + } -macro_rules! compare_op_primitive { - ($left: expr, $right:expr, $op:expr) => {{ - if $left.len() != $right.len() { - return Err(ArrowError::ComputeError( - "Cannot perform comparison operation on arrays of different length" - .to_string(), - )); - } + let null_bit_buffer = + combine_option_bitmap(&[left.data_ref(), right.data_ref()], left.len())?; - let null_bit_buffer = - combine_option_bitmap(&[$left.data_ref(), $right.data_ref()], $left.len())?; - - let mut values = MutableBuffer::from_len_zeroed(($left.len() + 7) / 8); - let lhs_chunks_iter = $left.values().chunks_exact(8); - let lhs_remainder = lhs_chunks_iter.remainder(); - let rhs_chunks_iter = $right.values().chunks_exact(8); - let rhs_remainder = rhs_chunks_iter.remainder(); - let chunks = $left.len() / 8; - - values[..chunks] - .iter_mut() - .zip(lhs_chunks_iter) - .zip(rhs_chunks_iter) - .for_each(|((byte, lhs), rhs)| { - lhs.iter() - .zip(rhs.iter()) - .enumerate() - .for_each(|(i, (&lhs, &rhs))| { - *byte |= if $op(lhs, rhs) { 1 << i } else { 0 }; - }); - }); + // Safety: + // `i < $left.len()` and $left.len() == $right.len() + let comparison = (0..left.len()) + .map(|i| unsafe { op(left.value_unchecked(i), right.value_unchecked(i)) }); + // same size as $left.len() and $right.len() + let buffer = unsafe { MutableBuffer::from_trusted_len_iter_bool(comparison) }; - if !lhs_remainder.is_empty() { - let last = &mut values[chunks]; - lhs_remainder - .iter() - .zip(rhs_remainder.iter()) - .enumerate() - .for_each(|(i, (&lhs, &rhs))| { - *last |= if $op(lhs, rhs) { 1 << i } else { 0 }; - }); - }; - let data = unsafe { - ArrayData::new_unchecked( - DataType::Boolean, - $left.len(), - None, - null_bit_buffer, - 0, - vec![Buffer::from(values)], - vec![], - ) - }; - Ok(BooleanArray::from(data)) - }}; + let data = unsafe { + ArrayData::new_unchecked( + DataType::Boolean, + left.len(), + None, + null_bit_buffer, + 0, + vec![Buffer::from(buffer)], + vec![], + ) + }; + Ok(BooleanArray::from(data)) } -macro_rules! compare_op_scalar { - ($left:expr, $op:expr) => {{ - let null_bit_buffer = $left - .data() - .null_buffer() - .map(|b| b.bit_slice($left.offset(), $left.len())); - - // Safety: - // `i < $left.len()` - let comparison = - (0..$left.len()).map(|i| unsafe { $op($left.value_unchecked(i)) }); - // same as $left.len() - let buffer = unsafe { MutableBuffer::from_trusted_len_iter_bool(comparison) }; - - let data = unsafe { - ArrayData::new_unchecked( - DataType::Boolean, - $left.len(), - None, - null_bit_buffer, - 0, - vec![Buffer::from(buffer)], - vec![], - ) - }; - Ok(BooleanArray::from(data)) - }}; -} +/// Helper function to perform boolean lambda function on values from array accessor, this +/// version does not attempt to use SIMD. +fn compare_op_scalar(left: T, op: F) -> Result +where + F: Fn(T::Item) -> bool, +{ + let null_bit_buffer = left + .data() + .null_buffer() + .map(|b| b.bit_slice(left.offset(), left.len())); -macro_rules! compare_op_scalar_primitive { - ($left: expr, $right:expr, $op:expr) => {{ - let null_bit_buffer = $left - .data() - .null_buffer() - .map(|b| b.bit_slice($left.offset(), $left.len())); - - let mut values = MutableBuffer::from_len_zeroed(($left.len() + 7) / 8); - let lhs_chunks_iter = $left.values().chunks_exact(8); - let lhs_remainder = lhs_chunks_iter.remainder(); - let chunks = $left.len() / 8; - - values[..chunks] - .iter_mut() - .zip(lhs_chunks_iter) - .for_each(|(byte, chunk)| { - chunk.iter().enumerate().for_each(|(i, &c_i)| { - *byte |= if $op(c_i, $right) { 1 << i } else { 0 }; - }); - }); - if !lhs_remainder.is_empty() { - let last = &mut values[chunks]; - lhs_remainder.iter().enumerate().for_each(|(i, &lhs)| { - *last |= if $op(lhs, $right) { 1 << i } else { 0 }; - }); - }; + // Safety: + // `i < $left.len()` + let comparison = (0..left.len()).map(|i| unsafe { op(left.value_unchecked(i)) }); + // same as $left.len() + let buffer = unsafe { MutableBuffer::from_trusted_len_iter_bool(comparison) }; - let data = unsafe { - ArrayData::new_unchecked( - DataType::Boolean, - $left.len(), - None, - null_bit_buffer, - 0, - vec![Buffer::from(values)], - vec![], - ) - }; - Ok(BooleanArray::from(data)) - }}; + let data = unsafe { + ArrayData::new_unchecked( + DataType::Boolean, + left.len(), + None, + null_bit_buffer, + 0, + vec![Buffer::from(buffer)], + vec![], + ) + }; + Ok(BooleanArray::from(data)) } /// Evaluate `op(left, right)` for [`PrimitiveArray`]s using a specified @@ -215,7 +118,7 @@ where T: ArrowNumericType, F: Fn(T::Native, T::Native) -> bool, { - compare_op_primitive!(left, right, op) + compare_op(left, right, op) } /// Evaluate `op(left, right)` for [`PrimitiveArray`] and scalar using @@ -229,7 +132,7 @@ where T: ArrowNumericType, F: Fn(T::Native, T::Native) -> bool, { - compare_op_scalar_primitive!(left, right, op) + compare_op_scalar(left, |l| op(l, right)) } fn is_like_pattern(c: char) -> bool { @@ -769,7 +672,7 @@ pub fn eq_utf8( left: &GenericStringArray, right: &GenericStringArray, ) -> Result { - compare_op!(left, right, |a, b| a == b) + compare_op(left, right, |a, b| a == b) } /// Perform `left == right` operation on [`StringArray`] / [`LargeStringArray`] and a scalar. @@ -777,66 +680,37 @@ pub fn eq_utf8_scalar( left: &GenericStringArray, right: &str, ) -> Result { - compare_op_scalar!(left, |a| a == right) -} - -#[inline] -fn binary_boolean_op( - left: &BooleanArray, - right: &BooleanArray, - op: F, -) -> Result -where - F: Copy + Fn(u64, u64) -> u64, -{ - binary_boolean_kernel( - left, - right, - |left: &Buffer, - left_offset_in_bits: usize, - right: &Buffer, - right_offset_in_bits: usize, - len_in_bits: usize| { - bitwise_bin_op_helper( - left, - left_offset_in_bits, - right, - right_offset_in_bits, - len_in_bits, - op, - ) - }, - ) + compare_op_scalar(left, |a| a == right) } /// Perform `left == right` operation on [`BooleanArray`] pub fn eq_bool(left: &BooleanArray, right: &BooleanArray) -> Result { - binary_boolean_op(left, right, |a, b| !(a ^ b)) + compare_op(left, right, |a, b| !(a ^ b)) } /// Perform `left != right` operation on [`BooleanArray`] pub fn neq_bool(left: &BooleanArray, right: &BooleanArray) -> Result { - binary_boolean_op(left, right, |a, b| (a ^ b)) + compare_op(left, right, |a, b| (a ^ b)) } /// Perform `left < right` operation on [`BooleanArray`] pub fn lt_bool(left: &BooleanArray, right: &BooleanArray) -> Result { - binary_boolean_op(left, right, |a, b| ((!a) & b)) + compare_op(left, right, |a, b| ((!a) & b)) } /// Perform `left <= right` operation on [`BooleanArray`] pub fn lt_eq_bool(left: &BooleanArray, right: &BooleanArray) -> Result { - binary_boolean_op(left, right, |a, b| !(a & (!b))) + compare_op(left, right, |a, b| !(a & (!b))) } /// Perform `left > right` operation on [`BooleanArray`] pub fn gt_bool(left: &BooleanArray, right: &BooleanArray) -> Result { - binary_boolean_op(left, right, |a, b| (a & (!b))) + compare_op(left, right, |a, b| (a & (!b))) } /// Perform `left >= right` operation on [`BooleanArray`] pub fn gt_eq_bool(left: &BooleanArray, right: &BooleanArray) -> Result { - binary_boolean_op(left, right, |a, b| !((!a) & b)) + compare_op(left, right, |a, b| !((!a) & b)) } /// Perform `left == right` operation on [`BooleanArray`] and a scalar @@ -870,22 +744,22 @@ pub fn eq_bool_scalar(left: &BooleanArray, right: bool) -> Result /// Perform `left < right` operation on [`BooleanArray`] and a scalar pub fn lt_bool_scalar(left: &BooleanArray, right: bool) -> Result { - compare_op_scalar!(left, |a: bool| !a & right) + compare_op_scalar(left, |a: bool| !a & right) } /// Perform `left <= right` operation on [`BooleanArray`] and a scalar pub fn lt_eq_bool_scalar(left: &BooleanArray, right: bool) -> Result { - compare_op_scalar!(left, |a| a <= right) + compare_op_scalar(left, |a| a <= right) } /// Perform `left > right` operation on [`BooleanArray`] and a scalar pub fn gt_bool_scalar(left: &BooleanArray, right: bool) -> Result { - compare_op_scalar!(left, |a: bool| a & !right) + compare_op_scalar(left, |a: bool| a & !right) } /// Perform `left >= right` operation on [`BooleanArray`] and a scalar pub fn gt_eq_bool_scalar(left: &BooleanArray, right: bool) -> Result { - compare_op_scalar!(left, |a| a >= right) + compare_op_scalar(left, |a| a >= right) } /// Perform `left != right` operation on [`BooleanArray`] and a scalar @@ -898,7 +772,7 @@ pub fn eq_binary( left: &GenericBinaryArray, right: &GenericBinaryArray, ) -> Result { - compare_op!(left, right, |a, b| a == b) + compare_op(left, right, |a, b| a == b) } /// Perform `left == right` operation on [`BinaryArray`] / [`LargeBinaryArray`] and a scalar @@ -906,7 +780,7 @@ pub fn eq_binary_scalar( left: &GenericBinaryArray, right: &[u8], ) -> Result { - compare_op_scalar!(left, |a| a == right) + compare_op_scalar(left, |a| a == right) } /// Perform `left != right` operation on [`BinaryArray`] / [`LargeBinaryArray`]. @@ -914,7 +788,7 @@ pub fn neq_binary( left: &GenericBinaryArray, right: &GenericBinaryArray, ) -> Result { - compare_op!(left, right, |a, b| a != b) + compare_op(left, right, |a, b| a != b) } /// Perform `left != right` operation on [`BinaryArray`] / [`LargeBinaryArray`] and a scalar. @@ -922,7 +796,7 @@ pub fn neq_binary_scalar( left: &GenericBinaryArray, right: &[u8], ) -> Result { - compare_op_scalar!(left, |a| a != right) + compare_op_scalar(left, |a| a != right) } /// Perform `left < right` operation on [`BinaryArray`] / [`LargeBinaryArray`]. @@ -930,7 +804,7 @@ pub fn lt_binary( left: &GenericBinaryArray, right: &GenericBinaryArray, ) -> Result { - compare_op!(left, right, |a, b| a < b) + compare_op(left, right, |a, b| a < b) } /// Perform `left < right` operation on [`BinaryArray`] / [`LargeBinaryArray`] and a scalar. @@ -938,7 +812,7 @@ pub fn lt_binary_scalar( left: &GenericBinaryArray, right: &[u8], ) -> Result { - compare_op_scalar!(left, |a| a < right) + compare_op_scalar(left, |a| a < right) } /// Perform `left <= right` operation on [`BinaryArray`] / [`LargeBinaryArray`]. @@ -946,7 +820,7 @@ pub fn lt_eq_binary( left: &GenericBinaryArray, right: &GenericBinaryArray, ) -> Result { - compare_op!(left, right, |a, b| a <= b) + compare_op(left, right, |a, b| a <= b) } /// Perform `left <= right` operation on [`BinaryArray`] / [`LargeBinaryArray`] and a scalar. @@ -954,7 +828,7 @@ pub fn lt_eq_binary_scalar( left: &GenericBinaryArray, right: &[u8], ) -> Result { - compare_op_scalar!(left, |a| a <= right) + compare_op_scalar(left, |a| a <= right) } /// Perform `left > right` operation on [`BinaryArray`] / [`LargeBinaryArray`]. @@ -962,7 +836,7 @@ pub fn gt_binary( left: &GenericBinaryArray, right: &GenericBinaryArray, ) -> Result { - compare_op!(left, right, |a, b| a > b) + compare_op(left, right, |a, b| a > b) } /// Perform `left > right` operation on [`BinaryArray`] / [`LargeBinaryArray`] and a scalar. @@ -970,7 +844,7 @@ pub fn gt_binary_scalar( left: &GenericBinaryArray, right: &[u8], ) -> Result { - compare_op_scalar!(left, |a| a > right) + compare_op_scalar(left, |a| a > right) } /// Perform `left >= right` operation on [`BinaryArray`] / [`LargeBinaryArray`]. @@ -978,7 +852,7 @@ pub fn gt_eq_binary( left: &GenericBinaryArray, right: &GenericBinaryArray, ) -> Result { - compare_op!(left, right, |a, b| a >= b) + compare_op(left, right, |a, b| a >= b) } /// Perform `left >= right` operation on [`BinaryArray`] / [`LargeBinaryArray`] and a scalar. @@ -986,7 +860,7 @@ pub fn gt_eq_binary_scalar( left: &GenericBinaryArray, right: &[u8], ) -> Result { - compare_op_scalar!(left, |a| a >= right) + compare_op_scalar(left, |a| a >= right) } /// Perform `left != right` operation on [`StringArray`] / [`LargeStringArray`]. @@ -994,7 +868,7 @@ pub fn neq_utf8( left: &GenericStringArray, right: &GenericStringArray, ) -> Result { - compare_op!(left, right, |a, b| a != b) + compare_op(left, right, |a, b| a != b) } /// Perform `left != right` operation on [`StringArray`] / [`LargeStringArray`] and a scalar. @@ -1002,7 +876,7 @@ pub fn neq_utf8_scalar( left: &GenericStringArray, right: &str, ) -> Result { - compare_op_scalar!(left, |a| a != right) + compare_op_scalar(left, |a| a != right) } /// Perform `left < right` operation on [`StringArray`] / [`LargeStringArray`]. @@ -1010,7 +884,7 @@ pub fn lt_utf8( left: &GenericStringArray, right: &GenericStringArray, ) -> Result { - compare_op!(left, right, |a, b| a < b) + compare_op(left, right, |a, b| a < b) } /// Perform `left < right` operation on [`StringArray`] / [`LargeStringArray`] and a scalar. @@ -1018,7 +892,7 @@ pub fn lt_utf8_scalar( left: &GenericStringArray, right: &str, ) -> Result { - compare_op_scalar!(left, |a| a < right) + compare_op_scalar(left, |a| a < right) } /// Perform `left <= right` operation on [`StringArray`] / [`LargeStringArray`]. @@ -1026,7 +900,7 @@ pub fn lt_eq_utf8( left: &GenericStringArray, right: &GenericStringArray, ) -> Result { - compare_op!(left, right, |a, b| a <= b) + compare_op(left, right, |a, b| a <= b) } /// Perform `left <= right` operation on [`StringArray`] / [`LargeStringArray`] and a scalar. @@ -1034,7 +908,7 @@ pub fn lt_eq_utf8_scalar( left: &GenericStringArray, right: &str, ) -> Result { - compare_op_scalar!(left, |a| a <= right) + compare_op_scalar(left, |a| a <= right) } /// Perform `left > right` operation on [`StringArray`] / [`LargeStringArray`]. @@ -1042,7 +916,7 @@ pub fn gt_utf8( left: &GenericStringArray, right: &GenericStringArray, ) -> Result { - compare_op!(left, right, |a, b| a > b) + compare_op(left, right, |a, b| a > b) } /// Perform `left > right` operation on [`StringArray`] / [`LargeStringArray`] and a scalar. @@ -1050,7 +924,7 @@ pub fn gt_utf8_scalar( left: &GenericStringArray, right: &str, ) -> Result { - compare_op_scalar!(left, |a| a > right) + compare_op_scalar(left, |a| a > right) } /// Perform `left >= right` operation on [`StringArray`] / [`LargeStringArray`]. @@ -1058,7 +932,7 @@ pub fn gt_eq_utf8( left: &GenericStringArray, right: &GenericStringArray, ) -> Result { - compare_op!(left, right, |a, b| a >= b) + compare_op(left, right, |a, b| a >= b) } /// Perform `left >= right` operation on [`StringArray`] / [`LargeStringArray`] and a scalar. @@ -1066,7 +940,7 @@ pub fn gt_eq_utf8_scalar( left: &GenericStringArray, right: &str, ) -> Result { - compare_op_scalar!(left, |a| a >= right) + compare_op_scalar(left, |a| a >= right) } /// Calls $RIGHT.$TY() (e.g. `right.to_i128()`) with a nice error message. @@ -1964,6 +1838,195 @@ macro_rules! typed_cmp { }}; } +fn eq_typed_compares(left: &dyn Array, right: &dyn Array) -> Result { + match (left.data_type(), left.data_type()) { + (DataType::Boolean, DataType::Boolean) => compare_op( + left.as_any().downcast_ref::().unwrap(), + right.as_any().downcast_ref::().unwrap(), + |a, b| !(a ^ b), + ), + (DataType::Int8, DataType::Int8) => compare_op( + left.as_any().downcast_ref::().unwrap(), + right.as_any().downcast_ref::().unwrap(), + |a, b| a == b, + ), + (DataType::Int16, DataType::Int16) => compare_op( + left.as_any().downcast_ref::().unwrap(), + right.as_any().downcast_ref::().unwrap(), + |a, b| a == b, + ), + (DataType::Int32, DataType::Int32) => compare_op( + left.as_any().downcast_ref::().unwrap(), + right.as_any().downcast_ref::().unwrap(), + |a, b| a == b, + ), + (DataType::Int64, DataType::Int64) => compare_op( + left.as_any().downcast_ref::().unwrap(), + right.as_any().downcast_ref::().unwrap(), + |a, b| a == b, + ), + (DataType::UInt8, DataType::UInt8) => compare_op( + left.as_any().downcast_ref::().unwrap(), + right.as_any().downcast_ref::().unwrap(), + |a, b| a == b, + ), + (DataType::UInt16, DataType::UInt16) => compare_op( + left.as_any().downcast_ref::().unwrap(), + right.as_any().downcast_ref::().unwrap(), + |a, b| a == b, + ), + (DataType::UInt32, DataType::UInt32) => compare_op( + left.as_any().downcast_ref::().unwrap(), + right.as_any().downcast_ref::().unwrap(), + |a, b| a == b, + ), + (DataType::UInt64, DataType::UInt64) => compare_op( + left.as_any().downcast_ref::().unwrap(), + right.as_any().downcast_ref::().unwrap(), + |a, b| a == b, + ), + (DataType::Float32, DataType::Float32) => compare_op( + left.as_any().downcast_ref::().unwrap(), + right.as_any().downcast_ref::().unwrap(), + |a, b| a == b, + ), + (DataType::Float64, DataType::Float64) => compare_op( + left.as_any().downcast_ref::().unwrap(), + right.as_any().downcast_ref::().unwrap(), + |a, b| a == b, + ), + (DataType::Utf8, DataType::Utf8) => compare_op( + left.as_any().downcast_ref::().unwrap(), + right.as_any().downcast_ref::().unwrap(), + |a, b| a == b, + ), + (DataType::LargeUtf8, DataType::LargeUtf8) => compare_op( + left.as_any().downcast_ref::().unwrap(), + right.as_any().downcast_ref::().unwrap(), + |a, b| a == b, + ), + (DataType::Binary, DataType::Binary) => compare_op( + left.as_any().downcast_ref::().unwrap(), + right.as_any().downcast_ref::().unwrap(), + |a, b| a == b, + ), + (DataType::LargeBinary, DataType::LargeBinary) => compare_op( + left.as_any().downcast_ref::().unwrap(), + right.as_any().downcast_ref::().unwrap(), + |a, b| a == b, + ), + ( + DataType::Timestamp(TimeUnit::Nanosecond, _), + DataType::Timestamp(TimeUnit::Nanosecond, _), + ) => compare_op( + left.as_any() + .downcast_ref::() + .unwrap(), + right + .as_any() + .downcast_ref::() + .unwrap(), + |a, b| a == b, + ), + ( + DataType::Timestamp(TimeUnit::Microsecond, _), + DataType::Timestamp(TimeUnit::Microsecond, _), + ) => compare_op( + left.as_any() + .downcast_ref::() + .unwrap(), + right + .as_any() + .downcast_ref::() + .unwrap(), + |a, b| a == b, + ), + ( + DataType::Timestamp(TimeUnit::Millisecond, _), + DataType::Timestamp(TimeUnit::Millisecond, _), + ) => compare_op( + left.as_any() + .downcast_ref::() + .unwrap(), + right + .as_any() + .downcast_ref::() + .unwrap(), + |a, b| a == b, + ), + ( + DataType::Timestamp(TimeUnit::Second, _), + DataType::Timestamp(TimeUnit::Second, _), + ) => compare_op( + left.as_any() + .downcast_ref::() + .unwrap(), + right + .as_any() + .downcast_ref::() + .unwrap(), + |a, b| a == b, + ), + (DataType::Date32, DataType::Date32) => compare_op( + left.as_any().downcast_ref::().unwrap(), + right.as_any().downcast_ref::().unwrap(), + |a, b| a == b, + ), + (DataType::Date64, DataType::Date64) => compare_op( + left.as_any().downcast_ref::().unwrap(), + right.as_any().downcast_ref::().unwrap(), + |a, b| a == b, + ), + ( + DataType::Interval(IntervalUnit::YearMonth), + DataType::Interval(IntervalUnit::YearMonth), + ) => compare_op( + left.as_any() + .downcast_ref::() + .unwrap(), + right + .as_any() + .downcast_ref::() + .unwrap(), + |a, b| a == b, + ), + ( + DataType::Interval(IntervalUnit::DayTime), + DataType::Interval(IntervalUnit::DayTime), + ) => compare_op( + left.as_any() + .downcast_ref::() + .unwrap(), + right + .as_any() + .downcast_ref::() + .unwrap(), + |a, b| a == b, + ), + ( + DataType::Interval(IntervalUnit::MonthDayNano), + DataType::Interval(IntervalUnit::MonthDayNano), + ) => compare_op( + left.as_any() + .downcast_ref::() + .unwrap(), + right + .as_any() + .downcast_ref::() + .unwrap(), + |a, b| a == b, + ), + (t1, t2) if t1 == t2 => Err(ArrowError::NotYetImplemented(format!( + "Comparing arrays of type {} is not yet implemented", + t1 + ))), + (t1, t2) => Err(ArrowError::CastError(format!( + "Cannot compare two arrays of different types ({} and {})", + t1, t2 + ))), + } +} + macro_rules! typed_compares { ($LEFT: expr, $RIGHT: expr, $OP_BOOL: ident, $OP_PRIM: ident, $OP_STR: ident, $OP_BINARY: ident) => {{ match ($LEFT.data_type(), $RIGHT.data_type()) { @@ -2410,7 +2473,7 @@ pub fn eq_dyn(left: &dyn Array, right: &dyn Array) -> Result { DataType::Dictionary(_, _) => { typed_dict_compares!(left, right, |a, b| a == b, |a, b| a == b) } - _ => typed_compares!(left, right, eq_bool, eq, eq_utf8, eq_binary), + _ => eq_typed_compares(left, right), } } @@ -2543,7 +2606,7 @@ where #[cfg(feature = "simd")] return simd_compare_op(left, right, T::eq, |a, b| a == b); #[cfg(not(feature = "simd"))] - return compare_op!(left, right, |a, b| a == b); + return compare_op(left, right, |a, b| a == b); } /// Perform `left == right` operation on a [`PrimitiveArray`] and a scalar value. @@ -2554,7 +2617,7 @@ where #[cfg(feature = "simd")] return simd_compare_op_scalar(left, right, T::eq, |a, b| a == b); #[cfg(not(feature = "simd"))] - return compare_op_scalar!(left, |a| a == right); + return compare_op_scalar(left, |a| a == right); } /// Applies an unary and infallible comparison function to a primitive array. @@ -2563,7 +2626,7 @@ where T: ArrowNumericType, F: Fn(T::Native) -> bool, { - return compare_op_scalar!(left, op); + return compare_op_scalar(left, op); } /// Perform `left != right` operation on two [`PrimitiveArray`]s. @@ -2574,7 +2637,7 @@ where #[cfg(feature = "simd")] return simd_compare_op(left, right, T::ne, |a, b| a != b); #[cfg(not(feature = "simd"))] - return compare_op!(left, right, |a, b| a != b); + return compare_op(left, right, |a, b| a != b); } /// Perform `left != right` operation on a [`PrimitiveArray`] and a scalar value. @@ -2585,7 +2648,7 @@ where #[cfg(feature = "simd")] return simd_compare_op_scalar(left, right, T::ne, |a, b| a != b); #[cfg(not(feature = "simd"))] - return compare_op_scalar!(left, |a| a != right); + return compare_op_scalar(left, |a| a != right); } /// Perform `left < right` operation on two [`PrimitiveArray`]s. Null values are less than non-null @@ -2597,7 +2660,7 @@ where #[cfg(feature = "simd")] return simd_compare_op(left, right, T::lt, |a, b| a < b); #[cfg(not(feature = "simd"))] - return compare_op!(left, right, |a, b| a < b); + return compare_op(left, right, |a, b| a < b); } /// Perform `left < right` operation on a [`PrimitiveArray`] and a scalar value. @@ -2609,7 +2672,7 @@ where #[cfg(feature = "simd")] return simd_compare_op_scalar(left, right, T::lt, |a, b| a < b); #[cfg(not(feature = "simd"))] - return compare_op_scalar!(left, |a| a < right); + return compare_op_scalar(left, |a| a < right); } /// Perform `left <= right` operation on two [`PrimitiveArray`]s. Null values are less than non-null @@ -2624,7 +2687,7 @@ where #[cfg(feature = "simd")] return simd_compare_op(left, right, T::le, |a, b| a <= b); #[cfg(not(feature = "simd"))] - return compare_op!(left, right, |a, b| a <= b); + return compare_op(left, right, |a, b| a <= b); } /// Perform `left <= right` operation on a [`PrimitiveArray`] and a scalar value. @@ -2636,7 +2699,7 @@ where #[cfg(feature = "simd")] return simd_compare_op_scalar(left, right, T::le, |a, b| a <= b); #[cfg(not(feature = "simd"))] - return compare_op_scalar!(left, |a| a <= right); + return compare_op_scalar(left, |a| a <= right); } /// Perform `left > right` operation on two [`PrimitiveArray`]s. Non-null values are greater than null @@ -2648,7 +2711,7 @@ where #[cfg(feature = "simd")] return simd_compare_op(left, right, T::gt, |a, b| a > b); #[cfg(not(feature = "simd"))] - return compare_op!(left, right, |a, b| a > b); + return compare_op(left, right, |a, b| a > b); } /// Perform `left > right` operation on a [`PrimitiveArray`] and a scalar value. @@ -2660,7 +2723,7 @@ where #[cfg(feature = "simd")] return simd_compare_op_scalar(left, right, T::gt, |a, b| a > b); #[cfg(not(feature = "simd"))] - return compare_op_scalar!(left, |a| a > right); + return compare_op_scalar(left, |a| a > right); } /// Perform `left >= right` operation on two [`PrimitiveArray`]s. Non-null values are greater than null @@ -2675,7 +2738,7 @@ where #[cfg(feature = "simd")] return simd_compare_op(left, right, T::ge, |a, b| a >= b); #[cfg(not(feature = "simd"))] - return compare_op!(left, right, |a, b| a >= b); + return compare_op(left, right, |a, b| a >= b); } /// Perform `left >= right` operation on a [`PrimitiveArray`] and a scalar value. @@ -2687,7 +2750,7 @@ where #[cfg(feature = "simd")] return simd_compare_op_scalar(left, right, T::ge, |a, b| a >= b); #[cfg(not(feature = "simd"))] - return compare_op_scalar!(left, |a| a >= right); + return compare_op_scalar(left, |a| a >= right); } /// Checks if a [`GenericListArray`] contains a value in the [`PrimitiveArray`] From aad1bb928a73c8d2c8c1670410870f2c50ba0a16 Mon Sep 17 00:00:00 2001 From: Liang-Chi Hsieh Date: Sun, 24 Jul 2022 23:18:44 -0700 Subject: [PATCH 2/3] More --- arrow/src/compute/kernels/comparison.rs | 368 ++++-------------------- 1 file changed, 54 insertions(+), 314 deletions(-) diff --git a/arrow/src/compute/kernels/comparison.rs b/arrow/src/compute/kernels/comparison.rs index a95c849e8eb..a5d88fb4d02 100644 --- a/arrow/src/compute/kernels/comparison.rs +++ b/arrow/src/compute/kernels/comparison.rs @@ -36,7 +36,6 @@ use crate::datatypes::{ use crate::error::{ArrowError, Result}; use crate::util::bit_util; use regex::{escape, Regex}; -use std::any::type_name; use std::collections::HashMap; /// Helper function to perform boolean lambda function on values from two array accessors, this @@ -1805,366 +1804,107 @@ where Ok(BooleanArray::from(data)) } -macro_rules! typed_cmp { - ($LEFT: expr, $RIGHT: expr, $T: ident, $OP: ident) => {{ - let left = $LEFT.as_any().downcast_ref::<$T>().ok_or_else(|| { - ArrowError::CastError(format!( - "Left array cannot be cast to {}", - type_name::<$T>() - )) - })?; - let right = $RIGHT.as_any().downcast_ref::<$T>().ok_or_else(|| { - ArrowError::CastError(format!( - "Right array cannot be cast to {}", - type_name::<$T>(), - )) - })?; - $OP(left, right) - }}; - ($LEFT: expr, $RIGHT: expr, $T: ident, $OP: ident, $TT: tt) => {{ - let left = $LEFT.as_any().downcast_ref::<$T>().ok_or_else(|| { - ArrowError::CastError(format!( - "Left array cannot be cast to {}", - type_name::<$T>() - )) - })?; - let right = $RIGHT.as_any().downcast_ref::<$T>().ok_or_else(|| { - ArrowError::CastError(format!( - "Right array cannot be cast to {}", - type_name::<$T>(), - )) - })?; - $OP::<$TT>(left, right) - }}; -} - -fn eq_typed_compares(left: &dyn Array, right: &dyn Array) -> Result { - match (left.data_type(), left.data_type()) { - (DataType::Boolean, DataType::Boolean) => compare_op( - left.as_any().downcast_ref::().unwrap(), - right.as_any().downcast_ref::().unwrap(), - |a, b| !(a ^ b), - ), - (DataType::Int8, DataType::Int8) => compare_op( - left.as_any().downcast_ref::().unwrap(), - right.as_any().downcast_ref::().unwrap(), - |a, b| a == b, - ), - (DataType::Int16, DataType::Int16) => compare_op( - left.as_any().downcast_ref::().unwrap(), - right.as_any().downcast_ref::().unwrap(), - |a, b| a == b, - ), - (DataType::Int32, DataType::Int32) => compare_op( - left.as_any().downcast_ref::().unwrap(), - right.as_any().downcast_ref::().unwrap(), - |a, b| a == b, - ), - (DataType::Int64, DataType::Int64) => compare_op( - left.as_any().downcast_ref::().unwrap(), - right.as_any().downcast_ref::().unwrap(), - |a, b| a == b, - ), - (DataType::UInt8, DataType::UInt8) => compare_op( - left.as_any().downcast_ref::().unwrap(), - right.as_any().downcast_ref::().unwrap(), - |a, b| a == b, - ), - (DataType::UInt16, DataType::UInt16) => compare_op( - left.as_any().downcast_ref::().unwrap(), - right.as_any().downcast_ref::().unwrap(), - |a, b| a == b, - ), - (DataType::UInt32, DataType::UInt32) => compare_op( - left.as_any().downcast_ref::().unwrap(), - right.as_any().downcast_ref::().unwrap(), - |a, b| a == b, - ), - (DataType::UInt64, DataType::UInt64) => compare_op( - left.as_any().downcast_ref::().unwrap(), - right.as_any().downcast_ref::().unwrap(), - |a, b| a == b, - ), - (DataType::Float32, DataType::Float32) => compare_op( - left.as_any().downcast_ref::().unwrap(), - right.as_any().downcast_ref::().unwrap(), - |a, b| a == b, - ), - (DataType::Float64, DataType::Float64) => compare_op( - left.as_any().downcast_ref::().unwrap(), - right.as_any().downcast_ref::().unwrap(), - |a, b| a == b, - ), - (DataType::Utf8, DataType::Utf8) => compare_op( - left.as_any().downcast_ref::().unwrap(), - right.as_any().downcast_ref::().unwrap(), - |a, b| a == b, - ), - (DataType::LargeUtf8, DataType::LargeUtf8) => compare_op( - left.as_any().downcast_ref::().unwrap(), - right.as_any().downcast_ref::().unwrap(), - |a, b| a == b, - ), - (DataType::Binary, DataType::Binary) => compare_op( - left.as_any().downcast_ref::().unwrap(), - right.as_any().downcast_ref::().unwrap(), - |a, b| a == b, - ), - (DataType::LargeBinary, DataType::LargeBinary) => compare_op( - left.as_any().downcast_ref::().unwrap(), - right.as_any().downcast_ref::().unwrap(), - |a, b| a == b, - ), - ( - DataType::Timestamp(TimeUnit::Nanosecond, _), - DataType::Timestamp(TimeUnit::Nanosecond, _), - ) => compare_op( - left.as_any() - .downcast_ref::() - .unwrap(), - right - .as_any() - .downcast_ref::() - .unwrap(), - |a, b| a == b, - ), - ( - DataType::Timestamp(TimeUnit::Microsecond, _), - DataType::Timestamp(TimeUnit::Microsecond, _), - ) => compare_op( - left.as_any() - .downcast_ref::() - .unwrap(), - right - .as_any() - .downcast_ref::() - .unwrap(), - |a, b| a == b, - ), - ( - DataType::Timestamp(TimeUnit::Millisecond, _), - DataType::Timestamp(TimeUnit::Millisecond, _), - ) => compare_op( - left.as_any() - .downcast_ref::() - .unwrap(), - right - .as_any() - .downcast_ref::() - .unwrap(), - |a, b| a == b, - ), - ( - DataType::Timestamp(TimeUnit::Second, _), - DataType::Timestamp(TimeUnit::Second, _), - ) => compare_op( - left.as_any() - .downcast_ref::() - .unwrap(), - right - .as_any() - .downcast_ref::() - .unwrap(), - |a, b| a == b, - ), - (DataType::Date32, DataType::Date32) => compare_op( - left.as_any().downcast_ref::().unwrap(), - right.as_any().downcast_ref::().unwrap(), - |a, b| a == b, - ), - (DataType::Date64, DataType::Date64) => compare_op( - left.as_any().downcast_ref::().unwrap(), - right.as_any().downcast_ref::().unwrap(), - |a, b| a == b, - ), - ( - DataType::Interval(IntervalUnit::YearMonth), - DataType::Interval(IntervalUnit::YearMonth), - ) => compare_op( - left.as_any() - .downcast_ref::() - .unwrap(), - right - .as_any() - .downcast_ref::() - .unwrap(), - |a, b| a == b, - ), - ( - DataType::Interval(IntervalUnit::DayTime), - DataType::Interval(IntervalUnit::DayTime), - ) => compare_op( - left.as_any() - .downcast_ref::() - .unwrap(), - right - .as_any() - .downcast_ref::() - .unwrap(), - |a, b| a == b, - ), - ( - DataType::Interval(IntervalUnit::MonthDayNano), - DataType::Interval(IntervalUnit::MonthDayNano), - ) => compare_op( - left.as_any() - .downcast_ref::() - .unwrap(), - right - .as_any() - .downcast_ref::() - .unwrap(), - |a, b| a == b, - ), - (t1, t2) if t1 == t2 => Err(ArrowError::NotYetImplemented(format!( - "Comparing arrays of type {} is not yet implemented", - t1 - ))), - (t1, t2) => Err(ArrowError::CastError(format!( - "Cannot compare two arrays of different types ({} and {})", - t1, t2 - ))), - } +fn cmp_primitive_array( + left: &dyn Array, + right: &dyn Array, + op: F, +) -> Result +where + F: Fn(T::Native, T::Native) -> bool, +{ + let left_array = as_primitive_array::(left); + let right_array = as_primitive_array::(right); + compare_op(left_array, right_array, op) } macro_rules! typed_compares { - ($LEFT: expr, $RIGHT: expr, $OP_BOOL: ident, $OP_PRIM: ident, $OP_STR: ident, $OP_BINARY: ident) => {{ + ($LEFT: expr, $RIGHT: expr, $OP_BOOL: expr, $OP: expr) => {{ match ($LEFT.data_type(), $RIGHT.data_type()) { (DataType::Boolean, DataType::Boolean) => { - typed_cmp!($LEFT, $RIGHT, BooleanArray, $OP_BOOL) + compare_op(as_boolean_array($LEFT), as_boolean_array($RIGHT), $OP_BOOL) } (DataType::Int8, DataType::Int8) => { - typed_cmp!($LEFT, $RIGHT, Int8Array, $OP_PRIM, Int8Type) + cmp_primitive_array::($LEFT, $RIGHT, $OP) } (DataType::Int16, DataType::Int16) => { - typed_cmp!($LEFT, $RIGHT, Int16Array, $OP_PRIM, Int16Type) + cmp_primitive_array::($LEFT, $RIGHT, $OP) } (DataType::Int32, DataType::Int32) => { - typed_cmp!($LEFT, $RIGHT, Int32Array, $OP_PRIM, Int32Type) + cmp_primitive_array::($LEFT, $RIGHT, $OP) } (DataType::Int64, DataType::Int64) => { - typed_cmp!($LEFT, $RIGHT, Int64Array, $OP_PRIM, Int64Type) + cmp_primitive_array::($LEFT, $RIGHT, $OP) } (DataType::UInt8, DataType::UInt8) => { - typed_cmp!($LEFT, $RIGHT, UInt8Array, $OP_PRIM, UInt8Type) + cmp_primitive_array::($LEFT, $RIGHT, $OP) } (DataType::UInt16, DataType::UInt16) => { - typed_cmp!($LEFT, $RIGHT, UInt16Array, $OP_PRIM, UInt16Type) + cmp_primitive_array::($LEFT, $RIGHT, $OP) } (DataType::UInt32, DataType::UInt32) => { - typed_cmp!($LEFT, $RIGHT, UInt32Array, $OP_PRIM, UInt32Type) + cmp_primitive_array::($LEFT, $RIGHT, $OP) } (DataType::UInt64, DataType::UInt64) => { - typed_cmp!($LEFT, $RIGHT, UInt64Array, $OP_PRIM, UInt64Type) + cmp_primitive_array::($LEFT, $RIGHT, $OP) } (DataType::Float32, DataType::Float32) => { - typed_cmp!($LEFT, $RIGHT, Float32Array, $OP_PRIM, Float32Type) + cmp_primitive_array::($LEFT, $RIGHT, $OP) } (DataType::Float64, DataType::Float64) => { - typed_cmp!($LEFT, $RIGHT, Float64Array, $OP_PRIM, Float64Type) + cmp_primitive_array::($LEFT, $RIGHT, $OP) } (DataType::Utf8, DataType::Utf8) => { - typed_cmp!($LEFT, $RIGHT, StringArray, $OP_STR, i32) - } - (DataType::LargeUtf8, DataType::LargeUtf8) => { - typed_cmp!($LEFT, $RIGHT, LargeStringArray, $OP_STR, i64) - } - (DataType::Binary, DataType::Binary) => { - typed_cmp!($LEFT, $RIGHT, BinaryArray, $OP_BINARY, i32) - } - (DataType::LargeBinary, DataType::LargeBinary) => { - typed_cmp!($LEFT, $RIGHT, LargeBinaryArray, $OP_BINARY, i64) + compare_op(as_string_array($LEFT), as_string_array($RIGHT), $OP) } + (DataType::LargeUtf8, DataType::LargeUtf8) => compare_op( + as_largestring_array($LEFT), + as_largestring_array($RIGHT), + $OP, + ), + (DataType::Binary, DataType::Binary) => compare_op( + as_generic_binary_array::($LEFT), + as_generic_binary_array::($RIGHT), + $OP, + ), + (DataType::LargeBinary, DataType::LargeBinary) => compare_op( + as_generic_binary_array::($LEFT), + as_generic_binary_array::($RIGHT), + $OP, + ), ( DataType::Timestamp(TimeUnit::Nanosecond, _), DataType::Timestamp(TimeUnit::Nanosecond, _), - ) => { - typed_cmp!( - $LEFT, - $RIGHT, - TimestampNanosecondArray, - $OP_PRIM, - TimestampNanosecondType - ) - } + ) => cmp_primitive_array::($LEFT, $RIGHT, $OP), ( DataType::Timestamp(TimeUnit::Microsecond, _), DataType::Timestamp(TimeUnit::Microsecond, _), - ) => { - typed_cmp!( - $LEFT, - $RIGHT, - TimestampMicrosecondArray, - $OP_PRIM, - TimestampMicrosecondType - ) - } + ) => cmp_primitive_array::($LEFT, $RIGHT, $OP), ( DataType::Timestamp(TimeUnit::Millisecond, _), DataType::Timestamp(TimeUnit::Millisecond, _), - ) => { - typed_cmp!( - $LEFT, - $RIGHT, - TimestampMillisecondArray, - $OP_PRIM, - TimestampMillisecondType - ) - } + ) => cmp_primitive_array::($LEFT, $RIGHT, $OP), ( DataType::Timestamp(TimeUnit::Second, _), DataType::Timestamp(TimeUnit::Second, _), - ) => { - typed_cmp!( - $LEFT, - $RIGHT, - TimestampSecondArray, - $OP_PRIM, - TimestampSecondType - ) - } + ) => cmp_primitive_array::($LEFT, $RIGHT, $OP), (DataType::Date32, DataType::Date32) => { - typed_cmp!($LEFT, $RIGHT, Date32Array, $OP_PRIM, Date32Type) + cmp_primitive_array::($LEFT, $RIGHT, $OP) } (DataType::Date64, DataType::Date64) => { - typed_cmp!($LEFT, $RIGHT, Date64Array, $OP_PRIM, Date64Type) + cmp_primitive_array::($LEFT, $RIGHT, $OP) } ( DataType::Interval(IntervalUnit::YearMonth), DataType::Interval(IntervalUnit::YearMonth), - ) => { - typed_cmp!( - $LEFT, - $RIGHT, - IntervalYearMonthArray, - $OP_PRIM, - IntervalYearMonthType - ) - } + ) => cmp_primitive_array::($LEFT, $RIGHT, $OP), ( DataType::Interval(IntervalUnit::DayTime), DataType::Interval(IntervalUnit::DayTime), - ) => { - typed_cmp!( - $LEFT, - $RIGHT, - IntervalDayTimeArray, - $OP_PRIM, - IntervalDayTimeType - ) - } + ) => cmp_primitive_array::($LEFT, $RIGHT, $OP), ( DataType::Interval(IntervalUnit::MonthDayNano), DataType::Interval(IntervalUnit::MonthDayNano), - ) => { - typed_cmp!( - $LEFT, - $RIGHT, - IntervalMonthDayNanoArray, - $OP_PRIM, - IntervalMonthDayNanoType - ) - } + ) => cmp_primitive_array::($LEFT, $RIGHT, $OP), (t1, t2) if t1 == t2 => Err(ArrowError::NotYetImplemented(format!( "Comparing arrays of type {} is not yet implemented", t1 @@ -2473,7 +2213,7 @@ pub fn eq_dyn(left: &dyn Array, right: &dyn Array) -> Result { DataType::Dictionary(_, _) => { typed_dict_compares!(left, right, |a, b| a == b, |a, b| a == b) } - _ => eq_typed_compares(left, right), + _ => typed_compares!(left, right, |a, b| !(a ^ b), |a, b| a == b), } } @@ -2498,7 +2238,7 @@ pub fn neq_dyn(left: &dyn Array, right: &dyn Array) -> Result { DataType::Dictionary(_, _) => { typed_dict_compares!(left, right, |a, b| a != b, |a, b| a != b) } - _ => typed_compares!(left, right, neq_bool, neq, neq_utf8, neq_binary), + _ => typed_compares!(left, right, |a, b| (a ^ b), |a, b| a != b), } } @@ -2523,7 +2263,7 @@ pub fn lt_dyn(left: &dyn Array, right: &dyn Array) -> Result { DataType::Dictionary(_, _) => { typed_dict_compares!(left, right, |a, b| a < b, |a, b| a < b) } - _ => typed_compares!(left, right, lt_bool, lt, lt_utf8, lt_binary), + _ => typed_compares!(left, right, |a, b| ((!a) & b), |a, b| a < b), } } @@ -2547,7 +2287,7 @@ pub fn lt_eq_dyn(left: &dyn Array, right: &dyn Array) -> Result { DataType::Dictionary(_, _) => { typed_dict_compares!(left, right, |a, b| a <= b, |a, b| a <= b) } - _ => typed_compares!(left, right, lt_eq_bool, lt_eq, lt_eq_utf8, lt_eq_binary), + _ => typed_compares!(left, right, |a, b| !(a & (!b)), |a, b| a <= b), } } @@ -2571,7 +2311,7 @@ pub fn gt_dyn(left: &dyn Array, right: &dyn Array) -> Result { DataType::Dictionary(_, _) => { typed_dict_compares!(left, right, |a, b| a > b, |a, b| a > b) } - _ => typed_compares!(left, right, gt_bool, gt, gt_utf8, gt_binary), + _ => typed_compares!(left, right, |a, b| (a & (!b)), |a, b| a > b), } } @@ -2594,7 +2334,7 @@ pub fn gt_eq_dyn(left: &dyn Array, right: &dyn Array) -> Result { DataType::Dictionary(_, _) => { typed_dict_compares!(left, right, |a, b| a >= b, |a, b| a >= b) } - _ => typed_compares!(left, right, gt_eq_bool, gt_eq, gt_eq_utf8, gt_eq_binary), + _ => typed_compares!(left, right, |a, b| !((!a) & b), |a, b| a >= b), } } From a4426e75d7829dcc10f3f43d8d380c8e0112917d Mon Sep 17 00:00:00 2001 From: Liang-Chi Hsieh Date: Sun, 24 Jul 2022 23:40:45 -0700 Subject: [PATCH 3/3] Fix clippy --- arrow/src/compute/kernels/comparison.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arrow/src/compute/kernels/comparison.rs b/arrow/src/compute/kernels/comparison.rs index a5d88fb4d02..7733ce67a76 100644 --- a/arrow/src/compute/kernels/comparison.rs +++ b/arrow/src/compute/kernels/comparison.rs @@ -2366,7 +2366,7 @@ where T: ArrowNumericType, F: Fn(T::Native) -> bool, { - return compare_op_scalar(left, op); + compare_op_scalar(left, op) } /// Perform `left != right` operation on two [`PrimitiveArray`]s.