-
Notifications
You must be signed in to change notification settings - Fork 2.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[pkg/ottl] Add contains function #33078
base: main
Are you sure you want to change the base?
[pkg/ottl] Add contains function #33078
Conversation
pkg/ottl/ottlfuncs/func_contains.go
Outdated
) | ||
|
||
type ContainsArguments[K any] struct { | ||
Target []ottl.StringLikeGetter[K] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this won't allow you to pass a slice, consider this use case
contains(attributes["tags"], "staging")
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe I'm wrong, but I tried to write e2e test and it seems that the following statement works and I can pass the slices:
set(attributes["test"], "pass") where Contains(["hello", "world"], "hello")
Did I miss anything?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the thing is you're just assuming StringLikeGetter,
when I want to use config like this
- context: log
statements:
- set(attributes["tags"], ["staging", "hello", "world", "work"])
- set(attributes["staging"], "true") where Contains(attributes["tags"], "staging")
Contains fail because first attribute is not an array.
so i need to fix it like this
log_statements:
- context: log
statements:
- set(attributes["tags"], ["staging", "hello", "world", "work"])
- set(attributes["staging"], "true") where Contains([attributes["tags"]], "staging")
by wrapping attributes["tags"]
with []
to make it an array.
when i do that, your StringLikeGetter will get the attributes["tags"]
and finds out it's a Slice. So it makes a string out of slice by marshaling the array.
Now you have marshaled array as a string["staging", "hello", "world", "work"]
that does not equal staging
in my condition.
What you need to do is to use Getter and work with different types you may get. You may get Slice
, Map
or a string wrapped in pcommon.Value
. You should handle all of these differently.
While you're at it changing behavior to match what i described i would be the same way to add support for ints, floats and boolean as you were asking in the other comment
It will also fix UX.
I want to use Contains(["a", "b"...]
and Contains(attributes["tags"]
at the same time without wrapping workaround
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I really appreciate the detailed answer that helps me understand the flow. Thanks.
I added e2e with the scenario you described. I hope it is better now.
a43631c
to
4ef84a9
Compare
4ef84a9
to
2809a2f
Compare
pkg/ottl/expression.go
Outdated
} | ||
|
||
// converts a generic slice to pcommon.Slice. It uses reflection to handle any slice type, creating a pcommon.Slice from it. | ||
func convertToSlice(val any) (pcommon.Slice, error) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
not sure i like that, especially when we have so few types we support
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You're right, I removed the reflection and it simplified things a bit.
component: pkg/ottl | ||
|
||
# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`). | ||
note: Add typed getter for `pcommon.Slice` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
note: Add typed getter for `pcommon.Slice` | |
note: Add `PSliceGetter`, a typed getter for `pcommon.Slice` |
# Include 'user' if the change is relevant to end users. | ||
# Include 'api' if there is a change to a library API. | ||
# Default: '[user]' | ||
change_logs: [user] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
change_logs: [user] | |
change_logs: [api] |
pkg/ottl/expression.go
Outdated
@@ -360,7 +401,7 @@ func (g StandardPMapGetter[K]) Get(ctx context.Context, tCtx K) (pcommon.Map, er | |||
if v.Type() == pcommon.ValueTypeMap { | |||
return v.Map(), nil | |||
} | |||
return pcommon.Map{}, TypeError(fmt.Sprintf("expected pcommon.Map but got %v", v.Type())) | |||
return pcommon.Map{}, TypeError(fmt.Sprintf("expected pcommon.Map but got %T", v)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
return pcommon.Map{}, TypeError(fmt.Sprintf("expected pcommon.Map but got %T", v)) | |
return pcommon.Map{}, TypeError(fmt.Sprintf("expected pcommon.Map but got %v", v.Type())) |
Sorry, I got this wrong before. Since this is a pdata object, we should use its Type
method.
This PR was marked stale due to lack of activity. It will be closed in 14 days. |
Description: Adds a new contains function to check if slice contains item.
Link to tracking Issue: Fixes #30420
Testing: Added unit test
Documentation: TODO