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
}