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