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