Merge pull request #2197 from tcolgate/fix_error_types

Report type names in the form used in documentation
This commit is contained in:
Fabian Reinartz 2016-11-21 09:49:49 +01:00 committed by GitHub
commit 0b1a07b531
3 changed files with 36 additions and 21 deletions

View File

@ -120,7 +120,7 @@ func (r *Result) Matrix() (model.Matrix, error) {
} }
v, ok := r.Value.(model.Matrix) v, ok := r.Value.(model.Matrix)
if !ok { if !ok {
return nil, fmt.Errorf("query result is not a matrix") return nil, fmt.Errorf("query result is not a range vector")
} }
return v, nil return v, nil
} }
@ -286,7 +286,7 @@ func (ng *Engine) NewRangeQuery(qs string, start, end model.Time, interval time.
return nil, err return nil, err
} }
if expr.Type() != model.ValVector && expr.Type() != model.ValScalar { if expr.Type() != model.ValVector && expr.Type() != model.ValScalar {
return nil, fmt.Errorf("invalid expression type %q for range query, must be scalar or vector", expr.Type()) return nil, fmt.Errorf("invalid expression type %q for range query, must be scalar or instant vector", documentedType(expr.Type()))
} }
qry := ng.newQuery(expr, start, end, interval) qry := ng.newQuery(expr, start, end, interval)
qry.q = qs qry.q = qs
@ -581,7 +581,7 @@ func (ev *evaluator) evalScalar(e Expr) *model.Scalar {
val := ev.eval(e) val := ev.eval(e)
sv, ok := val.(*model.Scalar) sv, ok := val.(*model.Scalar)
if !ok { if !ok {
ev.errorf("expected scalar but got %s", val.Type()) ev.errorf("expected scalar but got %s", documentedType(val.Type()))
} }
return sv return sv
} }
@ -591,7 +591,7 @@ func (ev *evaluator) evalVector(e Expr) vector {
val := ev.eval(e) val := ev.eval(e)
vec, ok := val.(vector) vec, ok := val.(vector)
if !ok { if !ok {
ev.errorf("expected vector but got %s", val.Type()) ev.errorf("expected instant vector but got %s", documentedType(val.Type()))
} }
return vec return vec
} }
@ -612,11 +612,13 @@ func (ev *evaluator) evalFloat(e Expr) float64 {
} }
// evalMatrix attempts to evaluate e into a matrix and errors otherwise. // evalMatrix attempts to evaluate e into a matrix and errors otherwise.
// The error message uses the term "range vector" to match the user facing
// documentation.
func (ev *evaluator) evalMatrix(e Expr) matrix { func (ev *evaluator) evalMatrix(e Expr) matrix {
val := ev.eval(e) val := ev.eval(e)
mat, ok := val.(matrix) mat, ok := val.(matrix)
if !ok { if !ok {
ev.errorf("expected matrix but got %s", val.Type()) ev.errorf("expected range vector but got %s", documentedType(val.Type()))
} }
return mat return mat
} }
@ -626,7 +628,7 @@ func (ev *evaluator) evalString(e Expr) *model.String {
val := ev.eval(e) val := ev.eval(e)
sv, ok := val.(*model.String) sv, ok := val.(*model.String)
if !ok { if !ok {
ev.errorf("expected string but got %s", val.Type()) ev.errorf("expected string but got %s", documentedType(val.Type()))
} }
return sv return sv
} }
@ -635,7 +637,7 @@ func (ev *evaluator) evalString(e Expr) *model.String {
func (ev *evaluator) evalOneOf(e Expr, t1, t2 model.ValueType) model.Value { func (ev *evaluator) evalOneOf(e Expr, t1, t2 model.ValueType) model.Value {
val := ev.eval(e) val := ev.eval(e)
if val.Type() != t1 && val.Type() != t2 { if val.Type() != t1 && val.Type() != t2 {
ev.errorf("expected %s or %s but got %s", t1, t2, val.Type()) ev.errorf("expected %s or %s but got %s", documentedType(t1), documentedType(t2), documentedType(val.Type()))
} }
return val return val
} }
@ -1337,3 +1339,16 @@ func (g *queryGate) Done() {
panic("engine.queryGate.Done: more operations done than started") panic("engine.queryGate.Done: more operations done than started")
} }
} }
// documentedType returns the internal type to the equivalent
// user facing terminology as defined in the documentation.
func documentedType(t model.ValueType) string {
switch t.String() {
case "vector":
return "instant vector"
case "matrix":
return "range vector"
default:
return t.String()
}
}

View File

