diff --git a/src/compute/comparison/mod.rs b/src/compute/comparison/mod.rs index 95ee88a17a9..f194d9f6775 100644 --- a/src/compute/comparison/mod.rs +++ b/src/compute/comparison/mod.rs @@ -297,12 +297,12 @@ macro_rules! compare_scalar { Utf8 => { let lhs = lhs.as_any().downcast_ref().unwrap(); let rhs = rhs.as_any().downcast_ref::>().unwrap(); - utf8::$op::(lhs, rhs.value()) + utf8::$op::(lhs, rhs.value().unwrap()) } LargeUtf8 => { let lhs = lhs.as_any().downcast_ref().unwrap(); let rhs = rhs.as_any().downcast_ref::>().unwrap(); - utf8::$op::(lhs, rhs.value()) + utf8::$op::(lhs, rhs.value().unwrap()) } Decimal(_, _) => { let lhs = lhs.as_any().downcast_ref().unwrap(); @@ -315,12 +315,12 @@ macro_rules! compare_scalar { Binary => { let lhs = lhs.as_any().downcast_ref().unwrap(); let rhs = rhs.as_any().downcast_ref::>().unwrap(); - binary::$op::(lhs, rhs.value()) + binary::$op::(lhs, rhs.value().unwrap()) } LargeBinary => { let lhs = lhs.as_any().downcast_ref().unwrap(); let rhs = rhs.as_any().downcast_ref::>().unwrap(); - binary::$op::(lhs, rhs.value()) + binary::$op::(lhs, rhs.value().unwrap()) } _ => todo!("Comparisons of {:?} are not yet supported", data_type), } diff --git a/src/scalar/binary.rs b/src/scalar/binary.rs index c5e1a40b978..7f0d61e025a 100644 --- a/src/scalar/binary.rs +++ b/src/scalar/binary.rs @@ -1,43 +1,32 @@ -use crate::{array::*, buffer::Buffer, datatypes::DataType}; +use crate::{array::*, datatypes::DataType}; use super::Scalar; -/// The [`Scalar`] implementation of binary (`Vec`). -#[derive(Debug, Clone)] +/// The [`Scalar`] implementation of binary ([`Option>`]). +#[derive(Debug, Clone, PartialEq)] pub struct BinaryScalar { - value: Buffer, - is_valid: bool, + value: Option>, phantom: std::marker::PhantomData, } -impl PartialEq for BinaryScalar { - fn eq(&self, other: &Self) -> bool { - self.is_valid == other.is_valid && ((!self.is_valid) | (self.value == other.value)) - } -} - impl BinaryScalar { /// Returns a new [`BinaryScalar`]. #[inline] - pub fn new>(v: Option

) -> Self { - let is_valid = v.is_some(); - O::from_usize(v.as_ref().map(|x| x.as_ref().len()).unwrap_or_default()).expect("Too large"); - let value = Buffer::from(v.as_ref().map(|x| x.as_ref()).unwrap_or(&[])); + pub fn new>>(value: Option

) -> Self { Self { - value, - is_valid, + value: value.map(|x| x.into()), phantom: std::marker::PhantomData, } } /// Its value #[inline] - pub fn value(&self) -> &[u8] { - self.value.as_slice() + pub fn value(&self) -> Option<&[u8]> { + self.value.as_ref().map(|x| x.as_ref()) } } -impl> From> for BinaryScalar { +impl>> From> for BinaryScalar { #[inline] fn from(v: Option

) -> Self { Self::new(v) @@ -52,7 +41,7 @@ impl Scalar for BinaryScalar { #[inline] fn is_valid(&self) -> bool { - self.is_valid + self.value.is_some() } #[inline] diff --git a/src/scalar/utf8.rs b/src/scalar/utf8.rs index 60417cb7813..66267127859 100644 --- a/src/scalar/utf8.rs +++ b/src/scalar/utf8.rs @@ -1,44 +1,32 @@ -use crate::{array::*, buffer::Buffer, datatypes::DataType}; +use crate::{array::*, datatypes::DataType}; use super::Scalar; -/// The implementation of [`Scalar`] for utf8, semantically equivalent to [`Option<&str>`]. -#[derive(Debug, Clone)] +/// The implementation of [`Scalar`] for utf8, semantically equivalent to [`Option`]. +#[derive(Debug, Clone, PartialEq)] pub struct Utf8Scalar { - value: Buffer, // safety: valid utf8 - is_valid: bool, + value: Option, phantom: std::marker::PhantomData, } -impl PartialEq for Utf8Scalar { - fn eq(&self, other: &Self) -> bool { - self.is_valid == other.is_valid && ((!self.is_valid) | (self.value == other.value)) - } -} - impl Utf8Scalar { /// Returns a new [`Utf8Scalar`] #[inline] - pub fn new>(v: Option

) -> Self { - let is_valid = v.is_some(); - O::from_usize(v.as_ref().map(|x| x.as_ref().len()).unwrap_or_default()).expect("Too large"); - let value = Buffer::from(v.as_ref().map(|x| x.as_ref().as_bytes()).unwrap_or(&[])); + pub fn new>(value: Option

) -> Self { Self { - value, - is_valid, + value: value.map(|x| x.into()), phantom: std::marker::PhantomData, } } /// Returns the value irrespectively of the validity. #[inline] - pub fn value(&self) -> &str { - // Safety: invariant of the struct - unsafe { std::str::from_utf8_unchecked(self.value.as_slice()) } + pub fn value(&self) -> Option<&str> { + self.value.as_ref().map(|x| x.as_ref()) } } -impl> From> for Utf8Scalar { +impl> From> for Utf8Scalar { #[inline] fn from(v: Option

) -> Self { Self::new(v) @@ -53,7 +41,7 @@ impl Scalar for Utf8Scalar { #[inline] fn is_valid(&self) -> bool { - self.is_valid + self.value.is_some() } #[inline] diff --git a/tests/it/scalar/binary.rs b/tests/it/scalar/binary.rs index 5abaf7a3a7a..ee71b20ba5b 100644 --- a/tests/it/scalar/binary.rs +++ b/tests/it/scalar/binary.rs @@ -20,7 +20,7 @@ fn equal() { fn basics() { let a = BinaryScalar::::from(Some("a")); - assert_eq!(a.value(), b"a"); + assert_eq!(a.value(), Some(b"a".as_ref())); assert_eq!(a.data_type(), &DataType::Binary); assert!(a.is_valid()); diff --git a/tests/it/scalar/utf8.rs b/tests/it/scalar/utf8.rs index edd95c6e24b..6c844e01f0d 100644 --- a/tests/it/scalar/utf8.rs +++ b/tests/it/scalar/utf8.rs @@ -20,7 +20,7 @@ fn equal() { fn basics() { let a = Utf8Scalar::::from(Some("a")); - assert_eq!(a.value(), "a"); + assert_eq!(a.value(), Some("a")); assert_eq!(a.data_type(), &DataType::Utf8); assert!(a.is_valid());