Fix conversion from string float to integer (#5518)

This commit is contained in:
Daniel Nelson 2019-03-04 12:35:57 -08:00 committed by GitHub
parent d09c213562
commit c0e0da7ef6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 43 additions and 19 deletions

View File

@ -336,7 +336,7 @@ func toInteger(v interface{}) (int64, bool) {
} else if value > float64(math.MaxInt64) { } else if value > float64(math.MaxInt64) {
return math.MaxInt64, true return math.MaxInt64, true
} else { } else {
return int64(value), true return int64(Round(value)), true
} }
case bool: case bool:
if value { if value {
@ -345,8 +345,11 @@ func toInteger(v interface{}) (int64, bool) {
return 0, true return 0, true
} }
case string: case string:
result, err := strconv.ParseInt(value, 10, 64) result, err := strconv.ParseFloat(value, 64)
return result, err == nil if err != nil {
return 0, false
}
return toInteger(result)
} }
return 0, false return 0, false
} }
@ -367,7 +370,7 @@ func toUnsigned(v interface{}) (uint64, bool) {
} else if value > float64(math.MaxUint64) { } else if value > float64(math.MaxUint64) {
return math.MaxUint64, true return math.MaxUint64, true
} else { } else {
return uint64(value), true return uint64(Round(value)), true
} }
case bool: case bool:
if value { if value {
@ -376,8 +379,11 @@ func toUnsigned(v interface{}) (uint64, bool) {
return 0, true return 0, true
} }
case string: case string:
result, err := strconv.ParseUint(value, 10, 64) result, err := strconv.ParseFloat(value, 64)
return result, err == nil if err != nil {
return 0, false
}
return toUnsigned(result)
} }
return 0, false return 0, false
} }
@ -419,6 +425,16 @@ func toString(v interface{}) (string, bool) {
return "", false return "", false
} }
// math.Round was not added until Go 1.10, can be removed when support for Go
// 1.9 is dropped.
func Round(x float64) float64 {
t := math.Trunc(x)
if math.Abs(x-t) >= 0.5 {
return t + math.Copysign(1, x)
}
return t
}
func logPrintf(format string, v ...interface{}) { func logPrintf(format string, v ...interface{}) {
log.Printf("D! [processors.converter] "+format, v...) log.Printf("D! [processors.converter] "+format, v...)
} }

View File

@ -129,8 +129,8 @@ func TestConverter(t *testing.T) {
converter: &Converter{ converter: &Converter{
Fields: &Conversion{ Fields: &Conversion{
String: []string{"a"}, String: []string{"a"},
Integer: []string{"b"}, Integer: []string{"b", "b1", "b2"},
Unsigned: []string{"c"}, Unsigned: []string{"c", "c1", "c2"},
Boolean: []string{"d"}, Boolean: []string{"d"},
Float: []string{"e"}, Float: []string{"e"},
Tag: []string{"f"}, Tag: []string{"f"},
@ -141,12 +141,16 @@ func TestConverter(t *testing.T) {
"cpu", "cpu",
map[string]string{}, map[string]string{},
map[string]interface{}{ map[string]interface{}{
"a": "howdy", "a": "howdy",
"b": "42", "b": "42",
"c": "42", "b1": "42.2",
"d": "true", "b2": "42.5",
"e": "42.0", "c": "42",
"f": "foo", "c1": "42.2",
"c2": "42.5",
"d": "true",
"e": "42.0",
"f": "foo",
}, },
time.Unix(0, 0), time.Unix(0, 0),
), ),
@ -158,11 +162,15 @@ func TestConverter(t *testing.T) {
"f": "foo", "f": "foo",
}, },
map[string]interface{}{ map[string]interface{}{
"a": "howdy", "a": "howdy",
"b": int64(42), "b": int64(42),
"c": uint64(42), "b1": int64(42),
"d": true, "b2": int64(43),
"e": 42.0, "c": uint64(42),
"c1": uint64(42),
"c2": uint64(43),
"d": true,
"e": 42.0,
}, },
time.Unix(0, 0), time.Unix(0, 0),
), ),