Browse Source

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.
pull/783/head
Fabian Reinartz 10 years ago
parent
commit
cb10ceac18
  1. 46
      promql/engine.go

46
promql/engine.go

@ -279,6 +279,9 @@ func (ng *Engine) NewRangeQuery(qs string, start, end clientmodel.Timestamp, int
if err != nil {
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.q = qs
@ -413,6 +416,7 @@ func (ng *Engine) execEvalStmt(ctx context.Context, query *query, s *EvalStmt) (
evalTimer.Stop()
return val, nil
}
numSteps := int(s.End.Sub(s.Start) / s.Interval)
// Range evaluation.
sampleStreams := map[clientmodel.Fingerprint]*SampleStream{}
@ -430,26 +434,36 @@ func (ng *Engine) execEvalStmt(ctx context.Context, query *query, s *EvalStmt) (
if err != nil {
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 {
samplePair := metric.SamplePair{
Value: sample.Value,
Timestamp: sample.Timestamp,
switch v := val.(type) {
case *Scalar:
// As the expression type does not change we can safely default to 0
// 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()
if sampleStreams[fp] == nil {
sampleStreams[fp] = &SampleStream{
Metric: sample.Metric,
Values: metric.Values{samplePair},
ss.Values = append(ss.Values, metric.SamplePair{
Value: v.Value,
Timestamp: v.Timestamp,
})
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 {
sampleStreams[fp].Values = append(sampleStreams[fp].Values, samplePair)
}
ss.Values = append(ss.Values, metric.SamplePair{
Value: sample.Value,
Timestamp: sample.Timestamp,
})
}
default:
panic(fmt.Errorf("promql.Engine.exec: invalid expression type %q", val.Type()))
}
}
evalTimer.Stop()

Loading…
Cancel
Save