mirror of
https://github.com/prometheus/prometheus.git
synced 2024-12-24 05:04:05 -08:00
promql: allow scalar expressions in range queries, improve errors.
These changes allow to do range queries over scalar expressions. Errors on bad types for range queries are now raised on query creation rather than evaluation.
This commit is contained in:
parent
db4df06414
commit
cb10ceac18
|
@ -279,6 +279,9 @@ func (ng *Engine) NewRangeQuery(qs string, start, end clientmodel.Timestamp, int
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
if expr.Type() != ExprVector && expr.Type() != ExprScalar {
|
||||||
|
return nil, fmt.Errorf("invalid expression type %q for range query, must be scalar or vector", expr.Type())
|
||||||
|
}
|
||||||
qry := ng.newQuery(expr, start, end, interval)
|
qry := ng.newQuery(expr, start, end, interval)
|
||||||
qry.q = qs
|
qry.q = qs
|
||||||
|
|
||||||
|
@ -413,6 +416,7 @@ func (ng *Engine) execEvalStmt(ctx context.Context, query *query, s *EvalStmt) (
|
||||||
evalTimer.Stop()
|
evalTimer.Stop()
|
||||||
return val, nil
|
return val, nil
|
||||||
}
|
}
|
||||||
|
numSteps := int(s.End.Sub(s.Start) / s.Interval)
|
||||||
|
|
||||||
// Range evaluation.
|
// Range evaluation.
|
||||||
sampleStreams := map[clientmodel.Fingerprint]*SampleStream{}
|
sampleStreams := map[clientmodel.Fingerprint]*SampleStream{}
|
||||||
|
@ -430,26 +434,36 @@ func (ng *Engine) execEvalStmt(ctx context.Context, query *query, s *EvalStmt) (
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
vector, ok := val.(Vector)
|
|
||||||
if !ok {
|
|
||||||
return nil, fmt.Errorf("value for expression %q must be of type vector but is %s", s.Expr, val.Type())
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, sample := range vector {
|
switch v := val.(type) {
|
||||||
samplePair := metric.SamplePair{
|
case *Scalar:
|
||||||
Value: sample.Value,
|
// As the expression type does not change we can safely default to 0
|
||||||
Timestamp: sample.Timestamp,
|
// as the fingerprint for scalar expressions.
|
||||||
|
ss := sampleStreams[0]
|
||||||
|
if ss == nil {
|
||||||
|
ss = &SampleStream{Values: make(metric.Values, 0, numSteps)}
|
||||||
|
sampleStreams[0] = ss
|
||||||
}
|
}
|
||||||
fp := sample.Metric.Metric.Fingerprint()
|
ss.Values = append(ss.Values, metric.SamplePair{
|
||||||
if sampleStreams[fp] == nil {
|
Value: v.Value,
|
||||||
sampleStreams[fp] = &SampleStream{
|
Timestamp: v.Timestamp,
|
||||||
Metric: sample.Metric,
|
})
|
||||||
Values: metric.Values{samplePair},
|
case Vector:
|
||||||
|
for _, sample := range v {
|
||||||
|
fp := sample.Metric.Metric.Fingerprint()
|
||||||
|
ss := sampleStreams[fp]
|
||||||
|
if ss == nil {
|
||||||
|
ss = &SampleStream{Values: make(metric.Values, 0, numSteps)}
|
||||||
|
sampleStreams[fp] = ss
|
||||||
}
|
}
|
||||||
} else {
|
ss.Values = append(ss.Values, metric.SamplePair{
|
||||||
sampleStreams[fp].Values = append(sampleStreams[fp].Values, samplePair)
|
Value: sample.Value,
|
||||||
}
|
Timestamp: sample.Timestamp,
|
||||||
|
})
|
||||||
|
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
panic(fmt.Errorf("promql.Engine.exec: invalid expression type %q", val.Type()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
evalTimer.Stop()
|
evalTimer.Stop()
|
||||||
|
|
Loading…
Reference in a new issue