Skip to content

Commit

Permalink
Allow indexing string slice type (#35581)
Browse files Browse the repository at this point in the history
**Description:** Allow indexing string slice type. I can also add
support for other types such as []int if needed. Let me know if this
approach is good enough.

I haven't found a more generic solution, thank you for any feedback.

**Link to tracking Issue:** Fixes  #29441

**Testing:** Unit test

**Documentation:**
  • Loading branch information
lkwronski authored Oct 14, 2024
1 parent 9b944d6 commit d20c3f8
Show file tree
Hide file tree
Showing 4 changed files with 79 additions and 3 deletions.
27 changes: 27 additions & 0 deletions .chloggen/lkwronski.issue-29441-slice.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# Use this changelog template to create an entry for release notes.

# One of 'breaking', 'deprecation', 'new_component', 'enhancement', 'bug_fix'
change_type: bug_fix

# The name of the component, or a single word describing the area of concern, (e.g. filelogreceiver)
component: pkg/ottl

# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`).
note: Allow indexing string slice type

# Mandatory: One or more tracking issues related to the change. You can use the PR number here if no issue exists.
issues: [29441]

# (Optional) One or more lines of additional information to render under the primary note.
# These lines will be padded with 2 spaces and then inserted directly into the document.
# Use pipe (|) for multiline entries.
subtext:

# If your change doesn't affect end users or the exported elements of any package,
# you should instead start your pull request title with [chore] or use the "Skip Changelog" label.
# Optional: The change log or logs in which this entry should be included.
# e.g. '[user]' or '[user, api]'
# 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]
7 changes: 7 additions & 0 deletions pkg/ottl/e2e/e2e_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1010,6 +1010,13 @@ func Test_e2e_ottl_features(t *testing.T) {
tCtx.GetLogRecord().Attributes().PutBool("isMap", true)
},
},
{
name: "extract value from Split function result slice of type []string",
statement: `set(attributes["my.environment.2"], Split(resource.attributes["host.name"],"h")[1])`,
want: func(tCtx ottllog.TransformContext) {
tCtx.GetLogRecord().Attributes().PutStr("my.environment.2", "ost")
},
},
}

for _, tt := range tests {
Expand Down
18 changes: 15 additions & 3 deletions pkg/ottl/expression.go
Original file line number Diff line number Diff line change
Expand Up @@ -111,10 +111,15 @@ func (g exprGetter[K]) Get(ctx context.Context, tCtx K) (any, error) {
}
result = ottlcommon.GetValue(r.At(int(*k.Int)))
case []any:
if int(*k.Int) >= len(r) || int(*k.Int) < 0 {
return nil, fmt.Errorf("index %v out of bounds", *k.Int)
result, err = getElementByIndex(r, k.Int)
if err != nil {
return nil, err
}
case []string:
result, err = getElementByIndex(r, k.Int)
if err != nil {
return nil, err
}
result = r[*k.Int]
default:
return nil, fmt.Errorf("type, %T, does not support int indexing", result)
}
Expand All @@ -125,6 +130,13 @@ func (g exprGetter[K]) Get(ctx context.Context, tCtx K) (any, error) {
return result, nil
}

func getElementByIndex[T any](r []T, idx *int64) (any, error) {
if int(*idx) >= len(r) || int(*idx) < 0 {
return nil, fmt.Errorf("index %v out of bounds", *idx)
}
return r[*idx], nil
}

type listGetter[K any] struct {
slice []Getter[K]
}
Expand Down
30 changes: 30 additions & 0 deletions pkg/ottl/expression_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,16 @@ func basicSlice() (ExprFunc[any], error) {
}, nil
}

func basicSliceString() (ExprFunc[any], error) {
return func(_ context.Context, _ any) (any, error) {
return []any{
[]string{
"pass",
},
}, nil
}, nil
}

func Test_newGetter(t *testing.T) {
tests := []struct {
name string
Expand Down Expand Up @@ -237,6 +247,25 @@ func Test_newGetter(t *testing.T) {
},
want: "pass",
},
{
name: "function call nested SliceString",
val: value{
Literal: &mathExprLiteral{
Converter: &converter{
Function: "SliceString",
Keys: []key{
{
Int: ottltest.Intp(0),
},
{
Int: ottltest.Intp(0),
},
},
},
},
},
want: "pass",
},
{
name: "enum",
val: value{
Expand Down Expand Up @@ -532,6 +561,7 @@ func Test_newGetter(t *testing.T) {
createFactory("Map", &struct{}{}, basicMap),
createFactory("PSlice", &struct{}{}, pslice),
createFactory("Slice", &struct{}{}, basicSlice),
createFactory("SliceString", &struct{}{}, basicSliceString),
)

p, _ := NewParser[any](
Expand Down

0 comments on commit d20c3f8

Please sign in to comment.