## Coverage Report

#### Created: 2025-11-22 06:00

next uncovered line (L), next uncovered region (R), next uncovered branch (B)

    /Users/andrewlamb/Software/datafusion/datafusion/expr-common/src/interval_arithmetic.rs

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