From 06bc25d64b6f9422a134c28a5335bf18ca0bc703 Mon Sep 17 00:00:00 2001 From: Nathaniel Cook Date: Fri, 4 Dec 2015 17:34:19 -0700 Subject: [PATCH 1/2] add integration tests for derivative calls and all other valid functions, convert PositionPoint to float64 --- cmd/influxd/run/server_test.go | 401 ++++++++++++++++++++++++++++++++- tsdb/raw.go | 45 ++-- 2 files changed, 422 insertions(+), 24 deletions(-) diff --git a/cmd/influxd/run/server_test.go b/cmd/influxd/run/server_test.go index cae867ce941..e0cffc352af 100644 --- a/cmd/influxd/run/server_test.go +++ b/cmd/influxd/run/server_test.go @@ -1482,8 +1482,8 @@ func TestServer_Query_SelectRelativeTime(t *testing.T) { } } -// Ensure the server can handle various simple calculus queries. -func TestServer_Query_SelectRawCalculus(t *testing.T) { +// Ensure the server can handle various simple derivative queries. +func TestServer_Query_SelectRawDerivative(t *testing.T) { t.Parallel() s := OpenServer(NewConfig(), "") defer s.Close() @@ -1501,6 +1501,403 @@ func TestServer_Query_SelectRawCalculus(t *testing.T) { command: `SELECT derivative(value) from db0.rp0.cpu`, exp: `{"results":[{"series":[{"name":"cpu","columns":["time","derivative"],"values":[["2010-07-01T18:47:02Z",-200]]}]}]}`, }, + &Query{ + name: "calculate derivate with unit", + command: `SELECT derivative(value, 10s) from db0.rp0.cpu`, + exp: `{"results":[{"series":[{"name":"cpu","columns":["time","derivative"],"values":[["2010-07-01T18:47:02Z",-2000]]}]}]}`, + }, + }...) + + for i, query := range test.queries { + if i == 0 { + if err := test.init(s); err != nil { + t.Fatalf("test init failed: %s", err) + } + } + if query.skip { + t.Logf("SKIP:: %s", query.name) + continue + } + if err := query.Execute(s); err != nil { + t.Error(query.Error(err)) + } else if !query.success() { + t.Error(query.failureMessage()) + } + } +} + +// Ensure the server can handle various simple non_negative_derivative queries. +func TestServer_Query_SelectRawNonNegativeDerivative(t *testing.T) { + t.Parallel() + s := OpenServer(NewConfig(), "") + defer s.Close() + + if err := s.CreateDatabaseAndRetentionPolicy("db0", newRetentionPolicyInfo("rp0", 1, 1*time.Hour)); err != nil { + t.Fatal(err) + } + + test := NewTest("db0", "rp0") + test.write = fmt.Sprintf(`cpu value=10 1278010021000000000 +cpu value=15 1278010022000000000 +cpu value=10 1278010023000000000 +cpu value=20 1278010024000000000 +`) + + test.addQueries([]*Query{ + &Query{ + name: "calculate single non_negative_derivative", + command: `SELECT non_negative_derivative(value) from db0.rp0.cpu`, + exp: `{"results":[{"series":[{"name":"cpu","columns":["time","non_negative_derivative"],"values":[["2010-07-01T18:47:02Z",5],["2010-07-01T18:47:04Z",10]]}]}]}`, + }, + &Query{ + name: "calculate single non_negative_derivative", + command: `SELECT non_negative_derivative(value, 10s) from db0.rp0.cpu`, + exp: `{"results":[{"series":[{"name":"cpu","columns":["time","non_negative_derivative"],"values":[["2010-07-01T18:47:02Z",50],["2010-07-01T18:47:04Z",100]]}]}]}`, + }, + }...) + + for i, query := range test.queries { + if i == 0 { + if err := test.init(s); err != nil { + t.Fatalf("test init failed: %s", err) + } + } + if query.skip { + t.Logf("SKIP:: %s", query.name) + continue + } + if err := query.Execute(s); err != nil { + t.Error(query.Error(err)) + } else if !query.success() { + t.Error(query.failureMessage()) + } + } +} + +// Ensure the server can handle various group by time derivative queries. +func TestServer_Query_SelectGroupByTimeDerivative(t *testing.T) { + t.Parallel() + s := OpenServer(NewConfig(), "") + defer s.Close() + + if err := s.CreateDatabaseAndRetentionPolicy("db0", newRetentionPolicyInfo("rp0", 1, 1*time.Hour)); err != nil { + t.Fatal(err) + } + + test := NewTest("db0", "rp0") + test.write = fmt.Sprintf(`cpu value=10 1278010020000000000 +cpu value=15 1278010021000000000 +cpu value=20 1278010022000000000 +cpu value=25 1278010023000000000 +`) + + test.addQueries([]*Query{ + &Query{ + name: "calculate derivative of count with unit default (2s) group by time", + command: `SELECT derivative(count(value)) from db0.rp0.cpu where time >= '2010-07-01 18:47:00' and time <= '2010-07-01 18:47:03' group by time(2s)`, + exp: `{"results":[{"series":[{"name":"cpu","columns":["time","derivative"],"values":[["2010-07-01T18:47:02Z",0]]}]}]}`, + }, + &Query{ + name: "calculate derivative of count with unit 4s group by time", + command: `SELECT derivative(count(value), 4s) from db0.rp0.cpu where time >= '2010-07-01 18:47:00' and time <= '2010-07-01 18:47:03' group by time(2s)`, + exp: `{"results":[{"series":[{"name":"cpu","columns":["time","derivative"],"values":[["2010-07-01T18:47:02Z",0]]}]}]}`, + }, + &Query{ + name: "calculate derivative of mean with unit default (2s) group by time", + command: `SELECT derivative(mean(value)) from db0.rp0.cpu where time >= '2010-07-01 18:47:00' and time <= '2010-07-01 18:47:03' group by time(2s)`, + exp: `{"results":[{"series":[{"name":"cpu","columns":["time","derivative"],"values":[["2010-07-01T18:47:02Z",10]]}]}]}`, + }, + &Query{ + name: "calculate derivative of mean with unit 4s group by time", + command: `SELECT derivative(mean(value), 4s) from db0.rp0.cpu where time >= '2010-07-01 18:47:00' and time <= '2010-07-01 18:47:03' group by time(2s)`, + exp: `{"results":[{"series":[{"name":"cpu","columns":["time","derivative"],"values":[["2010-07-01T18:47:02Z",20]]}]}]}`, + }, + &Query{ + name: "calculate derivative of median with unit default (2s) group by time", + command: `SELECT derivative(median(value)) from db0.rp0.cpu where time >= '2010-07-01 18:47:00' and time <= '2010-07-01 18:47:03' group by time(2s)`, + exp: `{"results":[{"series":[{"name":"cpu","columns":["time","derivative"],"values":[["2010-07-01T18:47:02Z",10]]}]}]}`, + }, + &Query{ + name: "calculate derivative of median with unit 4s group by time", + command: `SELECT derivative(median(value), 4s) from db0.rp0.cpu where time >= '2010-07-01 18:47:00' and time <= '2010-07-01 18:47:03' group by time(2s)`, + exp: `{"results":[{"series":[{"name":"cpu","columns":["time","derivative"],"values":[["2010-07-01T18:47:02Z",20]]}]}]}`, + }, + &Query{ + name: "calculate derivative of sum with unit default (2s) group by time", + command: `SELECT derivative(sum(value)) from db0.rp0.cpu where time >= '2010-07-01 18:47:00' and time <= '2010-07-01 18:47:03' group by time(2s)`, + exp: `{"results":[{"series":[{"name":"cpu","columns":["time","derivative"],"values":[["2010-07-01T18:47:02Z",20]]}]}]}`, + }, + &Query{ + name: "calculate derivative of sum with unit 4s group by time", + command: `SELECT derivative(sum(value), 4s) from db0.rp0.cpu where time >= '2010-07-01 18:47:00' and time <= '2010-07-01 18:47:03' group by time(2s)`, + exp: `{"results":[{"series":[{"name":"cpu","columns":["time","derivative"],"values":[["2010-07-01T18:47:02Z",40]]}]}]}`, + }, + &Query{ + name: "calculate derivative of first with unit default (2s) group by time", + command: `SELECT derivative(first(value)) from db0.rp0.cpu where time >= '2010-07-01 18:47:00' and time <= '2010-07-01 18:47:03' group by time(2s)`, + exp: `{"results":[{"series":[{"name":"cpu","columns":["time","derivative"],"values":[["2010-07-01T18:47:02Z",10]]}]}]}`, + }, + &Query{ + name: "calculate derivative of first with unit 4s group by time", + command: `SELECT derivative(first(value), 4s) from db0.rp0.cpu where time >= '2010-07-01 18:47:00' and time <= '2010-07-01 18:47:03' group by time(2s)`, + exp: `{"results":[{"series":[{"name":"cpu","columns":["time","derivative"],"values":[["2010-07-01T18:47:02Z",20]]}]}]}`, + }, + &Query{ + name: "calculate derivative of last with unit default (2s) group by time", + command: `SELECT derivative(last(value)) from db0.rp0.cpu where time >= '2010-07-01 18:47:00' and time <= '2010-07-01 18:47:03' group by time(2s)`, + exp: `{"results":[{"series":[{"name":"cpu","columns":["time","derivative"],"values":[["2010-07-01T18:47:02Z",10]]}]}]}`, + }, + &Query{ + name: "calculate derivative of last with unit 4s group by time", + command: `SELECT derivative(last(value), 4s) from db0.rp0.cpu where time >= '2010-07-01 18:47:00' and time <= '2010-07-01 18:47:03' group by time(2s)`, + exp: `{"results":[{"series":[{"name":"cpu","columns":["time","derivative"],"values":[["2010-07-01T18:47:02Z",20]]}]}]}`, + }, + &Query{ + name: "calculate derivative of min with unit default (2s) group by time", + command: `SELECT derivative(min(value)) from db0.rp0.cpu where time >= '2010-07-01 18:47:00' and time <= '2010-07-01 18:47:03' group by time(2s)`, + exp: `{"results":[{"series":[{"name":"cpu","columns":["time","derivative"],"values":[["2010-07-01T18:47:02Z",10]]}]}]}`, + }, + &Query{ + name: "calculate derivative of min with unit 4s group by time", + command: `SELECT derivative(min(value), 4s) from db0.rp0.cpu where time >= '2010-07-01 18:47:00' and time <= '2010-07-01 18:47:03' group by time(2s)`, + exp: `{"results":[{"series":[{"name":"cpu","columns":["time","derivative"],"values":[["2010-07-01T18:47:02Z",20]]}]}]}`, + }, + &Query{ + name: "calculate derivative of max with unit default (2s) group by time", + command: `SELECT derivative(max(value)) from db0.rp0.cpu where time >= '2010-07-01 18:47:00' and time <= '2010-07-01 18:47:03' group by time(2s)`, + exp: `{"results":[{"series":[{"name":"cpu","columns":["time","derivative"],"values":[["2010-07-01T18:47:02Z",10]]}]}]}`, + }, + &Query{ + name: "calculate derivative of max with unit 4s group by time", + command: `SELECT derivative(max(value), 4s) from db0.rp0.cpu where time >= '2010-07-01 18:47:00' and time <= '2010-07-01 18:47:03' group by time(2s)`, + exp: `{"results":[{"series":[{"name":"cpu","columns":["time","derivative"],"values":[["2010-07-01T18:47:02Z",20]]}]}]}`, + }, + &Query{ + name: "calculate derivative of percentile with unit default (2s) group by time", + command: `SELECT derivative(percentile(value, 50)) from db0.rp0.cpu where time >= '2010-07-01 18:47:00' and time <= '2010-07-01 18:47:03' group by time(2s)`, + exp: `{"results":[{"series":[{"name":"cpu","columns":["time","derivative"],"values":[["2010-07-01T18:47:02Z",10]]}]}]}`, + }, + &Query{ + name: "calculate derivative of percentile with unit 4s group by time", + command: `SELECT derivative(percentile(value, 50), 4s) from db0.rp0.cpu where time >= '2010-07-01 18:47:00' and time <= '2010-07-01 18:47:03' group by time(2s)`, + exp: `{"results":[{"series":[{"name":"cpu","columns":["time","derivative"],"values":[["2010-07-01T18:47:02Z",20]]}]}]}`, + }, + }...) + + for i, query := range test.queries { + if i == 0 { + if err := test.init(s); err != nil { + t.Fatalf("test init failed: %s", err) + } + } + if query.skip { + t.Logf("SKIP:: %s", query.name) + continue + } + if err := query.Execute(s); err != nil { + t.Error(query.Error(err)) + } else if !query.success() { + t.Error(query.failureMessage()) + } + } +} + +// Ensure the server can handle various group by time derivative queries. +func TestServer_Query_SelectGroupByTimeDerivativeWithFill(t *testing.T) { + t.Parallel() + s := OpenServer(NewConfig(), "") + defer s.Close() + + if err := s.CreateDatabaseAndRetentionPolicy("db0", newRetentionPolicyInfo("rp0", 1, 1*time.Hour)); err != nil { + t.Fatal(err) + } + + test := NewTest("db0", "rp0") + test.write = fmt.Sprintf(`cpu value=10 1278010020000000000 +cpu value=20 1278010021000000000 +`) + + test.addQueries([]*Query{ + &Query{ + name: "calculate derivative of count with unit default (2s) group by time with fill 0", + command: `SELECT derivative(count(value)) from db0.rp0.cpu where time >= '2010-07-01 18:47:00' and time <= '2010-07-01 18:47:03' group by time(2s) fill(0)`, + exp: `{"results":[{"series":[{"name":"cpu","columns":["time","derivative"],"values":[["2010-07-01T18:47:02Z",-2]]}]}]}`, + }, + &Query{ + name: "calculate derivative of count with unit 4s group by time with fill 0", + command: `SELECT derivative(count(value), 4s) from db0.rp0.cpu where time >= '2010-07-01 18:47:00' and time <= '2010-07-01 18:47:03' group by time(2s) fill(0)`, + exp: `{"results":[{"series":[{"name":"cpu","columns":["time","derivative"],"values":[["2010-07-01T18:47:02Z",-4]]}]}]}`, + }, + &Query{ + name: "calculate derivative of count with unit default (2s) group by time with fill previous", + command: `SELECT derivative(count(value)) from db0.rp0.cpu where time >= '2010-07-01 18:47:00' and time <= '2010-07-01 18:47:03' group by time(2s) fill(previous)`, + exp: `{"results":[{"series":[{"name":"cpu","columns":["time","derivative"],"values":[["2010-07-01T18:47:02Z",0]]}]}]}`, + }, + &Query{ + name: "calculate derivative of count with unit 4s group by time with fill previous", + command: `SELECT derivative(count(value), 4s) from db0.rp0.cpu where time >= '2010-07-01 18:47:00' and time <= '2010-07-01 18:47:03' group by time(2s) fill(previous)`, + exp: `{"results":[{"series":[{"name":"cpu","columns":["time","derivative"],"values":[["2010-07-01T18:47:02Z",0]]}]}]}`, + }, + &Query{ + name: "calculate derivative of mean with unit default (2s) group by time with fill 0", + command: `SELECT derivative(mean(value)) from db0.rp0.cpu where time >= '2010-07-01 18:47:00' and time <= '2010-07-01 18:47:03' group by time(2s) fill(0)`, + exp: `{"results":[{"series":[{"name":"cpu","columns":["time","derivative"],"values":[["2010-07-01T18:47:02Z",-15]]}]}]}`, + }, + &Query{ + name: "calculate derivative of mean with unit 4s group by time with fill 0", + command: `SELECT derivative(mean(value), 4s) from db0.rp0.cpu where time >= '2010-07-01 18:47:00' and time <= '2010-07-01 18:47:03' group by time(2s) fill(0)`, + exp: `{"results":[{"series":[{"name":"cpu","columns":["time","derivative"],"values":[["2010-07-01T18:47:02Z",-30]]}]}]}`, + }, + &Query{ + name: "calculate derivative of mean with unit default (2s) group by time with fill previous", + command: `SELECT derivative(mean(value)) from db0.rp0.cpu where time >= '2010-07-01 18:47:00' and time <= '2010-07-01 18:47:03' group by time(2s) fill(previous)`, + exp: `{"results":[{"series":[{"name":"cpu","columns":["time","derivative"],"values":[["2010-07-01T18:47:02Z",0]]}]}]}`, + }, + &Query{ + name: "calculate derivative of mean with unit 4s group by time with fill previous", + command: `SELECT derivative(mean(value), 4s) from db0.rp0.cpu where time >= '2010-07-01 18:47:00' and time <= '2010-07-01 18:47:03' group by time(2s) fill(previous)`, + exp: `{"results":[{"series":[{"name":"cpu","columns":["time","derivative"],"values":[["2010-07-01T18:47:02Z",0]]}]}]}`, + }, + &Query{ + name: "calculate derivative of median with unit default (2s) group by time with fill 0", + command: `SELECT derivative(median(value)) from db0.rp0.cpu where time >= '2010-07-01 18:47:00' and time <= '2010-07-01 18:47:03' group by time(2s) fill(0)`, + exp: `{"results":[{"series":[{"name":"cpu","columns":["time","derivative"],"values":[["2010-07-01T18:47:02Z",-15]]}]}]}`, + }, + &Query{ + name: "calculate derivative of median with unit 4s group by time with fill 0", + command: `SELECT derivative(median(value), 4s) from db0.rp0.cpu where time >= '2010-07-01 18:47:00' and time <= '2010-07-01 18:47:03' group by time(2s) fill(0)`, + exp: `{"results":[{"series":[{"name":"cpu","columns":["time","derivative"],"values":[["2010-07-01T18:47:02Z",-30]]}]}]}`, + }, + &Query{ + name: "calculate derivative of median with unit default (2s) group by time with fill previous", + command: `SELECT derivative(median(value)) from db0.rp0.cpu where time >= '2010-07-01 18:47:00' and time <= '2010-07-01 18:47:03' group by time(2s) fill(previous)`, + exp: `{"results":[{"series":[{"name":"cpu","columns":["time","derivative"],"values":[["2010-07-01T18:47:02Z",0]]}]}]}`, + }, + &Query{ + name: "calculate derivative of median with unit 4s group by time with fill previous", + command: `SELECT derivative(median(value), 4s) from db0.rp0.cpu where time >= '2010-07-01 18:47:00' and time <= '2010-07-01 18:47:03' group by time(2s) fill(previous)`, + exp: `{"results":[{"series":[{"name":"cpu","columns":["time","derivative"],"values":[["2010-07-01T18:47:02Z",0]]}]}]}`, + }, + &Query{ + name: "calculate derivative of sum with unit default (2s) group by time with fill 0", + command: `SELECT derivative(sum(value)) from db0.rp0.cpu where time >= '2010-07-01 18:47:00' and time <= '2010-07-01 18:47:03' group by time(2s) fill(0)`, + exp: `{"results":[{"series":[{"name":"cpu","columns":["time","derivative"],"values":[["2010-07-01T18:47:02Z",-30]]}]}]}`, + }, + &Query{ + name: "calculate derivative of sum with unit 4s group by time with fill 0", + command: `SELECT derivative(sum(value), 4s) from db0.rp0.cpu where time >= '2010-07-01 18:47:00' and time <= '2010-07-01 18:47:03' group by time(2s) fill(0)`, + exp: `{"results":[{"series":[{"name":"cpu","columns":["time","derivative"],"values":[["2010-07-01T18:47:02Z",-60]]}]}]}`, + }, + &Query{ + name: "calculate derivative of sum with unit default (2s) group by time with fill previous", + command: `SELECT derivative(sum(value)) from db0.rp0.cpu where time >= '2010-07-01 18:47:00' and time <= '2010-07-01 18:47:03' group by time(2s) fill(previous)`, + exp: `{"results":[{"series":[{"name":"cpu","columns":["time","derivative"],"values":[["2010-07-01T18:47:02Z",0]]}]}]}`, + }, + &Query{ + name: "calculate derivative of sum with unit 4s group by time with fill previous", + command: `SELECT derivative(sum(value), 4s) from db0.rp0.cpu where time >= '2010-07-01 18:47:00' and time <= '2010-07-01 18:47:03' group by time(2s) fill(previous)`, + exp: `{"results":[{"series":[{"name":"cpu","columns":["time","derivative"],"values":[["2010-07-01T18:47:02Z",0]]}]}]}`, + }, + &Query{ + name: "calculate derivative of first with unit default (2s) group by time with fill 0", + command: `SELECT derivative(first(value)) from db0.rp0.cpu where time >= '2010-07-01 18:47:00' and time <= '2010-07-01 18:47:03' group by time(2s) fill(0)`, + exp: `{"results":[{"series":[{"name":"cpu","columns":["time","derivative"],"values":[["2010-07-01T18:47:02Z",-10]]}]}]}`, + }, + &Query{ + name: "calculate derivative of first with unit 4s group by time with fill 0", + command: `SELECT derivative(first(value), 4s) from db0.rp0.cpu where time >= '2010-07-01 18:47:00' and time <= '2010-07-01 18:47:03' group by time(2s) fill(0)`, + exp: `{"results":[{"series":[{"name":"cpu","columns":["time","derivative"],"values":[["2010-07-01T18:47:02Z",-20]]}]}]}`, + }, + &Query{ + name: "calculate derivative of first with unit default (2s) group by time with fill previous", + command: `SELECT derivative(first(value)) from db0.rp0.cpu where time >= '2010-07-01 18:47:00' and time <= '2010-07-01 18:47:03' group by time(2s) fill(previous)`, + exp: `{"results":[{"series":[{"name":"cpu","columns":["time","derivative"],"values":[["2010-07-01T18:47:02Z",0]]}]}]}`, + }, + &Query{ + name: "calculate derivative of first with unit 4s group by time with fill previous", + command: `SELECT derivative(first(value), 4s) from db0.rp0.cpu where time >= '2010-07-01 18:47:00' and time <= '2010-07-01 18:47:03' group by time(2s) fill(previous)`, + exp: `{"results":[{"series":[{"name":"cpu","columns":["time","derivative"],"values":[["2010-07-01T18:47:02Z",0]]}]}]}`, + }, + &Query{ + name: "calculate derivative of last with unit default (2s) group by time with fill 0", + command: `SELECT derivative(last(value)) from db0.rp0.cpu where time >= '2010-07-01 18:47:00' and time <= '2010-07-01 18:47:03' group by time(2s) fill(0)`, + exp: `{"results":[{"series":[{"name":"cpu","columns":["time","derivative"],"values":[["2010-07-01T18:47:02Z",-20]]}]}]}`, + }, + &Query{ + name: "calculate derivative of last with unit 4s group by time with fill 0", + command: `SELECT derivative(last(value), 4s) from db0.rp0.cpu where time >= '2010-07-01 18:47:00' and time <= '2010-07-01 18:47:03' group by time(2s) fill(0)`, + exp: `{"results":[{"series":[{"name":"cpu","columns":["time","derivative"],"values":[["2010-07-01T18:47:02Z",-40]]}]}]}`, + }, + &Query{ + name: "calculate derivative of last with unit default (2s) group by time with fill previous", + command: `SELECT derivative(last(value)) from db0.rp0.cpu where time >= '2010-07-01 18:47:00' and time <= '2010-07-01 18:47:03' group by time(2s) fill(previous)`, + exp: `{"results":[{"series":[{"name":"cpu","columns":["time","derivative"],"values":[["2010-07-01T18:47:02Z",0]]}]}]}`, + }, + &Query{ + name: "calculate derivative of last with unit 4s group by time with fill previous", + command: `SELECT derivative(last(value), 4s) from db0.rp0.cpu where time >= '2010-07-01 18:47:00' and time <= '2010-07-01 18:47:03' group by time(2s) fill(previous)`, + exp: `{"results":[{"series":[{"name":"cpu","columns":["time","derivative"],"values":[["2010-07-01T18:47:02Z",0]]}]}]}`, + }, + &Query{ + name: "calculate derivative of min with unit default (2s) group by time with fill 0", + command: `SELECT derivative(min(value)) from db0.rp0.cpu where time >= '2010-07-01 18:47:00' and time <= '2010-07-01 18:47:03' group by time(2s) fill(0)`, + exp: `{"results":[{"series":[{"name":"cpu","columns":["time","derivative"],"values":[["2010-07-01T18:47:02Z",-10]]}]}]}`, + }, + &Query{ + name: "calculate derivative of min with unit 4s group by time with fill 0", + command: `SELECT derivative(min(value), 4s) from db0.rp0.cpu where time >= '2010-07-01 18:47:00' and time <= '2010-07-01 18:47:03' group by time(2s) fill(0)`, + exp: `{"results":[{"series":[{"name":"cpu","columns":["time","derivative"],"values":[["2010-07-01T18:47:02Z",-20]]}]}]}`, + }, + &Query{ + name: "calculate derivative of min with unit default (2s) group by time with fill previous", + command: `SELECT derivative(min(value)) from db0.rp0.cpu where time >= '2010-07-01 18:47:00' and time <= '2010-07-01 18:47:03' group by time(2s) fill(previous)`, + exp: `{"results":[{"series":[{"name":"cpu","columns":["time","derivative"],"values":[["2010-07-01T18:47:02Z",0]]}]}]}`, + }, + &Query{ + name: "calculate derivative of min with unit 4s group by time with fill previous", + command: `SELECT derivative(min(value), 4s) from db0.rp0.cpu where time >= '2010-07-01 18:47:00' and time <= '2010-07-01 18:47:03' group by time(2s) fill(previous)`, + exp: `{"results":[{"series":[{"name":"cpu","columns":["time","derivative"],"values":[["2010-07-01T18:47:02Z",0]]}]}]}`, + }, + &Query{ + name: "calculate derivative of max with unit default (2s) group by time with fill 0", + command: `SELECT derivative(max(value)) from db0.rp0.cpu where time >= '2010-07-01 18:47:00' and time <= '2010-07-01 18:47:03' group by time(2s) fill(0)`, + exp: `{"results":[{"series":[{"name":"cpu","columns":["time","derivative"],"values":[["2010-07-01T18:47:02Z",-20]]}]}]}`, + }, + &Query{ + name: "calculate derivative of max with unit 4s group by time with fill 0", + command: `SELECT derivative(max(value), 4s) from db0.rp0.cpu where time >= '2010-07-01 18:47:00' and time <= '2010-07-01 18:47:03' group by time(2s) fill(0)`, + exp: `{"results":[{"series":[{"name":"cpu","columns":["time","derivative"],"values":[["2010-07-01T18:47:02Z",-40]]}]}]}`, + }, + &Query{ + name: "calculate derivative of max with unit default (2s) group by time with fill previous", + command: `SELECT derivative(max(value)) from db0.rp0.cpu where time >= '2010-07-01 18:47:00' and time <= '2010-07-01 18:47:03' group by time(2s) fill(previous)`, + exp: `{"results":[{"series":[{"name":"cpu","columns":["time","derivative"],"values":[["2010-07-01T18:47:02Z",0]]}]}]}`, + }, + &Query{ + name: "calculate derivative of max with unit 4s group by time with fill previous", + command: `SELECT derivative(max(value), 4s) from db0.rp0.cpu where time >= '2010-07-01 18:47:00' and time <= '2010-07-01 18:47:03' group by time(2s) fill(previous)`, + exp: `{"results":[{"series":[{"name":"cpu","columns":["time","derivative"],"values":[["2010-07-01T18:47:02Z",0]]}]}]}`, + }, + &Query{ + name: "calculate derivative of percentile with unit default (2s) group by time with fill 0", + command: `SELECT derivative(percentile(value, 50)) from db0.rp0.cpu where time >= '2010-07-01 18:47:00' and time <= '2010-07-01 18:47:03' group by time(2s) fill(0)`, + exp: `{"results":[{"series":[{"name":"cpu","columns":["time","derivative"],"values":[["2010-07-01T18:47:02Z",-10]]}]}]}`, + }, + &Query{ + name: "calculate derivative of percentile with unit 4s group by time with fill 0", + command: `SELECT derivative(percentile(value, 50), 4s) from db0.rp0.cpu where time >= '2010-07-01 18:47:00' and time <= '2010-07-01 18:47:03' group by time(2s) fill(0)`, + exp: `{"results":[{"series":[{"name":"cpu","columns":["time","derivative"],"values":[["2010-07-01T18:47:02Z",-20]]}]}]}`, + }, + &Query{ + name: "calculate derivative of percentile with unit default (2s) group by time with fill previous", + command: `SELECT derivative(percentile(value, 50)) from db0.rp0.cpu where time >= '2010-07-01 18:47:00' and time <= '2010-07-01 18:47:03' group by time(2s) fill(previous)`, + exp: `{"results":[{"series":[{"name":"cpu","columns":["time","derivative"],"values":[["2010-07-01T18:47:02Z",0]]}]}]}`, + }, + &Query{ + name: "calculate derivative of percentile with unit 4s group by time with fill previous", + command: `SELECT derivative(percentile(value, 50), 4s) from db0.rp0.cpu where time >= '2010-07-01 18:47:00' and time <= '2010-07-01 18:47:03' group by time(2s) fill(previous)`, + exp: `{"results":[{"series":[{"name":"cpu","columns":["time","derivative"],"values":[["2010-07-01T18:47:02Z",0]]}]}]}`, + }, }...) for i, query := range test.queries { diff --git a/tsdb/raw.go b/tsdb/raw.go index 9f02e9ba454..22812d8a388 100644 --- a/tsdb/raw.go +++ b/tsdb/raw.go @@ -702,23 +702,9 @@ func ProcessAggregateDerivative(results [][]interface{}, isNonNegative bool, int // Check the value's type to ensure it's an numeric, if not, return a nil result. We only check the first value // because derivatives cannot be combined with other aggregates currently. - curValidType := false - switch cur[1].(type) { - case int64: - curValidType = true - case float64: - curValidType = true - } - - prevValidType := false - switch prev[1].(type) { - case int64: - prevValidType = true - case float64: - prevValidType = true - } - - if !curValidType || !prevValidType { + prevValue, prevOK := toFloat64(prev[1]) + curValue, curOK := toFloat64(cur[1]) + if !prevOK || !curOK { derivatives = append(derivatives, []interface{}{ cur[0], nil, }) @@ -726,7 +712,7 @@ func ProcessAggregateDerivative(results [][]interface{}, isNonNegative bool, int } elapsed := cur[0].(time.Time).Sub(prev[0].(time.Time)) - diff := int64toFloat64(cur[1]) - int64toFloat64(prev[1]) + diff := curValue - prevValue value := 0.0 if elapsed > 0 { value = float64(diff) / (float64(elapsed) / float64(interval)) @@ -775,14 +761,29 @@ func resultsEmpty(resultValues [][]interface{}) bool { return true } +// Convert commonly understood types to a float64 +// Valid types are int64, float64 or PositionPoint with a Value of int64 or float64 +// The second retuned boolean indicates if the conversion was successful. +func toFloat64(v interface{}) (float64, bool) { + switch value := v.(type) { + case int64: + return float64(value), true + case float64: + return value, true + case PositionPoint: + return toFloat64(value.Value) + } + return 0, false +} + func int64toFloat64(v interface{}) float64 { - switch v.(type) { + switch value := v.(type) { case int64: - return float64(v.(int64)) + return float64(value) case float64: - return v.(float64) + return value } - panic(fmt.Sprintf("expected either int64 or float64, got %v", v)) + panic(fmt.Sprintf("expected either int64 or float64, got %T", v)) } // RawMapper runs the map phase for non-aggregate, raw SELECT queries. From 7ffbbc1072470f6f7c53cd2b07afa6390449d038 Mon Sep 17 00:00:00 2001 From: Nathaniel Cook Date: Mon, 7 Dec 2015 10:21:15 -0700 Subject: [PATCH 2/2] make fill previous for count() queries work --- CHANGELOG.md | 1 + cmd/influxd/run/server_test.go | 5 +++++ influxql/ast.go | 28 ++++++++++++++++++++++++++++ tsdb/aggregate.go | 17 +++++++++++++++-- 4 files changed, 49 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0acf44b11d1..46822742fd5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ - [#4872](https://github.com/influxdb/influxdb/pull/4872): Add option to disable logging for meta service. ### Bugfixes +- [#4849](https://github.com/influxdb/influxdb/issues/4849): Derivative works with count, mean, median, sum, first, last, max, min, and percentile. - [#4984](https://github.com/influxdb/influxdb/pull/4984): Allow math on fields, fixes regression. Thanks @mengjinglei - [#4666](https://github.com/influxdb/influxdb/issues/4666): Fix panic in derivative with invalid values. - [#4404](https://github.com/influxdb/influxdb/issues/4404): Return better error for currently unsupported DELETE queries. diff --git a/cmd/influxd/run/server_test.go b/cmd/influxd/run/server_test.go index e0cffc352af..e95cf6c343d 100644 --- a/cmd/influxd/run/server_test.go +++ b/cmd/influxd/run/server_test.go @@ -1738,6 +1738,11 @@ cpu value=20 1278010021000000000 command: `SELECT derivative(count(value), 4s) from db0.rp0.cpu where time >= '2010-07-01 18:47:00' and time <= '2010-07-01 18:47:03' group by time(2s) fill(previous)`, exp: `{"results":[{"series":[{"name":"cpu","columns":["time","derivative"],"values":[["2010-07-01T18:47:02Z",0]]}]}]}`, }, + &Query{ + name: "calculate derivative of count of distinct with unit default (4s) group by time with fill previous", + command: `SELECT derivative(count(distinct(value))) from db0.rp0.position where time >= '2010-07-01 18:47:00' and time <= '2010-07-01 18:47:07' group by time(4s) fill(previous)`, + exp: `{"results":[{"error":"aggregate call didn't contain a field derivative(count(distinct(value)))"}]}`, + }, &Query{ name: "calculate derivative of mean with unit default (2s) group by time with fill 0", command: `SELECT derivative(mean(value)) from db0.rp0.cpu where time >= '2010-07-01 18:47:00' and time <= '2010-07-01 18:47:03' group by time(2s) fill(0)`, diff --git a/influxql/ast.go b/influxql/ast.go index 0f0a1020330..a7afc59d76a 100644 --- a/influxql/ast.go +++ b/influxql/ast.go @@ -793,6 +793,34 @@ func (s *SelectStatement) IsSimpleDerivative() bool { return false } +// HasSimpleCount return true if one of the function calls is a count function with a +// variable ref as the first arg +func (s *SelectStatement) HasSimpleCount() bool { + // recursively check for a simple count(varref) function + var hasCount func(f *Call) bool + hasCount = func(f *Call) bool { + if strings.HasSuffix(f.Name, "count") { + // it's nested if the first argument is an aggregate function + if _, ok := f.Args[0].(*VarRef); ok { + return true + } + } else { + for _, arg := range f.Args { + if child, ok := arg.(*Call); ok { + return hasCount(child) + } + } + } + return false + } + for _, f := range s.FunctionCalls() { + if hasCount(f) { + return true + } + } + return false +} + // TimeAscending returns true if the time field is sorted in chronological order. func (s *SelectStatement) TimeAscending() bool { return len(s.SortFields) == 0 || s.SortFields[0].Ascending diff --git a/tsdb/aggregate.go b/tsdb/aggregate.go index f6b67a1e697..1dd2a40f6c4 100644 --- a/tsdb/aggregate.go +++ b/tsdb/aggregate.go @@ -342,11 +342,12 @@ func (e *AggregateExecutor) processFill(results [][]interface{}) [][]interface{} return newResults } + isCount := e.stmt.HasSimpleCount() // They're either filling with previous values or a specific number for i, vals := range results { // start at 1 because the first value is always time for j := 1; j < len(vals); j++ { - if vals[j] == nil { + if vals[j] == nil || (isCount && isZero(vals[j])) { switch e.stmt.Fill { case influxql.PreviousFill: if i != 0 { @@ -361,6 +362,18 @@ func (e *AggregateExecutor) processFill(results [][]interface{}) [][]interface{} return results } +// Returns true if the given interface is a zero valued int64 or float64. +func isZero(i interface{}) bool { + switch v := i.(type) { + case int64: + return v == 0 + case float64: + return v == 0 + default: + return false + } +} + // processDerivative returns the derivatives of the results func (e *AggregateExecutor) processDerivative(results [][]interface{}) [][]interface{} { // Return early if we're not supposed to process the derivatives @@ -694,7 +707,7 @@ func (m *AggregateMapper) initializeMapFunctions() error { } m.mapFuncs[i] = mfn - // Check for calls like `derivative(lmean(value), 1d)` + // Check for calls like `derivative(mean(value), 1d)` var nested *influxql.Call = c if fn, ok := c.Args[0].(*influxql.Call); ok { nested = fn