diff --git a/x-pack/osquerybeat/internal/osqdcli/client.go b/x-pack/osquerybeat/internal/osqdcli/client.go index 9ddab622dc7f..a0a6c6959041 100644 --- a/x-pack/osquerybeat/internal/osqdcli/client.go +++ b/x-pack/osquerybeat/internal/osqdcli/client.go @@ -253,7 +253,7 @@ func resolveTypes(hits []map[string]string, colTypes map[string]string) []map[st } // Best effort to convert value types and replace values in the -// If conversion fails the value is kept as string +// If type conversion fails the value is preserved as string func resolveHitTypes(hit, colTypes map[string]string) map[string]interface{} { m := make(map[string]interface{}) for k, v := range hit { @@ -266,25 +266,26 @@ func resolveHitTypes(hit, colTypes map[string]string) map[string]interface{} { n, err = strconv.ParseInt(v, 10, 64) if err == nil { m[k] = n + continue } case "UNSIGNED_BIGINT": var n uint64 n, err = strconv.ParseUint(v, 10, 64) if err == nil { m[k] = n + continue } case "DOUBLE": var n float64 n, err = strconv.ParseFloat(v, 64) if err == nil { m[k] = n + continue } - default: - m[k] = v } - } else { - m[k] = v } + // Keep the original string value if the value can not be converted + m[k] = v } return m } diff --git a/x-pack/osquerybeat/internal/osqdcli/client_test.go b/x-pack/osquerybeat/internal/osqdcli/client_test.go new file mode 100644 index 000000000000..885f421665db --- /dev/null +++ b/x-pack/osquerybeat/internal/osqdcli/client_test.go @@ -0,0 +1,71 @@ +// Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one +// or more contributor license agreements. Licensed under the Elastic License; +// you may not use this file except in compliance with the Elastic License. + +package osqdcli + +import ( + "testing" + + "github.com/google/go-cmp/cmp" +) + +func TestResolveHitTypes(t *testing.T) { + + tests := []struct { + name string + hit, colTypes map[string]string + res map[string]interface{} + }{ + { + name: "empty", + res: map[string]interface{}{}, + }, + { + name: "resolvable", + hit: map[string]string{ + "pid": "5551", + "pid_int": "5552", + "pid_uint": "5553", + "pid_text": "5543", + "foo": "bar", + }, + colTypes: map[string]string{ + "pid": "BIGINT", + "pid_int": "INTEGER", + "pid_uint": "UNSIGNED_BIGINT", + "pid_text": "TEXT", + }, + res: map[string]interface{}{ + "pid": int64(5551), + "pid_int": int64(5552), + "pid_uint": uint64(5553), + "pid_text": "5543", + "foo": "bar", + }, + }, + { + // Should preserve the field if it can not be parsed into the type + name: "wrong type", + hit: map[string]string{ + "data": "0,22,137,138,29754,49154,49155", + "foo": "bar", + }, + colTypes: map[string]string{"data": "BIGINT"}, + res: map[string]interface{}{ + "data": "0,22,137,138,29754,49154,49155", + "foo": "bar", + }, + }, + } + + for _, tc := range tests { + t.Run(tc.name, func(t *testing.T) { + res := resolveHitTypes(tc.hit, tc.colTypes) + diff := cmp.Diff(tc.res, res) + if diff != "" { + t.Fatal(diff) + } + }) + } +}