-
Notifications
You must be signed in to change notification settings - Fork 796
Description
Summary
The != comparator in DataFilter with multiple values exhibits unintuitive behavior that makes it practically unusable. Instead of implementing true "NOT IN" semantics (value must not match ALL items in array), it currently implements "not equal to ANY" (passes on first mismatch).
Current Behavior
When using comparator: "!=" with multiple values, the filter passes if the event value is different from ANY value in the array, which means it will pass for almost any input.
Example:
filters:
data:
- path: body.brandId
type: string
value: ["id1", "id2", "id3"]
comparator: "!="Event: {"brandId": "id1"}
- Current result: PASSES ✓ (because
"id1" != "id2"is true) - Expected result: FAILS ✗ (because
"id1"IS in the array)
Expected Behavior
The != comparator should implement true "NOT IN" semantics:
- PASS: if value does not match ANY item in the array (value NOT IN array)
- FAIL: if value matches any item in the array (value IN array)
Root Cause
In pkg/sensors/dependencies/filter.go, the implementation exits early on the first mismatch:
// Lines ~361-399 (string type)
for _, value := range f.Value {
// ... regex matching ...
switch f.Comparator {
case v1alpha1.NotEqualTo:
if !match {
matchResult = true // First mismatch
}
}
if matchResult {
continue filterData // Exits loop early - WRONG!
}
}
return false // Only reached if ALL values matchedThe same issue exists for number types (lines ~306-359) and bool types (lines ~278-304).
Test Coverage Gap
The existing test suite in filter_data_test.go has no test cases for != comparator with multiple values - all != tests use single-value arrays.
Reproduction Test Cases
{
name: "string filter NotEqualTo with multiple values - value IN array",
args: args{
data: []v1alpha1.DataFilter{
{
Path: "k",
Type: v1alpha1.JSONTypeString,
Value: []string{"id1", "id2", "id3"},
Comparator: "!=",
},
},
operator: v1alpha1.EmptyLogicalOperator,
event: &v1alpha1.Event{
Data: []byte(`{"k": "id1"}`),
},
},
expectedResult: false, // Should FAIL
expectErr: false,
}Running this test with current code: PASSES (bug)
Running with fixed code: FAILS (correct)
Impact
- The
!=comparator is essentially broken for practical use with multiple values - Users expecting "NOT IN" behavior will get incorrect results
- No workaround except using expr filters with explicit AND logic
Proposed Fix
Check ALL values before deciding:
for _, value := range f.Value {
if match {
matchFound = true
break
}
}
// For != comparator, pass only if NO match was found
if f.Comparator == v1alpha1.NotEqualTo {
if !matchFound {
continue filterData // PASS
} else {
return false // FAIL
}
}Environment
- All versions affected (present in current master branch)
- Affects string, number, and bool data types
I'll prepare a PR with the fix and comprehensive test coverage.