Skip to content
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

Open
wants to merge 5 commits into
base: main
Choose a base branch
from

Conversation

lkwronski
Copy link
Contributor

Description: Adds a new contains function to check if slice contains item.

Link to tracking Issue: Fixes #30420

Testing: Added unit test

Documentation: TODO

)

type ContainsArguments[K any] struct {
Target []ottl.StringLikeGetter[K]
Copy link
Contributor

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")

Copy link
Contributor Author

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?

Copy link
Contributor

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

Copy link
Contributor Author

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.

@lkwronski lkwronski force-pushed the lkwronski.issue-30420-contains branch 2 times, most recently from a43631c to 4ef84a9 Compare May 19, 2024 08:51
@lkwronski lkwronski force-pushed the lkwronski.issue-30420-contains branch from 4ef84a9 to 2809a2f Compare May 19, 2024 09:07
}

// 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) {
Copy link
Contributor

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

Copy link
Contributor Author

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.

pkg/ottl/expression.go Show resolved Hide resolved
pkg/ottl/expression.go Show resolved Hide resolved
pkg/ottl/ottlfuncs/README.md Outdated Show resolved Hide resolved
pkg/ottl/ottlfuncs/func_contains.go Outdated Show resolved Hide resolved
pkg/ottl/ottlfuncs/func_contains.go Outdated Show resolved Hide resolved
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`
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
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]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
change_logs: [user]
change_logs: [api]

@@ -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))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
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.

Copy link
Contributor

github-actions bot commented Jun 5, 2024

This PR was marked stale due to lack of activity. It will be closed in 14 days.

@github-actions github-actions bot added the Stale label Jun 5, 2024
@evan-bradley evan-bradley removed the Stale label Jun 5, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

ottl: Efficiently test if a value is in a list or map
4 participants