Skip to main content

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