datafusion_expr_common/
interval_arithmetic.rs

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