From 09666e2e2a8e017fe6026e838b69e5d5f22d2198 Mon Sep 17 00:00:00 2001 From: Fabian Reinartz Date: Sat, 24 Dec 2016 10:44:04 +0100 Subject: [PATCH] promql: make scalar public --- promql/ast.go | 2 +- promql/engine.go | 58 ++++++++++++++++++++++---------------------- promql/functions.go | 36 +++++++++++++-------------- promql/parse.go | 12 ++++----- promql/test.go | 4 +-- template/template.go | 5 ++-- 6 files changed, 59 insertions(+), 58 deletions(-) diff --git a/promql/ast.go b/promql/ast.go index 7de36cc8d..e24e0cb21 100644 --- a/promql/ast.go +++ b/promql/ast.go @@ -156,7 +156,7 @@ type StringLiteral struct { } // UnaryExpr represents a unary operation on another expression. -// Currently unary operations are only supported for scalars. +// Currently unary operations are only supported for Scalars. type UnaryExpr struct { Op itemType Expr Expr diff --git a/promql/engine.go b/promql/engine.go index 7244a57e5..427828968 100644 --- a/promql/engine.go +++ b/promql/engine.go @@ -52,7 +52,7 @@ type Value interface { func (Matrix) Type() ValueType { return ValueTypeMatrix } func (Vector) Type() ValueType { return ValueTypeVector } -func (scalar) Type() ValueType { return ValueTypeScalar } +func (Scalar) Type() ValueType { return ValueTypeScalar } func (stringVal) Type() ValueType { return ValueTypeString } // ValueType describes a type of a value. @@ -62,7 +62,7 @@ type ValueType string const ( ValueTypeNone = "none" ValueTypeVector = "Vector" - ValueTypeScalar = "scalar" + ValueTypeScalar = "Scalar" ValueTypeMatrix = "Matrix" ValueTypeString = "string" ) @@ -76,12 +76,12 @@ func (s stringVal) String() string { return s.s } -type scalar struct { +type Scalar struct { t int64 v float64 } -func (s scalar) String() string { +func (s Scalar) String() string { return "" } @@ -175,15 +175,15 @@ func (r *Result) Matrix() (Matrix, error) { return v, nil } -// Scalar returns a scalar value. An error is returned if -// the result was an error or the result value is not a scalar. -func (r *Result) Scalar() (scalar, error) { +// Scalar returns a Scalar value. An error is returned if +// the result was an error or the result value is not a Scalar. +func (r *Result) Scalar() (Scalar, error) { if r.Err != nil { - return scalar{}, r.Err + return Scalar{}, r.Err } - v, ok := r.Value.(scalar) + v, ok := r.Value.(Scalar) if !ok { - return scalar{}, fmt.Errorf("query result is not a scalar") + return Scalar{}, fmt.Errorf("query result is not a Scalar") } return v, nil } @@ -336,7 +336,7 @@ func (ng *Engine) NewRangeQuery(qs string, start, end time.Time, interval time.D return nil, err } 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.q = qs @@ -470,9 +470,9 @@ func (ng *Engine) execEvalStmt(ctx context.Context, query *query, s *EvalStmt) ( } switch v := val.(type) { - case scalar: + case Scalar: // As the expression type does not change we can safely default to 0 - // as the fingerprint for scalar expressions. + // as the fingerprint for Scalar expressions. ss, ok := sampleStreams[0] if !ok { ss = sampleStream{Values: make([]samplePair, 0, numSteps)} @@ -633,12 +633,12 @@ func (ev *evaluator) recover(errp *error) { } } -// evalScalar attempts to evaluate e to a scalar value and errors otherwise. -func (ev *evaluator) evalScalar(e Expr) scalar { +// evalScalar attempts to evaluate e to a Scalar value and errors otherwise. +func (ev *evaluator) evalScalar(e Expr) Scalar { val := ev.eval(e) - sv, ok := val.(scalar) + sv, ok := val.(Scalar) if !ok { - ev.errorf("expected scalar but got %s", documentedType(val.Type())) + ev.errorf("expected Scalar but got %s", documentedType(val.Type())) } return sv } @@ -657,7 +657,7 @@ func (ev *evaluator) evalVector(e Expr) Vector { func (ev *evaluator) evalInt(e Expr) int64 { sc := ev.evalScalar(e) if !convertibleToInt64(sc.v) { - ev.errorf("scalar value %v overflows int64", sc.v) + ev.errorf("Scalar value %v overflows int64", sc.v) } return int64(sc.v) } @@ -723,8 +723,8 @@ func (ev *evaluator) eval(expr Expr) Value { switch lt, rt := lhs.Type(), rhs.Type(); { case lt == ValueTypeScalar && rt == ValueTypeScalar: - return scalar{ - v: scalarBinop(e.Op, lhs.(scalar).v, rhs.(scalar).v), + return Scalar{ + v: ScalarBinop(e.Op, lhs.(Scalar).v, rhs.(Scalar).v), t: ev.Timestamp, } @@ -740,10 +740,10 @@ func (ev *evaluator) eval(expr Expr) Value { return ev.VectorBinop(e.Op, lhs.(Vector), rhs.(Vector), e.VectorMatching, e.ReturnBool) } 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: - 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: @@ -753,7 +753,7 @@ func (ev *evaluator) eval(expr Expr) Value { return ev.MatrixSelector(e) case *NumberLiteral: - return scalar{v: e.Val, t: ev.Timestamp} + return Scalar{v: e.Val, t: ev.Timestamp} case *ParenExpr: return ev.eval(e.Expr) @@ -766,7 +766,7 @@ func (ev *evaluator) eval(expr Expr) Value { // Only + and - are possible operators. if e.Op == itemSUB { switch v := se.(type) { - case scalar: + case Scalar: v.v = -v.v case Vector: for i, sv := range v { @@ -1116,8 +1116,8 @@ Outer: return res } -// 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 { +// 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 { vec := make(Vector, 0, len(lhs)) for _, lhsSample := range lhs { @@ -1161,8 +1161,8 @@ func copyLabels(metric labels.Labels, withName bool) labels.Labels { return cm } -// scalarBinop evaluates a binary operation between two scalars. -func scalarBinop(op itemType, lhs, rhs float64) float64 { +// ScalarBinop evaluates a binary operation between two Scalars. +func ScalarBinop(op itemType, lhs, rhs float64) float64 { switch op { case itemADD: return lhs + rhs @@ -1189,7 +1189,7 @@ func scalarBinop(op itemType, lhs, rhs float64) float64 { case itemLTE: return btos(lhs <= rhs) } - 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. diff --git a/promql/functions.go b/promql/functions.go index bf5e4d0e3..808d0ab24 100644 --- a/promql/functions.go +++ b/promql/functions.go @@ -36,7 +36,7 @@ type Function struct { // === time() float64 === func funcTime(ev *evaluator, args Expressions) Value { - return scalar{ + return Scalar{ v: float64(ev.Timestamp / 1000), t: ev.Timestamp, } @@ -384,24 +384,24 @@ func funcRound(ev *evaluator, args Expressions) Value { return vec } -// === scalar(node ValueTypeVector) Scalar === +// === Scalar(node ValueTypeVector) Scalar === func funcScalar(ev *evaluator, args Expressions) Value { v := ev.evalVector(args[0]) if len(v) != 1 { - return scalar{ + return Scalar{ v: math.NaN(), t: ev.Timestamp, } } - return scalar{ + return Scalar{ v: v[0].Value, t: ev.Timestamp, } } -// === count_scalar(Vector ValueTypeVector) float64 === +// === count_Scalar(Vector ValueTypeVector) float64 === func funcCountScalar(ev *evaluator, args Expressions) Value { - return scalar{ + return Scalar{ v: float64(len(ev.evalVector(args[0]))), t: ev.Timestamp, } @@ -840,7 +840,7 @@ func funcLabelReplace(ev *evaluator, args Expressions) Value { return Vector } -// === Vector(s scalar) Vector === +// === Vector(s Scalar) Vector === func funcVector(ev *evaluator, args Expressions) Value { return Vector{ sample{ @@ -872,49 +872,49 @@ func dateWrapper(ev *evaluator, args Expressions, f func(time.Time) float64) Val return v } -// === days_in_month(v Vector) scalar === +// === days_in_month(v Vector) Scalar === func funcDaysInMonth(ev *evaluator, args Expressions) Value { 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()) }) } -// === day_of_month(v Vector) scalar === +// === day_of_month(v Vector) Scalar === func funcDayOfMonth(ev *evaluator, args Expressions) Value { return dateWrapper(ev, args, func(t time.Time) float64 { return float64(t.Day()) }) } -// === day_of_week(v Vector) scalar === +// === day_of_week(v Vector) Scalar === func funcDayOfWeek(ev *evaluator, args Expressions) Value { return dateWrapper(ev, args, func(t time.Time) float64 { return float64(t.Weekday()) }) } -// === hour(v Vector) scalar === +// === hour(v Vector) Scalar === func funcHour(ev *evaluator, args Expressions) Value { return dateWrapper(ev, args, func(t time.Time) float64 { return float64(t.Hour()) }) } -// === minute(v Vector) scalar === +// === minute(v Vector) Scalar === func funcMinute(ev *evaluator, args Expressions) Value { return dateWrapper(ev, args, func(t time.Time) float64 { return float64(t.Minute()) }) } -// === month(v Vector) scalar === +// === month(v Vector) Scalar === func funcMonth(ev *evaluator, args Expressions) Value { return dateWrapper(ev, args, func(t time.Time) float64 { return float64(t.Month()) }) } -// === year(v Vector) scalar === +// === year(v Vector) Scalar === func funcYear(ev *evaluator, args Expressions) Value { return dateWrapper(ev, args, func(t time.Time) float64 { return float64(t.Year()) @@ -970,8 +970,8 @@ var functions = map[string]*Function{ ReturnType: ValueTypeVector, Call: funcCountOverTime, }, - "count_scalar": { - Name: "count_scalar", + "count_Scalar": { + Name: "count_Scalar", ArgTypes: []ValueType{ValueTypeVector}, ReturnType: ValueTypeScalar, Call: funcCountScalar, @@ -1145,8 +1145,8 @@ var functions = map[string]*Function{ ReturnType: ValueTypeVector, Call: funcRound, }, - "scalar": { - Name: "scalar", + "Scalar": { + Name: "Scalar", ArgTypes: []ValueType{ValueTypeVector}, ReturnType: ValueTypeScalar, Call: funcScalar, diff --git a/promql/parse.go b/promql/parse.go index 27015a114..09bb761a7 100644 --- a/promql/parse.go +++ b/promql/parse.go @@ -506,7 +506,7 @@ func (p *parser) balance(lhs Expr, op itemType, rhs Expr, vecMatching *VectorMat if (precd < 0) || (precd == 0 && op.isRightAssociative()) { balanced := p.balance(lhsBE.RHS, op, rhs, vecMatching, returnBool) if lhsBE.Op.isComparisonOperator() && !lhsBE.ReturnBool && balanced.Type() == ValueTypeScalar && lhsBE.LHS.Type() == ValueTypeScalar { - p.errorf("comparisons between scalars must use BOOL modifier") + p.errorf("comparisons between Scalars must use BOOL modifier") } return &BinaryExpr{ Op: lhsBE.Op, @@ -518,7 +518,7 @@ func (p *parser) balance(lhs Expr, op itemType, rhs Expr, vecMatching *VectorMat } } if op.isComparisonOperator() && !returnBool && rhs.Type() == ValueTypeScalar && lhs.Type() == ValueTypeScalar { - p.errorf("comparisons between scalars must use BOOL modifier") + p.errorf("comparisons between Scalars must use BOOL modifier") } return &BinaryExpr{ Op: op, @@ -1028,7 +1028,7 @@ func (p *parser) checkType(node Node) (typ ValueType) { case *RecordStmt: ty := p.checkType(n.Expr) 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: @@ -1058,7 +1058,7 @@ func (p *parser) checkType(node Node) (typ ValueType) { p.errorf("binary expression does not support operator %q", n.Op) } 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 { @@ -1079,7 +1079,7 @@ func (p *parser) checkType(node Node) (typ ValueType) { } if (lt == ValueTypeScalar || rt == ValueTypeScalar) && n.Op.isSetOperator() { - p.errorf("set operator %q not allowed in binary scalar expression", n.Op) + p.errorf("set operator %q not allowed in binary Scalar expression", n.Op) } case *Call: @@ -1102,7 +1102,7 @@ func (p *parser) checkType(node Node) (typ ValueType) { p.errorf("only + and - operators allowed for unary expressions") } 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: diff --git a/promql/test.go b/promql/test.go index 424ce01c4..1b3e6b54d 100644 --- a/promql/test.go +++ b/promql/test.go @@ -404,9 +404,9 @@ func (ev *evalCmd) compareResult(result Value) error { } } - case scalar: + case Scalar: if !almostEqual(ev.expected[0].vals[0].value, val.v) { - return fmt.Errorf("expected scalar %v but got %v", val.v, ev.expected[0].vals[0].value) + return fmt.Errorf("expected Scalar %v but got %v", val.v, ev.expected[0].vals[0].value) } default: diff --git a/template/template.go b/template/template.go index f468b9b6e..e02c1b51c 100644 --- a/template/template.go +++ b/template/template.go @@ -21,6 +21,7 @@ import ( "regexp" "sort" "strings" + "time" html_template "html/template" text_template "text/template" @@ -56,8 +57,8 @@ func (q queryResultByLabelSorter) Swap(i, j int) { q.results[i], q.results[j] = q.results[j], q.results[i] } -func query(ctx context.Context, q string, timestamp model.Time, queryEngine *promql.Engine) (queryResult, error) { - query, err := queryEngine.NewInstantQuery(q, timestamp) +func query(ctx context.Context, q string, ts time.Time, queryEngine *promql.Engine) (queryResult, error) { + query, err := queryEngine.NewInstantQuery(q, ts) if err != nil { return nil, err }