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