Skip to content

Commit

Permalink
✨ support []string.in([]string) (#2989)
Browse files Browse the repository at this point in the history
This finally supports use-cases like:

```coffee
sshd.config.ciphers.in( props.allowedCiphers )
```

Signed-off-by: Dominik Richter <[email protected]>
  • Loading branch information
arlimus authored Jan 10, 2024
1 parent d0e170f commit 2026f2a
Show file tree
Hide file tree
Showing 6 changed files with 60 additions and 1 deletion.
1 change: 1 addition & 0 deletions llx/builtin.go
Original file line number Diff line number Diff line change
Expand Up @@ -596,6 +596,7 @@ func init() {
"fieldDuplicates": {f: arrayFieldDuplicatesV2},
"unique": {f: arrayUniqueV2},
"difference": {f: arrayDifferenceV2},
"in": {f: anyArrayInStringArray},
"containsAll": {f: arrayContainsAll},
"containsNone": {f: arrayContainsNone},
"==": {Compiler: compileArrayOpArray("=="), f: tarrayCmpTarrayV2, Label: "=="},
Expand Down
39 changes: 39 additions & 0 deletions llx/builtin_array.go
Original file line number Diff line number Diff line change
Expand Up @@ -743,6 +743,45 @@ func arrayDifferenceV2(e *blockExecutor, bind *RawData, chunk *Chunk, ref uint64
return &RawData{Type: bind.Type, Value: res}, 0, nil
}

func anyArrayInStringArray(e *blockExecutor, bind *RawData, chunk *Chunk, ref uint64) (*RawData, uint64, error) {
if bind.Value == nil {
return &RawData{Type: bind.Type, Error: bind.Error}, 0, nil
}

anyArray := bind.Value.([]any)
argRef := chunk.Function.Args[0]
arg, rref, err := e.resolveValue(argRef, ref)
if err != nil || rref > 0 {
return nil, rref, err
}

if arg.Value == nil {
return BoolFalse, 0, nil
}

for b := range anyArray {
binds, ok := anyArray[b].(string)
if !ok {
return BoolFalse, 0, nil
}

arr := arg.Value.([]any)
found := false
for i := range arr {
v := arr[i].(string)
if binds == v {
found = true
break
}
}
if !found {
return BoolFalse, 0, nil
}
}

return BoolTrue, 0, nil
}

func arrayContainsAll(e *blockExecutor, bind *RawData, chunk *Chunk, ref uint64) (*RawData, uint64, error) {
if bind.Value == nil {
return &RawData{Type: bind.Type, Error: bind.Error}, 0, nil
Expand Down
4 changes: 3 additions & 1 deletion llx/builtin_map.go
Original file line number Diff line number Diff line change
Expand Up @@ -532,7 +532,7 @@ func dictBlockCallV2(e *blockExecutor, bind *RawData, chunk *Chunk, ref uint64)
func dictCamelcaseV2(e *blockExecutor, bind *RawData, chunk *Chunk, ref uint64) (*RawData, uint64, error) {
_, ok := bind.Value.(string)
if !ok {
return nil, 0, errors.New("dict value does not support field `downcase`")
return nil, 0, errors.New("dict value does not support field `camelcase`")
}

return stringCamelcaseV2(e, bind, chunk, ref)
Expand Down Expand Up @@ -1283,6 +1283,8 @@ func dictIn(e *blockExecutor, bind *RawData, chunk *Chunk, ref uint64) (*RawData
switch bind.Value.(type) {
case string:
return stringInArray(e, bind, chunk, ref)
case []any:
return anyArrayInStringArray(e, bind, chunk, ref)
default:
return nil, 0, errors.New("dict value does not support field `in`")
}
Expand Down
1 change: 1 addition & 0 deletions mqlc/builtin.go
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@ func init() {
"where": {compile: compileArrayWhere, signature: FunctionSignature{Required: 1, Args: []types.Type{types.FunctionLike}}},
"duplicates": {compile: compileArrayDuplicates, signature: FunctionSignature{Required: 0, Args: []types.Type{types.String}}},
"unique": {compile: compileArrayUnique, signature: FunctionSignature{Required: 0}},
"in": {typ: boolType, compile: compileStringIn, signature: FunctionSignature{Required: 1, Args: []types.Type{types.Array(types.String)}}},
"contains": {compile: compileArrayContains, signature: FunctionSignature{Required: 1, Args: []types.Type{types.FunctionLike}}},
"containsOnly": {compile: compileArrayContainsOnly, signature: FunctionSignature{Required: 1, Args: []types.Type{types.FunctionLike}}},
"containsAll": {compile: compileArrayContainsAll, signature: FunctionSignature{Required: 1, Args: []types.Type{types.FunctionLike}}},
Expand Down
8 changes: 8 additions & 0 deletions providers/core/resources/mql_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -609,6 +609,14 @@ func TestArray(t *testing.T) {
ResultIndex: 1,
Expectation: true,
},
{
Code: "['hi'].in(['one','hi','five'])",
Expectation: true,
},
{
Code: "['hi', 'bob'].in(['one','hi','five'])",
Expectation: false,
},
{
Code: "[1,2,3].all(_ < 9)",
ResultIndex: 1,
Expand Down
8 changes: 8 additions & 0 deletions providers/os/resources/mql_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -383,6 +383,14 @@ func TestDict_Methods_Map(t *testing.T) {
Code: p + "params['string-array'].where(_ == 'a')",
Expectation: []interface{}{"a"},
},
{
Code: p + "params['string-array'].in(['a', 'b', 'c'])",
Expectation: true,
},
{
Code: p + "params['string-array'].in(['z', 'b'])",
Expectation: false,
},
{
Code: p + "params['string-array'].one(_ == 'a')",
ResultIndex: 1,
Expand Down

0 comments on commit 2026f2a

Please sign in to comment.