## Coverage Report

#### Created: 2024-10-13 08:39

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

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