diff --git a/mqlc/mqlc.go b/mqlc/mqlc.go index 268dfaa4d5..3f26046fdb 100644 --- a/mqlc/mqlc.go +++ b/mqlc/mqlc.go @@ -1558,7 +1558,10 @@ func (c *compiler) compileOperand(operand *parser.Operand) (*llx.Primitive, erro return nil, err } if !found { - if typ != types.Dict || !reAccessor.MatchString(id) { + // we add simple accessors for maps and dicts, but this also requires + // the `id` to look like a regular accessor (to avoid matching against more + // native internal operators) + if !((typ == types.Dict || typ.IsMap()) && reAccessor.MatchString(id)) { addFieldSuggestions(availableFields(c, typ), id, c.Result) return nil, errors.New("cannot find field '" + id + "' in " + typ.Label()) } @@ -1569,7 +1572,7 @@ func (c *compiler) compileOperand(operand *parser.Operand) (*llx.Primitive, erro Call: llx.Chunk_FUNCTION, Id: "[]", Function: &llx.Function{ - Type: string(typ), + Type: string(typ.Child()), Binding: ref, Args: []*llx.Primitive{llx.StringPrimitive(id)}, }, diff --git a/mqlc/mqlc_test.go b/mqlc/mqlc_test.go index 645e23dbb3..9b0425fcee 100644 --- a/mqlc/mqlc_test.go +++ b/mqlc/mqlc_test.go @@ -1946,9 +1946,9 @@ func TestSuggestions(t *testing.T) { }, { // native type function call - "sshd.config.params.leng", + "sshd.config.ciphers.leng", []string{"length"}, - errors.New("cannot find field 'leng' in map[string]string"), + errors.New("cannot find field 'leng' in []string"), nil, }, { diff --git a/providers/core/resources/mql_test.go b/providers/core/resources/mql_test.go index dd046f1bb3..39d3d5c1dc 100644 --- a/providers/core/resources/mql_test.go +++ b/providers/core/resources/mql_test.go @@ -704,6 +704,14 @@ func TestMap(t *testing.T) { m := "{'a': 1, 'b': 1, 'c': 2}" x := testutils.InitTester(testutils.LinuxMock()) x.TestSimple(t, []testutils.SimpleTest{ + { + Code: m + "['c']", + ResultIndex: 0, Expectation: int64(2), + }, + { + Code: m + ".c", + ResultIndex: 0, Expectation: int64(2), + }, // contains { Code: m + ".contains(key == 'a')",