vortex_compute/comparison/
binaryview_scalar.rs

1// SPDX-License-Identifier: Apache-2.0
2// SPDX-FileCopyrightText: Copyright the Vortex contributors
3
4//! Compare implementations for BinaryViewScalar.
5
6use vortex_vector::binaryview::BinaryViewScalar;
7use vortex_vector::binaryview::BinaryViewType;
8use vortex_vector::bool::BoolScalar;
9
10use crate::comparison::Compare;
11use crate::comparison::Equal;
12use crate::comparison::GreaterThan;
13use crate::comparison::GreaterThanOrEqual;
14use crate::comparison::LessThan;
15use crate::comparison::LessThanOrEqual;
16use crate::comparison::NotEqual;
17
18/// Compare two BinaryViewScalars using the provided comparison function.
19fn compare_binaryview_scalar<T: BinaryViewType, F>(
20    lhs: BinaryViewScalar<T>,
21    rhs: BinaryViewScalar<T>,
22    cmp: F,
23) -> BoolScalar
24where
25    F: Fn(&[u8], &[u8]) -> bool,
26{
27    match (lhs.value(), rhs.value()) {
28        (Some(l), Some(r)) => {
29            let l_bytes: &[u8] = AsRef::<T::Slice>::as_ref(l).as_ref();
30            let r_bytes: &[u8] = AsRef::<T::Slice>::as_ref(r).as_ref();
31            BoolScalar::new(Some(cmp(l_bytes, r_bytes)))
32        }
33        _ => BoolScalar::new(None),
34    }
35}
36
37impl<T: BinaryViewType> Compare<Equal> for BinaryViewScalar<T> {
38    type Output = BoolScalar;
39
40    fn compare(self, rhs: Self) -> Self::Output {
41        compare_binaryview_scalar(self, rhs, |l, r| l == r)
42    }
43}
44
45impl<T: BinaryViewType> Compare<NotEqual> for BinaryViewScalar<T> {
46    type Output = BoolScalar;
47
48    fn compare(self, rhs: Self) -> Self::Output {
49        compare_binaryview_scalar(self, rhs, |l, r| l != r)
50    }
51}
52
53impl<T: BinaryViewType> Compare<LessThan> for BinaryViewScalar<T> {
54    type Output = BoolScalar;
55
56    fn compare(self, rhs: Self) -> Self::Output {
57        compare_binaryview_scalar(self, rhs, |l, r| l < r)
58    }
59}
60
61impl<T: BinaryViewType> Compare<LessThanOrEqual> for BinaryViewScalar<T> {
62    type Output = BoolScalar;
63
64    fn compare(self, rhs: Self) -> Self::Output {
65        compare_binaryview_scalar(self, rhs, |l, r| l <= r)
66    }
67}
68
69impl<T: BinaryViewType> Compare<GreaterThan> for BinaryViewScalar<T> {
70    type Output = BoolScalar;
71
72    fn compare(self, rhs: Self) -> Self::Output {
73        compare_binaryview_scalar(self, rhs, |l, r| l > r)
74    }
75}
76
77impl<T: BinaryViewType> Compare<GreaterThanOrEqual> for BinaryViewScalar<T> {
78    type Output = BoolScalar;
79
80    fn compare(self, rhs: Self) -> Self::Output {
81        compare_binaryview_scalar(self, rhs, |l, r| l >= r)
82    }
83}
84
85#[cfg(test)]
86mod tests {
87    use vortex_buffer::BufferString;
88    use vortex_vector::binaryview::StringType;
89
90    use super::*;
91
92    #[test]
93    fn test_string_scalar_equal() {
94        let left = BinaryViewScalar::<StringType>::new(Some(BufferString::from("hello")));
95        let right = BinaryViewScalar::<StringType>::new(Some(BufferString::from("hello")));
96
97        assert_eq!(Compare::<Equal>::compare(left, right).value(), Some(true));
98    }
99
100    #[test]
101    fn test_string_scalar_not_equal() {
102        let left = BinaryViewScalar::<StringType>::new(Some(BufferString::from("hello")));
103        let right = BinaryViewScalar::<StringType>::new(Some(BufferString::from("world")));
104
105        assert_eq!(
106            Compare::<NotEqual>::compare(left, right).value(),
107            Some(true)
108        );
109    }
110
111    #[test]
112    fn test_string_scalar_less_than() {
113        let left = BinaryViewScalar::<StringType>::new(Some(BufferString::from("apple")));
114        let right = BinaryViewScalar::<StringType>::new(Some(BufferString::from("banana")));
115
116        assert_eq!(
117            Compare::<LessThan>::compare(left, right).value(),
118            Some(true)
119        );
120    }
121
122    #[test]
123    fn test_string_scalar_with_null() {
124        let left = BinaryViewScalar::<StringType>::new(Some(BufferString::from("hello")));
125        let right = BinaryViewScalar::<StringType>::new(None);
126
127        assert_eq!(Compare::<Equal>::compare(left, right).value(), None);
128    }
129}