promql: rename vector

This commit is contained in:
Fabian Reinartz 2016-12-24 10:40:09 +01:00
parent 15a931dbdb
commit a62df87022
6 changed files with 198 additions and 198 deletions

View File

@ -51,7 +51,7 @@ type Value interface {
} }
func (matrix) Type() ValueType { return ValueTypeMatrix } func (matrix) Type() ValueType { return ValueTypeMatrix }
func (vector) Type() ValueType { return ValueTypeVector } func (Vector) Type() ValueType { return ValueTypeVector }
func (scalar) Type() ValueType { return ValueTypeScalar } func (scalar) Type() ValueType { return ValueTypeScalar }
func (stringVal) Type() ValueType { return ValueTypeString } func (stringVal) Type() ValueType { return ValueTypeString }
@ -61,7 +61,7 @@ type ValueType string
// The valid value types. // The valid value types.
const ( const (
ValueTypeNone = "none" ValueTypeNone = "none"
ValueTypeVector = "vector" ValueTypeVector = "Vector"
ValueTypeScalar = "scalar" ValueTypeScalar = "scalar"
ValueTypeMatrix = "matrix" ValueTypeMatrix = "matrix"
ValueTypeString = "string" ValueTypeString = "string"
@ -115,11 +115,11 @@ func (s sample) String() string {
return "" return ""
} }
// vector is basically only an alias for model.Samples, but the // Vector is basically only an alias for model.Samples, but the
// contract is that in a Vector, all Samples have the same timestamp. // contract is that in a Vector, all Samples have the same timestamp.
type vector []sample type Vector []sample
func (vec vector) String() string { func (vec Vector) String() string {
entries := make([]string, len(vec)) entries := make([]string, len(vec))
for i, s := range vec { for i, s := range vec {
entries[i] = s.String() entries[i] = s.String()
@ -149,15 +149,15 @@ type Result struct {
Value Value Value Value
} }
// Vector returns a vector if the result value is one. An error is returned if // Vector returns a Vector if the result value is one. An error is returned if
// the result was an error or the result value is not a vector. // the result was an error or the result value is not a Vector.
func (r *Result) Vector() (vector, error) { func (r *Result) Vector() (Vector, error) {
if r.Err != nil { if r.Err != nil {
return nil, r.Err return nil, r.Err
} }
v, ok := r.Value.(vector) v, ok := r.Value.(Vector)
if !ok { if !ok {
return nil, fmt.Errorf("query result is not a vector") return nil, fmt.Errorf("query result is not a Vector")
} }
return v, nil return v, nil
} }
@ -170,7 +170,7 @@ func (r *Result) Matrix() (matrix, error) {
} }
v, ok := r.Value.(matrix) v, ok := r.Value.(matrix)
if !ok { if !ok {
return nil, fmt.Errorf("query result is not a range vector") return nil, fmt.Errorf("query result is not a range Vector")
} }
return v, nil return v, nil
} }
@ -336,7 +336,7 @@ func (ng *Engine) NewRangeQuery(qs string, start, end time.Time, interval time.D
return nil, err return nil, err
} }
if expr.Type() != ValueTypeVector && expr.Type() != ValueTypeScalar { if expr.Type() != ValueTypeVector && expr.Type() != ValueTypeScalar {
return nil, fmt.Errorf("invalid expression type %q for range query, must be scalar or instant vector", documentedType(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
@ -482,7 +482,7 @@ func (ng *Engine) execEvalStmt(ctx context.Context, query *query, s *EvalStmt) (
v: v.v, v: v.v,
t: v.t, t: v.t,
}) })
case vector: case Vector:
for _, sample := range v { for _, sample := range v {
h := sample.Metric.Hash() h := sample.Metric.Hash()
ss, ok := sampleStreams[h] ss, ok := sampleStreams[h]
@ -643,12 +643,12 @@ func (ev *evaluator) evalScalar(e Expr) scalar {
return sv return sv
} }
// evalVector attempts to evaluate e to a vector value and errors otherwise. // evalVector attempts to evaluate e to a Vector value and errors otherwise.
func (ev *evaluator) evalVector(e Expr) vector { 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 instant vector but got %s", documentedType(val.Type())) ev.errorf("expected instant Vector but got %s", documentedType(val.Type()))
} }
return vec return vec
} }
@ -669,13 +669,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 // The error message uses the term "range Vector" to match the user facing
// documentation. // 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 range vector but got %s", documentedType(val.Type())) ev.errorf("expected range Vector but got %s", documentedType(val.Type()))
} }
return mat return mat
} }
@ -714,8 +714,8 @@ func (ev *evaluator) eval(expr Expr) Value {
switch e := expr.(type) { switch e := expr.(type) {
case *AggregateExpr: case *AggregateExpr:
vector := ev.evalVector(e.Expr) Vector := ev.evalVector(e.Expr)
return ev.aggregation(e.Op, e.Grouping, e.Without, e.KeepCommonLabels, e.Param, vector) return ev.aggregation(e.Op, e.Grouping, e.Without, e.KeepCommonLabels, e.Param, Vector)
case *BinaryExpr: case *BinaryExpr:
lhs := ev.evalOneOf(e.LHS, ValueTypeScalar, ValueTypeVector) lhs := ev.evalOneOf(e.LHS, ValueTypeScalar, ValueTypeVector)
@ -731,19 +731,19 @@ func (ev *evaluator) eval(expr Expr) Value {
case lt == ValueTypeVector && rt == ValueTypeVector: case lt == ValueTypeVector && rt == ValueTypeVector:
switch e.Op { switch e.Op {
case itemLAND: case itemLAND:
return ev.vectorAnd(lhs.(vector), rhs.(vector), e.VectorMatching) return ev.VectorAnd(lhs.(Vector), rhs.(Vector), e.VectorMatching)
case itemLOR: case itemLOR:
return ev.vectorOr(lhs.(vector), rhs.(vector), e.VectorMatching) return ev.VectorOr(lhs.(Vector), rhs.(Vector), e.VectorMatching)
case itemLUnless: case itemLUnless:
return ev.vectorUnless(lhs.(vector), rhs.(vector), e.VectorMatching) return ev.VectorUnless(lhs.(Vector), rhs.(Vector), e.VectorMatching)
default: default:
return ev.vectorBinop(e.Op, lhs.(vector), rhs.(vector), e.VectorMatching, e.ReturnBool) return ev.VectorBinop(e.Op, lhs.(Vector), rhs.(Vector), e.VectorMatching, e.ReturnBool)
} }
case lt == ValueTypeVector && rt == ValueTypeScalar: case lt == ValueTypeVector && rt == ValueTypeScalar:
return ev.vectorScalarBinop(e.Op, lhs.(vector), rhs.(scalar), false, e.ReturnBool) return ev.VectorScalarBinop(e.Op, lhs.(Vector), rhs.(scalar), false, e.ReturnBool)
case lt == ValueTypeScalar && rt == ValueTypeVector: case lt == ValueTypeScalar && rt == ValueTypeVector:
return ev.vectorScalarBinop(e.Op, rhs.(vector), lhs.(scalar), true, e.ReturnBool) return ev.VectorScalarBinop(e.Op, rhs.(Vector), lhs.(scalar), true, e.ReturnBool)
} }
case *Call: case *Call:
@ -768,7 +768,7 @@ func (ev *evaluator) eval(expr Expr) Value {
switch v := se.(type) { switch v := se.(type) {
case scalar: case scalar:
v.v = -v.v v.v = -v.v
case vector: case Vector:
for i, sv := range v { for i, sv := range v {
v[i].Value = -sv.Value v[i].Value = -sv.Value
} }
@ -777,16 +777,16 @@ func (ev *evaluator) eval(expr Expr) Value {
return se return se
case *VectorSelector: case *VectorSelector:
return ev.vectorSelector(e) return ev.VectorSelector(e)
} }
panic(fmt.Errorf("unhandled expression of type: %T", expr)) panic(fmt.Errorf("unhandled expression of type: %T", expr))
} }
// vectorSelector evaluates a *VectorSelector expression. // VectorSelector evaluates a *VectorSelector expression.
func (ev *evaluator) vectorSelector(node *VectorSelector) vector { func (ev *evaluator) VectorSelector(node *VectorSelector) Vector {
var ( var (
ok bool ok bool
vec = make(vector, 0, len(node.series)) vec = make(Vector, 0, len(node.series))
refTime = ev.Timestamp - durationMilliseconds(node.Offset) refTime = ev.Timestamp - durationMilliseconds(node.Offset)
) )
@ -856,14 +856,14 @@ func (ev *evaluator) matrixSelector(node *MatrixSelector) matrix {
return matrix return matrix
} }
func (ev *evaluator) vectorAnd(lhs, rhs vector, matching *VectorMatching) vector { func (ev *evaluator) VectorAnd(lhs, rhs Vector, matching *VectorMatching) Vector {
if matching.Card != CardManyToMany { if matching.Card != CardManyToMany {
panic("set operations must only use many-to-many matching") panic("set operations must only use many-to-many matching")
} }
sigf := signatureFunc(matching.On, matching.MatchingLabels...) sigf := signatureFunc(matching.On, matching.MatchingLabels...)
var result vector var result Vector
// The set of signatures for the right-hand side vector. // The set of signatures for the right-hand side Vector.
rightSigs := map[uint64]struct{}{} rightSigs := map[uint64]struct{}{}
// Add all rhs samples to a map so we can easily find matches later. // Add all rhs samples to a map so we can easily find matches later.
for _, rs := range rhs { for _, rs := range rhs {
@ -871,7 +871,7 @@ func (ev *evaluator) vectorAnd(lhs, rhs vector, matching *VectorMatching) vector
} }
for _, ls := range lhs { for _, ls := range lhs {
// If there's a matching entry in the right-hand side vector, add the sample. // If there's a matching entry in the right-hand side Vector, add the sample.
if _, ok := rightSigs[sigf(ls.Metric)]; ok { if _, ok := rightSigs[sigf(ls.Metric)]; ok {
result = append(result, ls) result = append(result, ls)
} }
@ -879,15 +879,15 @@ func (ev *evaluator) vectorAnd(lhs, rhs vector, matching *VectorMatching) vector
return result return result
} }
func (ev *evaluator) vectorOr(lhs, rhs vector, matching *VectorMatching) vector { func (ev *evaluator) VectorOr(lhs, rhs Vector, matching *VectorMatching) Vector {
if matching.Card != CardManyToMany { if matching.Card != CardManyToMany {
panic("set operations must only use many-to-many matching") panic("set operations must only use many-to-many matching")
} }
sigf := signatureFunc(matching.On, matching.MatchingLabels...) sigf := signatureFunc(matching.On, matching.MatchingLabels...)
var result vector var result Vector
leftSigs := map[uint64]struct{}{} leftSigs := map[uint64]struct{}{}
// Add everything from the left-hand-side vector. // Add everything from the left-hand-side Vector.
for _, ls := range lhs { for _, ls := range lhs {
leftSigs[sigf(ls.Metric)] = struct{}{} leftSigs[sigf(ls.Metric)] = struct{}{}
result = append(result, ls) result = append(result, ls)
@ -901,7 +901,7 @@ func (ev *evaluator) vectorOr(lhs, rhs vector, matching *VectorMatching) vector
return result return result
} }
func (ev *evaluator) vectorUnless(lhs, rhs vector, matching *VectorMatching) vector { func (ev *evaluator) VectorUnless(lhs, rhs Vector, matching *VectorMatching) Vector {
if matching.Card != CardManyToMany { if matching.Card != CardManyToMany {
panic("set operations must only use many-to-many matching") panic("set operations must only use many-to-many matching")
} }
@ -912,7 +912,7 @@ func (ev *evaluator) vectorUnless(lhs, rhs vector, matching *VectorMatching) vec
rightSigs[sigf(rs.Metric)] = struct{}{} rightSigs[sigf(rs.Metric)] = struct{}{}
} }
var result vector var result Vector
for _, ls := range lhs { for _, ls := range lhs {
if _, ok := rightSigs[sigf(ls.Metric)]; !ok { if _, ok := rightSigs[sigf(ls.Metric)]; !ok {
result = append(result, ls) result = append(result, ls)
@ -921,13 +921,13 @@ func (ev *evaluator) vectorUnless(lhs, rhs vector, matching *VectorMatching) vec
return result return result
} }
// vectorBinop evaluates a binary operation between two vectors, excluding set operators. // VectorBinop evaluates a binary operation between two Vectors, excluding set operators.
func (ev *evaluator) vectorBinop(op itemType, lhs, rhs vector, matching *VectorMatching, returnBool bool) vector { func (ev *evaluator) VectorBinop(op itemType, lhs, rhs Vector, matching *VectorMatching, returnBool bool) Vector {
if matching.Card == CardManyToMany { if matching.Card == CardManyToMany {
panic("many-to-many only allowed for set operators") panic("many-to-many only allowed for set operators")
} }
var ( var (
result = vector{} result = Vector{}
sigf = signatureFunc(matching.On, matching.MatchingLabels...) sigf = signatureFunc(matching.On, matching.MatchingLabels...)
) )
@ -962,7 +962,7 @@ func (ev *evaluator) vectorBinop(op itemType, lhs, rhs vector, matching *VectorM
for _, ls := range lhs { for _, ls := range lhs {
sig := sigf(ls.Metric) sig := sigf(ls.Metric)
rs, found := rightSigs[sig] // Look for a match in the rhs vector. rs, found := rightSigs[sig] // Look for a match in the rhs Vector.
if !found { if !found {
continue continue
} }
@ -972,7 +972,7 @@ func (ev *evaluator) vectorBinop(op itemType, lhs, rhs vector, matching *VectorM
if matching.Card == CardOneToMany { if matching.Card == CardOneToMany {
vl, vr = vr, vl vl, vr = vr, vl
} }
value, keep := vectorElemBinop(op, vl, vr) value, keep := VectorElemBinop(op, vl, vr)
if returnBool { if returnBool {
if keep { if keep {
value = 1.0 value = 1.0
@ -992,7 +992,7 @@ func (ev *evaluator) vectorBinop(op itemType, lhs, rhs vector, matching *VectorM
matchedSigs[sig] = nil // Set existence to true. matchedSigs[sig] = nil // Set existence to true.
} else { } else {
// In many-to-one matching the grouping labels have to ensure a unique metric // In many-to-one matching the grouping labels have to ensure a unique metric
// for the result vector. Check whether those labels have already been added for // for the result Vector. Check whether those labels have already been added for
// the same matching labels. // the same matching labels.
insertSig := metric.Hash() insertSig := metric.Hash()
@ -1059,7 +1059,7 @@ func signatureFunc(on bool, names ...string) func(labels.Labels) uint64 {
return func(lset labels.Labels) uint64 { return hashWithoutLabels(lset, names...) } return func(lset labels.Labels) uint64 { return hashWithoutLabels(lset, names...) }
} }
// resultMetric returns the metric for the given sample(s) based on the vector // resultMetric returns the metric for the given sample(s) based on the Vector
// binary operation and the matching options. // binary operation and the matching options.
func resultMetric(lhs, rhs labels.Labels, op itemType, matching *VectorMatching) labels.Labels { func resultMetric(lhs, rhs labels.Labels, op itemType, matching *VectorMatching) labels.Labels {
// del and add hold modifications to the LHS input metric. // del and add hold modifications to the LHS input metric.
@ -1116,18 +1116,18 @@ Outer:
return res return res
} }
// vectorScalarBinop evaluates a binary operation between a vector and a scalar. // VectorScalarBinop evaluates a binary operation between a Vector and a scalar.
func (ev *evaluator) vectorScalarBinop(op itemType, lhs vector, rhs scalar, swap, returnBool bool) vector { func (ev *evaluator) VectorScalarBinop(op itemType, lhs Vector, rhs scalar, swap, returnBool bool) Vector {
vec := make(vector, 0, len(lhs)) vec := make(Vector, 0, len(lhs))
for _, lhsSample := range lhs { for _, lhsSample := range lhs {
lv, rv := lhsSample.Value, rhs.v lv, rv := lhsSample.Value, rhs.v
// lhs always contains the vector. If the original position was different // lhs always contains the Vector. If the original position was different
// swap for calculating the value. // swap for calculating the value.
if swap { if swap {
lv, rv = rv, lv lv, rv = rv, lv
} }
value, keep := vectorElemBinop(op, lv, rv) value, keep := VectorElemBinop(op, lv, rv)
if returnBool { if returnBool {
if keep { if keep {
value = 1.0 value = 1.0
@ -1192,8 +1192,8 @@ func scalarBinop(op itemType, lhs, rhs float64) float64 {
panic(fmt.Errorf("operator %q not allowed for scalar operations", op)) panic(fmt.Errorf("operator %q not allowed for scalar operations", op))
} }
// vectorElemBinop evaluates a binary operation between two vector elements. // VectorElemBinop evaluates a binary operation between two Vector elements.
func vectorElemBinop(op itemType, lhs, rhs float64) (float64, bool) { func VectorElemBinop(op itemType, lhs, rhs float64) (float64, bool) {
switch op { switch op {
case itemADD: case itemADD:
return lhs + rhs, true return lhs + rhs, true
@ -1220,7 +1220,7 @@ func vectorElemBinop(op itemType, lhs, rhs float64) (float64, bool) {
case itemLTE: case itemLTE:
return lhs, lhs <= rhs return lhs, lhs <= rhs
} }
panic(fmt.Errorf("operator %q not allowed for operations between vectors", op)) panic(fmt.Errorf("operator %q not allowed for operations between Vectors", op))
} }
// intersection returns the metric of common label/value pairs of two input metrics. // intersection returns the metric of common label/value pairs of two input metrics.
@ -1243,19 +1243,19 @@ type groupedAggregation struct {
value float64 value float64
valuesSquaredSum float64 valuesSquaredSum float64
groupCount int groupCount int
heap vectorByValueHeap heap VectorByValueHeap
reverseHeap vectorByReverseValueHeap reverseHeap VectorByReverseValueHeap
} }
// aggregation evaluates an aggregation operation on a vector. // aggregation evaluates an aggregation operation on a Vector.
func (ev *evaluator) aggregation(op itemType, grouping []string, without bool, keepCommon bool, param Expr, vec vector) vector { func (ev *evaluator) aggregation(op itemType, grouping []string, without bool, keepCommon bool, param Expr, vec Vector) Vector {
result := map[uint64]*groupedAggregation{} result := map[uint64]*groupedAggregation{}
var k int64 var k int64
if op == itemTopK || op == itemBottomK { if op == itemTopK || op == itemBottomK {
k = ev.evalInt(param) k = ev.evalInt(param)
if k < 1 { if k < 1 {
return vector{} return Vector{}
} }
} }
var q float64 var q float64
@ -1313,10 +1313,10 @@ func (ev *evaluator) aggregation(op itemType, grouping []string, without bool, k
groupCount: 1, groupCount: 1,
} }
if op == itemTopK || op == itemQuantile { if op == itemTopK || op == itemQuantile {
result[groupingKey].heap = make(vectorByValueHeap, 0, k) result[groupingKey].heap = make(VectorByValueHeap, 0, k)
heap.Push(&result[groupingKey].heap, &sample{Value: s.Value, Metric: s.Metric}) heap.Push(&result[groupingKey].heap, &sample{Value: s.Value, Metric: s.Metric})
} else if op == itemBottomK { } else if op == itemBottomK {
result[groupingKey].reverseHeap = make(vectorByReverseValueHeap, 0, k) result[groupingKey].reverseHeap = make(VectorByReverseValueHeap, 0, k)
heap.Push(&result[groupingKey].reverseHeap, &sample{Value: s.Value, Metric: s.Metric}) heap.Push(&result[groupingKey].reverseHeap, &sample{Value: s.Value, Metric: s.Metric})
} }
continue continue
@ -1376,8 +1376,8 @@ func (ev *evaluator) aggregation(op itemType, grouping []string, without bool, k
} }
} }
// Construct the result vector from the aggregated groups. // Construct the result Vector from the aggregated groups.
resultVector := make(vector, 0, len(result)) resultVector := make(Vector, 0, len(result))
for _, aggr := range result { for _, aggr := range result {
switch op { switch op {
@ -1494,10 +1494,10 @@ func (g *queryGate) Done() {
// user facing terminology as defined in the documentation. // user facing terminology as defined in the documentation.
func documentedType(t ValueType) string { func documentedType(t ValueType) string {
switch t { switch t {
case "vector": case "Vector":
return "instant vector" return "instant Vector"
case "matrix": case "matrix":
return "range vector" return "range Vector"
default: default:
return string(t) return string(t)
} }

View File

@ -52,12 +52,12 @@ func extrapolatedRate(ev *evaluator, arg Expr, isCounter bool, isRate bool) Valu
rangeStart := ev.Timestamp - durationMilliseconds(ms.Range+ms.Offset) rangeStart := ev.Timestamp - durationMilliseconds(ms.Range+ms.Offset)
rangeEnd := ev.Timestamp - durationMilliseconds(ms.Offset) rangeEnd := ev.Timestamp - durationMilliseconds(ms.Offset)
resultVector := vector{} resultVector := Vector{}
matrixValue := ev.evalMatrix(ms) matrixValue := ev.evalMatrix(ms)
for _, samples := range matrixValue { for _, samples := range matrixValue {
// No sense in trying to compute a rate without at least two points. Drop // No sense in trying to compute a rate without at least two points. Drop
// this vector element. // this Vector element.
if len(samples.Values) < 2 { if len(samples.Values) < 2 {
continue continue
} }
@ -151,10 +151,10 @@ func funcIdelta(ev *evaluator, args Expressions) Value {
} }
func instantValue(ev *evaluator, arg Expr, isRate bool) Value { func instantValue(ev *evaluator, arg Expr, isRate bool) Value {
resultVector := vector{} resultVector := Vector{}
for _, samples := range ev.evalMatrix(arg) { for _, samples := range ev.evalMatrix(arg) {
// No sense in trying to compute a rate without at least two points. Drop // No sense in trying to compute a rate without at least two points. Drop
// this vector element. // this Vector element.
if len(samples.Values) < 2 { if len(samples.Values) < 2 {
continue continue
} }
@ -230,8 +230,8 @@ func funcHoltWinters(ev *evaluator, args Expressions) Value {
ev.errorf("invalid trend factor. Expected: 0 < tf < 1 got: %f", sf) ev.errorf("invalid trend factor. Expected: 0 < tf < 1 got: %f", sf)
} }
// Make an output vector large enough to hold the entire result. // Make an output Vector large enough to hold the entire result.
resultVector := make(vector, 0, len(mat)) resultVector := make(Vector, 0, len(mat))
// Create scratch values. // Create scratch values.
var s, b, d []float64 var s, b, d []float64
@ -276,7 +276,7 @@ func funcHoltWinters(ev *evaluator, args Expressions) Value {
resultVector = append(resultVector, sample{ resultVector = append(resultVector, sample{
Metric: copyLabels(samples.Metric, false), Metric: copyLabels(samples.Metric, false),
Value: s[len(s)-1], // The last value in the vector is the smoothed result. Value: s[len(s)-1], // The last value in the Vector is the smoothed result.
Timestamp: ev.Timestamp, Timestamp: ev.Timestamp,
}) })
} }
@ -288,21 +288,21 @@ func funcHoltWinters(ev *evaluator, args Expressions) Value {
func funcSort(ev *evaluator, args Expressions) Value { func funcSort(ev *evaluator, args Expressions) Value {
// NaN should sort to the bottom, so take descending sort with NaN first and // NaN should sort to the bottom, so take descending sort with NaN first and
// reverse it. // reverse it.
byValueSorter := vectorByReverseValueHeap(ev.evalVector(args[0])) byValueSorter := VectorByReverseValueHeap(ev.evalVector(args[0]))
sort.Sort(sort.Reverse(byValueSorter)) sort.Sort(sort.Reverse(byValueSorter))
return vector(byValueSorter) return Vector(byValueSorter)
} }
// === sortDesc(node ValueTypeVector) Vector === // === sortDesc(node ValueTypeVector) Vector ===
func funcSortDesc(ev *evaluator, args Expressions) Value { func funcSortDesc(ev *evaluator, args Expressions) Value {
// NaN should sort to the bottom, so take ascending sort with NaN first and // NaN should sort to the bottom, so take ascending sort with NaN first and
// reverse it. // reverse it.
byValueSorter := vectorByValueHeap(ev.evalVector(args[0])) byValueSorter := VectorByValueHeap(ev.evalVector(args[0]))
sort.Sort(sort.Reverse(byValueSorter)) sort.Sort(sort.Reverse(byValueSorter))
return vector(byValueSorter) return Vector(byValueSorter)
} }
// === clamp_max(vector ValueTypeVector, max Scalar) Vector === // === clamp_max(Vector ValueTypeVector, max Scalar) Vector ===
func funcClampMax(ev *evaluator, args Expressions) Value { func funcClampMax(ev *evaluator, args Expressions) Value {
vec := ev.evalVector(args[0]) vec := ev.evalVector(args[0])
max := ev.evalFloat(args[1]) max := ev.evalFloat(args[1])
@ -313,7 +313,7 @@ func funcClampMax(ev *evaluator, args Expressions) Value {
return vec return vec
} }
// === clamp_min(vector ValueTypeVector, min Scalar) Vector === // === clamp_min(Vector ValueTypeVector, min Scalar) Vector ===
func funcClampMin(ev *evaluator, args Expressions) Value { func funcClampMin(ev *evaluator, args Expressions) Value {
vec := ev.evalVector(args[0]) vec := ev.evalVector(args[0])
min := ev.evalFloat(args[1]) min := ev.evalFloat(args[1])
@ -328,7 +328,7 @@ func funcClampMin(ev *evaluator, args Expressions) Value {
func funcDropCommonLabels(ev *evaluator, args Expressions) Value { func funcDropCommonLabels(ev *evaluator, args Expressions) Value {
vec := ev.evalVector(args[0]) vec := ev.evalVector(args[0])
if len(vec) < 1 { if len(vec) < 1 {
return vector{} return Vector{}
} }
common := map[string]string{} common := map[string]string{}
@ -365,7 +365,7 @@ func funcDropCommonLabels(ev *evaluator, args Expressions) Value {
return vec return vec
} }
// === round(vector ValueTypeVector, toNearest=1 Scalar) Vector === // === round(Vector ValueTypeVector, toNearest=1 Scalar) Vector ===
func funcRound(ev *evaluator, args Expressions) Value { func funcRound(ev *evaluator, args Expressions) Value {
// round returns a number rounded to toNearest. // round returns a number rounded to toNearest.
// Ties are solved by rounding up. // Ties are solved by rounding up.
@ -399,7 +399,7 @@ func funcScalar(ev *evaluator, args Expressions) Value {
} }
} }
// === count_scalar(vector ValueTypeVector) float64 === // === count_scalar(Vector ValueTypeVector) float64 ===
func funcCountScalar(ev *evaluator, args Expressions) Value { func funcCountScalar(ev *evaluator, args Expressions) Value {
return scalar{ return scalar{
v: float64(len(ev.evalVector(args[0]))), v: float64(len(ev.evalVector(args[0]))),
@ -409,7 +409,7 @@ func funcCountScalar(ev *evaluator, args Expressions) Value {
func aggrOverTime(ev *evaluator, args Expressions, aggrFn func([]samplePair) float64) Value { func aggrOverTime(ev *evaluator, args Expressions, aggrFn func([]samplePair) float64) Value {
mat := ev.evalMatrix(args[0]) mat := ev.evalMatrix(args[0])
resultVector := vector{} resultVector := Vector{}
for _, el := range mat { for _, el := range mat {
if len(el.Values) == 0 { if len(el.Values) == 0 {
@ -443,14 +443,14 @@ func funcCountOverTime(ev *evaluator, args Expressions) Value {
}) })
} }
// === floor(vector ValueTypeVector) Vector === // === floor(Vector ValueTypeVector) Vector ===
func funcFloor(ev *evaluator, args Expressions) Value { func funcFloor(ev *evaluator, args Expressions) Value {
vector := ev.evalVector(args[0]) Vector := ev.evalVector(args[0])
for _, el := range vector { for _, el := range Vector {
el.Metric = copyLabels(el.Metric, false) el.Metric = copyLabels(el.Metric, false)
el.Value = math.Floor(float64(el.Value)) el.Value = math.Floor(float64(el.Value))
} }
return vector return Vector
} }
// === max_over_time(matrix ValueTypeMatrix) Vector === // === max_over_time(matrix ValueTypeMatrix) Vector ===
@ -490,7 +490,7 @@ func funcSumOverTime(ev *evaluator, args Expressions) Value {
func funcQuantileOverTime(ev *evaluator, args Expressions) Value { func funcQuantileOverTime(ev *evaluator, args Expressions) Value {
q := ev.evalFloat(args[0]) q := ev.evalFloat(args[0])
mat := ev.evalMatrix(args[1]) mat := ev.evalMatrix(args[1])
resultVector := vector{} resultVector := Vector{}
for _, el := range mat { for _, el := range mat {
if len(el.Values) == 0 { if len(el.Values) == 0 {
@ -498,7 +498,7 @@ func funcQuantileOverTime(ev *evaluator, args Expressions) Value {
} }
el.Metric = copyLabels(el.Metric, false) el.Metric = copyLabels(el.Metric, false)
values := make(vectorByValueHeap, 0, len(el.Values)) values := make(VectorByValueHeap, 0, len(el.Values))
for _, v := range el.Values { for _, v := range el.Values {
values = append(values, sample{Value: v.v}) values = append(values, sample{Value: v.v})
} }
@ -539,20 +539,20 @@ func funcStdvarOverTime(ev *evaluator, args Expressions) Value {
}) })
} }
// === abs(vector ValueTypeVector) Vector === // === abs(Vector ValueTypeVector) Vector ===
func funcAbs(ev *evaluator, args Expressions) Value { func funcAbs(ev *evaluator, args Expressions) Value {
vector := ev.evalVector(args[0]) Vector := ev.evalVector(args[0])
for _, el := range vector { for _, el := range Vector {
el.Metric = copyLabels(el.Metric, false) el.Metric = copyLabels(el.Metric, false)
el.Value = math.Abs(float64(el.Value)) el.Value = math.Abs(float64(el.Value))
} }
return vector return Vector
} }
// === absent(vector ValueTypeVector) Vector === // === absent(Vector ValueTypeVector) Vector ===
func funcAbsent(ev *evaluator, args Expressions) Value { func funcAbsent(ev *evaluator, args Expressions) Value {
if len(ev.evalVector(args[0])) > 0 { if len(ev.evalVector(args[0])) > 0 {
return vector{} return Vector{}
} }
m := []labels.Label{} m := []labels.Label{}
@ -563,7 +563,7 @@ func funcAbsent(ev *evaluator, args Expressions) Value {
} }
} }
} }
return vector{ return Vector{
sample{ sample{
Metric: labels.New(m...), Metric: labels.New(m...),
Value: 1, Value: 1,
@ -572,64 +572,64 @@ func funcAbsent(ev *evaluator, args Expressions) Value {
} }
} }
// === ceil(vector ValueTypeVector) Vector === // === ceil(Vector ValueTypeVector) Vector ===
func funcCeil(ev *evaluator, args Expressions) Value { func funcCeil(ev *evaluator, args Expressions) Value {
vector := ev.evalVector(args[0]) Vector := ev.evalVector(args[0])
for _, el := range vector { for _, el := range Vector {
el.Metric = copyLabels(el.Metric, false) el.Metric = copyLabels(el.Metric, false)
el.Value = math.Ceil(float64(el.Value)) el.Value = math.Ceil(float64(el.Value))
} }
return vector return Vector
} }
// === exp(vector ValueTypeVector) Vector === // === exp(Vector ValueTypeVector) Vector ===
func funcExp(ev *evaluator, args Expressions) Value { func funcExp(ev *evaluator, args Expressions) Value {
vector := ev.evalVector(args[0]) Vector := ev.evalVector(args[0])
for _, el := range vector { for _, el := range Vector {
el.Metric = copyLabels(el.Metric, false) el.Metric = copyLabels(el.Metric, false)
el.Value = math.Exp(float64(el.Value)) el.Value = math.Exp(float64(el.Value))
} }
return vector return Vector
} }
// === sqrt(vector VectorNode) Vector === // === sqrt(Vector VectorNode) Vector ===
func funcSqrt(ev *evaluator, args Expressions) Value { func funcSqrt(ev *evaluator, args Expressions) Value {
vector := ev.evalVector(args[0]) Vector := ev.evalVector(args[0])
for _, el := range vector { for _, el := range Vector {
el.Metric = copyLabels(el.Metric, false) el.Metric = copyLabels(el.Metric, false)
el.Value = math.Sqrt(float64(el.Value)) el.Value = math.Sqrt(float64(el.Value))
} }
return vector return Vector
} }
// === ln(vector ValueTypeVector) Vector === // === ln(Vector ValueTypeVector) Vector ===
func funcLn(ev *evaluator, args Expressions) Value { func funcLn(ev *evaluator, args Expressions) Value {
vector := ev.evalVector(args[0]) Vector := ev.evalVector(args[0])
for _, el := range vector { for _, el := range Vector {
el.Metric = copyLabels(el.Metric, false) el.Metric = copyLabels(el.Metric, false)
el.Value = math.Log(float64(el.Value)) el.Value = math.Log(float64(el.Value))
} }
return vector return Vector
} }
// === log2(vector ValueTypeVector) Vector === // === log2(Vector ValueTypeVector) Vector ===
func funcLog2(ev *evaluator, args Expressions) Value { func funcLog2(ev *evaluator, args Expressions) Value {
vector := ev.evalVector(args[0]) Vector := ev.evalVector(args[0])
for _, el := range vector { for _, el := range Vector {
el.Metric = copyLabels(el.Metric, false) el.Metric = copyLabels(el.Metric, false)
el.Value = math.Log2(float64(el.Value)) el.Value = math.Log2(float64(el.Value))
} }
return vector return Vector
} }
// === log10(vector ValueTypeVector) Vector === // === log10(Vector ValueTypeVector) Vector ===
func funcLog10(ev *evaluator, args Expressions) Value { func funcLog10(ev *evaluator, args Expressions) Value {
vector := ev.evalVector(args[0]) Vector := ev.evalVector(args[0])
for _, el := range vector { for _, el := range Vector {
el.Metric = copyLabels(el.Metric, false) el.Metric = copyLabels(el.Metric, false)
el.Value = math.Log10(float64(el.Value)) el.Value = math.Log10(float64(el.Value))
} }
return vector return Vector
} }
// linearRegression performs a least-square linear regression analysis on the // linearRegression performs a least-square linear regression analysis on the
@ -660,11 +660,11 @@ func linearRegression(samples []samplePair, interceptTime int64) (slope, interce
// === deriv(node ValueTypeMatrix) Vector === // === deriv(node ValueTypeMatrix) Vector ===
func funcDeriv(ev *evaluator, args Expressions) Value { func funcDeriv(ev *evaluator, args Expressions) Value {
mat := ev.evalMatrix(args[0]) mat := ev.evalMatrix(args[0])
resultVector := make(vector, 0, len(mat)) resultVector := make(Vector, 0, len(mat))
for _, samples := range mat { for _, samples := range mat {
// No sense in trying to compute a derivative without at least two points. // No sense in trying to compute a derivative without at least two points.
// Drop this vector element. // Drop this Vector element.
if len(samples.Values) < 2 { if len(samples.Values) < 2 {
continue continue
} }
@ -683,12 +683,12 @@ func funcDeriv(ev *evaluator, args Expressions) Value {
// === predict_linear(node ValueTypeMatrix, k ValueTypeScalar) Vector === // === predict_linear(node ValueTypeMatrix, k ValueTypeScalar) Vector ===
func funcPredictLinear(ev *evaluator, args Expressions) Value { func funcPredictLinear(ev *evaluator, args Expressions) Value {
mat := ev.evalMatrix(args[0]) mat := ev.evalMatrix(args[0])
resultVector := make(vector, 0, len(mat)) resultVector := make(Vector, 0, len(mat))
duration := ev.evalFloat(args[1]) duration := ev.evalFloat(args[1])
for _, samples := range mat { for _, samples := range mat {
// No sense in trying to predict anything without at least two points. // No sense in trying to predict anything without at least two points.
// Drop this vector element. // Drop this Vector element.
if len(samples.Values) < 2 { if len(samples.Values) < 2 {
continue continue
} }
@ -703,12 +703,12 @@ func funcPredictLinear(ev *evaluator, args Expressions) Value {
return resultVector return resultVector
} }
// === histogram_quantile(k ValueTypeScalar, vector ValueTypeVector) Vector === // === histogram_quantile(k ValueTypeScalar, Vector ValueTypeVector) Vector ===
func funcHistogramQuantile(ev *evaluator, args Expressions) Value { func funcHistogramQuantile(ev *evaluator, args Expressions) Value {
q := ev.evalFloat(args[0]) q := ev.evalFloat(args[0])
inVec := ev.evalVector(args[1]) inVec := ev.evalVector(args[1])
outVec := vector{} outVec := Vector{}
signatureToMetricWithBuckets := map[uint64]*metricWithBuckets{} signatureToMetricWithBuckets := map[uint64]*metricWithBuckets{}
for _, el := range inVec { for _, el := range inVec {
upperBound, err := strconv.ParseFloat( upperBound, err := strconv.ParseFloat(
@ -748,7 +748,7 @@ func funcHistogramQuantile(ev *evaluator, args Expressions) Value {
// === resets(matrix ValueTypeMatrix) Vector === // === resets(matrix ValueTypeMatrix) Vector ===
func funcResets(ev *evaluator, args Expressions) Value { func funcResets(ev *evaluator, args Expressions) Value {
in := ev.evalMatrix(args[0]) in := ev.evalMatrix(args[0])
out := make(vector, 0, len(in)) out := make(Vector, 0, len(in))
for _, samples := range in { for _, samples := range in {
resets := 0 resets := 0
@ -773,7 +773,7 @@ func funcResets(ev *evaluator, args Expressions) Value {
// === changes(matrix ValueTypeMatrix) Vector === // === changes(matrix ValueTypeMatrix) Vector ===
func funcChanges(ev *evaluator, args Expressions) Value { func funcChanges(ev *evaluator, args Expressions) Value {
in := ev.evalMatrix(args[0]) in := ev.evalMatrix(args[0])
out := make(vector, 0, len(in)) out := make(Vector, 0, len(in))
for _, samples := range in { for _, samples := range in {
changes := 0 changes := 0
@ -795,10 +795,10 @@ func funcChanges(ev *evaluator, args Expressions) Value {
return out return out
} }
// === label_replace(vector ValueTypeVector, dst_label, replacement, src_labelname, regex ValueTypeString) Vector === // === label_replace(Vector ValueTypeVector, dst_label, replacement, src_labelname, regex ValueTypeString) Vector ===
func funcLabelReplace(ev *evaluator, args Expressions) Value { func funcLabelReplace(ev *evaluator, args Expressions) Value {
var ( var (
vector = ev.evalVector(args[0]) Vector = ev.evalVector(args[0])
dst = ev.evalString(args[1]).s dst = ev.evalString(args[1]).s
repl = ev.evalString(args[2]).s repl = ev.evalString(args[2]).s
src = ev.evalString(args[3]).s src = ev.evalString(args[3]).s
@ -813,8 +813,8 @@ func funcLabelReplace(ev *evaluator, args Expressions) Value {
ev.errorf("invalid destination label name in label_replace(): %s", dst) ev.errorf("invalid destination label name in label_replace(): %s", dst)
} }
outSet := make(map[uint64]struct{}, len(vector)) outSet := make(map[uint64]struct{}, len(Vector))
for _, el := range vector { for _, el := range Vector {
srcVal := el.Metric.Get(src) srcVal := el.Metric.Get(src)
indexes := regex.FindStringSubmatchIndex(srcVal) indexes := regex.FindStringSubmatchIndex(srcVal)
// If there is no match, no replacement should take place. // If there is no match, no replacement should take place.
@ -837,12 +837,12 @@ func funcLabelReplace(ev *evaluator, args Expressions) Value {
} }
} }
return vector return Vector
} }
// === vector(s scalar) Vector === // === Vector(s scalar) Vector ===
func funcVector(ev *evaluator, args Expressions) Value { func funcVector(ev *evaluator, args Expressions) Value {
return vector{ return Vector{
sample{ sample{
Metric: labels.Labels{}, Metric: labels.Labels{},
Value: ev.evalFloat(args[0]), Value: ev.evalFloat(args[0]),
@ -853,9 +853,9 @@ func funcVector(ev *evaluator, args Expressions) Value {
// Common code for date related functions. // Common code for date related functions.
func dateWrapper(ev *evaluator, args Expressions, f func(time.Time) float64) Value { func dateWrapper(ev *evaluator, args Expressions, f func(time.Time) float64) Value {
var v vector var v Vector
if len(args) == 0 { if len(args) == 0 {
v = vector{ v = Vector{
sample{ sample{
Metric: labels.Labels{}, Metric: labels.Labels{},
Value: float64(ev.Timestamp) / 1000, Value: float64(ev.Timestamp) / 1000,
@ -872,49 +872,49 @@ func dateWrapper(ev *evaluator, args Expressions, f func(time.Time) float64) Val
return v return v
} }
// === days_in_month(v vector) scalar === // === days_in_month(v Vector) scalar ===
func funcDaysInMonth(ev *evaluator, args Expressions) Value { func funcDaysInMonth(ev *evaluator, args Expressions) Value {
return dateWrapper(ev, args, func(t time.Time) float64 { return dateWrapper(ev, args, func(t time.Time) float64 {
return float64(32 - time.Date(t.Year(), t.Month(), 32, 0, 0, 0, 0, time.UTC).Day()) return float64(32 - time.Date(t.Year(), t.Month(), 32, 0, 0, 0, 0, time.UTC).Day())
}) })
} }
// === day_of_month(v vector) scalar === // === day_of_month(v Vector) scalar ===
func funcDayOfMonth(ev *evaluator, args Expressions) Value { func funcDayOfMonth(ev *evaluator, args Expressions) Value {
return dateWrapper(ev, args, func(t time.Time) float64 { return dateWrapper(ev, args, func(t time.Time) float64 {
return float64(t.Day()) return float64(t.Day())
}) })
} }
// === day_of_week(v vector) scalar === // === day_of_week(v Vector) scalar ===
func funcDayOfWeek(ev *evaluator, args Expressions) Value { func funcDayOfWeek(ev *evaluator, args Expressions) Value {
return dateWrapper(ev, args, func(t time.Time) float64 { return dateWrapper(ev, args, func(t time.Time) float64 {
return float64(t.Weekday()) return float64(t.Weekday())
}) })
} }
// === hour(v vector) scalar === // === hour(v Vector) scalar ===
func funcHour(ev *evaluator, args Expressions) Value { func funcHour(ev *evaluator, args Expressions) Value {
return dateWrapper(ev, args, func(t time.Time) float64 { return dateWrapper(ev, args, func(t time.Time) float64 {
return float64(t.Hour()) return float64(t.Hour())
}) })
} }
// === minute(v vector) scalar === // === minute(v Vector) scalar ===
func funcMinute(ev *evaluator, args Expressions) Value { func funcMinute(ev *evaluator, args Expressions) Value {
return dateWrapper(ev, args, func(t time.Time) float64 { return dateWrapper(ev, args, func(t time.Time) float64 {
return float64(t.Minute()) return float64(t.Minute())
}) })
} }
// === month(v vector) scalar === // === month(v Vector) scalar ===
func funcMonth(ev *evaluator, args Expressions) Value { func funcMonth(ev *evaluator, args Expressions) Value {
return dateWrapper(ev, args, func(t time.Time) float64 { return dateWrapper(ev, args, func(t time.Time) float64 {
return float64(t.Month()) return float64(t.Month())
}) })
} }
// === year(v vector) scalar === // === year(v Vector) scalar ===
func funcYear(ev *evaluator, args Expressions) Value { func funcYear(ev *evaluator, args Expressions) Value {
return dateWrapper(ev, args, func(t time.Time) float64 { return dateWrapper(ev, args, func(t time.Time) float64 {
return float64(t.Year()) return float64(t.Year())
@ -1193,8 +1193,8 @@ var functions = map[string]*Function{
ReturnType: ValueTypeScalar, ReturnType: ValueTypeScalar,
Call: funcTime, Call: funcTime,
}, },
"vector": { "Vector": {
Name: "vector", Name: "Vector",
ArgTypes: []ValueType{ValueTypeScalar}, ArgTypes: []ValueType{ValueTypeScalar},
ReturnType: ValueTypeVector, ReturnType: ValueTypeVector,
Call: funcVector, Call: funcVector,
@ -1214,28 +1214,28 @@ func getFunction(name string) (*Function, bool) {
return function, ok return function, ok
} }
type vectorByValueHeap vector type VectorByValueHeap Vector
func (s vectorByValueHeap) Len() int { func (s VectorByValueHeap) Len() int {
return len(s) return len(s)
} }
func (s vectorByValueHeap) Less(i, j int) bool { func (s VectorByValueHeap) Less(i, j int) bool {
if math.IsNaN(float64(s[i].Value)) { if math.IsNaN(float64(s[i].Value)) {
return true return true
} }
return s[i].Value < s[j].Value return s[i].Value < s[j].Value
} }
func (s vectorByValueHeap) Swap(i, j int) { func (s VectorByValueHeap) Swap(i, j int) {
s[i], s[j] = s[j], s[i] s[i], s[j] = s[j], s[i]
} }
func (s *vectorByValueHeap) Push(x interface{}) { func (s *VectorByValueHeap) Push(x interface{}) {
*s = append(*s, x.(sample)) *s = append(*s, x.(sample))
} }
func (s *vectorByValueHeap) Pop() interface{} { func (s *VectorByValueHeap) Pop() interface{} {
old := *s old := *s
n := len(old) n := len(old)
el := old[n-1] el := old[n-1]
@ -1243,28 +1243,28 @@ func (s *vectorByValueHeap) Pop() interface{} {
return el return el
} }
type vectorByReverseValueHeap vector type VectorByReverseValueHeap Vector
func (s vectorByReverseValueHeap) Len() int { func (s VectorByReverseValueHeap) Len() int {
return len(s) return len(s)
} }
func (s vectorByReverseValueHeap) Less(i, j int) bool { func (s VectorByReverseValueHeap) Less(i, j int) bool {
if math.IsNaN(float64(s[i].Value)) { if math.IsNaN(float64(s[i].Value)) {
return true return true
} }
return s[i].Value > s[j].Value return s[i].Value > s[j].Value
} }
func (s vectorByReverseValueHeap) Swap(i, j int) { func (s VectorByReverseValueHeap) Swap(i, j int) {
s[i], s[j] = s[j], s[i] s[i], s[j] = s[j], s[i]
} }
func (s *vectorByReverseValueHeap) Push(x interface{}) { func (s *VectorByReverseValueHeap) Push(x interface{}) {
*s = append(*s, x.(sample)) *s = append(*s, x.(sample))
} }
func (s *vectorByReverseValueHeap) Pop() interface{} { func (s *VectorByReverseValueHeap) Pop() interface{} {
old := *s old := *s
n := len(old) n := len(old)
el := old[n-1] el := old[n-1]

View File

@ -95,7 +95,7 @@ func ParseMetricSelector(input string) (m []*LabelMatcher, err error) {
if t := p.peek().typ; t == itemMetricIdentifier || t == itemIdentifier { if t := p.peek().typ; t == itemMetricIdentifier || t == itemIdentifier {
name = p.next().val name = p.next().val
} }
vs := p.vectorSelector(name) vs := p.VectorSelector(name)
if p.peek().typ != itemEOF { if p.peek().typ != itemEOF {
p.errorf("could not parse remaining input %.15q...", p.lex.input[p.lex.lastPos:]) p.errorf("could not parse remaining input %.15q...", p.lex.input[p.lex.lastPos:])
} }
@ -367,7 +367,7 @@ func (p *parser) alertStmt() *AlertStmt {
p.expect(itemAlert, ctx) p.expect(itemAlert, ctx)
name := p.expect(itemIdentifier, ctx) name := p.expect(itemIdentifier, ctx)
// Alerts require a vector typed expression. // Alerts require a Vector typed expression.
p.expect(itemIf, ctx) p.expect(itemIf, ctx)
expr := p.expr() expr := p.expr()
@ -531,7 +531,7 @@ func (p *parser) balance(lhs Expr, op itemType, rhs Expr, vecMatching *VectorMat
// unaryExpr parses a unary expression. // unaryExpr parses a unary expression.
// //
// <vector_selector> | <matrix_selector> | (+|-) <number_literal> | '(' <expr> ')' // <Vector_selector> | <matrix_selector> | (+|-) <number_literal> | '(' <expr> ')'
// //
func (p *parser) unaryExpr() Expr { func (p *parser) unaryExpr() Expr {
switch t := p.peek(); t.typ { switch t := p.peek(); t.typ {
@ -584,9 +584,9 @@ func (p *parser) unaryExpr() Expr {
} }
// rangeSelector parses a matrix (a.k.a. range) selector based on a given // rangeSelector parses a matrix (a.k.a. range) selector based on a given
// vector selector. // Vector selector.
// //
// <vector_selector> '[' <duration> ']' // <Vector_selector> '[' <duration> ']'
// //
func (p *parser) rangeSelector(vs *VectorSelector) *MatrixSelector { func (p *parser) rangeSelector(vs *VectorSelector) *MatrixSelector {
const ctx = "range selector" const ctx = "range selector"
@ -626,7 +626,7 @@ func (p *parser) number(val string) float64 {
// primaryExpr parses a primary expression. // primaryExpr parses a primary expression.
// //
// <metric_name> | <function_call> | <vector_aggregation> | <literal> // <metric_name> | <function_call> | <Vector_aggregation> | <literal>
// //
func (p *parser) primaryExpr() Expr { func (p *parser) primaryExpr() Expr {
switch t := p.next(); { switch t := p.next(); {
@ -640,7 +640,7 @@ func (p *parser) primaryExpr() Expr {
case t.typ == itemLeftBrace: case t.typ == itemLeftBrace:
// Metric selector without metric name. // Metric selector without metric name.
p.backup() p.backup()
return p.vectorSelector("") return p.VectorSelector("")
case t.typ == itemIdentifier: case t.typ == itemIdentifier:
// Check for function call. // Check for function call.
@ -650,7 +650,7 @@ func (p *parser) primaryExpr() Expr {
fallthrough // Else metric selector. fallthrough // Else metric selector.
case t.typ == itemMetricIdentifier: case t.typ == itemMetricIdentifier:
return p.vectorSelector(t.val) return p.VectorSelector(t.val)
case t.typ.isAggregator(): case t.typ.isAggregator():
p.backup() p.backup()
@ -693,8 +693,8 @@ func (p *parser) labels() []string {
// aggrExpr parses an aggregation expression. // aggrExpr parses an aggregation expression.
// //
// <aggr_op> (<vector_expr>) [by <labels>] [keep_common] // <aggr_op> (<Vector_expr>) [by <labels>] [keep_common]
// <aggr_op> [by <labels>] [keep_common] (<vector_expr>) // <aggr_op> [by <labels>] [keep_common] (<Vector_expr>)
// //
func (p *parser) aggrExpr() *AggregateExpr { func (p *parser) aggrExpr() *AggregateExpr {
const ctx = "aggregation" const ctx = "aggregation"
@ -935,12 +935,12 @@ func (p *parser) offset() time.Duration {
return offset return offset
} }
// vectorSelector parses a new (instant) vector selector. // VectorSelector parses a new (instant) Vector selector.
// //
// <metric_identifier> [<label_matchers>] // <metric_identifier> [<label_matchers>]
// [<metric_identifier>] <label_matchers> // [<metric_identifier>] <label_matchers>
// //
func (p *parser) vectorSelector(name string) *VectorSelector { func (p *parser) VectorSelector(name string) *VectorSelector {
var matchers []*LabelMatcher var matchers []*LabelMatcher
// Parse label matching if any. // Parse label matching if any.
if t := p.peek(); t.typ == itemLeftBrace { if t := p.peek(); t.typ == itemLeftBrace {
@ -949,7 +949,7 @@ func (p *parser) vectorSelector(name string) *VectorSelector {
// Metric name must not be set in the label matchers and before at the same time. // Metric name must not be set in the label matchers and before at the same time.
if name != "" { if name != "" {
for _, m := range matchers { for _, m := range matchers {
if m.Name == model.MetricNameLabel { if m.Name == MetricNameLabel {
p.errorf("metric name must not be set twice: %q or %q", name, m.Value) p.errorf("metric name must not be set twice: %q or %q", name, m.Value)
} }
} }
@ -962,9 +962,9 @@ func (p *parser) vectorSelector(name string) *VectorSelector {
} }
if len(matchers) == 0 { if len(matchers) == 0 {
p.errorf("vector selector must contain label matchers or metric name") p.errorf("Vector selector must contain label matchers or metric name")
} }
// A vector selector must contain at least one non-empty matcher to prevent // A Vector selector must contain at least one non-empty matcher to prevent
// implicit selection of all metrics (e.g. by a typo). // implicit selection of all metrics (e.g. by a typo).
notEmpty := false notEmpty := false
for _, lm := range matchers { for _, lm := range matchers {
@ -974,7 +974,7 @@ func (p *parser) vectorSelector(name string) *VectorSelector {
} }
} }
if !notEmpty { if !notEmpty {
p.errorf("vector selector must contain at least one non-empty matcher") p.errorf("Vector selector must contain at least one non-empty matcher")
} }
return &VectorSelector{ return &VectorSelector{
@ -1028,7 +1028,7 @@ func (p *parser) checkType(node Node) (typ ValueType) {
case *RecordStmt: case *RecordStmt:
ty := p.checkType(n.Expr) ty := p.checkType(n.Expr)
if ty != ValueTypeVector && ty != ValueTypeScalar { if ty != ValueTypeVector && ty != ValueTypeScalar {
p.errorf("record statement must have a valid expression of type instant vector or scalar but got %s", documentedType(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:
@ -1058,16 +1058,16 @@ func (p *parser) checkType(node Node) (typ 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 != ValueTypeScalar && lt != ValueTypeVector) || (rt != ValueTypeScalar && rt != ValueTypeVector) { if (lt != ValueTypeScalar && lt != ValueTypeVector) || (rt != ValueTypeScalar && rt != ValueTypeVector) {
p.errorf("binary expression must contain only scalar and instant vector types") p.errorf("binary expression must contain only scalar and instant Vector types")
} }
if (lt != ValueTypeVector || rt != ValueTypeVector) && n.VectorMatching != nil { if (lt != ValueTypeVector || rt != ValueTypeVector) && n.VectorMatching != nil {
if len(n.VectorMatching.MatchingLabels) > 0 { if len(n.VectorMatching.MatchingLabels) > 0 {
p.errorf("vector matching only allowed between instant vectors") p.errorf("Vector matching only allowed between instant Vectors")
} }
n.VectorMatching = nil n.VectorMatching = nil
} else { } else {
// Both operands are vectors. // Both operands are Vectors.
if n.Op.isSetOperator() { if n.Op.isSetOperator() {
if n.VectorMatching.Card == CardOneToMany || n.VectorMatching.Card == CardManyToOne { if n.VectorMatching.Card == CardOneToMany || n.VectorMatching.Card == CardManyToOne {
p.errorf("no grouping allowed for %q operation", n.Op) p.errorf("no grouping allowed for %q operation", n.Op)
@ -1102,7 +1102,7 @@ func (p *parser) checkType(node Node) (typ 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 != ValueTypeScalar && t != ValueTypeVector { if t := p.checkType(n.Expr); t != ValueTypeScalar && t != ValueTypeVector {
p.errorf("unary expression only allowed on expressions of type scalar or instant vector, got %q", documentedType(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

@ -236,11 +236,11 @@ var testExpr = []struct {
}, { }, {
input: `-"string"`, input: `-"string"`,
fail: true, fail: true,
errMsg: `unary expression only allowed on expressions of type scalar or instant 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 instant vector, got "range vector"`, errMsg: `unary expression only allowed on expressions of type scalar or instant Vector, got "range Vector"`,
}, { }, {
input: `*test`, input: `*test`,
fail: true, fail: true,
@ -771,11 +771,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 instant 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 instant 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,
@ -817,7 +817,7 @@ var testExpr = []struct {
fail: true, fail: true,
errMsg: "bool modifier can only be used on comparison operators", errMsg: "bool modifier can only be used on comparison operators",
}, },
// Test vector selector. // Test Vector selector.
{ {
input: "foo", input: "foo",
expected: &VectorSelector{ expected: &VectorSelector{
@ -914,23 +914,23 @@ var testExpr = []struct {
}, { }, {
input: `{}`, input: `{}`,
fail: true, fail: true,
errMsg: "vector selector must contain label matchers or metric name", errMsg: "Vector selector must contain label matchers or metric name",
}, { }, {
input: `{x=""}`, input: `{x=""}`,
fail: true, fail: true,
errMsg: "vector selector must contain at least one non-empty matcher", errMsg: "Vector selector must contain at least one non-empty matcher",
}, { }, {
input: `{x=~".*"}`, input: `{x=~".*"}`,
fail: true, fail: true,
errMsg: "vector selector must contain at least one non-empty matcher", errMsg: "Vector selector must contain at least one non-empty matcher",
}, { }, {
input: `{x!~".+"}`, input: `{x!~".+"}`,
fail: true, fail: true,
errMsg: "vector selector must contain at least one non-empty matcher", errMsg: "Vector selector must contain at least one non-empty matcher",
}, { }, {
input: `{x!="a"}`, input: `{x!="a"}`,
fail: true, fail: true,
errMsg: "vector selector must contain at least one non-empty matcher", errMsg: "Vector selector must contain at least one non-empty matcher",
}, { }, {
input: `foo{__name__="bar"}`, input: `foo{__name__="bar"}`,
fail: true, fail: true,
@ -1285,7 +1285,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 instant 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,
@ -1363,7 +1363,7 @@ var testExpr = []struct {
}, { }, {
input: "floor(1)", input: "floor(1)",
fail: true, fail: true,
errMsg: "expected type instant 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,
@ -1371,7 +1371,7 @@ var testExpr = []struct {
}, { }, {
input: "rate(some_metric)", input: "rate(some_metric)",
fail: true, fail: true,
errMsg: "expected type range vector in call to function \"rate\", got instant vector", errMsg: "expected type range Vector in call to function \"rate\", got instant Vector",
}, },
// Fuzzing regression tests. // Fuzzing regression tests.
{ {

View File

@ -106,13 +106,13 @@ func bucketQuantile(q float64, buckets buckets) float64 {
return bucketStart + (bucketEnd-bucketStart)*float64(rank/count) return bucketStart + (bucketEnd-bucketStart)*float64(rank/count)
} }
// qauntile calculates the given quantile of a vector of samples. // qauntile calculates the given quantile of a Vector of samples.
// //
// The vector will be sorted. // The Vector will be sorted.
// If 'values' has zero elements, NaN is returned. // If 'values' has zero elements, NaN is returned.
// If q<0, -Inf is returned. // If q<0, -Inf is returned.
// If q>1, +Inf is returned. // If q>1, +Inf is returned.
func quantile(q float64, values vectorByValueHeap) float64 { func quantile(q float64, values VectorByValueHeap) float64 {
if len(values) == 0 { if len(values) == 0 {
return math.NaN() return math.NaN()
} }

View File

@ -378,7 +378,7 @@ func (ev *evalCmd) compareResult(result Value) error {
} }
} }
case vector: case Vector:
if !ev.instant { if !ev.instant {
return fmt.Errorf("received instant result on range evaluation") return fmt.Errorf("received instant result on range evaluation")
} }