@ -990,7 +990,7 @@ func (p *parser) vectorSelector(name string) *VectorSelector {
func (p *parser) expectType(node Node, want model.ValueType, context string) { func (p *parser) expectType(node Node, want model.ValueType, context string) {
t := p.checkType(node) t := p.checkType(node)
if t != want { if t != want {
p.errorf("expected type %s in %s, got %s", want, context, t) p.errorf("expected type %s in %s, got %s", documentedType(want), context, documentedType(t))
} }
} }
@ -1024,20 +1024,20 @@ func (p *parser) checkType(node Node) (typ model.ValueType) {
case *EvalStmt: case *EvalStmt:
ty := p.checkType(n.Expr) ty := p.checkType(n.Expr)
if ty == model.ValNone { if ty == model.ValNone {
p.errorf("evaluation statement must have a valid expression type but got %s", ty) p.errorf("evaluation statement must have a valid expression type but got %s", documentedType(ty))
} }
case *RecordStmt: case *RecordStmt:
ty := p.checkType(n.Expr) ty := p.checkType(n.Expr)
if ty != model.ValVector && ty != model.ValScalar { if ty != model.ValVector && ty != model.ValScalar {
p.errorf("record statement must have a valid expression of type vector or scalar but got %s", ty) p.errorf("record statement must have a valid expression of type instant vector or scalar but got %s", documentedType(ty))
} }
case Expressions: case Expressions:
for _, e := range n { for _, e := range n {
ty := p.checkType(e) ty := p.checkType(e)
if ty == model.ValNone { if ty == model.ValNone {
p.errorf("expression must have a valid expression type but got %s", ty) p.errorf("expression must have a valid expression type but got %s", documentedType(ty))
} }
} }
case *AggregateExpr: case *AggregateExpr:
@ -1060,12 +1060,12 @@ func (p *parser) checkType(node Node) (typ model.ValueType) {
p.errorf("binary expression does not support operator %q", n.Op) p.errorf("binary expression does not support operator %q", n.Op)
} }
if (lt != model.ValScalar && lt != model.ValVector) || (rt != model.ValScalar && rt != model.ValVector) { if (lt != model.ValScalar && lt != model.ValVector) || (rt != model.ValScalar && rt != model.ValVector) {
p.errorf("binary expression must contain only scalar and vector types") p.errorf("binary expression must contain only scalar and instant vector types")
} }
if (lt != model.ValVector || rt != model.ValVector) && n.VectorMatching != nil { if (lt != model.ValVector || rt != model.ValVector) && n.VectorMatching != nil {
if len(n.VectorMatching.MatchingLabels) > 0 { if len(n.VectorMatching.MatchingLabels) > 0 {
p.errorf("vector matching only allowed between vectors") p.errorf("vector matching only allowed between instant vectors")
} }
n.VectorMatching = nil n.VectorMatching = nil
} else { } else {
@ -1104,7 +1104,7 @@ func (p *parser) checkType(node Node) (typ model.ValueType) {
p.errorf("only + and - operators allowed for unary expressions") p.errorf("only + and - operators allowed for unary expressions")
} }
if t := p.checkType(n.Expr); t != model.ValScalar && t != model.ValVector { if t := p.checkType(n.Expr); t != model.ValScalar && t != model.ValVector {
p.errorf("unary expression only allowed on expressions of type scalar or vector, got %q", t) p.errorf("unary expression only allowed on expressions of type scalar or instant vector, got %q", documentedType(t))
} }
case *NumberLiteral, *MatrixSelector, *StringLiteral, *VectorSelector: case *NumberLiteral, *MatrixSelector, *StringLiteral, *VectorSelector:

View File

@ -237,11 +237,11 @@ var testExpr = []struct {
}, { }, {
input: `-"string"`, input: `-"string"`,
fail: true, fail: true,
errMsg: `unary expression only allowed on expressions of type scalar or vector, got "string"`, errMsg: `unary expression only allowed on expressions of type scalar or instant vector, got "string"`,
}, { }, {
input: `-test[5m]`, input: `-test[5m]`,
fail: true, fail: true,
errMsg: `unary expression only allowed on expressions of type scalar or vector, got "matrix"`, errMsg: `unary expression only allowed on expressions of type scalar or instant vector, got "range vector"`,
}, { }, {
input: `*test`, input: `*test`,
fail: true, fail: true,
@ -772,11 +772,11 @@ var testExpr = []struct {
}, { }, {
input: "1 or on(bar) foo", input: "1 or on(bar) foo",
fail: true, fail: true,
errMsg: "vector matching only allowed between vectors", errMsg: "vector matching only allowed between instant vectors",
}, { }, {
input: "foo == on(bar) 10", input: "foo == on(bar) 10",
fail: true, fail: true,
errMsg: "vector matching only allowed between vectors", errMsg: "vector matching only allowed between instant vectors",
}, { }, {
input: "foo and on(bar) group_left(baz) bar", input: "foo and on(bar) group_left(baz) bar",
fail: true, fail: true,
@ -1286,7 +1286,7 @@ var testExpr = []struct {
}, { }, {
input: `topk(some_metric, other_metric)`, input: `topk(some_metric, other_metric)`,
fail: true, fail: true,
errMsg: "parse error at char 32: expected type scalar in aggregation parameter, got vector", errMsg: "parse error at char 32: expected type scalar in aggregation parameter, got instant vector",
}, { }, {
input: `count_values(5, other_metric)`, input: `count_values(5, other_metric)`,
fail: true, fail: true,
@ -1364,7 +1364,7 @@ var testExpr = []struct {
}, { }, {
input: "floor(1)", input: "floor(1)",
fail: true, fail: true,
errMsg: "expected type vector in call to function \"floor\", got scalar", errMsg: "expected type instant vector in call to function \"floor\", got scalar",
}, { }, {
input: "non_existent_function_far_bar()", input: "non_existent_function_far_bar()",
fail: true, fail: true,
@ -1372,7 +1372,7 @@ var testExpr = []struct {
}, { }, {
input: "rate(some_metric)", input: "rate(some_metric)",
fail: true, fail: true,
errMsg: "expected type matrix in call to function \"rate\", got vector", errMsg: "expected type range vector in call to function \"rate\", got instant vector",
}, },
// Fuzzing regression tests. // Fuzzing regression tests.
{ {