diff --git a/src/checkers/series_equal.go b/src/checkers/series_equal.go index 58cc59e2e98..17898ce9301 100644 --- a/src/checkers/series_equal.go +++ b/src/checkers/series_equal.go @@ -2,9 +2,9 @@ package checkers import ( "fmt" - . "launchpad.net/gocheck" "protocol" "reflect" + . "launchpad.net/gocheck" ) type SeriesEqualsChecker struct { @@ -89,8 +89,8 @@ func CheckSeriesEquality(s1, s2 *protocol.Series) bool { firstSimplePoint := SimplePoint{} secondSimplePoint := SimplePoint{} for fieldIndex, _ := range s1.Fields { - firstSimplePoint[fieldIndex] = point.Values[fieldIndex].GetValue() - secondSimplePoint[fieldIndex] = point.Values[fieldIndex].GetValue() + firstSimplePoint[fieldIndex], _ = point.Values[fieldIndex].GetValue() + secondSimplePoint[fieldIndex], _ = point.Values[fieldIndex].GetValue() } pointsMap := firstSeriesPoints[*point.Timestamp] diff --git a/src/common/serialize_series.go b/src/common/serialize_series.go index 8f718d78f76..05a66276f93 100644 --- a/src/common/serialize_series.go +++ b/src/common/serialize_series.go @@ -3,6 +3,8 @@ package common import ( "fmt" "protocol" + + log "code.google.com/p/log4go" ) var ( @@ -166,7 +168,13 @@ func SerializeSeries(memSeries map[string]*protocol.Series, precision TimePrecis rowValues = append(rowValues, nil) continue } - rowValues = append(rowValues, value.GetValue()) + v, ok := value.GetValue() + if !ok { + rowValues = append(rowValues, nil) + log.Warn("Infinite or NaN value encountered") + continue + } + rowValues = append(rowValues, v) } points = append(points, rowValues) } diff --git a/src/integration/data_test.go b/src/integration/data_test.go index 0194e4c5957..3c215f8fd1f 100644 --- a/src/integration/data_test.go +++ b/src/integration/data_test.go @@ -96,6 +96,32 @@ func (self *DataTestSuite) TestAll(c *C) { type Fun func(client Client) +// issue #518 +func (self *DataTestSuite) InfiniteValues(c *C) (Fun, Fun) { + // make sure we exceed the pointBatchSize, so we force a yield to + // the filtering engine + return func(client Client) { + data := ` +[ + { + "points": [ + [1399590718, 0.0], + [1399590718, 0.0] + ], + "name": "test_infinite_values", + "columns": ["time", "value"] + } +]` + client.WriteJsonData(data, c, influxdb.Second) + }, func(client Client) { + serieses := client.RunQuery("select derivative(value) from test_infinite_values", c, "m") + c.Assert(serieses, HasLen, 1) + maps := ToMap(serieses[0]) + c.Assert(maps, HasLen, 1) + c.Assert(maps[0]["derivative"], IsNil) + } +} + // issue #512 func (self *DataTestSuite) GroupByNullValues(c *C) (Fun, Fun) { // make sure we exceed the pointBatchSize, so we force a yield to diff --git a/src/protocol/protocol_extensions.go b/src/protocol/protocol_extensions.go index 483b7ab12bc..cafc70b4dff 100644 --- a/src/protocol/protocol_extensions.go +++ b/src/protocol/protocol_extensions.go @@ -6,6 +6,8 @@ import ( "sort" "strconv" + "math" + "code.google.com/p/goprotobuf/proto" ) @@ -31,25 +33,31 @@ func (self *Point) SetTimestampInMicroseconds(t int64) { self.Timestamp = &t } -func (self *FieldValue) GetValue() interface{} { +// Returns the value as an interface and true for all values, except +// for infinite and NaN values +func (self *FieldValue) GetValue() (interface{}, bool) { if self.StringValue != nil { - return *self.StringValue + return *self.StringValue, true } if self.DoubleValue != nil { - return *self.DoubleValue + fv := *self.DoubleValue + if math.IsNaN(fv) || math.IsInf(fv, 0) { + return 0, false + } + return fv, true } if self.Int64Value != nil { - return *self.Int64Value + return *self.Int64Value, true } if self.BoolValue != nil { - return *self.BoolValue + return *self.BoolValue, true } // TODO: should we do something here ? - return nil + return nil, true } func (self *Point) GetFieldValue(idx int) interface{} { @@ -58,7 +66,8 @@ func (self *Point) GetFieldValue(idx int) interface{} { if v == nil { return nil } - return v.GetValue() + iv, _ := v.GetValue() + return iv } func (self *Point) GetFieldValueAsString(idx int) string {