From 0994c8d9d56c47bf6bd7d68cf6462cac85b23609 Mon Sep 17 00:00:00 2001 From: Philip O'Toole Date: Fri, 24 Apr 2015 18:22:05 -0700 Subject: [PATCH] Ensure no field value is null Fix issue #2420. --- CHANGELOG.md | 1 + httpd/handler_test.go | 20 ++++++++++++++++++++ influxdb.go | 3 +++ server.go | 8 +++++++- 4 files changed, 31 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 40965cf9e0..d950d0f947 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ - [#2415](https://github.com/influxdb/influxdb/pull/2415): Raft leader ID now set on election after failover. Thanks @xiaost - [#2426](https://github.com/influxdb/influxdb/pull/2426): Fix race condition around listener address in openTSDB server. - [#2426](https://github.com/influxdb/influxdb/pull/2426): Fix race condition around listener address in Graphite server. +- [#2429](https://github.com/influxdb/influxdb/pull/2429): Ensure no field value is null. ### Features - [#2410](https://github.com/influxdb/influxdb/pull/2410) Allow configuration of Raft timers diff --git a/httpd/handler_test.go b/httpd/handler_test.go index 07fe36ad53..9954b70542 100644 --- a/httpd/handler_test.go +++ b/httpd/handler_test.go @@ -1184,6 +1184,26 @@ func TestHandler_serveWriteSeriesWithNoFields(t *testing.T) { } } +func TestHandler_serveWriteSeriesWithNullFields(t *testing.T) { + c := test.NewDefaultMessagingClient() + defer c.Close() + srvr := OpenAuthenticatedServer(c) + srvr.CreateDatabase("foo") + srvr.CreateRetentionPolicy("foo", influxdb.NewRetentionPolicy("bar")) + s := NewAPIServer(srvr) + defer s.Close() + + status, body := MustHTTP("POST", s.URL+`/write`, nil, nil, `{"database" : "foo", "retentionPolicy" : "bar", "points": [{"name": "cpu", "fields": {"country": null}}]}`) + + expected := fmt.Sprintf(`{"error":"%s"}`, influxdb.ErrFieldIsNull.Error()) + + if status != http.StatusInternalServerError { + t.Fatalf("unexpected status: %d", status) + } else if body != expected { + t.Fatalf("result mismatch:\n\texp=%s\n\tgot=%s\n", expected, body) + } +} + func TestHandler_serveWriteSeriesWithAuthNilUser(t *testing.T) { c := test.NewDefaultMessagingClient() defer c.Close() diff --git a/influxdb.go b/influxdb.go index 446d88a1a7..e076254636 100644 --- a/influxdb.go +++ b/influxdb.go @@ -117,6 +117,9 @@ var ( // ErrFieldsRequired is returned when a point does not any fields. ErrFieldsRequired = errors.New("fields required") + // FieldIsNull is returned when one of a point's field is null. + ErrFieldIsNull = errors.New("field value is null") + // ErrFieldOverflow is returned when too many fields are created on a measurement. ErrFieldOverflow = errors.New("field overflow") diff --git a/server.go b/server.go index 0654468c44..f6dfd056e0 100644 --- a/server.go +++ b/server.go @@ -1766,11 +1766,17 @@ func (s *Server) WriteSeries(database, retentionPolicy string, points []Point) ( database, retentionPolicy, len(points)) } - // Make sure every point has at least one field. + // Make sure every point is valid. for _, p := range points { if len(p.Fields) == 0 { return 0, ErrFieldsRequired } + + for _, f := range p.Fields { + if f == nil { + return 0, ErrFieldIsNull + } + } } // If the retention policy is not set, use the default for this database.