Merge pull request #2197 from tcolgate/fix_error_types
Report type names in the form used in documentation
This commit is contained in:
commit
0b1a07b531
|
@ -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()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -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:
|
||||||
|
|
|
@ -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.
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue