From b9166a60ff51ee3f8561b6627665e2ca59996a2d Mon Sep 17 00:00:00 2001 From: Aliaksandr Valialkin Date: Mon, 1 Jul 2019 17:14:49 +0300 Subject: [PATCH] app/vmselect: do not return empty time series in `/api/v1/query` result --- app/vmselect/prometheus/prometheus.go | 4 ++-- app/vmselect/promql/exec.go | 12 ++++++++++-- app/vmselect/promql/exec_test.go | 11 +++++++++-- 3 files changed, 21 insertions(+), 6 deletions(-) diff --git a/app/vmselect/prometheus/prometheus.go b/app/vmselect/prometheus/prometheus.go index c7c5b8a3c..259611f95 100644 --- a/app/vmselect/prometheus/prometheus.go +++ b/app/vmselect/prometheus/prometheus.go @@ -426,7 +426,7 @@ func QueryHandler(w http.ResponseWriter, r *http.Request) error { Step: step, Deadline: deadline, } - result, err := promql.Exec(&ec, query) + result, err := promql.Exec(&ec, query, true) if err != nil { return fmt.Errorf("cannot execute %q: %s", query, err) } @@ -484,7 +484,7 @@ func QueryRangeHandler(w http.ResponseWriter, r *http.Request) error { Deadline: deadline, MayCache: mayCache, } - result, err := promql.Exec(&ec, query) + result, err := promql.Exec(&ec, query, false) if err != nil { return fmt.Errorf("cannot execute %q: %s", query, err) } diff --git a/app/vmselect/promql/exec.go b/app/vmselect/promql/exec.go index 696ee8038..55ee288bd 100644 --- a/app/vmselect/promql/exec.go +++ b/app/vmselect/promql/exec.go @@ -27,8 +27,8 @@ func ExpandWithExprs(q string) (string, error) { return string(buf), nil } -// Exec executes q for the given ec until the deadline. -func Exec(ec *EvalConfig, q string) ([]netstorage.Result, error) { +// Exec executes q for the given ec. +func Exec(ec *EvalConfig, q string, isFirstPointOnly bool) ([]netstorage.Result, error) { if *logSlowQueryDuration > 0 { startTime := time.Now() defer func() { @@ -65,6 +65,14 @@ func Exec(ec *EvalConfig, q string) ([]netstorage.Result, error) { } ec.End -= ec.Step + if isFirstPointOnly { + // Remove all the points except the first one from every time series. + for _, ts := range rv { + ts.Values = ts.Values[:1] + ts.Timestamps = ts.Timestamps[:1] + } + } + maySort := maySortResults(e, rv) result, err := timeseriesToResult(rv, maySort) if err != nil { diff --git a/app/vmselect/promql/exec_test.go b/app/vmselect/promql/exec_test.go index 345df5369..2c52f606e 100644 --- a/app/vmselect/promql/exec_test.go +++ b/app/vmselect/promql/exec_test.go @@ -62,7 +62,7 @@ func TestExecSuccess(t *testing.T) { Deadline: netstorage.NewDeadline(time.Minute), } for i := 0; i < 5; i++ { - result, err := Exec(ec, q) + result, err := Exec(ec, q, false) if err != nil { t.Fatalf(`unexpected error when executing %q: %s`, q, err) } @@ -3665,7 +3665,14 @@ func TestExecError(t *testing.T) { Deadline: netstorage.NewDeadline(time.Minute), } for i := 0; i < 4; i++ { - rv, err := Exec(ec, q) + rv, err := Exec(ec, q, false) + if err == nil { + t.Fatalf(`expecting non-nil error on %q`, q) + } + if rv != nil { + t.Fatalf(`expecting nil rv`) + } + rv, err = Exec(ec, q, true) if err == nil { t.Fatalf(`expecting non-nil error on %q`, q) }