This is an automated email from the ASF dual-hosted git repository.
berkay pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/datafusion.git
The following commit(s) were added to refs/heads/main by this push:
new 84c8881b64 minor: add is_superset() method for Interval's (#16895)
84c8881b64 is described below
commit 84c8881b643f0e2b042ea40070e2e3111c893301
Author: Berkay Şahin <[email protected]>
AuthorDate: Sat Jul 26 14:36:55 2025 +0300
minor: add is_superset() method for Interval's (#16895)
* Update interval_arithmetic.rs
* Update interval_arithmetic.rs
* Update interval_arithmetic.rs
---
datafusion/expr-common/src/interval_arithmetic.rs | 145 ++++++++++++++++++++++
1 file changed, 145 insertions(+)
diff --git a/datafusion/expr-common/src/interval_arithmetic.rs
b/datafusion/expr-common/src/interval_arithmetic.rs
index d656c676bd..16a8caad82 100644
--- a/datafusion/expr-common/src/interval_arithmetic.rs
+++ b/datafusion/expr-common/src/interval_arithmetic.rs
@@ -754,6 +754,17 @@ impl Interval {
}
}
+ /// Decide if this interval is a superset of `other`. If argument `strict`
+ /// is `true`, only returns `true` if this interval is a strict superset.
+ ///
+ /// NOTE: This function only works with intervals of the same data type.
+ /// Attempting to compare intervals of different data types will lead
+ /// to an error.
+ pub fn is_superset(&self, other: &Interval, strict: bool) -> Result<bool> {
+ Ok(!(strict && self.eq(other))
+ && (self.contains(other)? == Interval::CERTAINLY_TRUE))
+ }
+
/// Add the given interval (`other`) to this interval. Say we have
intervals
/// `[a1, b1]` and `[a2, b2]`, then their sum is `[a1 + a2, b1 + b2]`. Note
/// that this represents all possible values the sum can take if one can
@@ -3805,4 +3816,138 @@ mod tests {
let upper = 1.5;
capture_mode_change_f32((lower, upper), true, true);
}
+
+ #[test]
+ fn test_is_superset() -> Result<()> {
+ // Test cases: (interval1, interval2, strict, expected)
+ let test_cases = vec![
+ // Equal intervals - non-strict should be true, strict should be
false
+ (
+ Interval::make(Some(10_i32), Some(50_i32))?,
+ Interval::make(Some(10_i32), Some(50_i32))?,
+ false,
+ true,
+ ),
+ (
+ Interval::make(Some(10_i32), Some(50_i32))?,
+ Interval::make(Some(10_i32), Some(50_i32))?,
+ true,
+ false,
+ ),
+ // Unbounded intervals
+ (
+ Interval::make::<i32>(None, None)?,
+ Interval::make(Some(10_i32), Some(50_i32))?,
+ false,
+ true,
+ ),
+ (
+ Interval::make::<i32>(None, None)?,
+ Interval::make::<i32>(None, None)?,
+ false,
+ true,
+ ),
+ (
+ Interval::make::<i32>(None, None)?,
+ Interval::make::<i32>(None, None)?,
+ true,
+ false,
+ ),
+ // Half-bounded intervals
+ (
+ Interval::make(Some(0_i32), None)?,
+ Interval::make(Some(10_i32), Some(50_i32))?,
+ false,
+ true,
+ ),
+ (
+ Interval::make(None, Some(100_i32))?,
+ Interval::make(Some(10_i32), Some(50_i32))?,
+ false,
+ true,
+ ),
+ // Non-superset cases - partial overlap
+ (
+ Interval::make(Some(0_i32), Some(50_i32))?,
+ Interval::make(Some(25_i32), Some(75_i32))?,
+ false,
+ false,
+ ),
+ (
+ Interval::make(Some(0_i32), Some(50_i32))?,
+ Interval::make(Some(25_i32), Some(75_i32))?,
+ true,
+ false,
+ ),
+ // Non-superset cases - disjoint intervals
+ (
+ Interval::make(Some(0_i32), Some(50_i32))?,
+ Interval::make(Some(60_i32), Some(100_i32))?,
+ false,
+ false,
+ ),
+ // Subset relationship (reversed)
+ (
+ Interval::make(Some(20_i32), Some(80_i32))?,
+ Interval::make(Some(0_i32), Some(100_i32))?,
+ false,
+ false,
+ ),
+ // Float cases
+ (
+ Interval::make(Some(0.0_f32), Some(100.0_f32))?,
+ Interval::make(Some(25.5_f32), Some(75.5_f32))?,
+ false,
+ true,
+ ),
+ (
+ Interval::make(Some(0.0_f64), Some(100.0_f64))?,
+ Interval::make(Some(0.0_f64), Some(100.0_f64))?,
+ true,
+ false,
+ ),
+ // Edge cases with single point intervals
+ (
+ Interval::make(Some(0_i32), Some(100_i32))?,
+ Interval::make(Some(50_i32), Some(50_i32))?,
+ false,
+ true,
+ ),
+ (
+ Interval::make(Some(50_i32), Some(50_i32))?,
+ Interval::make(Some(50_i32), Some(50_i32))?,
+ false,
+ true,
+ ),
+ (
+ Interval::make(Some(50_i32), Some(50_i32))?,
+ Interval::make(Some(50_i32), Some(50_i32))?,
+ true,
+ false,
+ ),
+ // Boundary touch cases
+ (
+ Interval::make(Some(0_i32), Some(50_i32))?,
+ Interval::make(Some(0_i32), Some(25_i32))?,
+ false,
+ true,
+ ),
+ (
+ Interval::make(Some(0_i32), Some(50_i32))?,
+ Interval::make(Some(25_i32), Some(50_i32))?,
+ false,
+ true,
+ ),
+ ];
+
+ for (interval1, interval2, strict, expected) in test_cases {
+ let result = interval1.is_superset(&interval2, strict)?;
+ assert_eq!(
+ result, expected,
+ "Failed for interval1: {interval1}, interval2: {interval2},
strict: {strict}",
+ );
+ }
+
+ Ok(())
+ }
}
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]