Skip to content

[pkg/ottl] Add Contains function #40193

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

Merged
merged 34 commits into from
Jun 20, 2025

Conversation

francois07
Copy link
Contributor

Description

I've reused most of @lkwronski's work in #35482 to add a new Contains function that checks if an item is in a slice. The only difference is that I've used reflect.DeepEqual() for item comparison. This makes it possible to check if a slice is present in a slice, for example Contain([[1, 2], [3, 4]], [1,2]) and also returns false if there is a type mismatch. This is slower than basic equality check though, so let me know if you want a different implementation, I already have a few other ideas actually.

Link to tracking issue

Fixes #30420

Testing

Added tests at 3 locations

  1. pkg/ottl/funcs/func_contains_test.go
  2. pkg/ottl/functions_test.go
  3. pkg/ottl/e2e/e2e_test.go

Documentation

Documentation was added to pkg/ottl/funcs/README.md

atoulme pushed a commit that referenced this pull request Jun 4, 2025
…comparison (#40370)

<!--Ex. Fixing a bug - Describe the bug and how this fixes the issue.
Ex. Adding a feature - Explain what this achieves.-->
#### Description

This PR introduces two related changes and contains 2 change logs
because of that.

**1 - Comparator API**

Exposes the internal OTTL comparators logic as a new API
(`ottl.ValueComparator`), which can be used by API consumers to compare
raw values following the same OTTL [comparison rules
](https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/pkg/ottl/LANGUAGE.md#comparison-rules).

**Why?**

Existing and new functions that needs to compare values can be
leveraging this new API to compare them, and keep it consistent with the
OTTL comparison logic. For example, the new
[`Contains`](#40193)
function for slices, can be using this API to determine whether an slice
contains a particular value, following the same comparison logic the
grammar does.

```go
// Exported interface:
type ValueComparator interface {
	// Equal compares two values for equality, returning true if they are equals
	// according to the OTTL comparison rules.
	Equal(a any, b any) bool
	// NotEqual compares two values for equality, returning true if they are different
	// according to the OTTL comparison rules.
	NotEqual(a any, b any) bool
	// Less compares two values, returning true if the first value is less than the second
	// value, using the OTTL comparison rules.
	Less(a any, b any) bool
	// LessEqual compares two values, returning true if the first value is less or equal
	// to the second value, using the OTTL comparison rules.
	LessEqual(a any, b any) bool
	// Greater compares two values, returning true if the first value is greater than the
	// second value, using the OTTL comparison rules.
	Greater(a any, b any) bool
	// GreaterEqual compares two values, returning true if the first value is greater or
	// equal to the second value, using the OTTL comparison rules.
	GreaterEqual(a any, b any) bool
}

// Usage:
comp := ottl.NewValueComparator()
```

**2 - Add ability to compare slices**

We currently don't have the ability to compare slices, which means
conditions like `attributes["slice"] == attributes["slice"]` returns
false. This PR also adds the ability to compare slices/pcommon.Slices,
similar to the maps support
(#38611).

<!--Describe what testing was performed and which tests were added.-->
#### Testing
Manual and unit tests

<!--Describe the documentation added.-->
#### Documentation
Updated LANGUAGE.md
@francois07
Copy link
Contributor Author

I've updated the function to use the new ottl.ValueComparator API from #40370

rockdaboot pushed a commit to rockdaboot/opentelemetry-collector-contrib that referenced this pull request Jun 10, 2025
…comparison (open-telemetry#40370)

<!--Ex. Fixing a bug - Describe the bug and how this fixes the issue.
Ex. Adding a feature - Explain what this achieves.-->
#### Description

This PR introduces two related changes and contains 2 change logs
because of that.

**1 - Comparator API**

Exposes the internal OTTL comparators logic as a new API
(`ottl.ValueComparator`), which can be used by API consumers to compare
raw values following the same OTTL [comparison rules
](https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/pkg/ottl/LANGUAGE.md#comparison-rules).

**Why?**

Existing and new functions that needs to compare values can be
leveraging this new API to compare them, and keep it consistent with the
OTTL comparison logic. For example, the new
[`Contains`](open-telemetry#40193)
function for slices, can be using this API to determine whether an slice
contains a particular value, following the same comparison logic the
grammar does.

```go
// Exported interface:
type ValueComparator interface {
	// Equal compares two values for equality, returning true if they are equals
	// according to the OTTL comparison rules.
	Equal(a any, b any) bool
	// NotEqual compares two values for equality, returning true if they are different
	// according to the OTTL comparison rules.
	NotEqual(a any, b any) bool
	// Less compares two values, returning true if the first value is less than the second
	// value, using the OTTL comparison rules.
	Less(a any, b any) bool
	// LessEqual compares two values, returning true if the first value is less or equal
	// to the second value, using the OTTL comparison rules.
	LessEqual(a any, b any) bool
	// Greater compares two values, returning true if the first value is greater than the
	// second value, using the OTTL comparison rules.
	Greater(a any, b any) bool
	// GreaterEqual compares two values, returning true if the first value is greater or
	// equal to the second value, using the OTTL comparison rules.
	GreaterEqual(a any, b any) bool
}

// Usage:
comp := ottl.NewValueComparator()
```

**2 - Add ability to compare slices**

We currently don't have the ability to compare slices, which means
conditions like `attributes["slice"] == attributes["slice"]` returns
false. This PR also adds the ability to compare slices/pcommon.Slices,
similar to the maps support
(open-telemetry#38611).

<!--Describe what testing was performed and which tests were added.-->
#### Testing
Manual and unit tests

<!--Describe the documentation added.-->
#### Documentation
Updated LANGUAGE.md
Copy link
Contributor

@edmocosta edmocosta left a comment

Choose a reason for hiding this comment

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

It looks good to me, thank you for working on that. I've left a few final suggestions.

francois07 and others added 4 commits June 12, 2025 09:52
Co-authored-by: Edmo Vamerlatti Costa <[email protected]>
…t_StandardPSliceGetter and Test_StandardPSliceGetter_WrappedError
@francois07 francois07 requested review from edmocosta and mashhurs June 12, 2025 08:32
@francois07
Copy link
Contributor Author

Hello @edmocosta, any thoughts on my recent changes ? I've implemented all your suggestions 👍

Copy link
Contributor

@edmocosta edmocosta left a comment

Choose a reason for hiding this comment

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

Thanks again for working on this @francois07, I've added a comment here.

I know it's not related to your PR, but it seems there's a few lint issues on the expression_test test. If you don't mind fixing that on this PR as well, that would be great, so we can get the CI green.

Error: pkg/ottl/expression_test.go:2245:11: type assertion on error will fail on wrapped errors. Use errors.As to check for specific errors (errorlint)
level=warning msg="[runner/exclusion_rules] Skipped 0 issues by rules: [Path: \"third_party\", Linters: \"gci, gofumpt\"]"
	_, ok := err.(TypeError)

Fix:

var typeError TypeError
assert.ErrorAs(t, err, &typeError)

We should also drop the //nolint:errorlint on that failing test.
Thanks!

@francois07
Copy link
Contributor Author

francois07 commented Jun 19, 2025

Thanks again for working on this @francois07, I've added a comment here.

I know it's not related to your PR, but it seems there's a few lint issues on the expression_test test. If you don't mind fixing that on this PR as well, that would be great, so we can get the CI green.

Error: pkg/ottl/expression_test.go:2245:11: type assertion on error will fail on wrapped errors. Use errors.As to check for specific errors (errorlint)
level=warning msg="[runner/exclusion_rules] Skipped 0 issues by rules: [Path: \"third_party\", Linters: \"gci, gofumpt\"]"
	_, ok := err.(TypeError)

Fix:

var typeError TypeError
assert.ErrorAs(t, err, &typeError)

We should also drop the //nolint:errorlint on that failing test. Thanks!

Done ! Many thanks for you feedbacks too @edmocosta

I did kind of copy the existing tests stupidly so I didn't think about adding the tests for all possible types, sorry about that ! I fixed the linting error following your reply also👍

@francois07 francois07 requested a review from edmocosta June 19, 2025 09:21
Copy link
Contributor

@evan-bradley evan-bradley left a comment

Choose a reason for hiding this comment

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

Thanks @francois07!

@evan-bradley evan-bradley merged commit 00ca416 into open-telemetry:main Jun 20, 2025
177 checks passed
@github-actions github-actions bot added this to the next release milestone Jun 20, 2025
@francois07 francois07 deleted the ottl_func_contains branch June 23, 2025 08:06
dd-jasminesun pushed a commit to DataDog/opentelemetry-collector-contrib that referenced this pull request Jun 23, 2025
…comparison (open-telemetry#40370)

<!--Ex. Fixing a bug - Describe the bug and how this fixes the issue.
Ex. Adding a feature - Explain what this achieves.-->
#### Description

This PR introduces two related changes and contains 2 change logs
because of that.

**1 - Comparator API**

Exposes the internal OTTL comparators logic as a new API
(`ottl.ValueComparator`), which can be used by API consumers to compare
raw values following the same OTTL [comparison rules
](https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/pkg/ottl/LANGUAGE.md#comparison-rules).

**Why?**

Existing and new functions that needs to compare values can be
leveraging this new API to compare them, and keep it consistent with the
OTTL comparison logic. For example, the new
[`Contains`](open-telemetry#40193)
function for slices, can be using this API to determine whether an slice
contains a particular value, following the same comparison logic the
grammar does.

```go
// Exported interface:
type ValueComparator interface {
	// Equal compares two values for equality, returning true if they are equals
	// according to the OTTL comparison rules.
	Equal(a any, b any) bool
	// NotEqual compares two values for equality, returning true if they are different
	// according to the OTTL comparison rules.
	NotEqual(a any, b any) bool
	// Less compares two values, returning true if the first value is less than the second
	// value, using the OTTL comparison rules.
	Less(a any, b any) bool
	// LessEqual compares two values, returning true if the first value is less or equal
	// to the second value, using the OTTL comparison rules.
	LessEqual(a any, b any) bool
	// Greater compares two values, returning true if the first value is greater than the
	// second value, using the OTTL comparison rules.
	Greater(a any, b any) bool
	// GreaterEqual compares two values, returning true if the first value is greater or
	// equal to the second value, using the OTTL comparison rules.
	GreaterEqual(a any, b any) bool
}

// Usage:
comp := ottl.NewValueComparator()
```

**2 - Add ability to compare slices**

We currently don't have the ability to compare slices, which means
conditions like `attributes["slice"] == attributes["slice"]` returns
false. This PR also adds the ability to compare slices/pcommon.Slices,
similar to the maps support
(open-telemetry#38611).

<!--Describe what testing was performed and which tests were added.-->
#### Testing
Manual and unit tests

<!--Describe the documentation added.-->
#### Documentation
Updated LANGUAGE.md
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
7 participants