Skip to content

Commit 8d338d0

Browse files
authored
Treat!= filtering of numerical column as the inverse of == (aka. outer-NOT and ALL semantics) (#11372)
1 parent 5e62eac commit 8d338d0

8 files changed

+30
-73
lines changed

crates/viewer/re_dataframe_ui/src/filters/numerical.rs

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use arrow::datatypes::DataType;
77
use datafusion::common::{Column, Result as DataFusionResult, exec_err};
88
use datafusion::logical_expr::{
99
ArrayFunctionArgument, ArrayFunctionSignature, ColumnarValue, Expr, ScalarFunctionArgs,
10-
ScalarUDF, ScalarUDFImpl, Signature, TypeSignature, Volatility, col, lit,
10+
ScalarUDF, ScalarUDFImpl, Signature, TypeSignature, Volatility, col, lit, not,
1111
};
1212
use strum::VariantArray as _;
1313

@@ -57,8 +57,9 @@ impl ComparisonOperator {
5757
T: PartialOrd + PartialEq + Copy,
5858
{
5959
match self {
60-
Self::Eq => left == right,
61-
Self::Ne => left != right,
60+
// Consistent with other column types, we handle `Ne` as an outer-NOT on `Eq`, so the
61+
// `NOT` is applied in the `as_filter_expression` functions.
62+
Self::Eq | Self::Ne => left == right,
6263
Self::Lt => left < right,
6364
Self::Le => left <= right,
6465
Self::Gt => left > right,
@@ -144,8 +145,17 @@ impl IntFilter {
144145
};
145146

146147
let udf = ScalarUDF::new_from_impl(IntFilterUdf::new(self.operator, rhs_value));
148+
let expr = udf.call(vec![col(column.clone())]);
147149

148-
udf.call(vec![col(column.clone())])
150+
// Consistent with other column types, we treat `Ne` as an outer-NOT, so we applies it here
151+
// while the UDF handles `Ne` and `Eq` in the same way (see `ComparisonOperator::apply`).
152+
let apply_should_invert_expression_semantics = self.operator == ComparisonOperator::Ne;
153+
154+
if apply_should_invert_expression_semantics {
155+
not(expr.clone()).or(expr.is_null())
156+
} else {
157+
expr
158+
}
149159
}
150160
}
151161

@@ -227,7 +237,17 @@ impl FloatFilter {
227237

228238
let udf = ScalarUDF::new_from_impl(FloatFilterUdf::new(self.operator, rhs_value));
229239

230-
udf.call(vec![col(column.clone())])
240+
let expr = udf.call(vec![col(column.clone())]);
241+
242+
// Consistent with other column types, we treat `Ne` as an outer-NOT, so we applies it here
243+
// while the UDF handles `Ne` and `Eq` in the same way (see `ComparisonOperator::apply`).
244+
let apply_should_invert_expression_semantics = self.operator == ComparisonOperator::Ne;
245+
246+
if apply_should_invert_expression_semantics {
247+
not(expr.clone()).or(expr.is_null())
248+
} else {
249+
expr
250+
}
231251
}
232252
}
233253

crates/viewer/re_dataframe_ui/src/filters/string.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -73,9 +73,10 @@ impl StringFilter {
7373

7474
// The udf treats `DoesNotContains` in the same way as `Contains`, so we must apply an
7575
// outer `NOT` (or null) operation. This way, both operators yield complementary results.
76-
let apply_any_or_null_semantics = self.operator() == StringOperator::DoesNotContain;
76+
let apply_should_invert_expression_semantics =
77+
self.operator() == StringOperator::DoesNotContain;
7778

78-
if apply_any_or_null_semantics {
79+
if apply_should_invert_expression_semantics {
7980
not(expr.clone()).or(expr.is_null())
8081
} else {
8182
expr

crates/viewer/re_dataframe_ui/tests/snapshots/filter_tests__float_compares@nulls_ne_4.snap

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ TestResult {
3131
[
3232
1.0,
3333
2.0,
34+
null,
3435
5.0,
3536
],
3637
}

crates/viewer/re_dataframe_ui/tests/snapshots/filter_tests__float_lists@ne_2.0.snap

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -67,12 +67,6 @@ TestResult {
6767
filtered: ListArray
6868
[
6969
PrimitiveArray<Float64>
70-
[
71-
1.0,
72-
2.0,
73-
3.0,
74-
],
75-
PrimitiveArray<Float64>
7670
[
7771
4.0,
7872
5.0,
@@ -83,12 +77,6 @@ TestResult {
8377
7.0,
8478
4.0,
8579
9.0,
86-
],
87-
PrimitiveArray<Float64>
88-
[
89-
5.0,
90-
2.0,
91-
1.0,
9280
],
9381
],
9482
}

crates/viewer/re_dataframe_ui/tests/snapshots/filter_tests__float_lists@nulls_ne_2.0.snap

Lines changed: 0 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -86,12 +86,6 @@ TestResult {
8686
filtered: ListArray
8787
[
8888
PrimitiveArray<Float64>
89-
[
90-
1.0,
91-
2.0,
92-
3.0,
93-
],
94-
PrimitiveArray<Float64>
9589
[
9690
4.0,
9791
5.0,
@@ -103,24 +97,9 @@ TestResult {
10397
4.0,
10498
9.0,
10599
],
106-
PrimitiveArray<Float64>
107-
[
108-
5.0,
109-
2.0,
110-
1.0,
111-
],
112-
PrimitiveArray<Float64>
113-
[
114100
null,
115-
1.0,
116-
2.0,
117-
3.0,
118-
],
119101
PrimitiveArray<Float64>
120102
[
121-
1.0,
122-
2.0,
123-
3.0,
124103
null,
125104
],
126105
],

crates/viewer/re_dataframe_ui/tests/snapshots/filter_tests__int_compares@nulls_ne_4.snap

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ TestResult {
3131
[
3232
1,
3333
2,
34+
null,
3435
5,
3536
],
3637
}

crates/viewer/re_dataframe_ui/tests/snapshots/filter_tests__int_lists@ne_2.snap

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -67,12 +67,6 @@ TestResult {
6767
filtered: ListArray
6868
[
6969
PrimitiveArray<Int64>
70-
[
71-
1,
72-
2,
73-
3,
74-
],
75-
PrimitiveArray<Int64>
7670
[
7771
4,
7872
5,
@@ -83,12 +77,6 @@ TestResult {
8377
7,
8478
4,
8579
9,
86-
],
87-
PrimitiveArray<Int64>
88-
[
89-
5,
90-
2,
91-
1,
9280
],
9381
],
9482
}

crates/viewer/re_dataframe_ui/tests/snapshots/filter_tests__int_lists@nulls_ne_2.snap

Lines changed: 0 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -86,12 +86,6 @@ TestResult {
8686
filtered: ListArray
8787
[
8888
PrimitiveArray<Int64>
89-
[
90-
1,
91-
2,
92-
3,
93-
],
94-
PrimitiveArray<Int64>
9589
[
9690
4,
9791
5,
@@ -103,24 +97,9 @@ TestResult {
10397
4,
10498
9,
10599
],
106-
PrimitiveArray<Int64>
107-
[
108-
5,
109-
2,
110-
1,
111-
],
112-
PrimitiveArray<Int64>
113-
[
114100
null,
115-
1,
116-
2,
117-
3,
118-
],
119101
PrimitiveArray<Int64>
120102
[
121-
1,
122-
2,
123-
3,
124103
null,
125104
],
126105
],

0 commit comments

Comments
 (0)