From a3abed80ff4f2981d5614eaec6e176675b9f1557 Mon Sep 17 00:00:00 2001 From: Aliaksandr Valialkin <valyala@gmail.com> 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 44d2ace759..806fd22617 100644 --- a/app/vmselect/prometheus/prometheus.go +++ b/app/vmselect/prometheus/prometheus.go @@ -501,7 +501,7 @@ func QueryHandler(at *auth.Token, w http.ResponseWriter, r *http.Request) error DenyPartialResponse: getDenyPartialResponse(r), } - 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) } @@ -562,7 +562,7 @@ func QueryRangeHandler(at *auth.Token, w http.ResponseWriter, r *http.Request) e DenyPartialResponse: getDenyPartialResponse(r), } - 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 87e474759f..bec9fc9f62 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() { @@ -66,6 +66,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 9612778fe8..8f702c122e 100644 --- a/app/vmselect/promql/exec_test.go +++ b/app/vmselect/promql/exec_test.go @@ -72,7 +72,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) } @@ -3679,7 +3679,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) }