use crate::array::PrimitiveArray;
use crate::bitmap::Bitmap;
use crate::compute::comparison::{
primitive_compare_values_op, primitive_compare_values_op_scalar, Simd8, Simd8PartialEq,
};
use crate::datatypes::DataType;
use crate::scalar::PrimitiveScalar;
use crate::scalar::Scalar;
use crate::{array::Array, types::NativeType};
use super::utils::combine_validities;
pub fn primitive_nullif<T>(lhs: &PrimitiveArray<T>, rhs: &PrimitiveArray<T>) -> PrimitiveArray<T>
where
T: NativeType + Simd8,
T::Simd: Simd8PartialEq,
{
let equal = primitive_compare_values_op(lhs.values(), rhs.values(), |lhs, rhs| lhs.neq(rhs));
let equal: Option<Bitmap> = equal.into();
let validity = combine_validities(lhs.validity(), equal.as_ref());
PrimitiveArray::<T>::from_data(lhs.data_type().clone(), lhs.values().clone(), validity)
}
pub fn primitive_nullif_scalar<T>(lhs: &PrimitiveArray<T>, rhs: T) -> PrimitiveArray<T>
where
T: NativeType + Simd8,
T::Simd: Simd8PartialEq,
{
let equal = primitive_compare_values_op_scalar(lhs.values(), rhs, |lhs, rhs| lhs.neq(rhs));
let equal: Option<Bitmap> = equal.into();
let validity = combine_validities(lhs.validity(), equal.as_ref());
PrimitiveArray::<T>::from_data(lhs.data_type().clone(), lhs.values().clone(), validity)
}
pub fn nullif(lhs: &dyn Array, rhs: &dyn Array) -> Box<dyn Array> {
assert_eq!(lhs.data_type(), rhs.data_type());
assert_eq!(lhs.len(), rhs.len());
use crate::datatypes::PhysicalType::*;
match lhs.data_type().to_physical_type() {
Primitive(primitive) => with_match_primitive_type!(primitive, |$T| {
Box::new(primitive_nullif::<$T>(
lhs.as_any().downcast_ref().unwrap(),
rhs.as_any().downcast_ref().unwrap(),
))
}),
other => unimplemented!("Nullif is not implemented for physical type {:?}", other),
}
}
pub fn nullif_scalar(lhs: &dyn Array, rhs: &dyn Scalar) -> Box<dyn Array> {
assert_eq!(lhs.data_type(), rhs.data_type());
use crate::datatypes::PhysicalType::*;
match lhs.data_type().to_physical_type() {
Primitive(primitive) => with_match_primitive_type!(primitive, |$T| {
let scalar = rhs.as_any().downcast_ref::<PrimitiveScalar<$T>>().unwrap();
let scalar = scalar.value().expect("Scalar to be non-null");
Box::new(primitive_nullif_scalar::<$T>(
lhs.as_any().downcast_ref().unwrap(),
scalar,
))
}),
other => unimplemented!("Nullif is not implemented for physical type {:?}", other),
}
}
pub fn can_nullif(lhs: &DataType, rhs: &DataType) -> bool {
if lhs != rhs {
return false;
};
use crate::datatypes::PhysicalType;
matches!(lhs.to_physical_type(), PhysicalType::Primitive(_))
}