datafusion_expr_common/
interval_arithmetic.rs

1// Licensed to the Apache Software Foundation (ASF) under one
2// or more contributor license agreements.  See the NOTICE file
3// distributed with this work for additional information
4// regarding copyright ownership.  The ASF licenses this file
5// to you under the Apache License, Version 2.0 (the
6// "License"); you may not use this file except in compliance
7// with the License.  You may obtain a copy of the License at
8//
9//   http://www.apache.org/licenses/LICENSE-2.0
10//
11// Unless required by applicable law or agreed to in writing,
12// software distributed under the License is distributed on an
13// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14// KIND, either express or implied.  See the License for the
15// specific language governing permissions and limitations
16// under the License.
17
18//! Interval arithmetic library
19
20use std::borrow::Borrow;
21use std::fmt::{self, Display, Formatter};
22use std::ops::{AddAssign, SubAssign};
23
24use crate::operator::Operator;
25use crate::type_coercion::binary::{comparison_coercion_numeric, BinaryTypeCoercer};
26
27use arrow::compute::{cast_with_options, CastOptions};
28use arrow::datatypes::{
29    DataType, IntervalDayTime, IntervalMonthDayNano, IntervalUnit, TimeUnit,
30    MAX_DECIMAL128_FOR_EACH_PRECISION, MAX_DECIMAL256_FOR_EACH_PRECISION,
31    MIN_DECIMAL128_FOR_EACH_PRECISION, MIN_DECIMAL256_FOR_EACH_PRECISION,
32};
33use datafusion_common::rounding::{alter_fp_rounding_mode, next_down, next_up};
34use datafusion_common::{internal_err, Result, ScalarValue};
35
36macro_rules! get_extreme_value {
37    ($extreme:ident, $value:expr) => {
38        match $value {
39            DataType::UInt8 => ScalarValue::UInt8(Some(u8::$extreme)),
40            DataType::UInt16 => ScalarValue::UInt16(Some(u16::$extreme)),
41            DataType::UInt32 => ScalarValue::UInt32(Some(u32::$extreme)),
42            DataType::UInt64 => ScalarValue::UInt64(Some(u64::$extreme)),
43            DataType::Int8 => ScalarValue::Int8(Some(i8::$extreme)),
44            DataType::Int16 => ScalarValue::Int16(Some(i16::$extreme)),
45            DataType::Int32 => ScalarValue::Int32(Some(i32::$extreme)),
46            DataType::Int64 => ScalarValue::Int64(Some(i64::$extreme)),
47            DataType::Float32 => ScalarValue::Float32(Some(f32::$extreme)),
48            DataType::Float64 => ScalarValue::Float64(Some(f64::$extreme)),
49            DataType::Duration(TimeUnit::Second) => {
50                ScalarValue::DurationSecond(Some(i64::$extreme))
51            }
52            DataType::Duration(TimeUnit::Millisecond) => {
53                ScalarValue::DurationMillisecond(Some(i64::$extreme))
54            }
55            DataType::Duration(TimeUnit::Microsecond) => {
56                ScalarValue::DurationMicrosecond(Some(i64::$extreme))
57            }
58            DataType::Duration(TimeUnit::Nanosecond) => {
59                ScalarValue::DurationNanosecond(Some(i64::$extreme))
60            }
61            DataType::Timestamp(TimeUnit::Second, _) => {
62                ScalarValue::TimestampSecond(Some(i64::$extreme), None)
63            }
64            DataType::Timestamp(TimeUnit::Millisecond, _) => {
65                ScalarValue::TimestampMillisecond(Some(i64::$extreme), None)
66            }
67            DataType::Timestamp(TimeUnit::Microsecond, _) => {
68                ScalarValue::TimestampMicrosecond(Some(i64::$extreme), None)
69            }
70            DataType::Timestamp(TimeUnit::Nanosecond, _) => {
71                ScalarValue::TimestampNanosecond(Some(i64::$extreme), None)
72            }
73            DataType::Interval(IntervalUnit::YearMonth) => {
74                ScalarValue::IntervalYearMonth(Some(i32::$extreme))
75            }
76            DataType::Interval(IntervalUnit::DayTime) => {
77                ScalarValue::IntervalDayTime(Some(IntervalDayTime::$extreme))
78            }
79            DataType::Interval(IntervalUnit::MonthDayNano) => {
80                ScalarValue::IntervalMonthDayNano(Some(IntervalMonthDayNano::$extreme))
81            }
82            DataType::Decimal128(precision, scale) => ScalarValue::Decimal128(
83                Some(
84                    paste::paste! {[<$extreme _DECIMAL128_FOR_EACH_PRECISION>]}
85                        [*precision as usize],
86                ),
87                *precision,
88                *scale,
89            ),
90            DataType::Decimal256(precision, scale) => ScalarValue::Decimal256(
91                Some(
92                    paste::paste! {[<$extreme _DECIMAL256_FOR_EACH_PRECISION>]}
93                        [*precision as usize],
94                ),
95                *precision,
96                *scale,
97            ),
98            _ => unreachable!(),
99        }
100    };
101}
102
103macro_rules! value_transition {
104    ($bound:ident, $direction:expr, $value:expr) => {
105        match $value {
106            UInt8(Some(value)) if value == u8::$bound => UInt8(None),
107            UInt16(Some(value)) if value == u16::$bound => UInt16(None),
108            UInt32(Some(value)) if value == u32::$bound => UInt32(None),
109            UInt64(Some(value)) if value == u64::$bound => UInt64(None),
110            Int8(Some(value)) if value == i8::$bound => Int8(None),
111            Int16(Some(value)) if value == i16::$bound => Int16(None),
112            Int32(Some(value)) if value == i32::$bound => Int32(None),
113            Int64(Some(value)) if value == i64::$bound => Int64(None),
114            Float32(Some(value)) if value == f32::$bound => Float32(None),
115            Float64(Some(value)) if value == f64::$bound => Float64(None),
116            DurationSecond(Some(value)) if value == i64::$bound => DurationSecond(None),
117            DurationMillisecond(Some(value)) if value == i64::$bound => {
118                DurationMillisecond(None)
119            }
120            DurationMicrosecond(Some(value)) if value == i64::$bound => {
121                DurationMicrosecond(None)
122            }
123            DurationNanosecond(Some(value)) if value == i64::$bound => {
124                DurationNanosecond(None)
125            }
126            TimestampSecond(Some(value), tz) if value == i64::$bound => {
127                TimestampSecond(None, tz)
128            }
129            TimestampMillisecond(Some(value), tz) if value == i64::$bound => {
130                TimestampMillisecond(None, tz)
131            }
132            TimestampMicrosecond(Some(value), tz) if value == i64::$bound => {
133                TimestampMicrosecond(None, tz)
134            }
135            TimestampNanosecond(Some(value), tz) if value == i64::$bound => {
136                TimestampNanosecond(None, tz)
137            }
138            IntervalYearMonth(Some(value)) if value == i32::$bound => {
139                IntervalYearMonth(None)
140            }
141            IntervalDayTime(Some(value))
142                if value == arrow::datatypes::IntervalDayTime::$bound =>
143            {
144                IntervalDayTime(None)
145            }
146            IntervalMonthDayNano(Some(value))
147                if value == arrow::datatypes::IntervalMonthDayNano::$bound =>
148            {
149                IntervalMonthDayNano(None)
150            }
151            _ => next_value_helper::<$direction>($value),
152        }
153    };
154}
155
156/// The `Interval` type represents a closed interval used for computing
157/// reliable bounds for mathematical expressions.
158///
159/// Conventions:
160///
161/// 1. **Closed bounds**: The interval always encompasses its endpoints. We
162///    accommodate operations resulting in open intervals by incrementing or
163///    decrementing the interval endpoint value to its successor/predecessor.
164///
165/// 2. **Unbounded endpoints**: If the `lower` or `upper` bounds are indeterminate,
166///    they are labeled as *unbounded*. This is represented using a `NULL`.
167///
168/// 3. **Overflow handling**: If the `lower` or `upper` endpoints exceed their
169///    limits after any operation, they either become unbounded or they are fixed
170///    to the maximum/minimum value of the datatype, depending on the direction
171///    of the overflowing endpoint, opting for the safer choice.
172///
173/// 4. **Floating-point special cases**:
174///    - `INF` values are converted to `NULL`s while constructing an interval to
175///      ensure consistency, with other data types.
176///    - `NaN` (Not a Number) results are conservatively result in unbounded
177///      endpoints.
178#[derive(Debug, Clone, PartialEq, Eq)]
179pub struct Interval {
180    lower: ScalarValue,
181    upper: ScalarValue,
182}
183
184/// This macro handles the `NaN` and `INF` floating point values.
185///
186/// - `NaN` values are always converted to unbounded i.e. `NULL` values.
187/// - For lower bounds:
188///     - A `NEG_INF` value is converted to a `NULL`.
189///     - An `INF` value is conservatively converted to the maximum representable
190///       number for the floating-point type in question. In this case, converting
191///       to `NULL` doesn't make sense as it would be interpreted as a `NEG_INF`.
192/// - For upper bounds:
193///     - An `INF` value is converted to a `NULL`.
194///     - An `NEG_INF` value is conservatively converted to the minimum representable
195///       number for the floating-point type in question. In this case, converting
196///       to `NULL` doesn't make sense as it would be interpreted as an `INF`.
197macro_rules! handle_float_intervals {
198    ($scalar_type:ident, $primitive_type:ident, $lower:expr, $upper:expr) => {{
199        let lower = match $lower {
200            ScalarValue::$scalar_type(Some(l_val))
201                if l_val == $primitive_type::NEG_INFINITY || l_val.is_nan() =>
202            {
203                ScalarValue::$scalar_type(None)
204            }
205            ScalarValue::$scalar_type(Some(l_val))
206                if l_val == $primitive_type::INFINITY =>
207            {
208                ScalarValue::$scalar_type(Some($primitive_type::MAX))
209            }
210            value @ ScalarValue::$scalar_type(Some(_)) => value,
211            _ => ScalarValue::$scalar_type(None),
212        };
213
214        let upper = match $upper {
215            ScalarValue::$scalar_type(Some(r_val))
216                if r_val == $primitive_type::INFINITY || r_val.is_nan() =>
217            {
218                ScalarValue::$scalar_type(None)
219            }
220            ScalarValue::$scalar_type(Some(r_val))
221                if r_val == $primitive_type::NEG_INFINITY =>
222            {
223                ScalarValue::$scalar_type(Some($primitive_type::MIN))
224            }
225            value @ ScalarValue::$scalar_type(Some(_)) => value,
226            _ => ScalarValue::$scalar_type(None),
227        };
228
229        Interval { lower, upper }
230    }};
231}
232
233/// Ordering floating-point numbers according to their binary representations
234/// contradicts with their natural ordering. Floating-point number ordering
235/// after unsigned integer transmutation looks like:
236///
237/// ```text
238/// 0, 1, 2, 3, ..., MAX, -0, -1, -2, ..., -MAX
239/// ```
240///
241/// This macro applies a one-to-one map that fixes the ordering above.
242macro_rules! map_floating_point_order {
243    ($value:expr, $ty:ty) => {{
244        let num_bits = std::mem::size_of::<$ty>() * 8;
245        let sign_bit = 1 << (num_bits - 1);
246        if $value & sign_bit == sign_bit {
247            // Negative numbers:
248            !$value
249        } else {
250            // Positive numbers:
251            $value | sign_bit
252        }
253    }};
254}
255
256impl Interval {
257    /// Attempts to create a new `Interval` from the given lower and upper bounds.
258    ///
259    /// # Notes
260    ///
261    /// This constructor creates intervals in a "canonical" form where:
262    /// - **Boolean intervals**:
263    ///   - Unboundedness (`NULL`) for boolean endpoints is converted to `false`
264    ///     for lower and `true` for upper bounds.
265    /// - **Floating-point intervals**:
266    ///   - Floating-point endpoints with `NaN`, `INF`, or `NEG_INF` are converted
267    ///     to `NULL`s.
268    pub fn try_new(lower: ScalarValue, upper: ScalarValue) -> Result<Self> {
269        if lower.data_type() != upper.data_type() {
270            return internal_err!("Endpoints of an Interval should have the same type");
271        }
272
273        let interval = Self::new(lower, upper);
274
275        if interval.lower.is_null()
276            || interval.upper.is_null()
277            || interval.lower <= interval.upper
278        {
279            Ok(interval)
280        } else {
281            internal_err!(
282                "Interval's lower bound {} is greater than the upper bound {}",
283                interval.lower,
284                interval.upper
285            )
286        }
287    }
288
289    /// Only for internal usage. Responsible for standardizing booleans and
290    /// floating-point values, as well as fixing NaNs. It doesn't validate
291    /// the given bounds for ordering, or verify that they have the same data
292    /// type. For its user-facing counterpart and more details, see
293    /// [`Interval::try_new`].
294    fn new(lower: ScalarValue, upper: ScalarValue) -> Self {
295        if let ScalarValue::Boolean(lower_bool) = lower {
296            let ScalarValue::Boolean(upper_bool) = upper else {
297                // We are sure that upper and lower bounds have the same type.
298                unreachable!();
299            };
300            // Standardize boolean interval endpoints:
301            return Self {
302                lower: ScalarValue::Boolean(Some(lower_bool.unwrap_or(false))),
303                upper: ScalarValue::Boolean(Some(upper_bool.unwrap_or(true))),
304            };
305        }
306        match lower.data_type() {
307            // Standardize floating-point endpoints:
308            DataType::Float32 => handle_float_intervals!(Float32, f32, lower, upper),
309            DataType::Float64 => handle_float_intervals!(Float64, f64, lower, upper),
310            // Unsigned null values for lower bounds are set to zero:
311            DataType::UInt8 if lower.is_null() => Self {
312                lower: ScalarValue::UInt8(Some(0)),
313                upper,
314            },
315            DataType::UInt16 if lower.is_null() => Self {
316                lower: ScalarValue::UInt16(Some(0)),
317                upper,
318            },
319            DataType::UInt32 if lower.is_null() => Self {
320                lower: ScalarValue::UInt32(Some(0)),
321                upper,
322            },
323            DataType::UInt64 if lower.is_null() => Self {
324                lower: ScalarValue::UInt64(Some(0)),
325                upper,
326            },
327            // Other data types do not require standardization:
328            _ => Self { lower, upper },
329        }
330    }
331
332    /// Convenience function to create a new `Interval` from the given (optional)
333    /// bounds, for use in tests only. Absence of either endpoint indicates
334    /// unboundedness on that side. See [`Interval::try_new`] for more information.
335    pub fn make<T>(lower: Option<T>, upper: Option<T>) -> Result<Self>
336    where
337        ScalarValue: From<Option<T>>,
338    {
339        Self::try_new(ScalarValue::from(lower), ScalarValue::from(upper))
340    }
341
342    /// Creates a singleton zero interval if the datatype supported.
343    pub fn make_zero(data_type: &DataType) -> Result<Self> {
344        let zero_endpoint = ScalarValue::new_zero(data_type)?;
345        Ok(Self::new(zero_endpoint.clone(), zero_endpoint))
346    }
347
348    /// Creates an unbounded interval from both sides if the datatype supported.
349    pub fn make_unbounded(data_type: &DataType) -> Result<Self> {
350        let unbounded_endpoint = ScalarValue::try_from(data_type)?;
351        Ok(Self::new(unbounded_endpoint.clone(), unbounded_endpoint))
352    }
353
354    /// Creates an interval between -1 to 1.
355    pub fn make_symmetric_unit_interval(data_type: &DataType) -> Result<Self> {
356        Self::try_new(
357            ScalarValue::new_negative_one(data_type)?,
358            ScalarValue::new_one(data_type)?,
359        )
360    }
361
362    /// Create an interval from -π to π.
363    pub fn make_symmetric_pi_interval(data_type: &DataType) -> Result<Self> {
364        Self::try_new(
365            ScalarValue::new_negative_pi_lower(data_type)?,
366            ScalarValue::new_pi_upper(data_type)?,
367        )
368    }
369
370    /// Create an interval from -π/2 to π/2.
371    pub fn make_symmetric_half_pi_interval(data_type: &DataType) -> Result<Self> {
372        Self::try_new(
373            ScalarValue::new_neg_frac_pi_2_lower(data_type)?,
374            ScalarValue::new_frac_pi_2_upper(data_type)?,
375        )
376    }
377
378    /// Create an interval from 0 to infinity.
379    pub fn make_non_negative_infinity_interval(data_type: &DataType) -> Result<Self> {
380        Self::try_new(
381            ScalarValue::new_zero(data_type)?,
382            ScalarValue::try_from(data_type)?,
383        )
384    }
385
386    /// Returns a reference to the lower bound.
387    pub fn lower(&self) -> &ScalarValue {
388        &self.lower
389    }
390
391    /// Returns a reference to the upper bound.
392    pub fn upper(&self) -> &ScalarValue {
393        &self.upper
394    }
395
396    /// Converts this `Interval` into its boundary scalar values. It's useful
397    /// when you need to work with the individual bounds directly.
398    pub fn into_bounds(self) -> (ScalarValue, ScalarValue) {
399        (self.lower, self.upper)
400    }
401
402    /// This function returns the data type of this interval.
403    pub fn data_type(&self) -> DataType {
404        let lower_type = self.lower.data_type();
405        let upper_type = self.upper.data_type();
406
407        // There must be no way to create an interval whose endpoints have
408        // different types.
409        debug_assert!(
410            lower_type == upper_type,
411            "Interval bounds have different types: {lower_type} != {upper_type}"
412        );
413        lower_type
414    }
415
416    /// Checks if the interval is unbounded (on either side).
417    pub fn is_unbounded(&self) -> bool {
418        self.lower.is_null() || self.upper.is_null()
419    }
420
421    /// Casts this interval to `data_type` using `cast_options`.
422    pub fn cast_to(
423        &self,
424        data_type: &DataType,
425        cast_options: &CastOptions,
426    ) -> Result<Self> {
427        Self::try_new(
428            cast_scalar_value(&self.lower, data_type, cast_options)?,
429            cast_scalar_value(&self.upper, data_type, cast_options)?,
430        )
431    }
432
433    pub const CERTAINLY_FALSE: Self = Self {
434        lower: ScalarValue::Boolean(Some(false)),
435        upper: ScalarValue::Boolean(Some(false)),
436    };
437
438    pub const UNCERTAIN: Self = Self {
439        lower: ScalarValue::Boolean(Some(false)),
440        upper: ScalarValue::Boolean(Some(true)),
441    };
442
443    pub const CERTAINLY_TRUE: Self = Self {
444        lower: ScalarValue::Boolean(Some(true)),
445        upper: ScalarValue::Boolean(Some(true)),
446    };
447
448    /// Decide if this interval is certainly greater than, possibly greater than,
449    /// or can't be greater than `other` by returning `[true, true]`,
450    /// `[false, true]` or `[false, false]` respectively.
451    ///
452    /// NOTE: This function only works with intervals of the same data type.
453    ///       Attempting to compare intervals of different data types will lead
454    ///       to an error.
455    pub fn gt<T: Borrow<Self>>(&self, other: T) -> Result<Self> {
456        let rhs = other.borrow();
457        if self.data_type().ne(&rhs.data_type()) {
458            internal_err!(
459                "Only intervals with the same data type are comparable, lhs:{}, rhs:{}",
460                self.data_type(),
461                rhs.data_type()
462            )
463        } else if !(self.upper.is_null() || rhs.lower.is_null())
464            && self.upper <= rhs.lower
465        {
466            // Values in this interval are certainly less than or equal to
467            // those in the given interval.
468            Ok(Self::CERTAINLY_FALSE)
469        } else if !(self.lower.is_null() || rhs.upper.is_null())
470            && (self.lower > rhs.upper)
471        {
472            // Values in this interval are certainly greater than those in the
473            // given interval.
474            Ok(Self::CERTAINLY_TRUE)
475        } else {
476            // All outcomes are possible.
477            Ok(Self::UNCERTAIN)
478        }
479    }
480
481    /// Decide if this interval is certainly greater than or equal to, possibly
482    /// greater than or equal to, or can't be greater than or equal to `other`
483    /// by returning `[true, true]`, `[false, true]` or `[false, false]` respectively.
484    ///
485    /// NOTE: This function only works with intervals of the same data type.
486    ///       Attempting to compare intervals of different data types will lead
487    ///       to an error.
488    pub fn gt_eq<T: Borrow<Self>>(&self, other: T) -> Result<Self> {
489        let rhs = other.borrow();
490        if self.data_type().ne(&rhs.data_type()) {
491            internal_err!(
492                "Only intervals with the same data type are comparable, lhs:{}, rhs:{}",
493                self.data_type(),
494                rhs.data_type()
495            )
496        } else if !(self.lower.is_null() || rhs.upper.is_null())
497            && self.lower >= rhs.upper
498        {
499            // Values in this interval are certainly greater than or equal to
500            // those in the given interval.
501            Ok(Self::CERTAINLY_TRUE)
502        } else if !(self.upper.is_null() || rhs.lower.is_null())
503            && (self.upper < rhs.lower)
504        {
505            // Values in this interval are certainly less than those in the
506            // given interval.
507            Ok(Self::CERTAINLY_FALSE)
508        } else {
509            // All outcomes are possible.
510            Ok(Self::UNCERTAIN)
511        }
512    }
513
514    /// Decide if this interval is certainly less than, possibly less than, or
515    /// can't be less than `other` by returning `[true, true]`, `[false, true]`
516    /// or `[false, false]` respectively.
517    ///
518    /// NOTE: This function only works with intervals of the same data type.
519    ///       Attempting to compare intervals of different data types will lead
520    ///       to an error.
521    pub fn lt<T: Borrow<Self>>(&self, other: T) -> Result<Self> {
522        other.borrow().gt(self)
523    }
524
525    /// Decide if this interval is certainly less than or equal to, possibly
526    /// less than or equal to, or can't be less than or equal to `other` by
527    /// returning `[true, true]`, `[false, true]` or `[false, false]` respectively.
528    ///
529    /// NOTE: This function only works with intervals of the same data type.
530    ///       Attempting to compare intervals of different data types will lead
531    ///       to an error.
532    pub fn lt_eq<T: Borrow<Self>>(&self, other: T) -> Result<Self> {
533        other.borrow().gt_eq(self)
534    }
535
536    /// Decide if this interval is certainly equal to, possibly equal to, or
537    /// can't be equal to `other` by returning `[true, true]`, `[false, true]`
538    /// or `[false, false]` respectively.
539    ///
540    /// NOTE: This function only works with intervals of the same data type.
541    ///       Attempting to compare intervals of different data types will lead
542    ///       to an error.
543    pub fn equal<T: Borrow<Self>>(&self, other: T) -> Result<Self> {
544        let rhs = other.borrow();
545        if BinaryTypeCoercer::new(&self.data_type(), &Operator::Eq, &rhs.data_type())
546            .get_result_type()
547            .is_err()
548        {
549            internal_err!(
550                "Interval data types must be compatible for equality checks, lhs:{}, rhs:{}",
551                self.data_type(),
552                rhs.data_type()
553            )
554        } else if !self.lower.is_null()
555            && (self.lower == self.upper)
556            && (rhs.lower == rhs.upper)
557            && (self.lower == rhs.lower)
558        {
559            Ok(Self::CERTAINLY_TRUE)
560        } else if self.intersect(rhs)?.is_none() {
561            Ok(Self::CERTAINLY_FALSE)
562        } else {
563            Ok(Self::UNCERTAIN)
564        }
565    }
566
567    /// Compute the logical conjunction of this (boolean) interval with the
568    /// given boolean interval.
569    pub fn and<T: Borrow<Self>>(&self, other: T) -> Result<Self> {
570        let rhs = other.borrow();
571        match (&self.lower, &self.upper, &rhs.lower, &rhs.upper) {
572            (
573                &ScalarValue::Boolean(Some(self_lower)),
574                &ScalarValue::Boolean(Some(self_upper)),
575                &ScalarValue::Boolean(Some(other_lower)),
576                &ScalarValue::Boolean(Some(other_upper)),
577            ) => {
578                let lower = self_lower && other_lower;
579                let upper = self_upper && other_upper;
580
581                Ok(Self {
582                    lower: ScalarValue::Boolean(Some(lower)),
583                    upper: ScalarValue::Boolean(Some(upper)),
584                })
585            }
586
587            // Return UNCERTAIN when intervals don't have concrete boolean bounds
588            _ => Ok(Self::UNCERTAIN),
589        }
590    }
591
592    /// Compute the logical disjunction of this boolean interval with the
593    /// given boolean interval.
594    pub fn or<T: Borrow<Self>>(&self, other: T) -> Result<Self> {
595        let rhs = other.borrow();
596        match (&self.lower, &self.upper, &rhs.lower, &rhs.upper) {
597            (
598                &ScalarValue::Boolean(Some(self_lower)),
599                &ScalarValue::Boolean(Some(self_upper)),
600                &ScalarValue::Boolean(Some(other_lower)),
601                &ScalarValue::Boolean(Some(other_upper)),
602            ) => {
603                let lower = self_lower || other_lower;
604                let upper = self_upper || other_upper;
605
606                Ok(Self {
607                    lower: ScalarValue::Boolean(Some(lower)),
608                    upper: ScalarValue::Boolean(Some(upper)),
609                })
610            }
611
612            // Return UNCERTAIN when intervals don't have concrete boolean bounds
613            _ => Ok(Self::UNCERTAIN),
614        }
615    }
616
617    /// Compute the logical negation of this (boolean) interval.
618    pub fn not(&self) -> Result<Self> {
619        if self.data_type().ne(&DataType::Boolean) {
620            internal_err!("Cannot apply logical negation to a non-boolean interval")
621        } else if self == &Self::CERTAINLY_TRUE {
622            Ok(Self::CERTAINLY_FALSE)
623        } else if self == &Self::CERTAINLY_FALSE {
624            Ok(Self::CERTAINLY_TRUE)
625        } else {
626            Ok(Self::UNCERTAIN)
627        }
628    }
629
630    /// Compute the intersection of this interval with the given interval.
631    /// If the intersection is empty, return `None`.
632    ///
633    /// NOTE: This function only works with intervals of the same data type.
634    ///       Attempting to compare intervals of different data types will lead
635    ///       to an error.
636    pub fn intersect<T: Borrow<Self>>(&self, other: T) -> Result<Option<Self>> {
637        let rhs = other.borrow();
638        if self.data_type().ne(&rhs.data_type()) {
639            return internal_err!(
640                "Only intervals with the same data type are intersectable, lhs:{}, rhs:{}",
641                self.data_type(),
642                rhs.data_type()
643            );
644        };
645
646        // If it is evident that the result is an empty interval, short-circuit
647        // and directly return `None`.
648        if (!(self.lower.is_null() || rhs.upper.is_null()) && self.lower > rhs.upper)
649            || (!(self.upper.is_null() || rhs.lower.is_null()) && self.upper < rhs.lower)
650        {
651            return Ok(None);
652        }
653
654        let lower = max_of_bounds(&self.lower, &rhs.lower);
655        let upper = min_of_bounds(&self.upper, &rhs.upper);
656
657        // New lower and upper bounds must always construct a valid interval.
658        debug_assert!(
659            (lower.is_null() || upper.is_null() || (lower <= upper)),
660            "The intersection of two intervals can not be an invalid interval"
661        );
662
663        Ok(Some(Self { lower, upper }))
664    }
665
666    /// Compute the union of this interval with the given interval.
667    ///
668    /// NOTE: This function only works with intervals of the same data type.
669    ///       Attempting to compare intervals of different data types will lead
670    ///       to an error.
671    pub fn union<T: Borrow<Self>>(&self, other: T) -> Result<Self> {
672        let rhs = other.borrow();
673        if self.data_type().ne(&rhs.data_type()) {
674            return internal_err!(
675                "Cannot calculate the union of intervals with different data types, lhs:{}, rhs:{}",
676                self.data_type(),
677                rhs.data_type()
678            );
679        };
680
681        let lower = if self.lower.is_null()
682            || (!rhs.lower.is_null() && self.lower <= rhs.lower)
683        {
684            self.lower.clone()
685        } else {
686            rhs.lower.clone()
687        };
688        let upper = if self.upper.is_null()
689            || (!rhs.upper.is_null() && self.upper >= rhs.upper)
690        {
691            self.upper.clone()
692        } else {
693            rhs.upper.clone()
694        };
695
696        // New lower and upper bounds must always construct a valid interval.
697        debug_assert!(
698            (lower.is_null() || upper.is_null() || (lower <= upper)),
699            "The union of two intervals can not be an invalid interval"
700        );
701
702        Ok(Self { lower, upper })
703    }
704
705    /// Decide if this interval contains a [`ScalarValue`] (`other`) by returning `true` or `false`.
706    pub fn contains_value<T: Borrow<ScalarValue>>(&self, other: T) -> Result<bool> {
707        let rhs = other.borrow();
708
709        let (lhs_lower, lhs_upper, rhs) = if self.data_type().eq(&rhs.data_type()) {
710            (&self.lower, &self.upper, rhs)
711        } else if let Some(common_type) =
712            comparison_coercion_numeric(&self.data_type(), &rhs.data_type())
713        {
714            (
715                &self.lower.cast_to(&common_type)?,
716                &self.upper.cast_to(&common_type)?,
717                &rhs.cast_to(&common_type)?,
718            )
719        } else {
720            return internal_err!(
721                "Data types must be compatible for containment checks, lhs:{}, rhs:{}",
722                self.data_type(),
723                rhs.data_type()
724            );
725        };
726
727        // We only check the upper bound for a `None` value because `None`
728        // values are less than `Some` values according to Rust.
729        Ok(lhs_lower <= rhs && (lhs_upper.is_null() || rhs <= lhs_upper))
730    }
731
732    /// Decide if this interval is a superset of, overlaps with, or
733    /// disjoint with `other` by returning `[true, true]`, `[false, true]` or
734    /// `[false, false]` respectively.
735    ///
736    /// NOTE: This function only works with intervals of the same data type.
737    ///       Attempting to compare intervals of different data types will lead
738    ///       to an error.
739    pub fn contains<T: Borrow<Self>>(&self, other: T) -> Result<Self> {
740        let rhs = other.borrow();
741        if self.data_type().ne(&rhs.data_type()) {
742            return internal_err!(
743                "Interval data types must match for containment checks, lhs:{}, rhs:{}",
744                self.data_type(),
745                rhs.data_type()
746            );
747        };
748
749        match self.intersect(rhs)? {
750            Some(intersection) => {
751                if &intersection == rhs {
752                    Ok(Self::CERTAINLY_TRUE)
753                } else {
754                    Ok(Self::UNCERTAIN)
755                }
756            }
757            None => Ok(Self::CERTAINLY_FALSE),
758        }
759    }
760
761    /// Decide if this interval is a superset of `other`. If argument `strict`
762    /// is `true`, only returns `true` if this interval is a strict superset.
763    ///
764    /// NOTE: This function only works with intervals of the same data type.
765    ///       Attempting to compare intervals of different data types will lead
766    ///       to an error.
767    pub fn is_superset(&self, other: &Interval, strict: bool) -> Result<bool> {
768        Ok(!(strict && self.eq(other))
769            && (self.contains(other)? == Interval::CERTAINLY_TRUE))
770    }
771
772    /// Add the given interval (`other`) to this interval. Say we have intervals
773    /// `[a1, b1]` and `[a2, b2]`, then their sum is `[a1 + a2, b1 + b2]`. Note
774    /// that this represents all possible values the sum can take if one can
775    /// choose single values arbitrarily from each of the operands.
776    pub fn add<T: Borrow<Self>>(&self, other: T) -> Result<Self> {
777        let rhs = other.borrow();
778        let dt =
779            BinaryTypeCoercer::new(&self.data_type(), &Operator::Plus, &rhs.data_type())
780                .get_result_type()?;
781
782        Ok(Self::new(
783            add_bounds::<false>(&dt, &self.lower, &rhs.lower),
784            add_bounds::<true>(&dt, &self.upper, &rhs.upper),
785        ))
786    }
787
788    /// Subtract the given interval (`other`) from this interval. Say we have
789    /// intervals `[a1, b1]` and `[a2, b2]`, then their difference is
790    /// `[a1 - b2, b1 - a2]`. Note that this represents all possible values the
791    /// difference can take if one can choose single values arbitrarily from
792    /// each of the operands.
793    pub fn sub<T: Borrow<Interval>>(&self, other: T) -> Result<Self> {
794        let rhs = other.borrow();
795        let dt =
796            BinaryTypeCoercer::new(&self.data_type(), &Operator::Minus, &rhs.data_type())
797                .get_result_type()?;
798
799        Ok(Self::new(
800            sub_bounds::<false>(&dt, &self.lower, &rhs.upper),
801            sub_bounds::<true>(&dt, &self.upper, &rhs.lower),
802        ))
803    }
804
805    /// Multiply the given interval (`other`) with this interval. Say we have
806    /// intervals `[a1, b1]` and `[a2, b2]`, then their product is `[min(a1 * a2,
807    /// a1 * b2, b1 * a2, b1 * b2), max(a1 * a2, a1 * b2, b1 * a2, b1 * b2)]`.
808    /// Note that this represents all possible values the product can take if
809    /// one can choose single values arbitrarily from each of the operands.
810    ///
811    /// NOTE: This function only works with intervals of the same data type.
812    ///       Attempting to compare intervals of different data types will lead
813    ///       to an error.
814    pub fn mul<T: Borrow<Self>>(&self, other: T) -> Result<Self> {
815        let rhs = other.borrow();
816        let dt = if self.data_type().eq(&rhs.data_type()) {
817            self.data_type()
818        } else {
819            return internal_err!(
820                "Intervals must have the same data type for multiplication, lhs:{}, rhs:{}",
821                self.data_type(),
822                rhs.data_type()
823            );
824        };
825
826        let zero = ScalarValue::new_zero(&dt)?;
827
828        let result = match (
829            self.contains_value(&zero)?,
830            rhs.contains_value(&zero)?,
831            dt.is_unsigned_integer(),
832        ) {
833            (true, true, false) => mul_helper_multi_zero_inclusive(&dt, self, rhs),
834            (true, false, false) => {
835                mul_helper_single_zero_inclusive(&dt, self, rhs, zero)
836            }
837            (false, true, false) => {
838                mul_helper_single_zero_inclusive(&dt, rhs, self, zero)
839            }
840            _ => mul_helper_zero_exclusive(&dt, self, rhs, zero),
841        };
842        Ok(result)
843    }
844
845    /// Divide this interval by the given interval (`other`). Say we have intervals
846    /// `[a1, b1]` and `[a2, b2]`, then their division is `[a1, b1] * [1 / b2, 1 / a2]`
847    /// if `0 ∉ [a2, b2]` and `[NEG_INF, INF]` otherwise. Note that this represents
848    /// all possible values the quotient can take if one can choose single values
849    /// arbitrarily from each of the operands.
850    ///
851    /// NOTE: This function only works with intervals of the same data type.
852    ///       Attempting to compare intervals of different data types will lead
853    ///       to an error.
854    ///
855    /// **TODO**: Once interval sets are supported, cases where the divisor contains
856    ///           zero should result in an interval set, not the universal set.
857    pub fn div<T: Borrow<Self>>(&self, other: T) -> Result<Self> {
858        let rhs = other.borrow();
859        let dt = if self.data_type().eq(&rhs.data_type()) {
860            self.data_type()
861        } else {
862            return internal_err!(
863                "Intervals must have the same data type for division, lhs:{}, rhs:{}",
864                self.data_type(),
865                rhs.data_type()
866            );
867        };
868
869        let zero = ScalarValue::new_zero(&dt)?;
870        // We want 0 to be approachable from both negative and positive sides.
871        let zero_point = match &dt {
872            DataType::Float32 | DataType::Float64 => Self::new(zero.clone(), zero),
873            _ => Self::new(prev_value(zero.clone()), next_value(zero)),
874        };
875
876        // Exit early with an unbounded interval if zero is strictly inside the
877        // right hand side:
878        if rhs.contains(&zero_point)? == Self::CERTAINLY_TRUE && !dt.is_unsigned_integer()
879        {
880            Self::make_unbounded(&dt)
881        }
882        // At this point, we know that only one endpoint of the right hand side
883        // can be zero.
884        else if self.contains(&zero_point)? == Self::CERTAINLY_TRUE
885            && !dt.is_unsigned_integer()
886        {
887            Ok(div_helper_lhs_zero_inclusive(&dt, self, rhs, &zero_point))
888        } else {
889            Ok(div_helper_zero_exclusive(&dt, self, rhs, &zero_point))
890        }
891    }
892
893    /// Computes the width of this interval; i.e. the difference between its
894    /// bounds. For unbounded intervals, this function will return a `NULL`
895    /// `ScalarValue` If the underlying data type doesn't support subtraction,
896    /// this function will return an error.
897    pub fn width(&self) -> Result<ScalarValue> {
898        let dt = self.data_type();
899        let width_dt =
900            BinaryTypeCoercer::new(&dt, &Operator::Minus, &dt).get_result_type()?;
901        Ok(sub_bounds::<true>(&width_dt, &self.upper, &self.lower))
902    }
903
904    /// Returns the cardinality of this interval, which is the number of all
905    /// distinct points inside it. This function returns `None` if:
906    /// - The interval is unbounded from either side, or
907    /// - Cardinality calculations for the datatype in question is not
908    ///   implemented yet, or
909    /// - An overflow occurs during the calculation: This case can only arise
910    ///   when the calculated cardinality does not fit in an `u64`.
911    pub fn cardinality(&self) -> Option<u64> {
912        let data_type = self.data_type();
913        if data_type.is_integer() {
914            self.upper.distance(&self.lower).map(|diff| diff as u64)
915        } else if data_type.is_floating() {
916            // Negative numbers are sorted in the reverse order. To
917            // always have a positive difference after the subtraction,
918            // we perform following transformation:
919            match (&self.lower, &self.upper) {
920                // Exploit IEEE 754 ordering properties to calculate the correct
921                // cardinality in all cases (including subnormals).
922                (
923                    ScalarValue::Float32(Some(lower)),
924                    ScalarValue::Float32(Some(upper)),
925                ) => {
926                    let lower_bits = map_floating_point_order!(lower.to_bits(), u32);
927                    let upper_bits = map_floating_point_order!(upper.to_bits(), u32);
928                    Some((upper_bits - lower_bits) as u64)
929                }
930                (
931                    ScalarValue::Float64(Some(lower)),
932                    ScalarValue::Float64(Some(upper)),
933                ) => {
934                    let lower_bits = map_floating_point_order!(lower.to_bits(), u64);
935                    let upper_bits = map_floating_point_order!(upper.to_bits(), u64);
936                    let count = upper_bits - lower_bits;
937                    (count != u64::MAX).then_some(count)
938                }
939                _ => None,
940            }
941        } else {
942            // Cardinality calculations are not implemented for this data type yet:
943            None
944        }
945        .map(|result| result + 1)
946    }
947
948    /// Reflects an [`Interval`] around the point zero.
949    ///
950    /// This method computes the arithmetic negation of the interval, reflecting
951    /// it about the origin of the number line. This operation swaps and negates
952    /// the lower and upper bounds of the interval.
953    pub fn arithmetic_negate(&self) -> Result<Self> {
954        Ok(Self {
955            lower: self.upper.arithmetic_negate()?,
956            upper: self.lower.arithmetic_negate()?,
957        })
958    }
959}
960
961impl Display for Interval {
962    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
963        write!(f, "[{}, {}]", self.lower, self.upper)
964    }
965}
966
967impl From<ScalarValue> for Interval {
968    fn from(value: ScalarValue) -> Self {
969        Self::new(value.clone(), value)
970    }
971}
972
973impl From<&ScalarValue> for Interval {
974    fn from(value: &ScalarValue) -> Self {
975        Self::new(value.to_owned(), value.to_owned())
976    }
977}
978
979/// Applies the given binary operator the `lhs` and `rhs` arguments.
980pub fn apply_operator(op: &Operator, lhs: &Interval, rhs: &Interval) -> Result<Interval> {
981    match *op {
982        Operator::Eq => lhs.equal(rhs),
983        Operator::NotEq => lhs.equal(rhs)?.not(),
984        Operator::Gt => lhs.gt(rhs),
985        Operator::GtEq => lhs.gt_eq(rhs),
986        Operator::Lt => lhs.lt(rhs),
987        Operator::LtEq => lhs.lt_eq(rhs),
988        Operator::And => lhs.and(rhs),
989        Operator::Or => lhs.or(rhs),
990        Operator::Plus => lhs.add(rhs),
991        Operator::Minus => lhs.sub(rhs),
992        Operator::Multiply => lhs.mul(rhs),
993        Operator::Divide => lhs.div(rhs),
994        _ => internal_err!("Interval arithmetic does not support the operator {op}"),
995    }
996}
997
998/// Helper function used for adding the end-point values of intervals.
999///
1000/// **Caution:** This function contains multiple calls to `unwrap()`, and may
1001/// return non-standardized interval bounds. Therefore, it should be used
1002/// with caution. Currently, it is used in contexts where the `DataType`
1003/// (`dt`) is validated prior to calling this function, and the following
1004/// interval creation is standardized with `Interval::new`.
1005fn add_bounds<const UPPER: bool>(
1006    dt: &DataType,
1007    lhs: &ScalarValue,
1008    rhs: &ScalarValue,
1009) -> ScalarValue {
1010    if lhs.is_null() || rhs.is_null() {
1011        return ScalarValue::try_from(dt).unwrap();
1012    }
1013
1014    match dt {
1015        DataType::Float64 | DataType::Float32 => {
1016            alter_fp_rounding_mode::<UPPER, _>(lhs, rhs, |lhs, rhs| lhs.add_checked(rhs))
1017        }
1018        _ => lhs.add_checked(rhs),
1019    }
1020    .unwrap_or_else(|_| handle_overflow::<UPPER>(dt, Operator::Plus, lhs, rhs))
1021}
1022
1023/// Helper function used for subtracting the end-point values of intervals.
1024///
1025/// **Caution:** This function contains multiple calls to `unwrap()`, and may
1026/// return non-standardized interval bounds. Therefore, it should be used
1027/// with caution. Currently, it is used in contexts where the `DataType`
1028/// (`dt`) is validated prior to calling this function, and the following
1029/// interval creation is standardized with `Interval::new`.
1030fn sub_bounds<const UPPER: bool>(
1031    dt: &DataType,
1032    lhs: &ScalarValue,
1033    rhs: &ScalarValue,
1034) -> ScalarValue {
1035    if lhs.is_null() || rhs.is_null() {
1036        return ScalarValue::try_from(dt).unwrap();
1037    }
1038
1039    match dt {
1040        DataType::Float64 | DataType::Float32 => {
1041            alter_fp_rounding_mode::<UPPER, _>(lhs, rhs, |lhs, rhs| lhs.sub_checked(rhs))
1042        }
1043        _ => lhs.sub_checked(rhs),
1044    }
1045    .unwrap_or_else(|_| handle_overflow::<UPPER>(dt, Operator::Minus, lhs, rhs))
1046}
1047
1048/// Helper function used for multiplying the end-point values of intervals.
1049///
1050/// **Caution:** This function contains multiple calls to `unwrap()`, and may
1051/// return non-standardized interval bounds. Therefore, it should be used
1052/// with caution. Currently, it is used in contexts where the `DataType`
1053/// (`dt`) is validated prior to calling this function, and the following
1054/// interval creation is standardized with `Interval::new`.
1055fn mul_bounds<const UPPER: bool>(
1056    dt: &DataType,
1057    lhs: &ScalarValue,
1058    rhs: &ScalarValue,
1059) -> ScalarValue {
1060    if lhs.is_null() || rhs.is_null() {
1061        return ScalarValue::try_from(dt).unwrap();
1062    }
1063
1064    match dt {
1065        DataType::Float64 | DataType::Float32 => {
1066            alter_fp_rounding_mode::<UPPER, _>(lhs, rhs, |lhs, rhs| lhs.mul_checked(rhs))
1067        }
1068        _ => lhs.mul_checked(rhs),
1069    }
1070    .unwrap_or_else(|_| handle_overflow::<UPPER>(dt, Operator::Multiply, lhs, rhs))
1071}
1072
1073/// Helper function used for dividing the end-point values of intervals.
1074///
1075/// **Caution:** This function contains multiple calls to `unwrap()`, and may
1076/// return non-standardized interval bounds. Therefore, it should be used
1077/// with caution. Currently, it is used in contexts where the `DataType`
1078/// (`dt`) is validated prior to calling this function, and the following
1079/// interval creation is standardized with `Interval::new`.
1080fn div_bounds<const UPPER: bool>(
1081    dt: &DataType,
1082    lhs: &ScalarValue,
1083    rhs: &ScalarValue,
1084) -> ScalarValue {
1085    let zero = ScalarValue::new_zero(dt).unwrap();
1086
1087    if (lhs.is_null() || rhs.eq(&zero)) || (dt.is_unsigned_integer() && rhs.is_null()) {
1088        return ScalarValue::try_from(dt).unwrap();
1089    } else if rhs.is_null() {
1090        return zero;
1091    }
1092
1093    match dt {
1094        DataType::Float64 | DataType::Float32 => {
1095            alter_fp_rounding_mode::<UPPER, _>(lhs, rhs, |lhs, rhs| lhs.div(rhs))
1096        }
1097        _ => lhs.div(rhs),
1098    }
1099    .unwrap_or_else(|_| handle_overflow::<UPPER>(dt, Operator::Divide, lhs, rhs))
1100}
1101
1102/// This function handles cases where an operation results in an overflow. Such
1103/// results are converted to an *unbounded endpoint* if:
1104///   - We are calculating an upper bound and we have a positive overflow.
1105///   - We are calculating a lower bound and we have a negative overflow.
1106///
1107/// Otherwise, the function sets the endpoint as:
1108///   - The minimum representable number with the given datatype (`dt`) if
1109///     we are calculating an upper bound and we have a negative overflow.
1110///   - The maximum representable number with the given datatype (`dt`) if
1111///     we are calculating a lower bound and we have a positive overflow.
1112///
1113/// **Caution:** This function contains multiple calls to `unwrap()`, and may
1114/// return non-standardized interval bounds. Therefore, it should be used
1115/// with caution. Currently, it is used in contexts where the `DataType`
1116/// (`dt`) is validated prior to calling this function,  `op` is supported by
1117/// interval library, and the following interval creation is standardized with
1118/// `Interval::new`.
1119fn handle_overflow<const UPPER: bool>(
1120    dt: &DataType,
1121    op: Operator,
1122    lhs: &ScalarValue,
1123    rhs: &ScalarValue,
1124) -> ScalarValue {
1125    let lhs_zero = ScalarValue::new_zero(&lhs.data_type()).unwrap();
1126    let rhs_zero = ScalarValue::new_zero(&rhs.data_type()).unwrap();
1127    let positive_sign = match op {
1128        Operator::Multiply | Operator::Divide => {
1129            lhs.lt(&lhs_zero) && rhs.lt(&rhs_zero)
1130                || lhs.gt(&lhs_zero) && rhs.gt(&rhs_zero)
1131        }
1132        Operator::Plus => lhs.ge(&lhs_zero),
1133        Operator::Minus => lhs.ge(rhs),
1134        _ => {
1135            unreachable!()
1136        }
1137    };
1138
1139    match (UPPER, positive_sign) {
1140        (true, true) | (false, false) => ScalarValue::try_from(dt).unwrap(),
1141        (true, false) => {
1142            get_extreme_value!(MIN, dt)
1143        }
1144        (false, true) => {
1145            get_extreme_value!(MAX, dt)
1146        }
1147    }
1148}
1149
1150// This function should remain private since it may corrupt the an interval if
1151// used without caution.
1152fn next_value(value: ScalarValue) -> ScalarValue {
1153    use ScalarValue::*;
1154    value_transition!(MAX, true, value)
1155}
1156
1157// This function should remain private since it may corrupt the an interval if
1158// used without caution.
1159fn prev_value(value: ScalarValue) -> ScalarValue {
1160    use ScalarValue::*;
1161    value_transition!(MIN, false, value)
1162}
1163
1164trait OneTrait: Sized + std::ops::Add + std::ops::Sub {
1165    fn one() -> Self;
1166}
1167macro_rules! impl_OneTrait{
1168    ($($m:ty),*) => {$( impl OneTrait for $m  { fn one() -> Self { 1 as $m } })*}
1169}
1170impl_OneTrait! {u8, u16, u32, u64, i8, i16, i32, i64, i128}
1171
1172impl OneTrait for IntervalDayTime {
1173    fn one() -> Self {
1174        IntervalDayTime {
1175            days: 0,
1176            milliseconds: 1,
1177        }
1178    }
1179}
1180
1181impl OneTrait for IntervalMonthDayNano {
1182    fn one() -> Self {
1183        IntervalMonthDayNano {
1184            months: 0,
1185            days: 0,
1186            nanoseconds: 1,
1187        }
1188    }
1189}
1190
1191/// This function either increments or decrements its argument, depending on
1192/// the `INC` value (where a `true` value corresponds to the increment).
1193fn increment_decrement<const INC: bool, T: OneTrait + SubAssign + AddAssign>(
1194    mut value: T,
1195) -> T {
1196    if INC {
1197        value.add_assign(T::one());
1198    } else {
1199        value.sub_assign(T::one());
1200    }
1201    value
1202}
1203
1204/// This function returns the next/previous value depending on the `INC` value.
1205/// If `true`, it returns the next value; otherwise it returns the previous value.
1206fn next_value_helper<const INC: bool>(value: ScalarValue) -> ScalarValue {
1207    use ScalarValue::*;
1208    match value {
1209        // f32/f64::NEG_INF/INF and f32/f64::NaN values should not emerge at this point.
1210        Float32(Some(val)) => {
1211            debug_assert!(val.is_finite(), "Non-standardized floating point usage");
1212            Float32(Some(if INC { next_up(val) } else { next_down(val) }))
1213        }
1214        Float64(Some(val)) => {
1215            debug_assert!(val.is_finite(), "Non-standardized floating point usage");
1216            Float64(Some(if INC { next_up(val) } else { next_down(val) }))
1217        }
1218        Int8(Some(val)) => Int8(Some(increment_decrement::<INC, i8>(val))),
1219        Int16(Some(val)) => Int16(Some(increment_decrement::<INC, i16>(val))),
1220        Int32(Some(val)) => Int32(Some(increment_decrement::<INC, i32>(val))),
1221        Int64(Some(val)) => Int64(Some(increment_decrement::<INC, i64>(val))),
1222        UInt8(Some(val)) => UInt8(Some(increment_decrement::<INC, u8>(val))),
1223        UInt16(Some(val)) => UInt16(Some(increment_decrement::<INC, u16>(val))),
1224        UInt32(Some(val)) => UInt32(Some(increment_decrement::<INC, u32>(val))),
1225        UInt64(Some(val)) => UInt64(Some(increment_decrement::<INC, u64>(val))),
1226        DurationSecond(Some(val)) => {
1227            DurationSecond(Some(increment_decrement::<INC, i64>(val)))
1228        }
1229        DurationMillisecond(Some(val)) => {
1230            DurationMillisecond(Some(increment_decrement::<INC, i64>(val)))
1231        }
1232        DurationMicrosecond(Some(val)) => {
1233            DurationMicrosecond(Some(increment_decrement::<INC, i64>(val)))
1234        }
1235        DurationNanosecond(Some(val)) => {
1236            DurationNanosecond(Some(increment_decrement::<INC, i64>(val)))
1237        }
1238        TimestampSecond(Some(val), tz) => {
1239            TimestampSecond(Some(increment_decrement::<INC, i64>(val)), tz)
1240        }
1241        TimestampMillisecond(Some(val), tz) => {
1242            TimestampMillisecond(Some(increment_decrement::<INC, i64>(val)), tz)
1243        }
1244        TimestampMicrosecond(Some(val), tz) => {
1245            TimestampMicrosecond(Some(increment_decrement::<INC, i64>(val)), tz)
1246        }
1247        TimestampNanosecond(Some(val), tz) => {
1248            TimestampNanosecond(Some(increment_decrement::<INC, i64>(val)), tz)
1249        }
1250        IntervalYearMonth(Some(val)) => {
1251            IntervalYearMonth(Some(increment_decrement::<INC, i32>(val)))
1252        }
1253        IntervalDayTime(Some(val)) => IntervalDayTime(Some(increment_decrement::<
1254            INC,
1255            arrow::datatypes::IntervalDayTime,
1256        >(val))),
1257        IntervalMonthDayNano(Some(val)) => {
1258            IntervalMonthDayNano(Some(increment_decrement::<
1259                INC,
1260                arrow::datatypes::IntervalMonthDayNano,
1261            >(val)))
1262        }
1263        _ => value, // Unbounded values return without change.
1264    }
1265}
1266
1267/// Returns the greater of the given interval bounds. Assumes that a `NULL`
1268/// value represents `NEG_INF`.
1269fn max_of_bounds(first: &ScalarValue, second: &ScalarValue) -> ScalarValue {
1270    if !first.is_null() && (second.is_null() || first >= second) {
1271        first.clone()
1272    } else {
1273        second.clone()
1274    }
1275}
1276
1277/// Returns the lesser of the given interval bounds. Assumes that a `NULL`
1278/// value represents `INF`.
1279fn min_of_bounds(first: &ScalarValue, second: &ScalarValue) -> ScalarValue {
1280    if !first.is_null() && (second.is_null() || first <= second) {
1281        first.clone()
1282    } else {
1283        second.clone()
1284    }
1285}
1286
1287/// This function updates the given intervals by enforcing (i.e. propagating)
1288/// the inequality `left > right` (or the `left >= right` inequality, if `strict`
1289/// is `true`).
1290///
1291/// Returns a `Result` wrapping an `Option` containing the tuple of resulting
1292/// intervals. If the comparison is infeasible, returns `None`.
1293///
1294/// Example usage:
1295/// ```
1296/// use datafusion_common::DataFusionError;
1297/// use datafusion_expr_common::interval_arithmetic::{satisfy_greater, Interval};
1298///
1299/// let left = Interval::make(Some(-1000.0_f32), Some(1000.0_f32))?;
1300/// let right = Interval::make(Some(500.0_f32), Some(2000.0_f32))?;
1301/// let strict = false;
1302/// assert_eq!(
1303///     satisfy_greater(&left, &right, strict)?,
1304///     Some((
1305///         Interval::make(Some(500.0_f32), Some(1000.0_f32))?,
1306///         Interval::make(Some(500.0_f32), Some(1000.0_f32))?
1307///     ))
1308/// );
1309/// Ok::<(), DataFusionError>(())
1310/// ```
1311///
1312/// NOTE: This function only works with intervals of the same data type.
1313///       Attempting to compare intervals of different data types will lead
1314///       to an error.
1315pub fn satisfy_greater(
1316    left: &Interval,
1317    right: &Interval,
1318    strict: bool,
1319) -> Result<Option<(Interval, Interval)>> {
1320    if left.data_type().ne(&right.data_type()) {
1321        return internal_err!(
1322            "Intervals must have the same data type, lhs:{}, rhs:{}",
1323            left.data_type(),
1324            right.data_type()
1325        );
1326    }
1327
1328    if !left.upper.is_null() && left.upper <= right.lower {
1329        if !strict && left.upper == right.lower {
1330            // Singleton intervals:
1331            return Ok(Some((
1332                Interval::new(left.upper.clone(), left.upper.clone()),
1333                Interval::new(left.upper.clone(), left.upper.clone()),
1334            )));
1335        } else {
1336            // Left-hand side:  <--======----0------------>
1337            // Right-hand side: <------------0--======---->
1338            // No intersection, infeasible to propagate:
1339            return Ok(None);
1340        }
1341    }
1342
1343    // Only the lower bound of left-hand side and the upper bound of the right-hand
1344    // side can change after propagating the greater-than operation.
1345    let new_left_lower = if left.lower.is_null() || left.lower <= right.lower {
1346        if strict {
1347            next_value(right.lower.clone())
1348        } else {
1349            right.lower.clone()
1350        }
1351    } else {
1352        left.lower.clone()
1353    };
1354    // Below code is asymmetric relative to the above if statement, because
1355    // `None` compares less than `Some` in Rust.
1356    let new_right_upper = if right.upper.is_null()
1357        || (!left.upper.is_null() && left.upper <= right.upper)
1358    {
1359        if strict {
1360            prev_value(left.upper.clone())
1361        } else {
1362            left.upper.clone()
1363        }
1364    } else {
1365        right.upper.clone()
1366    };
1367    // No possibility to create an invalid interval:
1368    Ok(Some((
1369        Interval::new(new_left_lower, left.upper.clone()),
1370        Interval::new(right.lower.clone(), new_right_upper),
1371    )))
1372}
1373
1374/// Multiplies two intervals that both contain zero.
1375///
1376/// This function takes in two intervals (`lhs` and `rhs`) as arguments and
1377/// returns their product (whose data type is known to be `dt`). It is
1378/// specifically designed to handle intervals that contain zero within their
1379/// ranges. Returns an error if the multiplication of bounds fails.
1380///
1381/// ```text
1382/// Left-hand side:  <-------=====0=====------->
1383/// Right-hand side: <-------=====0=====------->
1384/// ```
1385///
1386/// **Caution:** This function contains multiple calls to `unwrap()`. Therefore,
1387/// it should be used with caution. Currently, it is used in contexts where the
1388/// `DataType` (`dt`) is validated prior to calling this function.
1389fn mul_helper_multi_zero_inclusive(
1390    dt: &DataType,
1391    lhs: &Interval,
1392    rhs: &Interval,
1393) -> Interval {
1394    if lhs.lower.is_null()
1395        || lhs.upper.is_null()
1396        || rhs.lower.is_null()
1397        || rhs.upper.is_null()
1398    {
1399        return Interval::make_unbounded(dt).unwrap();
1400    }
1401    // Since unbounded cases are handled above, we can safely
1402    // use the utility functions here to eliminate code duplication.
1403    let lower = min_of_bounds(
1404        &mul_bounds::<false>(dt, &lhs.lower, &rhs.upper),
1405        &mul_bounds::<false>(dt, &rhs.lower, &lhs.upper),
1406    );
1407    let upper = max_of_bounds(
1408        &mul_bounds::<true>(dt, &lhs.upper, &rhs.upper),
1409        &mul_bounds::<true>(dt, &lhs.lower, &rhs.lower),
1410    );
1411    // There is no possibility to create an invalid interval.
1412    Interval::new(lower, upper)
1413}
1414
1415/// Multiplies two intervals when only left-hand side interval contains zero.
1416///
1417/// This function takes in two intervals (`lhs` and `rhs`) as arguments and
1418/// returns their product (whose data type is known to be `dt`). This function
1419/// serves as a subroutine that handles the specific case when only `lhs` contains
1420/// zero within its range. The interval not containing zero, i.e. rhs, can lie
1421/// on either side of zero. Returns an error if the multiplication of bounds fails.
1422///
1423/// ``` text
1424/// Left-hand side:  <-------=====0=====------->
1425/// Right-hand side: <--======----0------------>
1426///
1427///                    or
1428///
1429/// Left-hand side:  <-------=====0=====------->
1430/// Right-hand side: <------------0--======---->
1431/// ```
1432///
1433/// **Caution:** This function contains multiple calls to `unwrap()`. Therefore,
1434/// it should be used with caution. Currently, it is used in contexts where the
1435/// `DataType` (`dt`) is validated prior to calling this function.
1436fn mul_helper_single_zero_inclusive(
1437    dt: &DataType,
1438    lhs: &Interval,
1439    rhs: &Interval,
1440    zero: ScalarValue,
1441) -> Interval {
1442    // With the following interval bounds, there is no possibility to create an invalid interval.
1443    if rhs.upper <= zero && !rhs.upper.is_null() {
1444        // <-------=====0=====------->
1445        // <--======----0------------>
1446        let lower = mul_bounds::<false>(dt, &lhs.upper, &rhs.lower);
1447        let upper = mul_bounds::<true>(dt, &lhs.lower, &rhs.lower);
1448        Interval::new(lower, upper)
1449    } else {
1450        // <-------=====0=====------->
1451        // <------------0--======---->
1452        let lower = mul_bounds::<false>(dt, &lhs.lower, &rhs.upper);
1453        let upper = mul_bounds::<true>(dt, &lhs.upper, &rhs.upper);
1454        Interval::new(lower, upper)
1455    }
1456}
1457
1458/// Multiplies two intervals when neither of them contains zero.
1459///
1460/// This function takes in two intervals (`lhs` and `rhs`) as arguments and
1461/// returns their product (whose data type is known to be `dt`). It is
1462/// specifically designed to handle intervals that do not contain zero within
1463/// their ranges. Returns an error if the multiplication of bounds fails.
1464///
1465/// ``` text
1466/// Left-hand side:  <--======----0------------>
1467/// Right-hand side: <--======----0------------>
1468///
1469///                    or
1470///
1471/// Left-hand side:  <--======----0------------>
1472/// Right-hand side: <------------0--======---->
1473///
1474///                    or
1475///
1476/// Left-hand side:  <------------0--======---->
1477/// Right-hand side: <--======----0------------>
1478///
1479///                    or
1480///
1481/// Left-hand side:  <------------0--======---->
1482/// Right-hand side: <------------0--======---->
1483/// ```
1484///
1485/// **Caution:** This function contains multiple calls to `unwrap()`. Therefore,
1486/// it should be used with caution. Currently, it is used in contexts where the
1487/// `DataType` (`dt`) is validated prior to calling this function.
1488fn mul_helper_zero_exclusive(
1489    dt: &DataType,
1490    lhs: &Interval,
1491    rhs: &Interval,
1492    zero: ScalarValue,
1493) -> Interval {
1494    let (lower, upper) = match (
1495        lhs.upper <= zero && !lhs.upper.is_null(),
1496        rhs.upper <= zero && !rhs.upper.is_null(),
1497    ) {
1498        // With the following interval bounds, there is no possibility to create an invalid interval.
1499        (true, true) => (
1500            // <--======----0------------>
1501            // <--======----0------------>
1502            mul_bounds::<false>(dt, &lhs.upper, &rhs.upper),
1503            mul_bounds::<true>(dt, &lhs.lower, &rhs.lower),
1504        ),
1505        (true, false) => (
1506            // <--======----0------------>
1507            // <------------0--======---->
1508            mul_bounds::<false>(dt, &lhs.lower, &rhs.upper),
1509            mul_bounds::<true>(dt, &lhs.upper, &rhs.lower),
1510        ),
1511        (false, true) => (
1512            // <------------0--======---->
1513            // <--======----0------------>
1514            mul_bounds::<false>(dt, &rhs.lower, &lhs.upper),
1515            mul_bounds::<true>(dt, &rhs.upper, &lhs.lower),
1516        ),
1517        (false, false) => (
1518            // <------------0--======---->
1519            // <------------0--======---->
1520            mul_bounds::<false>(dt, &lhs.lower, &rhs.lower),
1521            mul_bounds::<true>(dt, &lhs.upper, &rhs.upper),
1522        ),
1523    };
1524    Interval::new(lower, upper)
1525}
1526
1527/// Divides the left-hand side interval by the right-hand side interval when
1528/// the former contains zero.
1529///
1530/// This function takes in two intervals (`lhs` and `rhs`) as arguments and
1531/// returns their quotient (whose data type is known to be `dt`). This function
1532/// serves as a subroutine that handles the specific case when only `lhs` contains
1533/// zero within its range. Returns an error if the division of bounds fails.
1534///
1535/// ``` text
1536/// Left-hand side:  <-------=====0=====------->
1537/// Right-hand side: <--======----0------------>
1538///
1539///                    or
1540///
1541/// Left-hand side:  <-------=====0=====------->
1542/// Right-hand side: <------------0--======---->
1543/// ```
1544///
1545/// **Caution:** This function contains multiple calls to `unwrap()`. Therefore,
1546/// it should be used with caution. Currently, it is used in contexts where the
1547/// `DataType` (`dt`) is validated prior to calling this function.
1548fn div_helper_lhs_zero_inclusive(
1549    dt: &DataType,
1550    lhs: &Interval,
1551    rhs: &Interval,
1552    zero_point: &Interval,
1553) -> Interval {
1554    // With the following interval bounds, there is no possibility to create an invalid interval.
1555    if rhs.upper <= zero_point.lower && !rhs.upper.is_null() {
1556        // <-------=====0=====------->
1557        // <--======----0------------>
1558        let lower = div_bounds::<false>(dt, &lhs.upper, &rhs.upper);
1559        let upper = div_bounds::<true>(dt, &lhs.lower, &rhs.upper);
1560        Interval::new(lower, upper)
1561    } else {
1562        // <-------=====0=====------->
1563        // <------------0--======---->
1564        let lower = div_bounds::<false>(dt, &lhs.lower, &rhs.lower);
1565        let upper = div_bounds::<true>(dt, &lhs.upper, &rhs.lower);
1566        Interval::new(lower, upper)
1567    }
1568}
1569
1570/// Divides the left-hand side interval by the right-hand side interval when
1571/// neither interval contains zero.
1572///
1573/// This function takes in two intervals (`lhs` and `rhs`) as arguments and
1574/// returns their quotient (whose data type is known to be `dt`). It is
1575/// specifically designed to handle intervals that do not contain zero within
1576/// their ranges. Returns an error if the division of bounds fails.
1577///
1578/// ``` text
1579/// Left-hand side:  <--======----0------------>
1580/// Right-hand side: <--======----0------------>
1581///
1582///                    or
1583///
1584/// Left-hand side:  <--======----0------------>
1585/// Right-hand side: <------------0--======---->
1586///
1587///                    or
1588///
1589/// Left-hand side:  <------------0--======---->
1590/// Right-hand side: <--======----0------------>
1591///
1592///                    or
1593///
1594/// Left-hand side:  <------------0--======---->
1595/// Right-hand side: <------------0--======---->
1596/// ```
1597///
1598/// **Caution:** This function contains multiple calls to `unwrap()`. Therefore,
1599/// it should be used with caution. Currently, it is used in contexts where the
1600/// `DataType` (`dt`) is validated prior to calling this function.
1601fn div_helper_zero_exclusive(
1602    dt: &DataType,
1603    lhs: &Interval,
1604    rhs: &Interval,
1605    zero_point: &Interval,
1606) -> Interval {
1607    let (lower, upper) = match (
1608        lhs.upper <= zero_point.lower && !lhs.upper.is_null(),
1609        rhs.upper <= zero_point.lower && !rhs.upper.is_null(),
1610    ) {
1611        // With the following interval bounds, there is no possibility to create an invalid interval.
1612        (true, true) => (
1613            // <--======----0------------>
1614            // <--======----0------------>
1615            div_bounds::<false>(dt, &lhs.upper, &rhs.lower),
1616            div_bounds::<true>(dt, &lhs.lower, &rhs.upper),
1617        ),
1618        (true, false) => (
1619            // <--======----0------------>
1620            // <------------0--======---->
1621            div_bounds::<false>(dt, &lhs.lower, &rhs.lower),
1622            div_bounds::<true>(dt, &lhs.upper, &rhs.upper),
1623        ),
1624        (false, true) => (
1625            // <------------0--======---->
1626            // <--======----0------------>
1627            div_bounds::<false>(dt, &lhs.upper, &rhs.upper),
1628            div_bounds::<true>(dt, &lhs.lower, &rhs.lower),
1629        ),
1630        (false, false) => (
1631            // <------------0--======---->
1632            // <------------0--======---->
1633            div_bounds::<false>(dt, &lhs.lower, &rhs.upper),
1634            div_bounds::<true>(dt, &lhs.upper, &rhs.lower),
1635        ),
1636    };
1637    Interval::new(lower, upper)
1638}
1639
1640/// This function computes the selectivity of an operation by computing the
1641/// cardinality ratio of the given input/output intervals. If this can not be
1642/// calculated for some reason, it returns `1.0` meaning fully selective (no
1643/// filtering).
1644pub fn cardinality_ratio(initial_interval: &Interval, final_interval: &Interval) -> f64 {
1645    match (final_interval.cardinality(), initial_interval.cardinality()) {
1646        (Some(final_interval), Some(initial_interval)) => {
1647            (final_interval as f64) / (initial_interval as f64)
1648        }
1649        _ => 1.0,
1650    }
1651}
1652
1653/// Cast scalar value to the given data type using an arrow kernel.
1654fn cast_scalar_value(
1655    value: &ScalarValue,
1656    data_type: &DataType,
1657    cast_options: &CastOptions,
1658) -> Result<ScalarValue> {
1659    let cast_array = cast_with_options(&value.to_array()?, data_type, cast_options)?;
1660    ScalarValue::try_from_array(&cast_array, 0)
1661}
1662
1663/// An [Interval] that also tracks null status using a boolean interval.
1664///
1665/// This represents values that may be in a particular range or be null.
1666///
1667/// # Examples
1668///
1669/// ```
1670/// use arrow::datatypes::DataType;
1671/// use datafusion_common::ScalarValue;
1672/// use datafusion_expr_common::interval_arithmetic::Interval;
1673/// use datafusion_expr_common::interval_arithmetic::NullableInterval;
1674///
1675/// // [1, 2) U {NULL}
1676/// let maybe_null = NullableInterval::MaybeNull {
1677///     values: Interval::try_new(
1678///         ScalarValue::Int32(Some(1)),
1679///         ScalarValue::Int32(Some(2)),
1680///     )
1681///     .unwrap(),
1682/// };
1683///
1684/// // (0, ∞)
1685/// let not_null = NullableInterval::NotNull {
1686///     values: Interval::try_new(ScalarValue::Int32(Some(0)), ScalarValue::Int32(None))
1687///         .unwrap(),
1688/// };
1689///
1690/// // {NULL}
1691/// let null_interval = NullableInterval::Null {
1692///     datatype: DataType::Int32,
1693/// };
1694///
1695/// // {4}
1696/// let single_value = NullableInterval::from(ScalarValue::Int32(Some(4)));
1697/// ```
1698#[derive(Debug, Clone, PartialEq, Eq)]
1699pub enum NullableInterval {
1700    /// The value is always null. This is typed so it can be used in physical
1701    /// expressions, which don't do type coercion.
1702    Null { datatype: DataType },
1703    /// The value may or may not be null. If it is non-null, its is within the
1704    /// specified range.
1705    MaybeNull { values: Interval },
1706    /// The value is definitely not null, and is within the specified range.
1707    NotNull { values: Interval },
1708}
1709
1710impl Display for NullableInterval {
1711    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
1712        match self {
1713            Self::Null { .. } => write!(f, "NullableInterval: {{NULL}}"),
1714            Self::MaybeNull { values } => {
1715                write!(f, "NullableInterval: {values} U {{NULL}}")
1716            }
1717            Self::NotNull { values } => write!(f, "NullableInterval: {values}"),
1718        }
1719    }
1720}
1721
1722impl From<ScalarValue> for NullableInterval {
1723    /// Create an interval that represents a single value.
1724    fn from(value: ScalarValue) -> Self {
1725        if value.is_null() {
1726            Self::Null {
1727                datatype: value.data_type(),
1728            }
1729        } else {
1730            Self::NotNull {
1731                values: Interval {
1732                    lower: value.clone(),
1733                    upper: value,
1734                },
1735            }
1736        }
1737    }
1738}
1739
1740impl NullableInterval {
1741    /// Get the values interval, or None if this interval is definitely null.
1742    pub fn values(&self) -> Option<&Interval> {
1743        match self {
1744            Self::Null { .. } => None,
1745            Self::MaybeNull { values } | Self::NotNull { values } => Some(values),
1746        }
1747    }
1748
1749    /// Get the data type
1750    pub fn data_type(&self) -> DataType {
1751        match self {
1752            Self::Null { datatype } => datatype.clone(),
1753            Self::MaybeNull { values } | Self::NotNull { values } => values.data_type(),
1754        }
1755    }
1756
1757    /// Return true if the value is definitely true (and not null).
1758    pub fn is_certainly_true(&self) -> bool {
1759        match self {
1760            Self::Null { .. } | Self::MaybeNull { .. } => false,
1761            Self::NotNull { values } => values == &Interval::CERTAINLY_TRUE,
1762        }
1763    }
1764
1765    /// Return true if the value is definitely false (and not null).
1766    pub fn is_certainly_false(&self) -> bool {
1767        match self {
1768            Self::Null { .. } => false,
1769            Self::MaybeNull { .. } => false,
1770            Self::NotNull { values } => values == &Interval::CERTAINLY_FALSE,
1771        }
1772    }
1773
1774    /// Perform logical negation on a boolean nullable interval.
1775    fn not(&self) -> Result<Self> {
1776        match self {
1777            Self::Null { datatype } => Ok(Self::Null {
1778                datatype: datatype.clone(),
1779            }),
1780            Self::MaybeNull { values } => Ok(Self::MaybeNull {
1781                values: values.not()?,
1782            }),
1783            Self::NotNull { values } => Ok(Self::NotNull {
1784                values: values.not()?,
1785            }),
1786        }
1787    }
1788
1789    /// Apply the given operator to this interval and the given interval.
1790    ///
1791    /// # Examples
1792    ///
1793    /// ```
1794    /// use datafusion_common::ScalarValue;
1795    /// use datafusion_expr_common::interval_arithmetic::Interval;
1796    /// use datafusion_expr_common::interval_arithmetic::NullableInterval;
1797    /// use datafusion_expr_common::operator::Operator;
1798    ///
1799    /// // 4 > 3 -> true
1800    /// let lhs = NullableInterval::from(ScalarValue::Int32(Some(4)));
1801    /// let rhs = NullableInterval::from(ScalarValue::Int32(Some(3)));
1802    /// let result = lhs.apply_operator(&Operator::Gt, &rhs).unwrap();
1803    /// assert_eq!(
1804    ///     result,
1805    ///     NullableInterval::from(ScalarValue::Boolean(Some(true)))
1806    /// );
1807    ///
1808    /// // [1, 3) > NULL -> NULL
1809    /// let lhs = NullableInterval::NotNull {
1810    ///     values: Interval::try_new(
1811    ///         ScalarValue::Int32(Some(1)),
1812    ///         ScalarValue::Int32(Some(3)),
1813    ///     )
1814    ///     .unwrap(),
1815    /// };
1816    /// let rhs = NullableInterval::from(ScalarValue::Int32(None));
1817    /// let result = lhs.apply_operator(&Operator::Gt, &rhs).unwrap();
1818    /// assert_eq!(result.single_value(), Some(ScalarValue::Boolean(None)));
1819    ///
1820    /// // [1, 3] > [2, 4] -> [false, true]
1821    /// let lhs = NullableInterval::NotNull {
1822    ///     values: Interval::try_new(
1823    ///         ScalarValue::Int32(Some(1)),
1824    ///         ScalarValue::Int32(Some(3)),
1825    ///     )
1826    ///     .unwrap(),
1827    /// };
1828    /// let rhs = NullableInterval::NotNull {
1829    ///     values: Interval::try_new(
1830    ///         ScalarValue::Int32(Some(2)),
1831    ///         ScalarValue::Int32(Some(4)),
1832    ///     )
1833    ///     .unwrap(),
1834    /// };
1835    /// let result = lhs.apply_operator(&Operator::Gt, &rhs).unwrap();
1836    /// // Both inputs are valid (non-null), so result must be non-null
1837    /// assert_eq!(
1838    ///     result,
1839    ///     NullableInterval::NotNull {
1840    ///         // Uncertain whether inequality is true or false
1841    ///         values: Interval::UNCERTAIN,
1842    ///     }
1843    /// );
1844    /// ```
1845    pub fn apply_operator(&self, op: &Operator, rhs: &Self) -> Result<Self> {
1846        match op {
1847            Operator::IsDistinctFrom => {
1848                let values = match (self, rhs) {
1849                    // NULL is distinct from NULL -> False
1850                    (Self::Null { .. }, Self::Null { .. }) => Interval::CERTAINLY_FALSE,
1851                    // x is distinct from y -> x != y,
1852                    // if at least one of them is never null.
1853                    (Self::NotNull { .. }, _) | (_, Self::NotNull { .. }) => {
1854                        let lhs_values = self.values();
1855                        let rhs_values = rhs.values();
1856                        match (lhs_values, rhs_values) {
1857                            (Some(lhs_values), Some(rhs_values)) => {
1858                                lhs_values.equal(rhs_values)?.not()?
1859                            }
1860                            (Some(_), None) | (None, Some(_)) => Interval::CERTAINLY_TRUE,
1861                            (None, None) => unreachable!("Null case handled above"),
1862                        }
1863                    }
1864                    _ => Interval::UNCERTAIN,
1865                };
1866                // IsDistinctFrom never returns null.
1867                Ok(Self::NotNull { values })
1868            }
1869            Operator::IsNotDistinctFrom => self
1870                .apply_operator(&Operator::IsDistinctFrom, rhs)
1871                .map(|i| i.not())?,
1872            _ => {
1873                if let (Some(left_values), Some(right_values)) =
1874                    (self.values(), rhs.values())
1875                {
1876                    let values = apply_operator(op, left_values, right_values)?;
1877                    match (self, rhs) {
1878                        (Self::NotNull { .. }, Self::NotNull { .. }) => {
1879                            Ok(Self::NotNull { values })
1880                        }
1881                        _ => Ok(Self::MaybeNull { values }),
1882                    }
1883                } else if op.supports_propagation() {
1884                    Ok(Self::Null {
1885                        datatype: DataType::Boolean,
1886                    })
1887                } else {
1888                    Ok(Self::Null {
1889                        datatype: self.data_type(),
1890                    })
1891                }
1892            }
1893        }
1894    }
1895
1896    /// Decide if this interval is a superset of, overlaps with, or
1897    /// disjoint with `other` by returning `[true, true]`, `[false, true]` or
1898    /// `[false, false]` respectively.
1899    ///
1900    /// NOTE: This function only works with intervals of the same data type.
1901    ///       Attempting to compare intervals of different data types will lead
1902    ///       to an error.
1903    pub fn contains<T: Borrow<Self>>(&self, other: T) -> Result<Self> {
1904        let rhs = other.borrow();
1905        if let (Some(left_values), Some(right_values)) = (self.values(), rhs.values()) {
1906            left_values
1907                .contains(right_values)
1908                .map(|values| match (self, rhs) {
1909                    (Self::NotNull { .. }, Self::NotNull { .. }) => {
1910                        Self::NotNull { values }
1911                    }
1912                    _ => Self::MaybeNull { values },
1913                })
1914        } else {
1915            Ok(Self::Null {
1916                datatype: DataType::Boolean,
1917            })
1918        }
1919    }
1920
1921    /// If the interval has collapsed to a single value, return that value.
1922    /// Otherwise, returns `None`.
1923    ///
1924    /// # Examples
1925    ///
1926    /// ```
1927    /// use datafusion_common::ScalarValue;
1928    /// use datafusion_expr_common::interval_arithmetic::Interval;
1929    /// use datafusion_expr_common::interval_arithmetic::NullableInterval;
1930    ///
1931    /// let interval = NullableInterval::from(ScalarValue::Int32(Some(4)));
1932    /// assert_eq!(interval.single_value(), Some(ScalarValue::Int32(Some(4))));
1933    ///
1934    /// let interval = NullableInterval::from(ScalarValue::Int32(None));
1935    /// assert_eq!(interval.single_value(), Some(ScalarValue::Int32(None)));
1936    ///
1937    /// let interval = NullableInterval::MaybeNull {
1938    ///     values: Interval::try_new(
1939    ///         ScalarValue::Int32(Some(1)),
1940    ///         ScalarValue::Int32(Some(4)),
1941    ///     )
1942    ///     .unwrap(),
1943    /// };
1944    /// assert_eq!(interval.single_value(), None);
1945    /// ```
1946    pub fn single_value(&self) -> Option<ScalarValue> {
1947        match self {
1948            Self::Null { datatype } => {
1949                Some(ScalarValue::try_from(datatype).unwrap_or(ScalarValue::Null))
1950            }
1951            Self::MaybeNull { values } | Self::NotNull { values }
1952                if values.lower == values.upper && !values.lower.is_null() =>
1953            {
1954                Some(values.lower.clone())
1955            }
1956            _ => None,
1957        }
1958    }
1959}
1960
1961#[cfg(test)]
1962mod tests {
1963    use crate::{
1964        interval_arithmetic::{
1965            handle_overflow, next_value, prev_value, satisfy_greater, Interval,
1966        },
1967        operator::Operator,
1968    };
1969
1970    use arrow::datatypes::DataType;
1971    use datafusion_common::rounding::{next_down, next_up};
1972    use datafusion_common::{Result, ScalarValue};
1973
1974    #[test]
1975    fn test_next_prev_value() -> Result<()> {
1976        let zeros = vec![
1977            ScalarValue::new_zero(&DataType::UInt8)?,
1978            ScalarValue::new_zero(&DataType::UInt16)?,
1979            ScalarValue::new_zero(&DataType::UInt32)?,
1980            ScalarValue::new_zero(&DataType::UInt64)?,
1981            ScalarValue::new_zero(&DataType::Int8)?,
1982            ScalarValue::new_zero(&DataType::Int16)?,
1983            ScalarValue::new_zero(&DataType::Int32)?,
1984            ScalarValue::new_zero(&DataType::Int64)?,
1985        ];
1986        let ones = vec![
1987            ScalarValue::new_one(&DataType::UInt8)?,
1988            ScalarValue::new_one(&DataType::UInt16)?,
1989            ScalarValue::new_one(&DataType::UInt32)?,
1990            ScalarValue::new_one(&DataType::UInt64)?,
1991            ScalarValue::new_one(&DataType::Int8)?,
1992            ScalarValue::new_one(&DataType::Int16)?,
1993            ScalarValue::new_one(&DataType::Int32)?,
1994            ScalarValue::new_one(&DataType::Int64)?,
1995        ];
1996        zeros.into_iter().zip(ones).for_each(|(z, o)| {
1997            assert_eq!(next_value(z.clone()), o);
1998            assert_eq!(prev_value(o), z);
1999        });
2000
2001        let values = vec![
2002            ScalarValue::new_zero(&DataType::Float32)?,
2003            ScalarValue::new_zero(&DataType::Float64)?,
2004        ];
2005        let eps = vec![
2006            ScalarValue::Float32(Some(1e-6)),
2007            ScalarValue::Float64(Some(1e-6)),
2008        ];
2009        values.into_iter().zip(eps).for_each(|(value, eps)| {
2010            assert!(next_value(value.clone())
2011                .sub(value.clone())
2012                .unwrap()
2013                .lt(&eps));
2014            assert!(value.sub(prev_value(value.clone())).unwrap().lt(&eps));
2015            assert_ne!(next_value(value.clone()), value);
2016            assert_ne!(prev_value(value.clone()), value);
2017        });
2018
2019        let min_max = vec![
2020            (
2021                ScalarValue::UInt64(Some(u64::MIN)),
2022                ScalarValue::UInt64(Some(u64::MAX)),
2023            ),
2024            (
2025                ScalarValue::Int8(Some(i8::MIN)),
2026                ScalarValue::Int8(Some(i8::MAX)),
2027            ),
2028            (
2029                ScalarValue::Float32(Some(f32::MIN)),
2030                ScalarValue::Float32(Some(f32::MAX)),
2031            ),
2032            (
2033                ScalarValue::Float64(Some(f64::MIN)),
2034                ScalarValue::Float64(Some(f64::MAX)),
2035            ),
2036        ];
2037        let inf = vec![
2038            ScalarValue::UInt64(None),
2039            ScalarValue::Int8(None),
2040            ScalarValue::Float32(None),
2041            ScalarValue::Float64(None),
2042        ];
2043        min_max.into_iter().zip(inf).for_each(|((min, max), inf)| {
2044            assert_eq!(next_value(max.clone()), inf);
2045            assert_ne!(prev_value(max.clone()), max);
2046            assert_ne!(prev_value(max), inf);
2047
2048            assert_eq!(prev_value(min.clone()), inf);
2049            assert_ne!(next_value(min.clone()), min);
2050            assert_ne!(next_value(min), inf);
2051
2052            assert_eq!(next_value(inf.clone()), inf);
2053            assert_eq!(prev_value(inf.clone()), inf);
2054        });
2055
2056        Ok(())
2057    }
2058
2059    #[test]
2060    fn test_new_interval() -> Result<()> {
2061        use ScalarValue::*;
2062
2063        let cases = vec![
2064            (
2065                (Boolean(None), Boolean(Some(false))),
2066                Boolean(Some(false)),
2067                Boolean(Some(false)),
2068            ),
2069            (
2070                (Boolean(Some(false)), Boolean(None)),
2071                Boolean(Some(false)),
2072                Boolean(Some(true)),
2073            ),
2074            (
2075                (Boolean(Some(false)), Boolean(Some(true))),
2076                Boolean(Some(false)),
2077                Boolean(Some(true)),
2078            ),
2079            (
2080                (UInt16(Some(u16::MAX)), UInt16(None)),
2081                UInt16(Some(u16::MAX)),
2082                UInt16(None),
2083            ),
2084            (
2085                (Int16(None), Int16(Some(-1000))),
2086                Int16(None),
2087                Int16(Some(-1000)),
2088            ),
2089            (
2090                (Float32(Some(f32::MAX)), Float32(Some(f32::MAX))),
2091                Float32(Some(f32::MAX)),
2092                Float32(Some(f32::MAX)),
2093            ),
2094            (
2095                (Float32(Some(f32::NAN)), Float32(Some(f32::MIN))),
2096                Float32(None),
2097                Float32(Some(f32::MIN)),
2098            ),
2099            (
2100                (
2101                    Float64(Some(f64::NEG_INFINITY)),
2102                    Float64(Some(f64::INFINITY)),
2103                ),
2104                Float64(None),
2105                Float64(None),
2106            ),
2107        ];
2108        for (inputs, lower, upper) in cases {
2109            let result = Interval::try_new(inputs.0, inputs.1)?;
2110            assert_eq!(result.clone().lower(), &lower);
2111            assert_eq!(result.upper(), &upper);
2112        }
2113
2114        let invalid_intervals = vec![
2115            (Float32(Some(f32::INFINITY)), Float32(Some(100_f32))),
2116            (Float64(Some(0_f64)), Float64(Some(f64::NEG_INFINITY))),
2117            (Boolean(Some(true)), Boolean(Some(false))),
2118            (Int32(Some(1000)), Int32(Some(-2000))),
2119            (UInt64(Some(1)), UInt64(Some(0))),
2120        ];
2121        for (lower, upper) in invalid_intervals {
2122            Interval::try_new(lower, upper).expect_err(
2123                "Given parameters should have given an invalid interval error",
2124            );
2125        }
2126
2127        Ok(())
2128    }
2129
2130    #[test]
2131    fn test_make_unbounded() -> Result<()> {
2132        use ScalarValue::*;
2133
2134        let unbounded_cases = vec![
2135            (DataType::Boolean, Boolean(Some(false)), Boolean(Some(true))),
2136            (DataType::UInt8, UInt8(Some(0)), UInt8(None)),
2137            (DataType::UInt16, UInt16(Some(0)), UInt16(None)),
2138            (DataType::UInt32, UInt32(Some(0)), UInt32(None)),
2139            (DataType::UInt64, UInt64(Some(0)), UInt64(None)),
2140            (DataType::Int8, Int8(None), Int8(None)),
2141            (DataType::Int16, Int16(None), Int16(None)),
2142            (DataType::Int32, Int32(None), Int32(None)),
2143            (DataType::Int64, Int64(None), Int64(None)),
2144            (DataType::Float32, Float32(None), Float32(None)),
2145            (DataType::Float64, Float64(None), Float64(None)),
2146        ];
2147        for (dt, lower, upper) in unbounded_cases {
2148            let inf = Interval::make_unbounded(&dt)?;
2149            assert_eq!(inf.clone().lower(), &lower);
2150            assert_eq!(inf.upper(), &upper);
2151        }
2152
2153        Ok(())
2154    }
2155
2156    #[test]
2157    fn gt_lt_test() -> Result<()> {
2158        let exactly_gt_cases = vec![
2159            (
2160                Interval::make(Some(1000_i64), None)?,
2161                Interval::make(None, Some(999_i64))?,
2162            ),
2163            (
2164                Interval::make(Some(1000_i64), Some(1000_i64))?,
2165                Interval::make(None, Some(999_i64))?,
2166            ),
2167            (
2168                Interval::make(Some(501_i64), Some(1000_i64))?,
2169                Interval::make(Some(500_i64), Some(500_i64))?,
2170            ),
2171            (
2172                Interval::make(Some(-1000_i64), Some(1000_i64))?,
2173                Interval::make(None, Some(-1500_i64))?,
2174            ),
2175            (
2176                Interval::try_new(
2177                    next_value(ScalarValue::Float32(Some(0.0))),
2178                    next_value(ScalarValue::Float32(Some(0.0))),
2179                )?,
2180                Interval::make(Some(0.0_f32), Some(0.0_f32))?,
2181            ),
2182            (
2183                Interval::make(Some(-1.0_f32), Some(-1.0_f32))?,
2184                Interval::try_new(
2185                    prev_value(ScalarValue::Float32(Some(-1.0))),
2186                    prev_value(ScalarValue::Float32(Some(-1.0))),
2187                )?,
2188            ),
2189        ];
2190        for (first, second) in exactly_gt_cases {
2191            assert_eq!(first.gt(second.clone())?, Interval::CERTAINLY_TRUE);
2192            assert_eq!(second.lt(first)?, Interval::CERTAINLY_TRUE);
2193        }
2194
2195        let possibly_gt_cases = vec![
2196            (
2197                Interval::make(Some(1000_i64), Some(2000_i64))?,
2198                Interval::make(Some(1000_i64), Some(1000_i64))?,
2199            ),
2200            (
2201                Interval::make(Some(500_i64), Some(1000_i64))?,
2202                Interval::make(Some(500_i64), Some(1000_i64))?,
2203            ),
2204            (
2205                Interval::make(Some(1000_i64), None)?,
2206                Interval::make(Some(1000_i64), None)?,
2207            ),
2208            (
2209                Interval::make::<i64>(None, None)?,
2210                Interval::make::<i64>(None, None)?,
2211            ),
2212            (
2213                Interval::try_new(
2214                    ScalarValue::Float32(Some(0.0_f32)),
2215                    next_value(ScalarValue::Float32(Some(0.0_f32))),
2216                )?,
2217                Interval::make(Some(0.0_f32), Some(0.0_f32))?,
2218            ),
2219            (
2220                Interval::make(Some(-1.0_f32), Some(-1.0_f32))?,
2221                Interval::try_new(
2222                    prev_value(ScalarValue::Float32(Some(-1.0_f32))),
2223                    ScalarValue::Float32(Some(-1.0_f32)),
2224                )?,
2225            ),
2226        ];
2227        for (first, second) in possibly_gt_cases {
2228            assert_eq!(first.gt(second.clone())?, Interval::UNCERTAIN);
2229            assert_eq!(second.lt(first)?, Interval::UNCERTAIN);
2230        }
2231
2232        let not_gt_cases = vec![
2233            (
2234                Interval::make(Some(1000_i64), Some(1000_i64))?,
2235                Interval::make(Some(1000_i64), Some(1000_i64))?,
2236            ),
2237            (
2238                Interval::make(Some(500_i64), Some(1000_i64))?,
2239                Interval::make(Some(1000_i64), None)?,
2240            ),
2241            (
2242                Interval::make(None, Some(1000_i64))?,
2243                Interval::make(Some(1000_i64), Some(1500_i64))?,
2244            ),
2245            (
2246                Interval::make(Some(0_u8), Some(0_u8))?,
2247                Interval::make::<u8>(None, None)?,
2248            ),
2249            (
2250                Interval::try_new(
2251                    prev_value(ScalarValue::Float32(Some(0.0_f32))),
2252                    ScalarValue::Float32(Some(0.0_f32)),
2253                )?,
2254                Interval::make(Some(0.0_f32), Some(0.0_f32))?,
2255            ),
2256            (
2257                Interval::make(Some(-1.0_f32), Some(-1.0_f32))?,
2258                Interval::try_new(
2259                    ScalarValue::Float32(Some(-1.0_f32)),
2260                    next_value(ScalarValue::Float32(Some(-1.0_f32))),
2261                )?,
2262            ),
2263        ];
2264        for (first, second) in not_gt_cases {
2265            assert_eq!(first.gt(second.clone())?, Interval::CERTAINLY_FALSE);
2266            assert_eq!(second.lt(first)?, Interval::CERTAINLY_FALSE);
2267        }
2268
2269        Ok(())
2270    }
2271
2272    #[test]
2273    fn gteq_lteq_test() -> Result<()> {
2274        let exactly_gteq_cases = vec![
2275            (
2276                Interval::make(Some(1000_i64), None)?,
2277                Interval::make(None, Some(1000_i64))?,
2278            ),
2279            (
2280                Interval::make(Some(1000_i64), Some(1000_i64))?,
2281                Interval::make(None, Some(1000_i64))?,
2282            ),
2283            (
2284                Interval::make(Some(500_i64), Some(1000_i64))?,
2285                Interval::make(Some(500_i64), Some(500_i64))?,
2286            ),
2287            (
2288                Interval::make(Some(-1000_i64), Some(1000_i64))?,
2289                Interval::make(None, Some(-1500_i64))?,
2290            ),
2291            (
2292                Interval::make::<u64>(None, None)?,
2293                Interval::make(Some(0_u64), Some(0_u64))?,
2294            ),
2295            (
2296                Interval::make(Some(0.0_f32), Some(0.0_f32))?,
2297                Interval::make(Some(0.0_f32), Some(0.0_f32))?,
2298            ),
2299            (
2300                Interval::try_new(
2301                    ScalarValue::Float32(Some(-1.0)),
2302                    next_value(ScalarValue::Float32(Some(-1.0))),
2303                )?,
2304                Interval::try_new(
2305                    prev_value(ScalarValue::Float32(Some(-1.0))),
2306                    ScalarValue::Float32(Some(-1.0)),
2307                )?,
2308            ),
2309        ];
2310        for (first, second) in exactly_gteq_cases {
2311            assert_eq!(first.gt_eq(second.clone())?, Interval::CERTAINLY_TRUE);
2312            assert_eq!(second.lt_eq(first)?, Interval::CERTAINLY_TRUE);
2313        }
2314
2315        let possibly_gteq_cases = vec![
2316            (
2317                Interval::make(Some(999_i64), Some(2000_i64))?,
2318                Interval::make(Some(1000_i64), Some(1000_i64))?,
2319            ),
2320            (
2321                Interval::make(Some(500_i64), Some(1000_i64))?,
2322                Interval::make(Some(500_i64), Some(1001_i64))?,
2323            ),
2324            (
2325                Interval::make(Some(0_i64), None)?,
2326                Interval::make(Some(1000_i64), None)?,
2327            ),
2328            (
2329                Interval::make::<i64>(None, None)?,
2330                Interval::make::<i64>(None, None)?,
2331            ),
2332            (
2333                Interval::try_new(
2334                    prev_value(ScalarValue::Float32(Some(0.0))),
2335                    ScalarValue::Float32(Some(0.0)),
2336                )?,
2337                Interval::make(Some(0.0_f32), Some(0.0_f32))?,
2338            ),
2339            (
2340                Interval::make(Some(-1.0_f32), Some(-1.0_f32))?,
2341                Interval::try_new(
2342                    prev_value(ScalarValue::Float32(Some(-1.0_f32))),
2343                    next_value(ScalarValue::Float32(Some(-1.0_f32))),
2344                )?,
2345            ),
2346        ];
2347        for (first, second) in possibly_gteq_cases {
2348            assert_eq!(first.gt_eq(second.clone())?, Interval::UNCERTAIN);
2349            assert_eq!(second.lt_eq(first)?, Interval::UNCERTAIN);
2350        }
2351
2352        let not_gteq_cases = vec![
2353            (
2354                Interval::make(Some(1000_i64), Some(1000_i64))?,
2355                Interval::make(Some(2000_i64), Some(2000_i64))?,
2356            ),
2357            (
2358                Interval::make(Some(500_i64), Some(999_i64))?,
2359                Interval::make(Some(1000_i64), None)?,
2360            ),
2361            (
2362                Interval::make(None, Some(1000_i64))?,
2363                Interval::make(Some(1001_i64), Some(1500_i64))?,
2364            ),
2365            (
2366                Interval::try_new(
2367                    prev_value(ScalarValue::Float32(Some(0.0_f32))),
2368                    prev_value(ScalarValue::Float32(Some(0.0_f32))),
2369                )?,
2370                Interval::make(Some(0.0_f32), Some(0.0_f32))?,
2371            ),
2372            (
2373                Interval::make(Some(-1.0_f32), Some(-1.0_f32))?,
2374                Interval::try_new(
2375                    next_value(ScalarValue::Float32(Some(-1.0))),
2376                    next_value(ScalarValue::Float32(Some(-1.0))),
2377                )?,
2378            ),
2379        ];
2380        for (first, second) in not_gteq_cases {
2381            assert_eq!(first.gt_eq(second.clone())?, Interval::CERTAINLY_FALSE);
2382            assert_eq!(second.lt_eq(first)?, Interval::CERTAINLY_FALSE);
2383        }
2384
2385        Ok(())
2386    }
2387
2388    #[test]
2389    fn equal_test() -> Result<()> {
2390        let exactly_eq_cases = vec![
2391            (
2392                Interval::make(Some(1000_i64), Some(1000_i64))?,
2393                Interval::make(Some(1000_i64), Some(1000_i64))?,
2394            ),
2395            (
2396                Interval::make(Some(0_u64), Some(0_u64))?,
2397                Interval::make(Some(0_u64), Some(0_u64))?,
2398            ),
2399            (
2400                Interval::make(Some(f32::MAX), Some(f32::MAX))?,
2401                Interval::make(Some(f32::MAX), Some(f32::MAX))?,
2402            ),
2403            (
2404                Interval::make(Some(f64::MIN), Some(f64::MIN))?,
2405                Interval::make(Some(f64::MIN), Some(f64::MIN))?,
2406            ),
2407        ];
2408        for (first, second) in exactly_eq_cases {
2409            assert_eq!(first.equal(second.clone())?, Interval::CERTAINLY_TRUE);
2410            assert_eq!(second.equal(first)?, Interval::CERTAINLY_TRUE);
2411        }
2412
2413        let possibly_eq_cases = vec![
2414            (
2415                Interval::make::<i64>(None, None)?,
2416                Interval::make::<i64>(None, None)?,
2417            ),
2418            (
2419                Interval::make(Some(0_i64), Some(0_i64))?,
2420                Interval::make(Some(0_i64), Some(1000_i64))?,
2421            ),
2422            (
2423                Interval::make(Some(0_i64), Some(0_i64))?,
2424                Interval::make(Some(0_i64), Some(1000_i64))?,
2425            ),
2426            (
2427                Interval::make(Some(100.0_f32), Some(200.0_f32))?,
2428                Interval::make(Some(0.0_f32), Some(1000.0_f32))?,
2429            ),
2430            (
2431                Interval::try_new(
2432                    prev_value(ScalarValue::Float32(Some(0.0))),
2433                    ScalarValue::Float32(Some(0.0)),
2434                )?,
2435                Interval::make(Some(0.0_f32), Some(0.0_f32))?,
2436            ),
2437            (
2438                Interval::make(Some(-1.0_f32), Some(-1.0_f32))?,
2439                Interval::try_new(
2440                    prev_value(ScalarValue::Float32(Some(-1.0))),
2441                    next_value(ScalarValue::Float32(Some(-1.0))),
2442                )?,
2443            ),
2444        ];
2445        for (first, second) in possibly_eq_cases {
2446            assert_eq!(first.equal(second.clone())?, Interval::UNCERTAIN);
2447            assert_eq!(second.equal(first)?, Interval::UNCERTAIN);
2448        }
2449
2450        let not_eq_cases = vec![
2451            (
2452                Interval::make(Some(1000_i64), Some(1000_i64))?,
2453                Interval::make(Some(2000_i64), Some(2000_i64))?,
2454            ),
2455            (
2456                Interval::make(Some(500_i64), Some(999_i64))?,
2457                Interval::make(Some(1000_i64), None)?,
2458            ),
2459            (
2460                Interval::make(None, Some(1000_i64))?,
2461                Interval::make(Some(1001_i64), Some(1500_i64))?,
2462            ),
2463            (
2464                Interval::try_new(
2465                    prev_value(ScalarValue::Float32(Some(0.0))),
2466                    prev_value(ScalarValue::Float32(Some(0.0))),
2467                )?,
2468                Interval::make(Some(0.0_f32), Some(0.0_f32))?,
2469            ),
2470            (
2471                Interval::make(Some(-1.0_f32), Some(-1.0_f32))?,
2472                Interval::try_new(
2473                    next_value(ScalarValue::Float32(Some(-1.0))),
2474                    next_value(ScalarValue::Float32(Some(-1.0))),
2475                )?,
2476            ),
2477        ];
2478        for (first, second) in not_eq_cases {
2479            assert_eq!(first.equal(second.clone())?, Interval::CERTAINLY_FALSE);
2480            assert_eq!(second.equal(first)?, Interval::CERTAINLY_FALSE);
2481        }
2482
2483        Ok(())
2484    }
2485
2486    #[test]
2487    fn and_test() -> Result<()> {
2488        let cases = vec![
2489            (false, true, false, false, false, false),
2490            (false, false, false, true, false, false),
2491            (false, true, false, true, false, true),
2492            (false, true, true, true, false, true),
2493            (false, false, false, false, false, false),
2494            (true, true, true, true, true, true),
2495        ];
2496
2497        for case in cases {
2498            assert_eq!(
2499                Interval::make(Some(case.0), Some(case.1))?
2500                    .and(Interval::make(Some(case.2), Some(case.3))?)?,
2501                Interval::make(Some(case.4), Some(case.5))?
2502            );
2503        }
2504        Ok(())
2505    }
2506
2507    #[test]
2508    fn not_test() -> Result<()> {
2509        let cases = vec![
2510            (false, true, false, true),
2511            (false, false, true, true),
2512            (true, true, false, false),
2513        ];
2514
2515        for case in cases {
2516            assert_eq!(
2517                Interval::make(Some(case.0), Some(case.1))?.not()?,
2518                Interval::make(Some(case.2), Some(case.3))?
2519            );
2520        }
2521        Ok(())
2522    }
2523
2524    #[test]
2525    fn test_and_or_with_normalized_boolean_intervals() -> Result<()> {
2526        // Verify that NULL boolean bounds are normalized and don't cause errors
2527        let from_nulls =
2528            Interval::try_new(ScalarValue::Boolean(None), ScalarValue::Boolean(None))?;
2529
2530        assert!(from_nulls.or(&Interval::CERTAINLY_TRUE).is_ok());
2531        assert!(from_nulls.and(&Interval::CERTAINLY_FALSE).is_ok());
2532
2533        Ok(())
2534    }
2535
2536    #[test]
2537    fn test_and_null_boolean_intervals() -> Result<()> {
2538        let null_interval =
2539            Interval::try_new(ScalarValue::Boolean(None), ScalarValue::Boolean(None))?;
2540
2541        let and_result = null_interval.and(&Interval::CERTAINLY_FALSE)?;
2542        assert_eq!(and_result, Interval::CERTAINLY_FALSE);
2543
2544        let and_result = Interval::CERTAINLY_FALSE.and(&null_interval)?;
2545        assert_eq!(and_result, Interval::CERTAINLY_FALSE);
2546
2547        let and_result = null_interval.and(&Interval::CERTAINLY_TRUE)?;
2548        assert_eq!(and_result, Interval::UNCERTAIN);
2549
2550        let and_result = Interval::CERTAINLY_TRUE.and(&null_interval)?;
2551        assert_eq!(and_result, Interval::UNCERTAIN);
2552
2553        let and_result = null_interval.and(&null_interval)?;
2554        assert_eq!(and_result, Interval::UNCERTAIN);
2555
2556        Ok(())
2557    }
2558
2559    #[test]
2560    fn test_or_null_boolean_intervals() -> Result<()> {
2561        let null_interval =
2562            Interval::try_new(ScalarValue::Boolean(None), ScalarValue::Boolean(None))?;
2563
2564        let or_result = null_interval.or(&Interval::CERTAINLY_FALSE)?;
2565        assert_eq!(or_result, Interval::UNCERTAIN);
2566
2567        let or_result = Interval::CERTAINLY_FALSE.or(&null_interval)?;
2568        assert_eq!(or_result, Interval::UNCERTAIN);
2569
2570        let or_result = null_interval.or(&Interval::CERTAINLY_TRUE)?;
2571        assert_eq!(or_result, Interval::CERTAINLY_TRUE);
2572
2573        let or_result = Interval::CERTAINLY_TRUE.or(&null_interval)?;
2574        assert_eq!(or_result, Interval::CERTAINLY_TRUE);
2575
2576        let or_result = null_interval.or(&null_interval)?;
2577        assert_eq!(or_result, Interval::UNCERTAIN);
2578
2579        Ok(())
2580    }
2581
2582    #[test]
2583    fn intersect_test() -> Result<()> {
2584        let possible_cases = vec![
2585            (
2586                Interval::make(Some(1000_i64), None)?,
2587                Interval::make::<i64>(None, None)?,
2588                Interval::make(Some(1000_i64), None)?,
2589            ),
2590            (
2591                Interval::make(Some(1000_i64), None)?,
2592                Interval::make(None, Some(1000_i64))?,
2593                Interval::make(Some(1000_i64), Some(1000_i64))?,
2594            ),
2595            (
2596                Interval::make(Some(1000_i64), None)?,
2597                Interval::make(None, Some(2000_i64))?,
2598                Interval::make(Some(1000_i64), Some(2000_i64))?,
2599            ),
2600            (
2601                Interval::make(Some(1000_i64), Some(2000_i64))?,
2602                Interval::make(Some(1000_i64), None)?,
2603                Interval::make(Some(1000_i64), Some(2000_i64))?,
2604            ),
2605            (
2606                Interval::make(Some(1000_i64), Some(2000_i64))?,
2607                Interval::make(Some(1000_i64), Some(1500_i64))?,
2608                Interval::make(Some(1000_i64), Some(1500_i64))?,
2609            ),
2610            (
2611                Interval::make(Some(1000_i64), Some(2000_i64))?,
2612                Interval::make(Some(500_i64), Some(1500_i64))?,
2613                Interval::make(Some(1000_i64), Some(1500_i64))?,
2614            ),
2615            (
2616                Interval::make::<i64>(None, None)?,
2617                Interval::make::<i64>(None, None)?,
2618                Interval::make::<i64>(None, None)?,
2619            ),
2620            (
2621                Interval::make(None, Some(2000_u64))?,
2622                Interval::make(Some(500_u64), None)?,
2623                Interval::make(Some(500_u64), Some(2000_u64))?,
2624            ),
2625            (
2626                Interval::make(Some(0_u64), Some(0_u64))?,
2627                Interval::make(Some(0_u64), None)?,
2628                Interval::make(Some(0_u64), Some(0_u64))?,
2629            ),
2630            (
2631                Interval::make(Some(1000.0_f32), None)?,
2632                Interval::make(None, Some(1000.0_f32))?,
2633                Interval::make(Some(1000.0_f32), Some(1000.0_f32))?,
2634            ),
2635            (
2636                Interval::make(Some(1000.0_f32), Some(1500.0_f32))?,
2637                Interval::make(Some(0.0_f32), Some(1500.0_f32))?,
2638                Interval::make(Some(1000.0_f32), Some(1500.0_f32))?,
2639            ),
2640            (
2641                Interval::make(Some(-1000.0_f64), Some(1500.0_f64))?,
2642                Interval::make(Some(-1500.0_f64), Some(2000.0_f64))?,
2643                Interval::make(Some(-1000.0_f64), Some(1500.0_f64))?,
2644            ),
2645            (
2646                Interval::make(Some(16.0_f64), Some(32.0_f64))?,
2647                Interval::make(Some(32.0_f64), Some(64.0_f64))?,
2648                Interval::make(Some(32.0_f64), Some(32.0_f64))?,
2649            ),
2650        ];
2651        for (first, second, expected) in possible_cases {
2652            assert_eq!(first.intersect(second)?.unwrap(), expected)
2653        }
2654
2655        let empty_cases = vec![
2656            (
2657                Interval::make(Some(1000_i64), None)?,
2658                Interval::make(None, Some(0_i64))?,
2659            ),
2660            (
2661                Interval::make(Some(1000_i64), None)?,
2662                Interval::make(None, Some(999_i64))?,
2663            ),
2664            (
2665                Interval::make(Some(1500_i64), Some(2000_i64))?,
2666                Interval::make(Some(1000_i64), Some(1499_i64))?,
2667            ),
2668            (
2669                Interval::make(Some(0_i64), Some(1000_i64))?,
2670                Interval::make(Some(2000_i64), Some(3000_i64))?,
2671            ),
2672            (
2673                Interval::try_new(
2674                    prev_value(ScalarValue::Float32(Some(1.0))),
2675                    prev_value(ScalarValue::Float32(Some(1.0))),
2676                )?,
2677                Interval::make(Some(1.0_f32), Some(1.0_f32))?,
2678            ),
2679            (
2680                Interval::try_new(
2681                    next_value(ScalarValue::Float32(Some(1.0))),
2682                    next_value(ScalarValue::Float32(Some(1.0))),
2683                )?,
2684                Interval::make(Some(1.0_f32), Some(1.0_f32))?,
2685            ),
2686        ];
2687        for (first, second) in empty_cases {
2688            assert_eq!(first.intersect(second)?, None)
2689        }
2690
2691        Ok(())
2692    }
2693
2694    #[test]
2695    fn union_test() -> Result<()> {
2696        let possible_cases = vec![
2697            (
2698                Interval::make(Some(1000_i64), None)?,
2699                Interval::make::<i64>(None, None)?,
2700                Interval::make_unbounded(&DataType::Int64)?,
2701            ),
2702            (
2703                Interval::make(Some(1000_i64), None)?,
2704                Interval::make(None, Some(1000_i64))?,
2705                Interval::make_unbounded(&DataType::Int64)?,
2706            ),
2707            (
2708                Interval::make(Some(1000_i64), None)?,
2709                Interval::make(None, Some(2000_i64))?,
2710                Interval::make_unbounded(&DataType::Int64)?,
2711            ),
2712            (
2713                Interval::make(Some(1000_i64), Some(2000_i64))?,
2714                Interval::make(Some(1000_i64), None)?,
2715                Interval::make(Some(1000_i64), None)?,
2716            ),
2717            (
2718                Interval::make(Some(1000_i64), Some(2000_i64))?,
2719                Interval::make(Some(1000_i64), Some(1500_i64))?,
2720                Interval::make(Some(1000_i64), Some(2000_i64))?,
2721            ),
2722            (
2723                Interval::make(Some(1000_i64), Some(2000_i64))?,
2724                Interval::make(Some(500_i64), Some(1500_i64))?,
2725                Interval::make(Some(500_i64), Some(2000_i64))?,
2726            ),
2727            (
2728                Interval::make::<i64>(None, None)?,
2729                Interval::make::<i64>(None, None)?,
2730                Interval::make::<i64>(None, None)?,
2731            ),
2732            (
2733                Interval::make(Some(1000_i64), None)?,
2734                Interval::make(None, Some(0_i64))?,
2735                Interval::make_unbounded(&DataType::Int64)?,
2736            ),
2737            (
2738                Interval::make(Some(1000_i64), None)?,
2739                Interval::make(None, Some(999_i64))?,
2740                Interval::make_unbounded(&DataType::Int64)?,
2741            ),
2742            (
2743                Interval::make(Some(1500_i64), Some(2000_i64))?,
2744                Interval::make(Some(1000_i64), Some(1499_i64))?,
2745                Interval::make(Some(1000_i64), Some(2000_i64))?,
2746            ),
2747            (
2748                Interval::make(Some(0_i64), Some(1000_i64))?,
2749                Interval::make(Some(2000_i64), Some(3000_i64))?,
2750                Interval::make(Some(0_i64), Some(3000_i64))?,
2751            ),
2752            (
2753                Interval::make(None, Some(2000_u64))?,
2754                Interval::make(Some(500_u64), None)?,
2755                Interval::make(Some(0_u64), None)?,
2756            ),
2757            (
2758                Interval::make(Some(0_u64), Some(0_u64))?,
2759                Interval::make(Some(0_u64), None)?,
2760                Interval::make(Some(0_u64), None)?,
2761            ),
2762            (
2763                Interval::make(Some(1000.0_f32), None)?,
2764                Interval::make(None, Some(1000.0_f32))?,
2765                Interval::make_unbounded(&DataType::Float32)?,
2766            ),
2767            (
2768                Interval::make(Some(1000.0_f32), Some(1500.0_f32))?,
2769                Interval::make(Some(0.0_f32), Some(1500.0_f32))?,
2770                Interval::make(Some(0.0_f32), Some(1500.0_f32))?,
2771            ),
2772            (
2773                Interval::try_new(
2774                    prev_value(ScalarValue::Float32(Some(1.0))),
2775                    prev_value(ScalarValue::Float32(Some(1.0))),
2776                )?,
2777                Interval::make(Some(1.0_f32), Some(1.0_f32))?,
2778                Interval::try_new(
2779                    prev_value(ScalarValue::Float32(Some(1.0))),
2780                    ScalarValue::Float32(Some(1.0)),
2781                )?,
2782            ),
2783            (
2784                Interval::try_new(
2785                    next_value(ScalarValue::Float32(Some(1.0))),
2786                    next_value(ScalarValue::Float32(Some(1.0))),
2787                )?,
2788                Interval::make(Some(1.0_f32), Some(1.0_f32))?,
2789                Interval::try_new(
2790                    ScalarValue::Float32(Some(1.0)),
2791                    next_value(ScalarValue::Float32(Some(1.0))),
2792                )?,
2793            ),
2794            (
2795                Interval::make(Some(-1000.0_f64), Some(1500.0_f64))?,
2796                Interval::make(Some(-1500.0_f64), Some(2000.0_f64))?,
2797                Interval::make(Some(-1500.0_f64), Some(2000.0_f64))?,
2798            ),
2799            (
2800                Interval::make(Some(16.0_f64), Some(32.0_f64))?,
2801                Interval::make(Some(32.0_f64), Some(64.0_f64))?,
2802                Interval::make(Some(16.0_f64), Some(64.0_f64))?,
2803            ),
2804        ];
2805        for (first, second, expected) in possible_cases {
2806            println!("{first}");
2807            println!("{second}");
2808            assert_eq!(first.union(second)?, expected)
2809        }
2810
2811        Ok(())
2812    }
2813
2814    #[test]
2815    fn test_contains() -> Result<()> {
2816        let possible_cases = vec![
2817            (
2818                Interval::make::<i64>(None, None)?,
2819                Interval::make::<i64>(None, None)?,
2820                Interval::CERTAINLY_TRUE,
2821            ),
2822            (
2823                Interval::make(Some(1500_i64), Some(2000_i64))?,
2824                Interval::make(Some(1501_i64), Some(1999_i64))?,
2825                Interval::CERTAINLY_TRUE,
2826            ),
2827            (
2828                Interval::make(Some(1000_i64), None)?,
2829                Interval::make::<i64>(None, None)?,
2830                Interval::UNCERTAIN,
2831            ),
2832            (
2833                Interval::make(Some(1000_i64), Some(2000_i64))?,
2834                Interval::make(Some(500), Some(1500_i64))?,
2835                Interval::UNCERTAIN,
2836            ),
2837            (
2838                Interval::make(Some(16.0), Some(32.0))?,
2839                Interval::make(Some(32.0), Some(64.0))?,
2840                Interval::UNCERTAIN,
2841            ),
2842            (
2843                Interval::make(Some(1000_i64), None)?,
2844                Interval::make(None, Some(0_i64))?,
2845                Interval::CERTAINLY_FALSE,
2846            ),
2847            (
2848                Interval::make(Some(1500_i64), Some(2000_i64))?,
2849                Interval::make(Some(1000_i64), Some(1499_i64))?,
2850                Interval::CERTAINLY_FALSE,
2851            ),
2852            (
2853                Interval::try_new(
2854                    prev_value(ScalarValue::Float32(Some(1.0))),
2855                    prev_value(ScalarValue::Float32(Some(1.0))),
2856                )?,
2857                Interval::make(Some(1.0_f32), Some(1.0_f32))?,
2858                Interval::CERTAINLY_FALSE,
2859            ),
2860            (
2861                Interval::try_new(
2862                    next_value(ScalarValue::Float32(Some(1.0))),
2863                    next_value(ScalarValue::Float32(Some(1.0))),
2864                )?,
2865                Interval::make(Some(1.0_f32), Some(1.0_f32))?,
2866                Interval::CERTAINLY_FALSE,
2867            ),
2868        ];
2869        for (first, second, expected) in possible_cases {
2870            assert_eq!(first.contains(second)?, expected)
2871        }
2872
2873        Ok(())
2874    }
2875
2876    #[test]
2877    fn test_contains_value() -> Result<()> {
2878        let possible_cases = vec![
2879            (
2880                Interval::make(Some(0), Some(100))?,
2881                ScalarValue::Int32(Some(50)),
2882                true,
2883            ),
2884            (
2885                Interval::make(Some(0), Some(100))?,
2886                ScalarValue::Int32(Some(150)),
2887                false,
2888            ),
2889            (
2890                Interval::make(Some(0), Some(100))?,
2891                ScalarValue::Float64(Some(50.)),
2892                true,
2893            ),
2894            (
2895                Interval::make(Some(0), Some(100))?,
2896                ScalarValue::Float64(Some(next_down(100.))),
2897                true,
2898            ),
2899            (
2900                Interval::make(Some(0), Some(100))?,
2901                ScalarValue::Float64(Some(next_up(100.))),
2902                false,
2903            ),
2904        ];
2905
2906        for (interval, value, expected) in possible_cases {
2907            assert_eq!(interval.contains_value(value)?, expected)
2908        }
2909
2910        Ok(())
2911    }
2912
2913    #[test]
2914    fn test_add() -> Result<()> {
2915        let cases = vec![
2916            (
2917                Interval::make(Some(100_i64), Some(200_i64))?,
2918                Interval::make(None, Some(200_i64))?,
2919                Interval::make(None, Some(400_i64))?,
2920            ),
2921            (
2922                Interval::make(Some(100_i64), Some(200_i64))?,
2923                Interval::make(Some(200_i64), None)?,
2924                Interval::make(Some(300_i64), None)?,
2925            ),
2926            (
2927                Interval::make(None, Some(200_i64))?,
2928                Interval::make(Some(100_i64), Some(200_i64))?,
2929                Interval::make(None, Some(400_i64))?,
2930            ),
2931            (
2932                Interval::make(Some(200_i64), None)?,
2933                Interval::make(Some(100_i64), Some(200_i64))?,
2934                Interval::make(Some(300_i64), None)?,
2935            ),
2936            (
2937                Interval::make(Some(100_i64), Some(200_i64))?,
2938                Interval::make(Some(-300_i64), Some(150_i64))?,
2939                Interval::make(Some(-200_i64), Some(350_i64))?,
2940            ),
2941            (
2942                Interval::make(Some(f32::MAX), Some(f32::MAX))?,
2943                Interval::make(Some(11_f32), Some(11_f32))?,
2944                Interval::make(Some(f32::MAX), None)?,
2945            ),
2946            (
2947                Interval::make(Some(f32::MIN), Some(f32::MIN))?,
2948                Interval::make(Some(-10_f32), Some(10_f32))?,
2949                // Since rounding mode is up, the result would be much greater than f32::MIN
2950                // (f32::MIN = -3.4_028_235e38, the result is -3.4_028_233e38)
2951                Interval::make(
2952                    None,
2953                    Some(-340282330000000000000000000000000000000.0_f32),
2954                )?,
2955            ),
2956            (
2957                Interval::make(Some(f32::MIN), Some(f32::MIN))?,
2958                Interval::make(Some(-10_f32), Some(-10_f32))?,
2959                Interval::make(None, Some(f32::MIN))?,
2960            ),
2961            (
2962                Interval::make(Some(1.0), Some(f32::MAX))?,
2963                Interval::make(Some(f32::MAX), Some(f32::MAX))?,
2964                Interval::make(Some(f32::MAX), None)?,
2965            ),
2966            (
2967                Interval::make(Some(f32::MIN), Some(f32::MIN))?,
2968                Interval::make(Some(f32::MAX), Some(f32::MAX))?,
2969                Interval::make(Some(-0.0_f32), Some(0.0_f32))?,
2970            ),
2971            (
2972                Interval::make(Some(100_f64), None)?,
2973                Interval::make(None, Some(200_f64))?,
2974                Interval::make::<i64>(None, None)?,
2975            ),
2976            (
2977                Interval::make(None, Some(100_f64))?,
2978                Interval::make(None, Some(200_f64))?,
2979                Interval::make(None, Some(300_f64))?,
2980            ),
2981        ];
2982        for case in cases {
2983            let result = case.0.add(case.1)?;
2984            if case.0.data_type().is_floating() {
2985                assert!(
2986                    result.lower().is_null() && case.2.lower().is_null()
2987                        || result.lower().le(case.2.lower())
2988                );
2989                assert!(
2990                    result.upper().is_null() && case.2.upper().is_null()
2991                        || result.upper().ge(case.2.upper())
2992                );
2993            } else {
2994                assert_eq!(result, case.2);
2995            }
2996        }
2997
2998        Ok(())
2999    }
3000
3001    #[test]
3002    fn test_sub() -> Result<()> {
3003        let cases = vec![
3004            (
3005                Interval::make(Some(i32::MAX), Some(i32::MAX))?,
3006                Interval::make(Some(11_i32), Some(11_i32))?,
3007                Interval::make(Some(i32::MAX - 11), Some(i32::MAX - 11))?,
3008            ),
3009            (
3010                Interval::make(Some(100_i64), Some(200_i64))?,
3011                Interval::make(None, Some(200_i64))?,
3012                Interval::make(Some(-100_i64), None)?,
3013            ),
3014            (
3015                Interval::make(Some(100_i64), Some(200_i64))?,
3016                Interval::make(Some(200_i64), None)?,
3017                Interval::make(None, Some(0_i64))?,
3018            ),
3019            (
3020                Interval::make(None, Some(200_i64))?,
3021                Interval::make(Some(100_i64), Some(200_i64))?,
3022                Interval::make(None, Some(100_i64))?,
3023            ),
3024            (
3025                Interval::make(Some(200_i64), None)?,
3026                Interval::make(Some(100_i64), Some(200_i64))?,
3027                Interval::make(Some(0_i64), None)?,
3028            ),
3029            (
3030                Interval::make(Some(100_i64), Some(200_i64))?,
3031                Interval::make(Some(-300_i64), Some(150_i64))?,
3032                Interval::make(Some(-50_i64), Some(500_i64))?,
3033            ),
3034            (
3035                Interval::make(Some(i64::MIN), Some(i64::MIN))?,
3036                Interval::make(Some(-10_i64), Some(-10_i64))?,
3037                Interval::make(Some(i64::MIN + 10), Some(i64::MIN + 10))?,
3038            ),
3039            (
3040                Interval::make(Some(1), Some(i64::MAX))?,
3041                Interval::make(Some(i64::MAX), Some(i64::MAX))?,
3042                Interval::make(Some(1 - i64::MAX), Some(0))?,
3043            ),
3044            (
3045                Interval::make(Some(i64::MIN), Some(i64::MIN))?,
3046                Interval::make(Some(i64::MAX), Some(i64::MAX))?,
3047                Interval::make(None, Some(i64::MIN))?,
3048            ),
3049            (
3050                Interval::make(Some(2_u32), Some(10_u32))?,
3051                Interval::make(Some(4_u32), Some(6_u32))?,
3052                Interval::make(None, Some(6_u32))?,
3053            ),
3054            (
3055                Interval::make(Some(2_u32), Some(10_u32))?,
3056                Interval::make(Some(20_u32), Some(30_u32))?,
3057                Interval::make(None, Some(0_u32))?,
3058            ),
3059            (
3060                Interval::make(Some(f32::MIN), Some(f32::MIN))?,
3061                Interval::make(Some(-10_f32), Some(10_f32))?,
3062                // Since rounding mode is up, the result would be much larger than f32::MIN
3063                // (f32::MIN = -3.4_028_235e38, the result is -3.4_028_233e38)
3064                Interval::make(
3065                    None,
3066                    Some(-340282330000000000000000000000000000000.0_f32),
3067                )?,
3068            ),
3069            (
3070                Interval::make(Some(100_f64), None)?,
3071                Interval::make(None, Some(200_f64))?,
3072                Interval::make(Some(-100_f64), None)?,
3073            ),
3074            (
3075                Interval::make(None, Some(100_f64))?,
3076                Interval::make(None, Some(200_f64))?,
3077                Interval::make::<i64>(None, None)?,
3078            ),
3079        ];
3080        for case in cases {
3081            let result = case.0.sub(case.1)?;
3082            if case.0.data_type().is_floating() {
3083                assert!(
3084                    result.lower().is_null() && case.2.lower().is_null()
3085                        || result.lower().le(case.2.lower())
3086                );
3087                assert!(
3088                    result.upper().is_null() && case.2.upper().is_null()
3089                        || result.upper().ge(case.2.upper(),)
3090                );
3091            } else {
3092                assert_eq!(result, case.2);
3093            }
3094        }
3095
3096        Ok(())
3097    }
3098
3099    #[test]
3100    fn test_mul() -> Result<()> {
3101        let cases = vec![
3102            (
3103                Interval::make(Some(1_i64), Some(2_i64))?,
3104                Interval::make(None, Some(2_i64))?,
3105                Interval::make(None, Some(4_i64))?,
3106            ),
3107            (
3108                Interval::make(Some(1_i64), Some(2_i64))?,
3109                Interval::make(Some(2_i64), None)?,
3110                Interval::make(Some(2_i64), None)?,
3111            ),
3112            (
3113                Interval::make(None, Some(2_i64))?,
3114                Interval::make(Some(1_i64), Some(2_i64))?,
3115                Interval::make(None, Some(4_i64))?,
3116            ),
3117            (
3118                Interval::make(Some(2_i64), None)?,
3119                Interval::make(Some(1_i64), Some(2_i64))?,
3120                Interval::make(Some(2_i64), None)?,
3121            ),
3122            (
3123                Interval::make(Some(1_i64), Some(2_i64))?,
3124                Interval::make(Some(-3_i64), Some(15_i64))?,
3125                Interval::make(Some(-6_i64), Some(30_i64))?,
3126            ),
3127            (
3128                Interval::make(Some(-0.0), Some(0.0))?,
3129                Interval::make(None, Some(0.0))?,
3130                Interval::make::<i64>(None, None)?,
3131            ),
3132            (
3133                Interval::make(Some(f32::MIN), Some(f32::MIN))?,
3134                Interval::make(Some(-10_f32), Some(10_f32))?,
3135                Interval::make::<i64>(None, None)?,
3136            ),
3137            (
3138                Interval::make(Some(1_u32), Some(2_u32))?,
3139                Interval::make(Some(0_u32), Some(1_u32))?,
3140                Interval::make(Some(0_u32), Some(2_u32))?,
3141            ),
3142            (
3143                Interval::make(None, Some(2_u32))?,
3144                Interval::make(Some(0_u32), Some(1_u32))?,
3145                Interval::make(None, Some(2_u32))?,
3146            ),
3147            (
3148                Interval::make(None, Some(2_u32))?,
3149                Interval::make(Some(1_u32), Some(2_u32))?,
3150                Interval::make(None, Some(4_u32))?,
3151            ),
3152            (
3153                Interval::make(None, Some(2_u32))?,
3154                Interval::make(Some(1_u32), None)?,
3155                Interval::make::<u32>(None, None)?,
3156            ),
3157            (
3158                Interval::make::<u32>(None, None)?,
3159                Interval::make(Some(0_u32), None)?,
3160                Interval::make::<u32>(None, None)?,
3161            ),
3162            (
3163                Interval::make(Some(f32::MAX), Some(f32::MAX))?,
3164                Interval::make(Some(11_f32), Some(11_f32))?,
3165                Interval::make(Some(f32::MAX), None)?,
3166            ),
3167            (
3168                Interval::make(Some(f32::MIN), Some(f32::MIN))?,
3169                Interval::make(Some(-10_f32), Some(-10_f32))?,
3170                Interval::make(Some(f32::MAX), None)?,
3171            ),
3172            (
3173                Interval::make(Some(1.0), Some(f32::MAX))?,
3174                Interval::make(Some(f32::MAX), Some(f32::MAX))?,
3175                Interval::make(Some(f32::MAX), None)?,
3176            ),
3177            (
3178                Interval::make(Some(f32::MIN), Some(f32::MIN))?,
3179                Interval::make(Some(f32::MAX), Some(f32::MAX))?,
3180                Interval::make(None, Some(f32::MIN))?,
3181            ),
3182            (
3183                Interval::make(Some(-0.0_f32), Some(0.0_f32))?,
3184                Interval::make(Some(f32::MAX), None)?,
3185                Interval::make::<f32>(None, None)?,
3186            ),
3187            (
3188                Interval::make(Some(0.0_f32), Some(0.0_f32))?,
3189                Interval::make(Some(f32::MAX), None)?,
3190                Interval::make(Some(0.0_f32), None)?,
3191            ),
3192            (
3193                Interval::make(Some(1_f64), None)?,
3194                Interval::make(None, Some(2_f64))?,
3195                Interval::make::<f64>(None, None)?,
3196            ),
3197            (
3198                Interval::make(None, Some(1_f64))?,
3199                Interval::make(None, Some(2_f64))?,
3200                Interval::make::<f64>(None, None)?,
3201            ),
3202            (
3203                Interval::make(Some(-0.0_f64), Some(-0.0_f64))?,
3204                Interval::make(Some(1_f64), Some(2_f64))?,
3205                Interval::make(Some(-0.0_f64), Some(-0.0_f64))?,
3206            ),
3207            (
3208                Interval::make(Some(0.0_f64), Some(0.0_f64))?,
3209                Interval::make(Some(1_f64), Some(2_f64))?,
3210                Interval::make(Some(0.0_f64), Some(0.0_f64))?,
3211            ),
3212            (
3213                Interval::make(Some(-0.0_f64), Some(0.0_f64))?,
3214                Interval::make(Some(1_f64), Some(2_f64))?,
3215                Interval::make(Some(-0.0_f64), Some(0.0_f64))?,
3216            ),
3217            (
3218                Interval::make(Some(-0.0_f64), Some(1.0_f64))?,
3219                Interval::make(Some(1_f64), Some(2_f64))?,
3220                Interval::make(Some(-0.0_f64), Some(2.0_f64))?,
3221            ),
3222            (
3223                Interval::make(Some(0.0_f64), Some(1.0_f64))?,
3224                Interval::make(Some(1_f64), Some(2_f64))?,
3225                Interval::make(Some(0.0_f64), Some(2.0_f64))?,
3226            ),
3227            (
3228                Interval::make(Some(-0.0_f64), Some(1.0_f64))?,
3229                Interval::make(Some(-1_f64), Some(2_f64))?,
3230                Interval::make(Some(-1.0_f64), Some(2.0_f64))?,
3231            ),
3232            (
3233                Interval::make::<f64>(None, None)?,
3234                Interval::make(Some(-0.0_f64), Some(0.0_f64))?,
3235                Interval::make::<f64>(None, None)?,
3236            ),
3237            (
3238                Interval::make::<f64>(None, Some(10.0_f64))?,
3239                Interval::make(Some(-0.0_f64), Some(0.0_f64))?,
3240                Interval::make::<f64>(None, None)?,
3241            ),
3242        ];
3243        for case in cases {
3244            let result = case.0.mul(case.1)?;
3245            if case.0.data_type().is_floating() {
3246                assert!(
3247                    result.lower().is_null() && case.2.lower().is_null()
3248                        || result.lower().le(case.2.lower())
3249                );
3250                assert!(
3251                    result.upper().is_null() && case.2.upper().is_null()
3252                        || result.upper().ge(case.2.upper())
3253                );
3254            } else {
3255                assert_eq!(result, case.2);
3256            }
3257        }
3258
3259        Ok(())
3260    }
3261
3262    #[test]
3263    fn test_div() -> Result<()> {
3264        let cases = vec![
3265            (
3266                Interval::make(Some(100_i64), Some(200_i64))?,
3267                Interval::make(Some(1_i64), Some(2_i64))?,
3268                Interval::make(Some(50_i64), Some(200_i64))?,
3269            ),
3270            (
3271                Interval::make(Some(-200_i64), Some(-100_i64))?,
3272                Interval::make(Some(-2_i64), Some(-1_i64))?,
3273                Interval::make(Some(50_i64), Some(200_i64))?,
3274            ),
3275            (
3276                Interval::make(Some(100_i64), Some(200_i64))?,
3277                Interval::make(Some(-2_i64), Some(-1_i64))?,
3278                Interval::make(Some(-200_i64), Some(-50_i64))?,
3279            ),
3280            (
3281                Interval::make(Some(-200_i64), Some(-100_i64))?,
3282                Interval::make(Some(1_i64), Some(2_i64))?,
3283                Interval::make(Some(-200_i64), Some(-50_i64))?,
3284            ),
3285            (
3286                Interval::make(Some(-200_i64), Some(100_i64))?,
3287                Interval::make(Some(1_i64), Some(2_i64))?,
3288                Interval::make(Some(-200_i64), Some(100_i64))?,
3289            ),
3290            (
3291                Interval::make(Some(-100_i64), Some(200_i64))?,
3292                Interval::make(Some(1_i64), Some(2_i64))?,
3293                Interval::make(Some(-100_i64), Some(200_i64))?,
3294            ),
3295            (
3296                Interval::make(Some(10_i64), Some(20_i64))?,
3297                Interval::make::<i64>(None, None)?,
3298                Interval::make::<i64>(None, None)?,
3299            ),
3300            (
3301                Interval::make(Some(-100_i64), Some(200_i64))?,
3302                Interval::make(Some(-1_i64), Some(2_i64))?,
3303                Interval::make::<i64>(None, None)?,
3304            ),
3305            (
3306                Interval::make(Some(-100_i64), Some(200_i64))?,
3307                Interval::make(Some(-2_i64), Some(1_i64))?,
3308                Interval::make::<i64>(None, None)?,
3309            ),
3310            (
3311                Interval::make(Some(100_i64), Some(200_i64))?,
3312                Interval::make(Some(0_i64), Some(1_i64))?,
3313                Interval::make(Some(100_i64), None)?,
3314            ),
3315            (
3316                Interval::make(Some(100_i64), Some(200_i64))?,
3317                Interval::make(None, Some(0_i64))?,
3318                Interval::make(None, Some(0_i64))?,
3319            ),
3320            (
3321                Interval::make(Some(100_i64), Some(200_i64))?,
3322                Interval::make(Some(0_i64), Some(0_i64))?,
3323                Interval::make::<i64>(None, None)?,
3324            ),
3325            (
3326                Interval::make(Some(0_i64), Some(1_i64))?,
3327                Interval::make(Some(100_i64), Some(200_i64))?,
3328                Interval::make(Some(0_i64), Some(0_i64))?,
3329            ),
3330            (
3331                Interval::make(Some(0_i64), Some(1_i64))?,
3332                Interval::make(Some(100_i64), Some(200_i64))?,
3333                Interval::make(Some(0_i64), Some(0_i64))?,
3334            ),
3335            (
3336                Interval::make(Some(1_u32), Some(2_u32))?,
3337                Interval::make(Some(0_u32), Some(0_u32))?,
3338                Interval::make::<u32>(None, None)?,
3339            ),
3340            (
3341                Interval::make(Some(10_u32), Some(20_u32))?,
3342                Interval::make(None, Some(2_u32))?,
3343                Interval::make(Some(5_u32), None)?,
3344            ),
3345            (
3346                Interval::make(Some(10_u32), Some(20_u32))?,
3347                Interval::make(Some(0_u32), Some(2_u32))?,
3348                Interval::make(Some(5_u32), None)?,
3349            ),
3350            (
3351                Interval::make(Some(10_u32), Some(20_u32))?,
3352                Interval::make(Some(0_u32), Some(0_u32))?,
3353                Interval::make::<u32>(None, None)?,
3354            ),
3355            (
3356                Interval::make(Some(12_u64), Some(48_u64))?,
3357                Interval::make(Some(10_u64), Some(20_u64))?,
3358                Interval::make(Some(0_u64), Some(4_u64))?,
3359            ),
3360            (
3361                Interval::make(Some(12_u64), Some(48_u64))?,
3362                Interval::make(None, Some(2_u64))?,
3363                Interval::make(Some(6_u64), None)?,
3364            ),
3365            (
3366                Interval::make(Some(12_u64), Some(48_u64))?,
3367                Interval::make(Some(0_u64), Some(2_u64))?,
3368                Interval::make(Some(6_u64), None)?,
3369            ),
3370            (
3371                Interval::make(None, Some(48_u64))?,
3372                Interval::make(Some(0_u64), Some(2_u64))?,
3373                Interval::make::<u64>(None, None)?,
3374            ),
3375            (
3376                Interval::make(Some(f32::MAX), Some(f32::MAX))?,
3377                Interval::make(Some(-0.1_f32), Some(0.1_f32))?,
3378                Interval::make::<f32>(None, None)?,
3379            ),
3380            (
3381                Interval::make(Some(f32::MIN), None)?,
3382                Interval::make(Some(0.1_f32), Some(0.1_f32))?,
3383                Interval::make::<f32>(None, None)?,
3384            ),
3385            (
3386                Interval::make(Some(-10.0_f32), Some(10.0_f32))?,
3387                Interval::make(Some(-0.1_f32), Some(-0.1_f32))?,
3388                Interval::make(Some(-100.0_f32), Some(100.0_f32))?,
3389            ),
3390            (
3391                Interval::make(Some(-10.0_f32), Some(f32::MAX))?,
3392                Interval::make::<f32>(None, None)?,
3393                Interval::make::<f32>(None, None)?,
3394            ),
3395            (
3396                Interval::make(Some(f32::MIN), Some(10.0_f32))?,
3397                Interval::make(Some(1.0_f32), None)?,
3398                Interval::make(Some(f32::MIN), Some(10.0_f32))?,
3399            ),
3400            (
3401                Interval::make(Some(-0.0_f32), Some(0.0_f32))?,
3402                Interval::make(Some(f32::MAX), None)?,
3403                Interval::make(Some(-0.0_f32), Some(0.0_f32))?,
3404            ),
3405            (
3406                Interval::make(Some(-0.0_f32), Some(0.0_f32))?,
3407                Interval::make(None, Some(-0.0_f32))?,
3408                Interval::make::<f32>(None, None)?,
3409            ),
3410            (
3411                Interval::make(Some(0.0_f32), Some(0.0_f32))?,
3412                Interval::make(Some(f32::MAX), None)?,
3413                Interval::make(Some(0.0_f32), Some(0.0_f32))?,
3414            ),
3415            (
3416                Interval::make(Some(1.0_f32), Some(2.0_f32))?,
3417                Interval::make(Some(0.0_f32), Some(4.0_f32))?,
3418                Interval::make(Some(0.25_f32), None)?,
3419            ),
3420            (
3421                Interval::make(Some(1.0_f32), Some(2.0_f32))?,
3422                Interval::make(Some(-4.0_f32), Some(-0.0_f32))?,
3423                Interval::make(None, Some(-0.25_f32))?,
3424            ),
3425            (
3426                Interval::make(Some(-4.0_f64), Some(2.0_f64))?,
3427                Interval::make(Some(10.0_f64), Some(20.0_f64))?,
3428                Interval::make(Some(-0.4_f64), Some(0.2_f64))?,
3429            ),
3430            (
3431                Interval::make(Some(-0.0_f64), Some(-0.0_f64))?,
3432                Interval::make(None, Some(-0.0_f64))?,
3433                Interval::make(Some(0.0_f64), None)?,
3434            ),
3435            (
3436                Interval::make(Some(1.0_f64), Some(2.0_f64))?,
3437                Interval::make::<f64>(None, None)?,
3438                Interval::make(Some(0.0_f64), None)?,
3439            ),
3440        ];
3441        for case in cases {
3442            let result = case.0.div(case.1)?;
3443            if case.0.data_type().is_floating() {
3444                assert!(
3445                    result.lower().is_null() && case.2.lower().is_null()
3446                        || result.lower().le(case.2.lower())
3447                );
3448                assert!(
3449                    result.upper().is_null() && case.2.upper().is_null()
3450                        || result.upper().ge(case.2.upper())
3451                );
3452            } else {
3453                assert_eq!(result, case.2);
3454            }
3455        }
3456
3457        Ok(())
3458    }
3459
3460    #[test]
3461    fn test_overflow_handling() -> Result<()> {
3462        // Test integer overflow handling:
3463        let dt = DataType::Int32;
3464        let op = Operator::Plus;
3465        let lhs = ScalarValue::Int32(Some(i32::MAX));
3466        let rhs = ScalarValue::Int32(Some(1));
3467        let result = handle_overflow::<true>(&dt, op, &lhs, &rhs);
3468        assert_eq!(result, ScalarValue::Int32(None));
3469        let result = handle_overflow::<false>(&dt, op, &lhs, &rhs);
3470        assert_eq!(result, ScalarValue::Int32(Some(i32::MAX)));
3471
3472        // Test float overflow handling:
3473        let dt = DataType::Float32;
3474        let op = Operator::Multiply;
3475        let lhs = ScalarValue::Float32(Some(f32::MAX));
3476        let rhs = ScalarValue::Float32(Some(2.0));
3477        let result = handle_overflow::<true>(&dt, op, &lhs, &rhs);
3478        assert_eq!(result, ScalarValue::Float32(None));
3479        let result = handle_overflow::<false>(&dt, op, &lhs, &rhs);
3480        assert_eq!(result, ScalarValue::Float32(Some(f32::MAX)));
3481
3482        // Test float underflow handling:
3483        let lhs = ScalarValue::Float32(Some(f32::MIN));
3484        let rhs = ScalarValue::Float32(Some(2.0));
3485        let result = handle_overflow::<true>(&dt, op, &lhs, &rhs);
3486        assert_eq!(result, ScalarValue::Float32(Some(f32::MIN)));
3487        let result = handle_overflow::<false>(&dt, op, &lhs, &rhs);
3488        assert_eq!(result, ScalarValue::Float32(None));
3489
3490        // Test integer underflow handling:
3491        let dt = DataType::Int64;
3492        let op = Operator::Minus;
3493        let lhs = ScalarValue::Int64(Some(i64::MIN));
3494        let rhs = ScalarValue::Int64(Some(1));
3495        let result = handle_overflow::<true>(&dt, op, &lhs, &rhs);
3496        assert_eq!(result, ScalarValue::Int64(Some(i64::MIN)));
3497        let result = handle_overflow::<false>(&dt, op, &lhs, &rhs);
3498        assert_eq!(result, ScalarValue::Int64(None));
3499
3500        // Test unsigned integer handling:
3501        let dt = DataType::UInt32;
3502        let op = Operator::Minus;
3503        let lhs = ScalarValue::UInt32(Some(0));
3504        let rhs = ScalarValue::UInt32(Some(1));
3505        let result = handle_overflow::<true>(&dt, op, &lhs, &rhs);
3506        assert_eq!(result, ScalarValue::UInt32(Some(0)));
3507        let result = handle_overflow::<false>(&dt, op, &lhs, &rhs);
3508        assert_eq!(result, ScalarValue::UInt32(None));
3509
3510        // Test decimal handling:
3511        let dt = DataType::Decimal128(38, 35);
3512        let op = Operator::Plus;
3513        let lhs =
3514            ScalarValue::Decimal128(Some(54321543215432154321543215432154321), 35, 35);
3515        let rhs = ScalarValue::Decimal128(Some(10000), 20, 0);
3516        let result = handle_overflow::<true>(&dt, op, &lhs, &rhs);
3517        assert_eq!(result, ScalarValue::Decimal128(None, 38, 35));
3518        let result = handle_overflow::<false>(&dt, op, &lhs, &rhs);
3519        assert_eq!(
3520            result,
3521            ScalarValue::Decimal128(Some(99999999999999999999999999999999999999), 38, 35)
3522        );
3523
3524        Ok(())
3525    }
3526
3527    #[test]
3528    fn test_width_of_intervals() -> Result<()> {
3529        let intervals = [
3530            (
3531                Interval::make(Some(0.25_f64), Some(0.50_f64))?,
3532                ScalarValue::from(0.25_f64),
3533            ),
3534            (
3535                Interval::make(Some(0.5_f64), Some(1.0_f64))?,
3536                ScalarValue::from(0.5_f64),
3537            ),
3538            (
3539                Interval::make(Some(1.0_f64), Some(2.0_f64))?,
3540                ScalarValue::from(1.0_f64),
3541            ),
3542            (
3543                Interval::make(Some(32.0_f64), Some(64.0_f64))?,
3544                ScalarValue::from(32.0_f64),
3545            ),
3546            (
3547                Interval::make(Some(-0.50_f64), Some(-0.25_f64))?,
3548                ScalarValue::from(0.25_f64),
3549            ),
3550            (
3551                Interval::make(Some(-32.0_f64), Some(-16.0_f64))?,
3552                ScalarValue::from(16.0_f64),
3553            ),
3554            (
3555                Interval::make(Some(-0.50_f64), Some(0.25_f64))?,
3556                ScalarValue::from(0.75_f64),
3557            ),
3558            (
3559                Interval::make(Some(-32.0_f64), Some(16.0_f64))?,
3560                ScalarValue::from(48.0_f64),
3561            ),
3562            (
3563                Interval::make(Some(-32_i64), Some(16_i64))?,
3564                ScalarValue::from(48_i64),
3565            ),
3566        ];
3567        for (interval, expected) in intervals {
3568            assert_eq!(interval.width()?, expected);
3569        }
3570
3571        Ok(())
3572    }
3573
3574    #[test]
3575    fn test_cardinality_of_intervals() -> Result<()> {
3576        // In IEEE 754 standard for floating-point arithmetic, if we keep the sign and exponent fields same,
3577        // we can represent 4503599627370496+1 different numbers by changing the mantissa
3578        // (4503599627370496 = 2^52, since there are 52 bits in mantissa, and 2^23 = 8388608 for f32).
3579        // TODO: Add tests for non-exponential boundary aligned intervals too.
3580        let distinct_f64 = 4503599627370497;
3581        let distinct_f32 = 8388609;
3582        let intervals = [
3583            Interval::make(Some(0.25_f64), Some(0.50_f64))?,
3584            Interval::make(Some(0.5_f64), Some(1.0_f64))?,
3585            Interval::make(Some(1.0_f64), Some(2.0_f64))?,
3586            Interval::make(Some(32.0_f64), Some(64.0_f64))?,
3587            Interval::make(Some(-0.50_f64), Some(-0.25_f64))?,
3588            Interval::make(Some(-32.0_f64), Some(-16.0_f64))?,
3589        ];
3590        for interval in intervals {
3591            assert_eq!(interval.cardinality().unwrap(), distinct_f64);
3592        }
3593
3594        let intervals = [
3595            Interval::make(Some(0.25_f32), Some(0.50_f32))?,
3596            Interval::make(Some(-1_f32), Some(-0.5_f32))?,
3597        ];
3598        for interval in intervals {
3599            assert_eq!(interval.cardinality().unwrap(), distinct_f32);
3600        }
3601
3602        // The regular logarithmic distribution of floating-point numbers are
3603        // only applicable outside of the `(-phi, phi)` interval where `phi`
3604        // denotes the largest positive subnormal floating-point number. Since
3605        // the following intervals include such subnormal points, we cannot use
3606        // a simple powers-of-two type formula for our expectations. Therefore,
3607        // we manually supply the actual expected cardinality.
3608        let interval = Interval::make(Some(-0.0625), Some(0.0625))?;
3609        assert_eq!(interval.cardinality().unwrap(), 9178336040581070850);
3610
3611        let interval = Interval::try_new(
3612            ScalarValue::UInt64(Some(u64::MIN + 1)),
3613            ScalarValue::UInt64(Some(u64::MAX)),
3614        )?;
3615        assert_eq!(interval.cardinality().unwrap(), u64::MAX);
3616
3617        let interval = Interval::try_new(
3618            ScalarValue::Int64(Some(i64::MIN + 1)),
3619            ScalarValue::Int64(Some(i64::MAX)),
3620        )?;
3621        assert_eq!(interval.cardinality().unwrap(), u64::MAX);
3622
3623        let interval = Interval::try_new(
3624            ScalarValue::Float32(Some(-0.0_f32)),
3625            ScalarValue::Float32(Some(0.0_f32)),
3626        )?;
3627        assert_eq!(interval.cardinality().unwrap(), 2);
3628
3629        Ok(())
3630    }
3631
3632    #[test]
3633    fn test_satisfy_comparison() -> Result<()> {
3634        let cases = vec![
3635            (
3636                Interval::make(Some(1000_i64), None)?,
3637                Interval::make(None, Some(1000_i64))?,
3638                true,
3639                Interval::make(Some(1000_i64), None)?,
3640                Interval::make(None, Some(1000_i64))?,
3641            ),
3642            (
3643                Interval::make(None, Some(1000_i64))?,
3644                Interval::make(Some(1000_i64), None)?,
3645                true,
3646                Interval::make(Some(1000_i64), Some(1000_i64))?,
3647                Interval::make(Some(1000_i64), Some(1000_i64))?,
3648            ),
3649            (
3650                Interval::make(Some(1000_i64), None)?,
3651                Interval::make(None, Some(1000_i64))?,
3652                false,
3653                Interval::make(Some(1000_i64), None)?,
3654                Interval::make(None, Some(1000_i64))?,
3655            ),
3656            (
3657                Interval::make(Some(0_i64), Some(1000_i64))?,
3658                Interval::make(Some(500_i64), Some(1500_i64))?,
3659                true,
3660                Interval::make(Some(500_i64), Some(1000_i64))?,
3661                Interval::make(Some(500_i64), Some(1000_i64))?,
3662            ),
3663            (
3664                Interval::make(Some(500_i64), Some(1500_i64))?,
3665                Interval::make(Some(0_i64), Some(1000_i64))?,
3666                true,
3667                Interval::make(Some(500_i64), Some(1500_i64))?,
3668                Interval::make(Some(0_i64), Some(1000_i64))?,
3669            ),
3670            (
3671                Interval::make(Some(0_i64), Some(1000_i64))?,
3672                Interval::make(Some(500_i64), Some(1500_i64))?,
3673                false,
3674                Interval::make(Some(501_i64), Some(1000_i64))?,
3675                Interval::make(Some(500_i64), Some(999_i64))?,
3676            ),
3677            (
3678                Interval::make(Some(500_i64), Some(1500_i64))?,
3679                Interval::make(Some(0_i64), Some(1000_i64))?,
3680                false,
3681                Interval::make(Some(500_i64), Some(1500_i64))?,
3682                Interval::make(Some(0_i64), Some(1000_i64))?,
3683            ),
3684            (
3685                Interval::make::<i64>(None, None)?,
3686                Interval::make(Some(1_i64), Some(1_i64))?,
3687                false,
3688                Interval::make(Some(2_i64), None)?,
3689                Interval::make(Some(1_i64), Some(1_i64))?,
3690            ),
3691            (
3692                Interval::make::<i64>(None, None)?,
3693                Interval::make(Some(1_i64), Some(1_i64))?,
3694                true,
3695                Interval::make(Some(1_i64), None)?,
3696                Interval::make(Some(1_i64), Some(1_i64))?,
3697            ),
3698            (
3699                Interval::make(Some(1_i64), Some(1_i64))?,
3700                Interval::make::<i64>(None, None)?,
3701                false,
3702                Interval::make(Some(1_i64), Some(1_i64))?,
3703                Interval::make(None, Some(0_i64))?,
3704            ),
3705            (
3706                Interval::make(Some(1_i64), Some(1_i64))?,
3707                Interval::make::<i64>(None, None)?,
3708                true,
3709                Interval::make(Some(1_i64), Some(1_i64))?,
3710                Interval::make(None, Some(1_i64))?,
3711            ),
3712            (
3713                Interval::make(Some(1_i64), Some(1_i64))?,
3714                Interval::make::<i64>(None, None)?,
3715                false,
3716                Interval::make(Some(1_i64), Some(1_i64))?,
3717                Interval::make(None, Some(0_i64))?,
3718            ),
3719            (
3720                Interval::make(Some(1_i64), Some(1_i64))?,
3721                Interval::make::<i64>(None, None)?,
3722                true,
3723                Interval::make(Some(1_i64), Some(1_i64))?,
3724                Interval::make(None, Some(1_i64))?,
3725            ),
3726            (
3727                Interval::make::<i64>(None, None)?,
3728                Interval::make(Some(1_i64), Some(1_i64))?,
3729                false,
3730                Interval::make(Some(2_i64), None)?,
3731                Interval::make(Some(1_i64), Some(1_i64))?,
3732            ),
3733            (
3734                Interval::make::<i64>(None, None)?,
3735                Interval::make(Some(1_i64), Some(1_i64))?,
3736                true,
3737                Interval::make(Some(1_i64), None)?,
3738                Interval::make(Some(1_i64), Some(1_i64))?,
3739            ),
3740            (
3741                Interval::make(Some(-1000.0_f32), Some(1000.0_f32))?,
3742                Interval::make(Some(-500.0_f32), Some(500.0_f32))?,
3743                false,
3744                Interval::try_new(
3745                    next_value(ScalarValue::Float32(Some(-500.0))),
3746                    ScalarValue::Float32(Some(1000.0)),
3747                )?,
3748                Interval::make(Some(-500_f32), Some(500.0_f32))?,
3749            ),
3750            (
3751                Interval::make(Some(-500.0_f32), Some(500.0_f32))?,
3752                Interval::make(Some(-1000.0_f32), Some(1000.0_f32))?,
3753                true,
3754                Interval::make(Some(-500.0_f32), Some(500.0_f32))?,
3755                Interval::make(Some(-1000.0_f32), Some(500.0_f32))?,
3756            ),
3757            (
3758                Interval::make(Some(-500.0_f32), Some(500.0_f32))?,
3759                Interval::make(Some(-1000.0_f32), Some(1000.0_f32))?,
3760                false,
3761                Interval::make(Some(-500.0_f32), Some(500.0_f32))?,
3762                Interval::try_new(
3763                    ScalarValue::Float32(Some(-1000.0_f32)),
3764                    prev_value(ScalarValue::Float32(Some(500.0_f32))),
3765                )?,
3766            ),
3767            (
3768                Interval::make(Some(-1000.0_f64), Some(1000.0_f64))?,
3769                Interval::make(Some(-500.0_f64), Some(500.0_f64))?,
3770                true,
3771                Interval::make(Some(-500.0_f64), Some(1000.0_f64))?,
3772                Interval::make(Some(-500.0_f64), Some(500.0_f64))?,
3773            ),
3774            (
3775                Interval::make(Some(0_i64), Some(0_i64))?,
3776                Interval::make(Some(-0_i64), Some(0_i64))?,
3777                true,
3778                Interval::make(Some(0_i64), Some(0_i64))?,
3779                Interval::make(Some(-0_i64), Some(0_i64))?,
3780            ),
3781            (
3782                Interval::make(Some(-0_i64), Some(0_i64))?,
3783                Interval::make(Some(-0_i64), Some(-0_i64))?,
3784                true,
3785                Interval::make(Some(-0_i64), Some(0_i64))?,
3786                Interval::make(Some(-0_i64), Some(-0_i64))?,
3787            ),
3788            (
3789                Interval::make(Some(0.0_f64), Some(0.0_f64))?,
3790                Interval::make(Some(-0.0_f64), Some(0.0_f64))?,
3791                true,
3792                Interval::make(Some(0.0_f64), Some(0.0_f64))?,
3793                Interval::make(Some(-0.0_f64), Some(0.0_f64))?,
3794            ),
3795            (
3796                Interval::make(Some(0.0_f64), Some(0.0_f64))?,
3797                Interval::make(Some(-0.0_f64), Some(0.0_f64))?,
3798                false,
3799                Interval::make(Some(0.0_f64), Some(0.0_f64))?,
3800                Interval::make(Some(-0.0_f64), Some(-0.0_f64))?,
3801            ),
3802            (
3803                Interval::make(Some(-0.0_f64), Some(0.0_f64))?,
3804                Interval::make(Some(-0.0_f64), Some(-0.0_f64))?,
3805                true,
3806                Interval::make(Some(-0.0_f64), Some(0.0_f64))?,
3807                Interval::make(Some(-0.0_f64), Some(-0.0_f64))?,
3808            ),
3809            (
3810                Interval::make(Some(-0.0_f64), Some(0.0_f64))?,
3811                Interval::make(Some(-0.0_f64), Some(-0.0_f64))?,
3812                false,
3813                Interval::make(Some(0.0_f64), Some(0.0_f64))?,
3814                Interval::make(Some(-0.0_f64), Some(-0.0_f64))?,
3815            ),
3816            (
3817                Interval::make(Some(0_i64), None)?,
3818                Interval::make(Some(-0_i64), None)?,
3819                true,
3820                Interval::make(Some(0_i64), None)?,
3821                Interval::make(Some(-0_i64), None)?,
3822            ),
3823            (
3824                Interval::make(Some(0_i64), None)?,
3825                Interval::make(Some(-0_i64), None)?,
3826                false,
3827                Interval::make(Some(1_i64), None)?,
3828                Interval::make(Some(-0_i64), None)?,
3829            ),
3830            (
3831                Interval::make(Some(0.0_f64), None)?,
3832                Interval::make(Some(-0.0_f64), None)?,
3833                true,
3834                Interval::make(Some(0.0_f64), None)?,
3835                Interval::make(Some(-0.0_f64), None)?,
3836            ),
3837            (
3838                Interval::make(Some(0.0_f64), None)?,
3839                Interval::make(Some(-0.0_f64), None)?,
3840                false,
3841                Interval::make(Some(0.0_f64), None)?,
3842                Interval::make(Some(-0.0_f64), None)?,
3843            ),
3844        ];
3845        for (first, second, includes_endpoints, left_modified, right_modified) in cases {
3846            assert_eq!(
3847                satisfy_greater(&first, &second, !includes_endpoints)?.unwrap(),
3848                (left_modified, right_modified)
3849            );
3850        }
3851
3852        let infeasible_cases = vec![
3853            (
3854                Interval::make(None, Some(1000_i64))?,
3855                Interval::make(Some(1000_i64), None)?,
3856                false,
3857            ),
3858            (
3859                Interval::make(Some(-1000.0_f32), Some(1000.0_f32))?,
3860                Interval::make(Some(1500.0_f32), Some(2000.0_f32))?,
3861                false,
3862            ),
3863            (
3864                Interval::make(Some(0_i64), Some(0_i64))?,
3865                Interval::make(Some(-0_i64), Some(0_i64))?,
3866                false,
3867            ),
3868            (
3869                Interval::make(Some(-0_i64), Some(0_i64))?,
3870                Interval::make(Some(-0_i64), Some(-0_i64))?,
3871                false,
3872            ),
3873        ];
3874        for (first, second, includes_endpoints) in infeasible_cases {
3875            assert_eq!(satisfy_greater(&first, &second, !includes_endpoints)?, None);
3876        }
3877
3878        Ok(())
3879    }
3880
3881    #[test]
3882    fn test_interval_display() {
3883        let interval = Interval::make(Some(0.25_f32), Some(0.50_f32)).unwrap();
3884        assert_eq!(format!("{interval}"), "[0.25, 0.5]");
3885
3886        let interval = Interval::try_new(
3887            ScalarValue::Float32(Some(f32::NEG_INFINITY)),
3888            ScalarValue::Float32(Some(f32::INFINITY)),
3889        )
3890        .unwrap();
3891        assert_eq!(format!("{interval}"), "[NULL, NULL]");
3892    }
3893
3894    macro_rules! capture_mode_change {
3895        ($TYPE:ty) => {
3896            paste::item! {
3897                capture_mode_change_helper!([<capture_mode_change_ $TYPE>],
3898                                            [<create_interval_ $TYPE>],
3899                                            $TYPE);
3900            }
3901        };
3902    }
3903
3904    macro_rules! capture_mode_change_helper {
3905        ($TEST_FN_NAME:ident, $CREATE_FN_NAME:ident, $TYPE:ty) => {
3906            fn $CREATE_FN_NAME(lower: $TYPE, upper: $TYPE) -> Interval {
3907                Interval::try_new(
3908                    ScalarValue::try_from(Some(lower as $TYPE)).unwrap(),
3909                    ScalarValue::try_from(Some(upper as $TYPE)).unwrap(),
3910                )
3911                .unwrap()
3912            }
3913
3914            fn $TEST_FN_NAME(input: ($TYPE, $TYPE), expect_low: bool, expect_high: bool) {
3915                assert!(expect_low || expect_high);
3916                let interval1 = $CREATE_FN_NAME(input.0, input.0);
3917                let interval2 = $CREATE_FN_NAME(input.1, input.1);
3918                let result = interval1.add(&interval2).unwrap();
3919                let without_fe = $CREATE_FN_NAME(input.0 + input.1, input.0 + input.1);
3920                assert!(
3921                    (!expect_low || result.lower < without_fe.lower)
3922                        && (!expect_high || result.upper > without_fe.upper)
3923                );
3924            }
3925        };
3926    }
3927
3928    capture_mode_change!(f32);
3929    capture_mode_change!(f64);
3930
3931    #[cfg(all(
3932        any(target_arch = "x86_64", target_arch = "aarch64"),
3933        not(target_os = "windows")
3934    ))]
3935    #[test]
3936    fn test_add_intervals_lower_affected_f32() {
3937        // Lower is affected
3938        let lower = f32::from_bits(1073741887); //1000000000000000000000000111111
3939        let upper = f32::from_bits(1098907651); //1000001100000000000000000000011
3940        capture_mode_change_f32((lower, upper), true, false);
3941
3942        // Upper is affected
3943        let lower = f32::from_bits(1072693248); //111111111100000000000000000000
3944        let upper = f32::from_bits(715827883); //101010101010101010101010101011
3945        capture_mode_change_f32((lower, upper), false, true);
3946
3947        // Lower is affected
3948        let lower = 1.0; // 0x3FF0000000000000
3949        let upper = 0.3; // 0x3FD3333333333333
3950        capture_mode_change_f64((lower, upper), true, false);
3951
3952        // Upper is affected
3953        let lower = 1.4999999999999998; // 0x3FF7FFFFFFFFFFFF
3954        let upper = 0.000_000_000_000_000_022_044_604_925_031_31; // 0x3C796A6B413BB21F
3955        capture_mode_change_f64((lower, upper), false, true);
3956    }
3957
3958    #[cfg(any(
3959        not(any(target_arch = "x86_64", target_arch = "aarch64")),
3960        target_os = "windows"
3961    ))]
3962    #[test]
3963    fn test_next_impl_add_intervals_f64() {
3964        let lower = 1.5;
3965        let upper = 1.5;
3966        capture_mode_change_f64((lower, upper), true, true);
3967
3968        let lower = 1.5;
3969        let upper = 1.5;
3970        capture_mode_change_f32((lower, upper), true, true);
3971    }
3972
3973    #[test]
3974    fn test_is_superset() -> Result<()> {
3975        // Test cases: (interval1, interval2, strict, expected)
3976        let test_cases = vec![
3977            // Equal intervals - non-strict should be true, strict should be false
3978            (
3979                Interval::make(Some(10_i32), Some(50_i32))?,
3980                Interval::make(Some(10_i32), Some(50_i32))?,
3981                false,
3982                true,
3983            ),
3984            (
3985                Interval::make(Some(10_i32), Some(50_i32))?,
3986                Interval::make(Some(10_i32), Some(50_i32))?,
3987                true,
3988                false,
3989            ),
3990            // Unbounded intervals
3991            (
3992                Interval::make::<i32>(None, None)?,
3993                Interval::make(Some(10_i32), Some(50_i32))?,
3994                false,
3995                true,
3996            ),
3997            (
3998                Interval::make::<i32>(None, None)?,
3999                Interval::make::<i32>(None, None)?,
4000                false,
4001                true,
4002            ),
4003            (
4004                Interval::make::<i32>(None, None)?,
4005                Interval::make::<i32>(None, None)?,
4006                true,
4007                false,
4008            ),
4009            // Half-bounded intervals
4010            (
4011                Interval::make(Some(0_i32), None)?,
4012                Interval::make(Some(10_i32), Some(50_i32))?,
4013                false,
4014                true,
4015            ),
4016            (
4017                Interval::make(None, Some(100_i32))?,
4018                Interval::make(Some(10_i32), Some(50_i32))?,
4019                false,
4020                true,
4021            ),
4022            // Non-superset cases - partial overlap
4023            (
4024                Interval::make(Some(0_i32), Some(50_i32))?,
4025                Interval::make(Some(25_i32), Some(75_i32))?,
4026                false,
4027                false,
4028            ),
4029            (
4030                Interval::make(Some(0_i32), Some(50_i32))?,
4031                Interval::make(Some(25_i32), Some(75_i32))?,
4032                true,
4033                false,
4034            ),
4035            // Non-superset cases - disjoint intervals
4036            (
4037                Interval::make(Some(0_i32), Some(50_i32))?,
4038                Interval::make(Some(60_i32), Some(100_i32))?,
4039                false,
4040                false,
4041            ),
4042            // Subset relationship (reversed)
4043            (
4044                Interval::make(Some(20_i32), Some(80_i32))?,
4045                Interval::make(Some(0_i32), Some(100_i32))?,
4046                false,
4047                false,
4048            ),
4049            // Float cases
4050            (
4051                Interval::make(Some(0.0_f32), Some(100.0_f32))?,
4052                Interval::make(Some(25.5_f32), Some(75.5_f32))?,
4053                false,
4054                true,
4055            ),
4056            (
4057                Interval::make(Some(0.0_f64), Some(100.0_f64))?,
4058                Interval::make(Some(0.0_f64), Some(100.0_f64))?,
4059                true,
4060                false,
4061            ),
4062            // Edge cases with single point intervals
4063            (
4064                Interval::make(Some(0_i32), Some(100_i32))?,
4065                Interval::make(Some(50_i32), Some(50_i32))?,
4066                false,
4067                true,
4068            ),
4069            (
4070                Interval::make(Some(50_i32), Some(50_i32))?,
4071                Interval::make(Some(50_i32), Some(50_i32))?,
4072                false,
4073                true,
4074            ),
4075            (
4076                Interval::make(Some(50_i32), Some(50_i32))?,
4077                Interval::make(Some(50_i32), Some(50_i32))?,
4078                true,
4079                false,
4080            ),
4081            // Boundary touch cases
4082            (
4083                Interval::make(Some(0_i32), Some(50_i32))?,
4084                Interval::make(Some(0_i32), Some(25_i32))?,
4085                false,
4086                true,
4087            ),
4088            (
4089                Interval::make(Some(0_i32), Some(50_i32))?,
4090                Interval::make(Some(25_i32), Some(50_i32))?,
4091                false,
4092                true,
4093            ),
4094        ];
4095
4096        for (interval1, interval2, strict, expected) in test_cases {
4097            let result = interval1.is_superset(&interval2, strict)?;
4098            assert_eq!(
4099                result, expected,
4100                "Failed for interval1: {interval1}, interval2: {interval2}, strict: {strict}",
4101            );
4102        }
4103
4104        Ok(())
4105    }
4106}