mirror of
https://github.com/prometheus/prometheus
synced 2025-02-15 19:47:56 +00:00
promql: Use capitalized names for item types (#6371)
For yacc generated parsers there is the convention to capitalize the names of item types provided by the lexer, which makes it easy to distinct lexer tokens (capitalized) from nonterminal symbols (not capitalized) in language grammars. This convention is also followed by the (non generated) go compiler (see https://golang.org/pkg/go/token/#Token). Part of the parser rewrite described in #6256. Signed-off-by: Tobias Guggenmos <tguggenm@redhat.com>
This commit is contained in:
parent
c229ed17e2
commit
bbd92b85da
104
promql/engine.go
104
promql/engine.go
@ -1070,7 +1070,7 @@ func (ev *evaluator) eval(expr Expr) Value {
|
||||
|
||||
case *UnaryExpr:
|
||||
mat := ev.eval(e.Expr).(Matrix)
|
||||
if e.Op == ItemSUB {
|
||||
if e.Op == SUB {
|
||||
for i := range mat {
|
||||
mat[i].Metric = dropMetricName(mat[i].Metric)
|
||||
for j := range mat[i].Points {
|
||||
@ -1092,15 +1092,15 @@ func (ev *evaluator) eval(expr Expr) Value {
|
||||
}, e.LHS, e.RHS)
|
||||
case lt == ValueTypeVector && rt == ValueTypeVector:
|
||||
switch e.Op {
|
||||
case ItemLAND:
|
||||
case LAND:
|
||||
return ev.rangeEval(func(v []Value, enh *EvalNodeHelper) Vector {
|
||||
return ev.VectorAnd(v[0].(Vector), v[1].(Vector), e.VectorMatching, enh)
|
||||
}, e.LHS, e.RHS)
|
||||
case ItemLOR:
|
||||
case LOR:
|
||||
return ev.rangeEval(func(v []Value, enh *EvalNodeHelper) Vector {
|
||||
return ev.VectorOr(v[0].(Vector), v[1].(Vector), e.VectorMatching, enh)
|
||||
}, e.LHS, e.RHS)
|
||||
case ItemLUnless:
|
||||
case LUNLESS:
|
||||
return ev.rangeEval(func(v []Value, enh *EvalNodeHelper) Vector {
|
||||
return ev.VectorUnless(v[0].(Vector), v[1].(Vector), e.VectorMatching, enh)
|
||||
}, e.LHS, e.RHS)
|
||||
@ -1644,29 +1644,29 @@ func dropMetricName(l labels.Labels) labels.Labels {
|
||||
// scalarBinop evaluates a binary operation between two Scalars.
|
||||
func scalarBinop(op ItemType, lhs, rhs float64) float64 {
|
||||
switch op {
|
||||
case ItemADD:
|
||||
case ADD:
|
||||
return lhs + rhs
|
||||
case ItemSUB:
|
||||
case SUB:
|
||||
return lhs - rhs
|
||||
case ItemMUL:
|
||||
case MUL:
|
||||
return lhs * rhs
|
||||
case ItemDIV:
|
||||
case DIV:
|
||||
return lhs / rhs
|
||||
case ItemPOW:
|
||||
case POW:
|
||||
return math.Pow(lhs, rhs)
|
||||
case ItemMOD:
|
||||
case MOD:
|
||||
return math.Mod(lhs, rhs)
|
||||
case ItemEQL:
|
||||
case EQL:
|
||||
return btos(lhs == rhs)
|
||||
case ItemNEQ:
|
||||
case NEQ:
|
||||
return btos(lhs != rhs)
|
||||
case ItemGTR:
|
||||
case GTR:
|
||||
return btos(lhs > rhs)
|
||||
case ItemLSS:
|
||||
case LSS:
|
||||
return btos(lhs < rhs)
|
||||
case ItemGTE:
|
||||
case GTE:
|
||||
return btos(lhs >= rhs)
|
||||
case ItemLTE:
|
||||
case LTE:
|
||||
return btos(lhs <= rhs)
|
||||
}
|
||||
panic(errors.Errorf("operator %q not allowed for Scalar operations", op))
|
||||
@ -1675,29 +1675,29 @@ func scalarBinop(op ItemType, lhs, rhs float64) float64 {
|
||||
// vectorElemBinop evaluates a binary operation between two Vector elements.
|
||||
func vectorElemBinop(op ItemType, lhs, rhs float64) (float64, bool) {
|
||||
switch op {
|
||||
case ItemADD:
|
||||
case ADD:
|
||||
return lhs + rhs, true
|
||||
case ItemSUB:
|
||||
case SUB:
|
||||
return lhs - rhs, true
|
||||
case ItemMUL:
|
||||
case MUL:
|
||||
return lhs * rhs, true
|
||||
case ItemDIV:
|
||||
case DIV:
|
||||
return lhs / rhs, true
|
||||
case ItemPOW:
|
||||
case POW:
|
||||
return math.Pow(lhs, rhs), true
|
||||
case ItemMOD:
|
||||
case MOD:
|
||||
return math.Mod(lhs, rhs), true
|
||||
case ItemEQL:
|
||||
case EQL:
|
||||
return lhs, lhs == rhs
|
||||
case ItemNEQ:
|
||||
case NEQ:
|
||||
return lhs, lhs != rhs
|
||||
case ItemGTR:
|
||||
case GTR:
|
||||
return lhs, lhs > rhs
|
||||
case ItemLSS:
|
||||
case LSS:
|
||||
return lhs, lhs < rhs
|
||||
case ItemGTE:
|
||||
case GTE:
|
||||
return lhs, lhs >= rhs
|
||||
case ItemLTE:
|
||||
case LTE:
|
||||
return lhs, lhs <= rhs
|
||||
}
|
||||
panic(errors.Errorf("operator %q not allowed for operations between Vectors", op))
|
||||
@ -1717,7 +1717,7 @@ func (ev *evaluator) aggregation(op ItemType, grouping []string, without bool, p
|
||||
|
||||
result := map[uint64]*groupedAggregation{}
|
||||
var k int64
|
||||
if op == ItemTopK || op == ItemBottomK {
|
||||
if op == TOPK || op == BOTTOMK {
|
||||
f := param.(float64)
|
||||
if !convertibleToInt64(f) {
|
||||
ev.errorf("Scalar value %v overflows int64", f)
|
||||
@ -1728,11 +1728,11 @@ func (ev *evaluator) aggregation(op ItemType, grouping []string, without bool, p
|
||||
}
|
||||
}
|
||||
var q float64
|
||||
if op == ItemQuantile {
|
||||
if op == QUANTILE {
|
||||
q = param.(float64)
|
||||
}
|
||||
var valueLabel string
|
||||
if op == ItemCountValues {
|
||||
if op == COUNT_VALUES {
|
||||
valueLabel = param.(string)
|
||||
if !model.LabelName(valueLabel).IsValid() {
|
||||
ev.errorf("invalid label name %q", valueLabel)
|
||||
@ -1748,7 +1748,7 @@ func (ev *evaluator) aggregation(op ItemType, grouping []string, without bool, p
|
||||
for _, s := range vec {
|
||||
metric := s.Metric
|
||||
|
||||
if op == ItemCountValues {
|
||||
if op == COUNT_VALUES {
|
||||
lb.Reset(metric)
|
||||
lb.Set(valueLabel, strconv.FormatFloat(s.V, 'f', -1, 64))
|
||||
metric = lb.Labels()
|
||||
@ -1796,15 +1796,15 @@ func (ev *evaluator) aggregation(op ItemType, grouping []string, without bool, p
|
||||
if k > inputVecLen {
|
||||
resultSize = inputVecLen
|
||||
}
|
||||
if op == ItemStdvar || op == ItemStddev {
|
||||
if op == STDVAR || op == STDDEV {
|
||||
result[groupingKey].value = 0.0
|
||||
} else if op == ItemTopK || op == ItemQuantile {
|
||||
} else if op == TOPK || op == QUANTILE {
|
||||
result[groupingKey].heap = make(vectorByValueHeap, 0, resultSize)
|
||||
heap.Push(&result[groupingKey].heap, &Sample{
|
||||
Point: Point{V: s.V},
|
||||
Metric: s.Metric,
|
||||
})
|
||||
} else if op == ItemBottomK {
|
||||
} else if op == BOTTOMK {
|
||||
result[groupingKey].reverseHeap = make(vectorByReverseValueHeap, 0, resultSize)
|
||||
heap.Push(&result[groupingKey].reverseHeap, &Sample{
|
||||
Point: Point{V: s.V},
|
||||
@ -1815,33 +1815,33 @@ func (ev *evaluator) aggregation(op ItemType, grouping []string, without bool, p
|
||||
}
|
||||
|
||||
switch op {
|
||||
case ItemSum:
|
||||
case SUM:
|
||||
group.value += s.V
|
||||
|
||||
case ItemAvg:
|
||||
case AVG:
|
||||
group.groupCount++
|
||||
group.mean += (s.V - group.mean) / float64(group.groupCount)
|
||||
|
||||
case ItemMax:
|
||||
case MAX:
|
||||
if group.value < s.V || math.IsNaN(group.value) {
|
||||
group.value = s.V
|
||||
}
|
||||
|
||||
case ItemMin:
|
||||
case MIN:
|
||||
if group.value > s.V || math.IsNaN(group.value) {
|
||||
group.value = s.V
|
||||
}
|
||||
|
||||
case ItemCount, ItemCountValues:
|
||||
case COUNT, COUNT_VALUES:
|
||||
group.groupCount++
|
||||
|
||||
case ItemStdvar, ItemStddev:
|
||||
case STDVAR, STDDEV:
|
||||
group.groupCount++
|
||||
delta := s.V - group.mean
|
||||
group.mean += delta / float64(group.groupCount)
|
||||
group.value += delta * (s.V - group.mean)
|
||||
|
||||
case ItemTopK:
|
||||
case TOPK:
|
||||
if int64(len(group.heap)) < k || group.heap[0].V < s.V || math.IsNaN(group.heap[0].V) {
|
||||
if int64(len(group.heap)) == k {
|
||||
heap.Pop(&group.heap)
|
||||
@ -1852,7 +1852,7 @@ func (ev *evaluator) aggregation(op ItemType, grouping []string, without bool, p
|
||||
})
|
||||
}
|
||||
|
||||
case ItemBottomK:
|
||||
case BOTTOMK:
|
||||
if int64(len(group.reverseHeap)) < k || group.reverseHeap[0].V > s.V || math.IsNaN(group.reverseHeap[0].V) {
|
||||
if int64(len(group.reverseHeap)) == k {
|
||||
heap.Pop(&group.reverseHeap)
|
||||
@ -1863,7 +1863,7 @@ func (ev *evaluator) aggregation(op ItemType, grouping []string, without bool, p
|
||||
})
|
||||
}
|
||||
|
||||
case ItemQuantile:
|
||||
case QUANTILE:
|
||||
group.heap = append(group.heap, s)
|
||||
|
||||
default:
|
||||
@ -1874,19 +1874,19 @@ func (ev *evaluator) aggregation(op ItemType, grouping []string, without bool, p
|
||||
// Construct the result Vector from the aggregated groups.
|
||||
for _, aggr := range result {
|
||||
switch op {
|
||||
case ItemAvg:
|
||||
case AVG:
|
||||
aggr.value = aggr.mean
|
||||
|
||||
case ItemCount, ItemCountValues:
|
||||
case COUNT, COUNT_VALUES:
|
||||
aggr.value = float64(aggr.groupCount)
|
||||
|
||||
case ItemStdvar:
|
||||
case STDVAR:
|
||||
aggr.value = aggr.value / float64(aggr.groupCount)
|
||||
|
||||
case ItemStddev:
|
||||
case STDDEV:
|
||||
aggr.value = math.Sqrt(aggr.value / float64(aggr.groupCount))
|
||||
|
||||
case ItemTopK:
|
||||
case TOPK:
|
||||
// The heap keeps the lowest value on top, so reverse it.
|
||||
sort.Sort(sort.Reverse(aggr.heap))
|
||||
for _, v := range aggr.heap {
|
||||
@ -1897,7 +1897,7 @@ func (ev *evaluator) aggregation(op ItemType, grouping []string, without bool, p
|
||||
}
|
||||
continue // Bypass default append.
|
||||
|
||||
case ItemBottomK:
|
||||
case BOTTOMK:
|
||||
// The heap keeps the lowest value on top, so reverse it.
|
||||
sort.Sort(sort.Reverse(aggr.reverseHeap))
|
||||
for _, v := range aggr.reverseHeap {
|
||||
@ -1908,7 +1908,7 @@ func (ev *evaluator) aggregation(op ItemType, grouping []string, without bool, p
|
||||
}
|
||||
continue // Bypass default append.
|
||||
|
||||
case ItemQuantile:
|
||||
case QUANTILE:
|
||||
aggr.value = quantile(q, aggr.heap)
|
||||
|
||||
default:
|
||||
@ -1935,7 +1935,7 @@ func btos(b bool) float64 {
|
||||
// result of the op operation.
|
||||
func shouldDropMetricName(op ItemType) bool {
|
||||
switch op {
|
||||
case ItemADD, ItemSUB, ItemDIV, ItemMUL, ItemPOW, ItemMOD:
|
||||
case ADD, SUB, DIV, MUL, POW, MOD:
|
||||
return true
|
||||
default:
|
||||
return false
|
||||
|
348
promql/lex.go
348
promql/lex.go
@ -30,11 +30,11 @@ type item struct {
|
||||
// String returns a descriptive string for the item.
|
||||
func (i item) String() string {
|
||||
switch {
|
||||
case i.typ == ItemEOF:
|
||||
case i.typ == EOF:
|
||||
return "EOF"
|
||||
case i.typ == ItemError:
|
||||
case i.typ == ERROR:
|
||||
return i.val
|
||||
case i.typ == ItemIdentifier || i.typ == ItemMetricIdentifier:
|
||||
case i.typ == IDENTIFIER || i.typ == METRIC_IDENTIFIER:
|
||||
return fmt.Sprintf("%q", i.val)
|
||||
case i.typ.isKeyword():
|
||||
return fmt.Sprintf("<%s>", i.val)
|
||||
@ -59,7 +59,7 @@ func (i ItemType) isAggregator() bool { return i > aggregatorsStart && i < aggre
|
||||
// isAggregator returns true if the item is an aggregator that takes a parameter.
|
||||
// Returns false otherwise
|
||||
func (i ItemType) isAggregatorWithParam() bool {
|
||||
return i == ItemTopK || i == ItemBottomK || i == ItemCountValues || i == ItemQuantile
|
||||
return i == TOPK || i == BOTTOMK || i == COUNT_VALUES || i == QUANTILE
|
||||
}
|
||||
|
||||
// isKeyword returns true if the item corresponds to a keyword.
|
||||
@ -70,7 +70,7 @@ func (i ItemType) isKeyword() bool { return i > keywordsStart && i < keywordsEnd
|
||||
// Returns false otherwise.
|
||||
func (i ItemType) isComparisonOperator() bool {
|
||||
switch i {
|
||||
case ItemEQL, ItemNEQ, ItemLTE, ItemLSS, ItemGTE, ItemGTR:
|
||||
case EQL, NEQ, LTE, LSS, GTE, GTR:
|
||||
return true
|
||||
default:
|
||||
return false
|
||||
@ -80,7 +80,7 @@ func (i ItemType) isComparisonOperator() bool {
|
||||
// isSetOperator returns whether the item corresponds to a set operator.
|
||||
func (i ItemType) isSetOperator() bool {
|
||||
switch i {
|
||||
case ItemLAND, ItemLOR, ItemLUnless:
|
||||
case LAND, LOR, LUNLESS:
|
||||
return true
|
||||
}
|
||||
return false
|
||||
@ -94,17 +94,17 @@ const LowestPrec = 0 // Non-operators.
|
||||
// is LowestPrec.
|
||||
func (i ItemType) precedence() int {
|
||||
switch i {
|
||||
case ItemLOR:
|
||||
case LOR:
|
||||
return 1
|
||||
case ItemLAND, ItemLUnless:
|
||||
case LAND, LUNLESS:
|
||||
return 2
|
||||
case ItemEQL, ItemNEQ, ItemLTE, ItemLSS, ItemGTE, ItemGTR:
|
||||
case EQL, NEQ, LTE, LSS, GTE, GTR:
|
||||
return 3
|
||||
case ItemADD, ItemSUB:
|
||||
case ADD, SUB:
|
||||
return 4
|
||||
case ItemMUL, ItemDIV, ItemMOD:
|
||||
case MUL, DIV, MOD:
|
||||
return 5
|
||||
case ItemPOW:
|
||||
case POW:
|
||||
return 6
|
||||
default:
|
||||
return LowestPrec
|
||||
@ -113,7 +113,7 @@ func (i ItemType) precedence() int {
|
||||
|
||||
func (i ItemType) isRightAssociative() bool {
|
||||
switch i {
|
||||
case ItemPOW:
|
||||
case POW:
|
||||
return true
|
||||
default:
|
||||
return false
|
||||
@ -124,138 +124,138 @@ func (i ItemType) isRightAssociative() bool {
|
||||
type ItemType int
|
||||
|
||||
const (
|
||||
ItemError ItemType = iota // Error occurred, value is error message
|
||||
ItemEOF
|
||||
ItemComment
|
||||
ItemIdentifier
|
||||
ItemMetricIdentifier
|
||||
ItemLeftParen
|
||||
ItemRightParen
|
||||
ItemLeftBrace
|
||||
ItemRightBrace
|
||||
ItemLeftBracket
|
||||
ItemRightBracket
|
||||
ItemComma
|
||||
ItemAssign
|
||||
ItemColon
|
||||
ItemSemicolon
|
||||
ItemString
|
||||
ItemNumber
|
||||
ItemDuration
|
||||
ItemBlank
|
||||
ItemTimes
|
||||
ItemSpace
|
||||
ERROR ItemType = iota // Error occurred, value is error message
|
||||
EOF
|
||||
COMMENT
|
||||
IDENTIFIER
|
||||
METRIC_IDENTIFIER
|
||||
LEFT_PAREN
|
||||
RIGHT_PAREN
|
||||
LEFT_BRACE
|
||||
RIGHT_BRACE
|
||||
LEFT_BRACKET
|
||||
RIGHT_BRACKET
|
||||
COMMA
|
||||
ASSIGN
|
||||
COLON
|
||||
SEMICOLON
|
||||
STRING
|
||||
NUMBER
|
||||
DURATION
|
||||
BLANK
|
||||
TIMES
|
||||
SPACE
|
||||
|
||||
operatorsStart
|
||||
// Operators.
|
||||
ItemSUB
|
||||
ItemADD
|
||||
ItemMUL
|
||||
ItemMOD
|
||||
ItemDIV
|
||||
ItemLAND
|
||||
ItemLOR
|
||||
ItemLUnless
|
||||
ItemEQL
|
||||
ItemNEQ
|
||||
ItemLTE
|
||||
ItemLSS
|
||||
ItemGTE
|
||||
ItemGTR
|
||||
ItemEQLRegex
|
||||
ItemNEQRegex
|
||||
ItemPOW
|
||||
SUB
|
||||
ADD
|
||||
MUL
|
||||
MOD
|
||||
DIV
|
||||
LAND
|
||||
LOR
|
||||
LUNLESS
|
||||
EQL
|
||||
NEQ
|
||||
LTE
|
||||
LSS
|
||||
GTE
|
||||
GTR
|
||||
EQL_REGEX
|
||||
NEQ_REGEX
|
||||
POW
|
||||
operatorsEnd
|
||||
|
||||
aggregatorsStart
|
||||
// Aggregators.
|
||||
ItemAvg
|
||||
ItemCount
|
||||
ItemSum
|
||||
ItemMin
|
||||
ItemMax
|
||||
ItemStddev
|
||||
ItemStdvar
|
||||
ItemTopK
|
||||
ItemBottomK
|
||||
ItemCountValues
|
||||
ItemQuantile
|
||||
AVG
|
||||
COUNT
|
||||
SUM
|
||||
MIN
|
||||
MAX
|
||||
STDDEV
|
||||
STDVAR
|
||||
TOPK
|
||||
BOTTOMK
|
||||
COUNT_VALUES
|
||||
QUANTILE
|
||||
aggregatorsEnd
|
||||
|
||||
keywordsStart
|
||||
// Keywords.
|
||||
ItemOffset
|
||||
ItemBy
|
||||
ItemWithout
|
||||
ItemOn
|
||||
ItemIgnoring
|
||||
ItemGroupLeft
|
||||
ItemGroupRight
|
||||
ItemBool
|
||||
OFFSET
|
||||
BY
|
||||
WITHOUT
|
||||
ON
|
||||
IGNORING
|
||||
GROUP_LEFT
|
||||
GROUP_RIGHT
|
||||
BOOL
|
||||
keywordsEnd
|
||||
)
|
||||
|
||||
var key = map[string]ItemType{
|
||||
// Operators.
|
||||
"and": ItemLAND,
|
||||
"or": ItemLOR,
|
||||
"unless": ItemLUnless,
|
||||
"and": LAND,
|
||||
"or": LOR,
|
||||
"unless": LUNLESS,
|
||||
|
||||
// Aggregators.
|
||||
"sum": ItemSum,
|
||||
"avg": ItemAvg,
|
||||
"count": ItemCount,
|
||||
"min": ItemMin,
|
||||
"max": ItemMax,
|
||||
"stddev": ItemStddev,
|
||||
"stdvar": ItemStdvar,
|
||||
"topk": ItemTopK,
|
||||
"bottomk": ItemBottomK,
|
||||
"count_values": ItemCountValues,
|
||||
"quantile": ItemQuantile,
|
||||
"sum": SUM,
|
||||
"avg": AVG,
|
||||
"count": COUNT,
|
||||
"min": MIN,
|
||||
"max": MAX,
|
||||
"stddev": STDDEV,
|
||||
"stdvar": STDVAR,
|
||||
"topk": TOPK,
|
||||
"bottomk": BOTTOMK,
|
||||
"count_values": COUNT_VALUES,
|
||||
"quantile": QUANTILE,
|
||||
|
||||
// Keywords.
|
||||
"offset": ItemOffset,
|
||||
"by": ItemBy,
|
||||
"without": ItemWithout,
|
||||
"on": ItemOn,
|
||||
"ignoring": ItemIgnoring,
|
||||
"group_left": ItemGroupLeft,
|
||||
"group_right": ItemGroupRight,
|
||||
"bool": ItemBool,
|
||||
"offset": OFFSET,
|
||||
"by": BY,
|
||||
"without": WITHOUT,
|
||||
"on": ON,
|
||||
"ignoring": IGNORING,
|
||||
"group_left": GROUP_LEFT,
|
||||
"group_right": GROUP_RIGHT,
|
||||
"bool": BOOL,
|
||||
}
|
||||
|
||||
// These are the default string representations for common items. It does not
|
||||
// imply that those are the only character sequences that can be lexed to such an item.
|
||||
var itemTypeStr = map[ItemType]string{
|
||||
ItemLeftParen: "(",
|
||||
ItemRightParen: ")",
|
||||
ItemLeftBrace: "{",
|
||||
ItemRightBrace: "}",
|
||||
ItemLeftBracket: "[",
|
||||
ItemRightBracket: "]",
|
||||
ItemComma: ",",
|
||||
ItemAssign: "=",
|
||||
ItemColon: ":",
|
||||
ItemSemicolon: ";",
|
||||
ItemBlank: "_",
|
||||
ItemTimes: "x",
|
||||
ItemSpace: "<space>",
|
||||
LEFT_PAREN: "(",
|
||||
RIGHT_PAREN: ")",
|
||||
LEFT_BRACE: "{",
|
||||
RIGHT_BRACE: "}",
|
||||
LEFT_BRACKET: "[",
|
||||
RIGHT_BRACKET: "]",
|
||||
COMMA: ",",
|
||||
ASSIGN: "=",
|
||||
COLON: ":",
|
||||
SEMICOLON: ";",
|
||||
BLANK: "_",
|
||||
TIMES: "x",
|
||||
SPACE: "<space>",
|
||||
|
||||
ItemSUB: "-",
|
||||
ItemADD: "+",
|
||||
ItemMUL: "*",
|
||||
ItemMOD: "%",
|
||||
ItemDIV: "/",
|
||||
ItemEQL: "==",
|
||||
ItemNEQ: "!=",
|
||||
ItemLTE: "<=",
|
||||
ItemLSS: "<",
|
||||
ItemGTE: ">=",
|
||||
ItemGTR: ">",
|
||||
ItemEQLRegex: "=~",
|
||||
ItemNEQRegex: "!~",
|
||||
ItemPOW: "^",
|
||||
SUB: "-",
|
||||
ADD: "+",
|
||||
MUL: "*",
|
||||
MOD: "%",
|
||||
DIV: "/",
|
||||
EQL: "==",
|
||||
NEQ: "!=",
|
||||
LTE: "<=",
|
||||
LSS: "<",
|
||||
GTE: ">=",
|
||||
GTR: ">",
|
||||
EQL_REGEX: "=~",
|
||||
NEQ_REGEX: "!~",
|
||||
POW: "^",
|
||||
}
|
||||
|
||||
func init() {
|
||||
@ -264,8 +264,8 @@ func init() {
|
||||
itemTypeStr[ty] = s
|
||||
}
|
||||
// Special numbers.
|
||||
key["inf"] = ItemNumber
|
||||
key["nan"] = ItemNumber
|
||||
key["inf"] = NUMBER
|
||||
key["nan"] = NUMBER
|
||||
}
|
||||
|
||||
func (i ItemType) String() string {
|
||||
@ -279,7 +279,7 @@ func (i item) desc() string {
|
||||
if _, ok := itemTypeStr[i.typ]; ok {
|
||||
return i.String()
|
||||
}
|
||||
if i.typ == ItemEOF {
|
||||
if i.typ == EOF {
|
||||
return i.typ.desc()
|
||||
}
|
||||
return fmt.Sprintf("%s %s", i.typ.desc(), i)
|
||||
@ -287,21 +287,21 @@ func (i item) desc() string {
|
||||
|
||||
func (i ItemType) desc() string {
|
||||
switch i {
|
||||
case ItemError:
|
||||
case ERROR:
|
||||
return "error"
|
||||
case ItemEOF:
|
||||
case EOF:
|
||||
return "end of input"
|
||||
case ItemComment:
|
||||
case COMMENT:
|
||||
return "comment"
|
||||
case ItemIdentifier:
|
||||
case IDENTIFIER:
|
||||
return "identifier"
|
||||
case ItemMetricIdentifier:
|
||||
case METRIC_IDENTIFIER:
|
||||
return "metric identifier"
|
||||
case ItemString:
|
||||
case STRING:
|
||||
return "string"
|
||||
case ItemNumber:
|
||||
case NUMBER:
|
||||
return "number"
|
||||
case ItemDuration:
|
||||
case DURATION:
|
||||
return "duration"
|
||||
}
|
||||
return fmt.Sprintf("%q", i)
|
||||
@ -408,7 +408,7 @@ func (l *lexer) linePosition() int {
|
||||
// errorf returns an error token and terminates the scan by passing
|
||||
// back a nil pointer that will be the next state, terminating l.nextItem.
|
||||
func (l *lexer) errorf(format string, args ...interface{}) stateFn {
|
||||
l.items = append(l.items, item{ItemError, l.start, fmt.Sprintf(format, args...)})
|
||||
l.items = append(l.items, item{ERROR, l.start, fmt.Sprintf(format, args...)})
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -418,7 +418,7 @@ func (l *lexer) nextItem() item {
|
||||
if l.state != nil {
|
||||
l.state = l.state(l)
|
||||
} else {
|
||||
l.emit(ItemEOF)
|
||||
l.emit(EOF)
|
||||
}
|
||||
}
|
||||
item := l.items[0]
|
||||
@ -469,52 +469,52 @@ func lexStatements(l *lexer) stateFn {
|
||||
} else if l.bracketOpen {
|
||||
return l.errorf("unclosed left bracket")
|
||||
}
|
||||
l.emit(ItemEOF)
|
||||
l.emit(EOF)
|
||||
return nil
|
||||
case r == ',':
|
||||
l.emit(ItemComma)
|
||||
l.emit(COMMA)
|
||||
case isSpace(r):
|
||||
return lexSpace
|
||||
case r == '*':
|
||||
l.emit(ItemMUL)
|
||||
l.emit(MUL)
|
||||
case r == '/':
|
||||
l.emit(ItemDIV)
|
||||
l.emit(DIV)
|
||||
case r == '%':
|
||||
l.emit(ItemMOD)
|
||||
l.emit(MOD)
|
||||
case r == '+':
|
||||
l.emit(ItemADD)
|
||||
l.emit(ADD)
|
||||
case r == '-':
|
||||
l.emit(ItemSUB)
|
||||
l.emit(SUB)
|
||||
case r == '^':
|
||||
l.emit(ItemPOW)
|
||||
l.emit(POW)
|
||||
case r == '=':
|
||||
if t := l.peek(); t == '=' {
|
||||
l.next()
|
||||
l.emit(ItemEQL)
|
||||
l.emit(EQL)
|
||||
} else if t == '~' {
|
||||
return l.errorf("unexpected character after '=': %q", t)
|
||||
} else {
|
||||
l.emit(ItemAssign)
|
||||
l.emit(ASSIGN)
|
||||
}
|
||||
case r == '!':
|
||||
if t := l.next(); t == '=' {
|
||||
l.emit(ItemNEQ)
|
||||
l.emit(NEQ)
|
||||
} else {
|
||||
return l.errorf("unexpected character after '!': %q", t)
|
||||
}
|
||||
case r == '<':
|
||||
if t := l.peek(); t == '=' {
|
||||
l.next()
|
||||
l.emit(ItemLTE)
|
||||
l.emit(LTE)
|
||||
} else {
|
||||
l.emit(ItemLSS)
|
||||
l.emit(LSS)
|
||||
}
|
||||
case r == '>':
|
||||
if t := l.peek(); t == '=' {
|
||||
l.next()
|
||||
l.emit(ItemGTE)
|
||||
l.emit(GTE)
|
||||
} else {
|
||||
l.emit(ItemGTR)
|
||||
l.emit(GTR)
|
||||
}
|
||||
case isDigit(r) || (r == '.' && isDigit(l.peek())):
|
||||
l.backup()
|
||||
@ -533,21 +533,21 @@ func lexStatements(l *lexer) stateFn {
|
||||
if l.gotColon {
|
||||
return l.errorf("unexpected colon %q", r)
|
||||
}
|
||||
l.emit(ItemColon)
|
||||
l.emit(COLON)
|
||||
l.gotColon = true
|
||||
case r == '(':
|
||||
l.emit(ItemLeftParen)
|
||||
l.emit(LEFT_PAREN)
|
||||
l.parenDepth++
|
||||
return lexStatements
|
||||
case r == ')':
|
||||
l.emit(ItemRightParen)
|
||||
l.emit(RIGHT_PAREN)
|
||||
l.parenDepth--
|
||||
if l.parenDepth < 0 {
|
||||
return l.errorf("unexpected right parenthesis %q", r)
|
||||
}
|
||||
return lexStatements
|
||||
case r == '{':
|
||||
l.emit(ItemLeftBrace)
|
||||
l.emit(LEFT_BRACE)
|
||||
l.braceOpen = true
|
||||
return lexInsideBraces(l)
|
||||
case r == '[':
|
||||
@ -555,7 +555,7 @@ func lexStatements(l *lexer) stateFn {
|
||||
return l.errorf("unexpected left bracket %q", r)
|
||||
}
|
||||
l.gotColon = false
|
||||
l.emit(ItemLeftBracket)
|
||||
l.emit(LEFT_BRACKET)
|
||||
if isSpace(l.peek()) {
|
||||
skipSpaces(l)
|
||||
}
|
||||
@ -565,7 +565,7 @@ func lexStatements(l *lexer) stateFn {
|
||||
if !l.bracketOpen {
|
||||
return l.errorf("unexpected right bracket %q", r)
|
||||
}
|
||||
l.emit(ItemRightBracket)
|
||||
l.emit(RIGHT_BRACKET)
|
||||
l.bracketOpen = false
|
||||
|
||||
default:
|
||||
@ -590,7 +590,7 @@ func lexInsideBraces(l *lexer) stateFn {
|
||||
l.backup()
|
||||
return lexIdentifier
|
||||
case r == ',':
|
||||
l.emit(ItemComma)
|
||||
l.emit(COMMA)
|
||||
case r == '"' || r == '\'':
|
||||
l.stringOpen = r
|
||||
return lexString
|
||||
@ -599,24 +599,24 @@ func lexInsideBraces(l *lexer) stateFn {
|
||||
return lexRawString
|
||||
case r == '=':
|
||||
if l.next() == '~' {
|
||||
l.emit(ItemEQLRegex)
|
||||
l.emit(EQL_REGEX)
|
||||
break
|
||||
}
|
||||
l.backup()
|
||||
l.emit(ItemEQL)
|
||||
l.emit(EQL)
|
||||
case r == '!':
|
||||
switch nr := l.next(); {
|
||||
case nr == '~':
|
||||
l.emit(ItemNEQRegex)
|
||||
l.emit(NEQ_REGEX)
|
||||
case nr == '=':
|
||||
l.emit(ItemNEQ)
|
||||
l.emit(NEQ)
|
||||
default:
|
||||
return l.errorf("unexpected character after '!' inside braces: %q", nr)
|
||||
}
|
||||
case r == '{':
|
||||
return l.errorf("unexpected left brace %q", r)
|
||||
case r == '}':
|
||||
l.emit(ItemRightBrace)
|
||||
l.emit(RIGHT_BRACE)
|
||||
l.braceOpen = false
|
||||
|
||||
if l.seriesDesc {
|
||||
@ -635,16 +635,16 @@ func lexValueSequence(l *lexer) stateFn {
|
||||
case r == eof:
|
||||
return lexStatements
|
||||
case isSpace(r):
|
||||
l.emit(ItemSpace)
|
||||
l.emit(SPACE)
|
||||
lexSpace(l)
|
||||
case r == '+':
|
||||
l.emit(ItemADD)
|
||||
l.emit(ADD)
|
||||
case r == '-':
|
||||
l.emit(ItemSUB)
|
||||
l.emit(SUB)
|
||||
case r == 'x':
|
||||
l.emit(ItemTimes)
|
||||
l.emit(TIMES)
|
||||
case r == '_':
|
||||
l.emit(ItemBlank)
|
||||
l.emit(BLANK)
|
||||
case isDigit(r) || (r == '.' && isDigit(l.peek())):
|
||||
l.backup()
|
||||
lexNumber(l)
|
||||
@ -747,7 +747,7 @@ Loop:
|
||||
break Loop
|
||||
}
|
||||
}
|
||||
l.emit(ItemString)
|
||||
l.emit(STRING)
|
||||
return lexStatements
|
||||
}
|
||||
|
||||
@ -764,7 +764,7 @@ Loop:
|
||||
break Loop
|
||||
}
|
||||
}
|
||||
l.emit(ItemString)
|
||||
l.emit(STRING)
|
||||
return lexStatements
|
||||
}
|
||||
|
||||
@ -784,7 +784,7 @@ func lexLineComment(l *lexer) stateFn {
|
||||
r = l.next()
|
||||
}
|
||||
l.backup()
|
||||
l.emit(ItemComment)
|
||||
l.emit(COMMENT)
|
||||
return lexStatements
|
||||
}
|
||||
|
||||
@ -798,7 +798,7 @@ func lexDuration(l *lexer) stateFn {
|
||||
return l.errorf("bad duration syntax: %q", l.input[l.start:l.pos])
|
||||
}
|
||||
l.backup()
|
||||
l.emit(ItemDuration)
|
||||
l.emit(DURATION)
|
||||
return lexStatements
|
||||
}
|
||||
return l.errorf("bad duration syntax: %q", l.input[l.start:l.pos])
|
||||
@ -809,14 +809,14 @@ func lexNumber(l *lexer) stateFn {
|
||||
if !l.scanNumber() {
|
||||
return l.errorf("bad number syntax: %q", l.input[l.start:l.pos])
|
||||
}
|
||||
l.emit(ItemNumber)
|
||||
l.emit(NUMBER)
|
||||
return lexStatements
|
||||
}
|
||||
|
||||
// lexNumberOrDuration scans a number or a duration item.
|
||||
func lexNumberOrDuration(l *lexer) stateFn {
|
||||
if l.scanNumber() {
|
||||
l.emit(ItemNumber)
|
||||
l.emit(NUMBER)
|
||||
return lexStatements
|
||||
}
|
||||
// Next two chars must be a valid unit and a non-alphanumeric.
|
||||
@ -825,7 +825,7 @@ func lexNumberOrDuration(l *lexer) stateFn {
|
||||
return l.errorf("bad number or duration syntax: %q", l.input[l.start:l.pos])
|
||||
}
|
||||
l.backup()
|
||||
l.emit(ItemDuration)
|
||||
l.emit(DURATION)
|
||||
return lexStatements
|
||||
}
|
||||
return l.errorf("bad number or duration syntax: %q", l.input[l.start:l.pos])
|
||||
@ -862,7 +862,7 @@ func lexIdentifier(l *lexer) stateFn {
|
||||
// absorb
|
||||
}
|
||||
l.backup()
|
||||
l.emit(ItemIdentifier)
|
||||
l.emit(IDENTIFIER)
|
||||
return lexStatements
|
||||
}
|
||||
|
||||
@ -881,9 +881,9 @@ Loop:
|
||||
if kw, ok := key[strings.ToLower(word)]; ok {
|
||||
l.emit(kw)
|
||||
} else if !strings.Contains(word, ":") {
|
||||
l.emit(ItemIdentifier)
|
||||
l.emit(IDENTIFIER)
|
||||
} else {
|
||||
l.emit(ItemMetricIdentifier)
|
||||
l.emit(METRIC_IDENTIFIER)
|
||||
}
|
||||
break Loop
|
||||
}
|
||||
|
@ -35,40 +35,40 @@ var tests = []struct {
|
||||
tests: []testCase{
|
||||
{
|
||||
input: ",",
|
||||
expected: []item{{ItemComma, 0, ","}},
|
||||
expected: []item{{COMMA, 0, ","}},
|
||||
}, {
|
||||
input: "()",
|
||||
expected: []item{{ItemLeftParen, 0, `(`}, {ItemRightParen, 1, `)`}},
|
||||
expected: []item{{LEFT_PAREN, 0, `(`}, {RIGHT_PAREN, 1, `)`}},
|
||||
}, {
|
||||
input: "{}",
|
||||
expected: []item{{ItemLeftBrace, 0, `{`}, {ItemRightBrace, 1, `}`}},
|
||||
expected: []item{{LEFT_BRACE, 0, `{`}, {RIGHT_BRACE, 1, `}`}},
|
||||
}, {
|
||||
input: "[5m]",
|
||||
expected: []item{
|
||||
{ItemLeftBracket, 0, `[`},
|
||||
{ItemDuration, 1, `5m`},
|
||||
{ItemRightBracket, 3, `]`},
|
||||
{LEFT_BRACKET, 0, `[`},
|
||||
{DURATION, 1, `5m`},
|
||||
{RIGHT_BRACKET, 3, `]`},
|
||||
},
|
||||
}, {
|
||||
input: "[ 5m]",
|
||||
expected: []item{
|
||||
{ItemLeftBracket, 0, `[`},
|
||||
{ItemDuration, 2, `5m`},
|
||||
{ItemRightBracket, 4, `]`},
|
||||
{LEFT_BRACKET, 0, `[`},
|
||||
{DURATION, 2, `5m`},
|
||||
{RIGHT_BRACKET, 4, `]`},
|
||||
},
|
||||
}, {
|
||||
input: "[ 5m]",
|
||||
expected: []item{
|
||||
{ItemLeftBracket, 0, `[`},
|
||||
{ItemDuration, 3, `5m`},
|
||||
{ItemRightBracket, 5, `]`},
|
||||
{LEFT_BRACKET, 0, `[`},
|
||||
{DURATION, 3, `5m`},
|
||||
{RIGHT_BRACKET, 5, `]`},
|
||||
},
|
||||
}, {
|
||||
input: "[ 5m ]",
|
||||
expected: []item{
|
||||
{ItemLeftBracket, 0, `[`},
|
||||
{ItemDuration, 3, `5m`},
|
||||
{ItemRightBracket, 6, `]`},
|
||||
{LEFT_BRACKET, 0, `[`},
|
||||
{DURATION, 3, `5m`},
|
||||
{RIGHT_BRACKET, 6, `]`},
|
||||
},
|
||||
}, {
|
||||
input: "\r\n\r",
|
||||
@ -81,55 +81,55 @@ var tests = []struct {
|
||||
tests: []testCase{
|
||||
{
|
||||
input: "1",
|
||||
expected: []item{{ItemNumber, 0, "1"}},
|
||||
expected: []item{{NUMBER, 0, "1"}},
|
||||
}, {
|
||||
input: "4.23",
|
||||
expected: []item{{ItemNumber, 0, "4.23"}},
|
||||
expected: []item{{NUMBER, 0, "4.23"}},
|
||||
}, {
|
||||
input: ".3",
|
||||
expected: []item{{ItemNumber, 0, ".3"}},
|
||||
expected: []item{{NUMBER, 0, ".3"}},
|
||||
}, {
|
||||
input: "5.",
|
||||
expected: []item{{ItemNumber, 0, "5."}},
|
||||
expected: []item{{NUMBER, 0, "5."}},
|
||||
}, {
|
||||
input: "NaN",
|
||||
expected: []item{{ItemNumber, 0, "NaN"}},
|
||||
expected: []item{{NUMBER, 0, "NaN"}},
|
||||
}, {
|
||||
input: "nAN",
|
||||
expected: []item{{ItemNumber, 0, "nAN"}},
|
||||
expected: []item{{NUMBER, 0, "nAN"}},
|
||||
}, {
|
||||
input: "NaN 123",
|
||||
expected: []item{{ItemNumber, 0, "NaN"}, {ItemNumber, 4, "123"}},
|
||||
expected: []item{{NUMBER, 0, "NaN"}, {NUMBER, 4, "123"}},
|
||||
}, {
|
||||
input: "NaN123",
|
||||
expected: []item{{ItemIdentifier, 0, "NaN123"}},
|
||||
expected: []item{{IDENTIFIER, 0, "NaN123"}},
|
||||
}, {
|
||||
input: "iNf",
|
||||
expected: []item{{ItemNumber, 0, "iNf"}},
|
||||
expected: []item{{NUMBER, 0, "iNf"}},
|
||||
}, {
|
||||
input: "Inf",
|
||||
expected: []item{{ItemNumber, 0, "Inf"}},
|
||||
expected: []item{{NUMBER, 0, "Inf"}},
|
||||
}, {
|
||||
input: "+Inf",
|
||||
expected: []item{{ItemADD, 0, "+"}, {ItemNumber, 1, "Inf"}},
|
||||
expected: []item{{ADD, 0, "+"}, {NUMBER, 1, "Inf"}},
|
||||
}, {
|
||||
input: "+Inf 123",
|
||||
expected: []item{{ItemADD, 0, "+"}, {ItemNumber, 1, "Inf"}, {ItemNumber, 5, "123"}},
|
||||
expected: []item{{ADD, 0, "+"}, {NUMBER, 1, "Inf"}, {NUMBER, 5, "123"}},
|
||||
}, {
|
||||
input: "-Inf",
|
||||
expected: []item{{ItemSUB, 0, "-"}, {ItemNumber, 1, "Inf"}},
|
||||
expected: []item{{SUB, 0, "-"}, {NUMBER, 1, "Inf"}},
|
||||
}, {
|
||||
input: "Infoo",
|
||||
expected: []item{{ItemIdentifier, 0, "Infoo"}},
|
||||
expected: []item{{IDENTIFIER, 0, "Infoo"}},
|
||||
}, {
|
||||
input: "-Infoo",
|
||||
expected: []item{{ItemSUB, 0, "-"}, {ItemIdentifier, 1, "Infoo"}},
|
||||
expected: []item{{SUB, 0, "-"}, {IDENTIFIER, 1, "Infoo"}},
|
||||
}, {
|
||||
input: "-Inf 123",
|
||||
expected: []item{{ItemSUB, 0, "-"}, {ItemNumber, 1, "Inf"}, {ItemNumber, 5, "123"}},
|
||||
expected: []item{{SUB, 0, "-"}, {NUMBER, 1, "Inf"}, {NUMBER, 5, "123"}},
|
||||
}, {
|
||||
input: "0x123",
|
||||
expected: []item{{ItemNumber, 0, "0x123"}},
|
||||
expected: []item{{NUMBER, 0, "0x123"}},
|
||||
},
|
||||
},
|
||||
},
|
||||
@ -138,22 +138,22 @@ var tests = []struct {
|
||||
tests: []testCase{
|
||||
{
|
||||
input: "\"test\\tsequence\"",
|
||||
expected: []item{{ItemString, 0, `"test\tsequence"`}},
|
||||
expected: []item{{STRING, 0, `"test\tsequence"`}},
|
||||
},
|
||||
{
|
||||
input: "\"test\\\\.expression\"",
|
||||
expected: []item{{ItemString, 0, `"test\\.expression"`}},
|
||||
expected: []item{{STRING, 0, `"test\\.expression"`}},
|
||||
},
|
||||
{
|
||||
input: "\"test\\.expression\"",
|
||||
expected: []item{
|
||||
{ItemError, 0, "unknown escape sequence U+002E '.'"},
|
||||
{ItemString, 0, `"test\.expression"`},
|
||||
{ERROR, 0, "unknown escape sequence U+002E '.'"},
|
||||
{STRING, 0, `"test\.expression"`},
|
||||
},
|
||||
},
|
||||
{
|
||||
input: "`test\\.expression`",
|
||||
expected: []item{{ItemString, 0, "`test\\.expression`"}},
|
||||
expected: []item{{STRING, 0, "`test\\.expression`"}},
|
||||
},
|
||||
{
|
||||
// See https://github.com/prometheus/prometheus/issues/939.
|
||||
@ -167,19 +167,19 @@ var tests = []struct {
|
||||
tests: []testCase{
|
||||
{
|
||||
input: "5s",
|
||||
expected: []item{{ItemDuration, 0, "5s"}},
|
||||
expected: []item{{DURATION, 0, "5s"}},
|
||||
}, {
|
||||
input: "123m",
|
||||
expected: []item{{ItemDuration, 0, "123m"}},
|
||||
expected: []item{{DURATION, 0, "123m"}},
|
||||
}, {
|
||||
input: "1h",
|
||||
expected: []item{{ItemDuration, 0, "1h"}},
|
||||
expected: []item{{DURATION, 0, "1h"}},
|
||||
}, {
|
||||
input: "3w",
|
||||
expected: []item{{ItemDuration, 0, "3w"}},
|
||||
expected: []item{{DURATION, 0, "3w"}},
|
||||
}, {
|
||||
input: "1y",
|
||||
expected: []item{{ItemDuration, 0, "1y"}},
|
||||
expected: []item{{DURATION, 0, "1y"}},
|
||||
},
|
||||
},
|
||||
},
|
||||
@ -188,16 +188,16 @@ var tests = []struct {
|
||||
tests: []testCase{
|
||||
{
|
||||
input: "abc",
|
||||
expected: []item{{ItemIdentifier, 0, "abc"}},
|
||||
expected: []item{{IDENTIFIER, 0, "abc"}},
|
||||
}, {
|
||||
input: "a:bc",
|
||||
expected: []item{{ItemMetricIdentifier, 0, "a:bc"}},
|
||||
expected: []item{{METRIC_IDENTIFIER, 0, "a:bc"}},
|
||||
}, {
|
||||
input: "abc d",
|
||||
expected: []item{{ItemIdentifier, 0, "abc"}, {ItemIdentifier, 4, "d"}},
|
||||
expected: []item{{IDENTIFIER, 0, "abc"}, {IDENTIFIER, 4, "d"}},
|
||||
}, {
|
||||
input: ":bc",
|
||||
expected: []item{{ItemMetricIdentifier, 0, ":bc"}},
|
||||
expected: []item{{METRIC_IDENTIFIER, 0, ":bc"}},
|
||||
}, {
|
||||
input: "0a:bc",
|
||||
fail: true,
|
||||
@ -209,13 +209,13 @@ var tests = []struct {
|
||||
tests: []testCase{
|
||||
{
|
||||
input: "# some comment",
|
||||
expected: []item{{ItemComment, 0, "# some comment"}},
|
||||
expected: []item{{COMMENT, 0, "# some comment"}},
|
||||
}, {
|
||||
input: "5 # 1+1\n5",
|
||||
expected: []item{
|
||||
{ItemNumber, 0, "5"},
|
||||
{ItemComment, 2, "# 1+1"},
|
||||
{ItemNumber, 8, "5"},
|
||||
{NUMBER, 0, "5"},
|
||||
{COMMENT, 2, "# 1+1"},
|
||||
{NUMBER, 8, "5"},
|
||||
},
|
||||
},
|
||||
},
|
||||
@ -225,56 +225,56 @@ var tests = []struct {
|
||||
tests: []testCase{
|
||||
{
|
||||
input: `=`,
|
||||
expected: []item{{ItemAssign, 0, `=`}},
|
||||
expected: []item{{ASSIGN, 0, `=`}},
|
||||
}, {
|
||||
// Inside braces equality is a single '=' character.
|
||||
input: `{=}`,
|
||||
expected: []item{{ItemLeftBrace, 0, `{`}, {ItemEQL, 1, `=`}, {ItemRightBrace, 2, `}`}},
|
||||
expected: []item{{LEFT_BRACE, 0, `{`}, {EQL, 1, `=`}, {RIGHT_BRACE, 2, `}`}},
|
||||
}, {
|
||||
input: `==`,
|
||||
expected: []item{{ItemEQL, 0, `==`}},
|
||||
expected: []item{{EQL, 0, `==`}},
|
||||
}, {
|
||||
input: `!=`,
|
||||
expected: []item{{ItemNEQ, 0, `!=`}},
|
||||
expected: []item{{NEQ, 0, `!=`}},
|
||||
}, {
|
||||
input: `<`,
|
||||
expected: []item{{ItemLSS, 0, `<`}},
|
||||
expected: []item{{LSS, 0, `<`}},
|
||||
}, {
|
||||
input: `>`,
|
||||
expected: []item{{ItemGTR, 0, `>`}},
|
||||
expected: []item{{GTR, 0, `>`}},
|
||||
}, {
|
||||
input: `>=`,
|
||||
expected: []item{{ItemGTE, 0, `>=`}},
|
||||
expected: []item{{GTE, 0, `>=`}},
|
||||
}, {
|
||||
input: `<=`,
|
||||
expected: []item{{ItemLTE, 0, `<=`}},
|
||||
expected: []item{{LTE, 0, `<=`}},
|
||||
}, {
|
||||
input: `+`,
|
||||
expected: []item{{ItemADD, 0, `+`}},
|
||||
expected: []item{{ADD, 0, `+`}},
|
||||
}, {
|
||||
input: `-`,
|
||||
expected: []item{{ItemSUB, 0, `-`}},
|
||||
expected: []item{{SUB, 0, `-`}},
|
||||
}, {
|
||||
input: `*`,
|
||||
expected: []item{{ItemMUL, 0, `*`}},
|
||||
expected: []item{{MUL, 0, `*`}},
|
||||
}, {
|
||||
input: `/`,
|
||||
expected: []item{{ItemDIV, 0, `/`}},
|
||||
expected: []item{{DIV, 0, `/`}},
|
||||
}, {
|
||||
input: `^`,
|
||||
expected: []item{{ItemPOW, 0, `^`}},
|
||||
expected: []item{{POW, 0, `^`}},
|
||||
}, {
|
||||
input: `%`,
|
||||
expected: []item{{ItemMOD, 0, `%`}},
|
||||
expected: []item{{MOD, 0, `%`}},
|
||||
}, {
|
||||
input: `AND`,
|
||||
expected: []item{{ItemLAND, 0, `AND`}},
|
||||
expected: []item{{LAND, 0, `AND`}},
|
||||
}, {
|
||||
input: `or`,
|
||||
expected: []item{{ItemLOR, 0, `or`}},
|
||||
expected: []item{{LOR, 0, `or`}},
|
||||
}, {
|
||||
input: `unless`,
|
||||
expected: []item{{ItemLUnless, 0, `unless`}},
|
||||
expected: []item{{LUNLESS, 0, `unless`}},
|
||||
},
|
||||
},
|
||||
},
|
||||
@ -283,25 +283,25 @@ var tests = []struct {
|
||||
tests: []testCase{
|
||||
{
|
||||
input: `sum`,
|
||||
expected: []item{{ItemSum, 0, `sum`}},
|
||||
expected: []item{{SUM, 0, `sum`}},
|
||||
}, {
|
||||
input: `AVG`,
|
||||
expected: []item{{ItemAvg, 0, `AVG`}},
|
||||
expected: []item{{AVG, 0, `AVG`}},
|
||||
}, {
|
||||
input: `MAX`,
|
||||
expected: []item{{ItemMax, 0, `MAX`}},
|
||||
expected: []item{{MAX, 0, `MAX`}},
|
||||
}, {
|
||||
input: `min`,
|
||||
expected: []item{{ItemMin, 0, `min`}},
|
||||
expected: []item{{MIN, 0, `min`}},
|
||||
}, {
|
||||
input: `count`,
|
||||
expected: []item{{ItemCount, 0, `count`}},
|
||||
expected: []item{{COUNT, 0, `count`}},
|
||||
}, {
|
||||
input: `stdvar`,
|
||||
expected: []item{{ItemStdvar, 0, `stdvar`}},
|
||||
expected: []item{{STDVAR, 0, `stdvar`}},
|
||||
}, {
|
||||
input: `stddev`,
|
||||
expected: []item{{ItemStddev, 0, `stddev`}},
|
||||
expected: []item{{STDDEV, 0, `stddev`}},
|
||||
},
|
||||
},
|
||||
},
|
||||
@ -310,28 +310,28 @@ var tests = []struct {
|
||||
tests: []testCase{
|
||||
{
|
||||
input: "offset",
|
||||
expected: []item{{ItemOffset, 0, "offset"}},
|
||||
expected: []item{{OFFSET, 0, "offset"}},
|
||||
}, {
|
||||
input: "by",
|
||||
expected: []item{{ItemBy, 0, "by"}},
|
||||
expected: []item{{BY, 0, "by"}},
|
||||
}, {
|
||||
input: "without",
|
||||
expected: []item{{ItemWithout, 0, "without"}},
|
||||
expected: []item{{WITHOUT, 0, "without"}},
|
||||
}, {
|
||||
input: "on",
|
||||
expected: []item{{ItemOn, 0, "on"}},
|
||||
expected: []item{{ON, 0, "on"}},
|
||||
}, {
|
||||
input: "ignoring",
|
||||
expected: []item{{ItemIgnoring, 0, "ignoring"}},
|
||||
expected: []item{{IGNORING, 0, "ignoring"}},
|
||||
}, {
|
||||
input: "group_left",
|
||||
expected: []item{{ItemGroupLeft, 0, "group_left"}},
|
||||
expected: []item{{GROUP_LEFT, 0, "group_left"}},
|
||||
}, {
|
||||
input: "group_right",
|
||||
expected: []item{{ItemGroupRight, 0, "group_right"}},
|
||||
expected: []item{{GROUP_RIGHT, 0, "group_right"}},
|
||||
}, {
|
||||
input: "bool",
|
||||
expected: []item{{ItemBool, 0, "bool"}},
|
||||
expected: []item{{BOOL, 0, "bool"}},
|
||||
},
|
||||
},
|
||||
},
|
||||
@ -350,56 +350,56 @@ var tests = []struct {
|
||||
}, {
|
||||
input: `{foo='bar'}`,
|
||||
expected: []item{
|
||||
{ItemLeftBrace, 0, `{`},
|
||||
{ItemIdentifier, 1, `foo`},
|
||||
{ItemEQL, 4, `=`},
|
||||
{ItemString, 5, `'bar'`},
|
||||
{ItemRightBrace, 10, `}`},
|
||||
{LEFT_BRACE, 0, `{`},
|
||||
{IDENTIFIER, 1, `foo`},
|
||||
{EQL, 4, `=`},
|
||||
{STRING, 5, `'bar'`},
|
||||
{RIGHT_BRACE, 10, `}`},
|
||||
},
|
||||
}, {
|
||||
input: `{foo="bar"}`,
|
||||
expected: []item{
|
||||
{ItemLeftBrace, 0, `{`},
|
||||
{ItemIdentifier, 1, `foo`},
|
||||
{ItemEQL, 4, `=`},
|
||||
{ItemString, 5, `"bar"`},
|
||||
{ItemRightBrace, 10, `}`},
|
||||
{LEFT_BRACE, 0, `{`},
|
||||
{IDENTIFIER, 1, `foo`},
|
||||
{EQL, 4, `=`},
|
||||
{STRING, 5, `"bar"`},
|
||||
{RIGHT_BRACE, 10, `}`},
|
||||
},
|
||||
}, {
|
||||
input: `{foo="bar\"bar"}`,
|
||||
expected: []item{
|
||||
{ItemLeftBrace, 0, `{`},
|
||||
{ItemIdentifier, 1, `foo`},
|
||||
{ItemEQL, 4, `=`},
|
||||
{ItemString, 5, `"bar\"bar"`},
|
||||
{ItemRightBrace, 15, `}`},
|
||||
{LEFT_BRACE, 0, `{`},
|
||||
{IDENTIFIER, 1, `foo`},
|
||||
{EQL, 4, `=`},
|
||||
{STRING, 5, `"bar\"bar"`},
|
||||
{RIGHT_BRACE, 15, `}`},
|
||||
},
|
||||
}, {
|
||||
input: `{NaN != "bar" }`,
|
||||
expected: []item{
|
||||
{ItemLeftBrace, 0, `{`},
|
||||
{ItemIdentifier, 1, `NaN`},
|
||||
{ItemNEQ, 5, `!=`},
|
||||
{ItemString, 8, `"bar"`},
|
||||
{ItemRightBrace, 14, `}`},
|
||||
{LEFT_BRACE, 0, `{`},
|
||||
{IDENTIFIER, 1, `NaN`},
|
||||
{NEQ, 5, `!=`},
|
||||
{STRING, 8, `"bar"`},
|
||||
{RIGHT_BRACE, 14, `}`},
|
||||
},
|
||||
}, {
|
||||
input: `{alert=~"bar" }`,
|
||||
expected: []item{
|
||||
{ItemLeftBrace, 0, `{`},
|
||||
{ItemIdentifier, 1, `alert`},
|
||||
{ItemEQLRegex, 6, `=~`},
|
||||
{ItemString, 8, `"bar"`},
|
||||
{ItemRightBrace, 14, `}`},
|
||||
{LEFT_BRACE, 0, `{`},
|
||||
{IDENTIFIER, 1, `alert`},
|
||||
{EQL_REGEX, 6, `=~`},
|
||||
{STRING, 8, `"bar"`},
|
||||
{RIGHT_BRACE, 14, `}`},
|
||||
},
|
||||
}, {
|
||||
input: `{on!~"bar"}`,
|
||||
expected: []item{
|
||||
{ItemLeftBrace, 0, `{`},
|
||||
{ItemIdentifier, 1, `on`},
|
||||
{ItemNEQRegex, 3, `!~`},
|
||||
{ItemString, 5, `"bar"`},
|
||||
{ItemRightBrace, 10, `}`},
|
||||
{LEFT_BRACE, 0, `{`},
|
||||
{IDENTIFIER, 1, `on`},
|
||||
{NEQ_REGEX, 3, `!~`},
|
||||
{STRING, 5, `"bar"`},
|
||||
{RIGHT_BRACE, 10, `}`},
|
||||
},
|
||||
}, {
|
||||
input: `{alert!#"bar"}`, fail: true,
|
||||
@ -469,43 +469,43 @@ var tests = []struct {
|
||||
{
|
||||
input: `{} _ 1 x .3`,
|
||||
expected: []item{
|
||||
{ItemLeftBrace, 0, `{`},
|
||||
{ItemRightBrace, 1, `}`},
|
||||
{ItemSpace, 2, ` `},
|
||||
{ItemBlank, 3, `_`},
|
||||
{ItemSpace, 4, ` `},
|
||||
{ItemNumber, 5, `1`},
|
||||
{ItemSpace, 6, ` `},
|
||||
{ItemTimes, 7, `x`},
|
||||
{ItemSpace, 8, ` `},
|
||||
{ItemNumber, 9, `.3`},
|
||||
{LEFT_BRACE, 0, `{`},
|
||||
{RIGHT_BRACE, 1, `}`},
|
||||
{SPACE, 2, ` `},
|
||||
{BLANK, 3, `_`},
|
||||
{SPACE, 4, ` `},
|
||||
{NUMBER, 5, `1`},
|
||||
{SPACE, 6, ` `},
|
||||
{TIMES, 7, `x`},
|
||||
{SPACE, 8, ` `},
|
||||
{NUMBER, 9, `.3`},
|
||||
},
|
||||
seriesDesc: true,
|
||||
},
|
||||
{
|
||||
input: `metric +Inf Inf NaN`,
|
||||
expected: []item{
|
||||
{ItemIdentifier, 0, `metric`},
|
||||
{ItemSpace, 6, ` `},
|
||||
{ItemADD, 7, `+`},
|
||||
{ItemNumber, 8, `Inf`},
|
||||
{ItemSpace, 11, ` `},
|
||||
{ItemNumber, 12, `Inf`},
|
||||
{ItemSpace, 15, ` `},
|
||||
{ItemNumber, 16, `NaN`},
|
||||
{IDENTIFIER, 0, `metric`},
|
||||
{SPACE, 6, ` `},
|
||||
{ADD, 7, `+`},
|
||||
{NUMBER, 8, `Inf`},
|
||||
{SPACE, 11, ` `},
|
||||
{NUMBER, 12, `Inf`},
|
||||
{SPACE, 15, ` `},
|
||||
{NUMBER, 16, `NaN`},
|
||||
},
|
||||
seriesDesc: true,
|
||||
},
|
||||
{
|
||||
input: `metric 1+1x4`,
|
||||
expected: []item{
|
||||
{ItemIdentifier, 0, `metric`},
|
||||
{ItemSpace, 6, ` `},
|
||||
{ItemNumber, 7, `1`},
|
||||
{ItemADD, 8, `+`},
|
||||
{ItemNumber, 9, `1`},
|
||||
{ItemTimes, 10, `x`},
|
||||
{ItemNumber, 11, `4`},
|
||||
{IDENTIFIER, 0, `metric`},
|
||||
{SPACE, 6, ` `},
|
||||
{NUMBER, 7, `1`},
|
||||
{ADD, 8, `+`},
|
||||
{NUMBER, 9, `1`},
|
||||
{TIMES, 10, `x`},
|
||||
{NUMBER, 11, `4`},
|
||||
},
|
||||
seriesDesc: true,
|
||||
},
|
||||
@ -517,150 +517,150 @@ var tests = []struct {
|
||||
{
|
||||
input: `test_name{on!~"bar"}[4m:4s]`,
|
||||
expected: []item{
|
||||
{ItemIdentifier, 0, `test_name`},
|
||||
{ItemLeftBrace, 9, `{`},
|
||||
{ItemIdentifier, 10, `on`},
|
||||
{ItemNEQRegex, 12, `!~`},
|
||||
{ItemString, 14, `"bar"`},
|
||||
{ItemRightBrace, 19, `}`},
|
||||
{ItemLeftBracket, 20, `[`},
|
||||
{ItemDuration, 21, `4m`},
|
||||
{ItemColon, 23, `:`},
|
||||
{ItemDuration, 24, `4s`},
|
||||
{ItemRightBracket, 26, `]`},
|
||||
{IDENTIFIER, 0, `test_name`},
|
||||
{LEFT_BRACE, 9, `{`},
|
||||
{IDENTIFIER, 10, `on`},
|
||||
{NEQ_REGEX, 12, `!~`},
|
||||
{STRING, 14, `"bar"`},
|
||||
{RIGHT_BRACE, 19, `}`},
|
||||
{LEFT_BRACKET, 20, `[`},
|
||||
{DURATION, 21, `4m`},
|
||||
{COLON, 23, `:`},
|
||||
{DURATION, 24, `4s`},
|
||||
{RIGHT_BRACKET, 26, `]`},
|
||||
},
|
||||
},
|
||||
{
|
||||
input: `test:name{on!~"bar"}[4m:4s]`,
|
||||
expected: []item{
|
||||
{ItemMetricIdentifier, 0, `test:name`},
|
||||
{ItemLeftBrace, 9, `{`},
|
||||
{ItemIdentifier, 10, `on`},
|
||||
{ItemNEQRegex, 12, `!~`},
|
||||
{ItemString, 14, `"bar"`},
|
||||
{ItemRightBrace, 19, `}`},
|
||||
{ItemLeftBracket, 20, `[`},
|
||||
{ItemDuration, 21, `4m`},
|
||||
{ItemColon, 23, `:`},
|
||||
{ItemDuration, 24, `4s`},
|
||||
{ItemRightBracket, 26, `]`},
|
||||
{METRIC_IDENTIFIER, 0, `test:name`},
|
||||
{LEFT_BRACE, 9, `{`},
|
||||
{IDENTIFIER, 10, `on`},
|
||||
{NEQ_REGEX, 12, `!~`},
|
||||
{STRING, 14, `"bar"`},
|
||||
{RIGHT_BRACE, 19, `}`},
|
||||
{LEFT_BRACKET, 20, `[`},
|
||||
{DURATION, 21, `4m`},
|
||||
{COLON, 23, `:`},
|
||||
{DURATION, 24, `4s`},
|
||||
{RIGHT_BRACKET, 26, `]`},
|
||||
},
|
||||
}, {
|
||||
input: `test:name{on!~"b:ar"}[4m:4s]`,
|
||||
expected: []item{
|
||||
{ItemMetricIdentifier, 0, `test:name`},
|
||||
{ItemLeftBrace, 9, `{`},
|
||||
{ItemIdentifier, 10, `on`},
|
||||
{ItemNEQRegex, 12, `!~`},
|
||||
{ItemString, 14, `"b:ar"`},
|
||||
{ItemRightBrace, 20, `}`},
|
||||
{ItemLeftBracket, 21, `[`},
|
||||
{ItemDuration, 22, `4m`},
|
||||
{ItemColon, 24, `:`},
|
||||
{ItemDuration, 25, `4s`},
|
||||
{ItemRightBracket, 27, `]`},
|
||||
{METRIC_IDENTIFIER, 0, `test:name`},
|
||||
{LEFT_BRACE, 9, `{`},
|
||||
{IDENTIFIER, 10, `on`},
|
||||
{NEQ_REGEX, 12, `!~`},
|
||||
{STRING, 14, `"b:ar"`},
|
||||
{RIGHT_BRACE, 20, `}`},
|
||||
{LEFT_BRACKET, 21, `[`},
|
||||
{DURATION, 22, `4m`},
|
||||
{COLON, 24, `:`},
|
||||
{DURATION, 25, `4s`},
|
||||
{RIGHT_BRACKET, 27, `]`},
|
||||
},
|
||||
}, {
|
||||
input: `test:name{on!~"b:ar"}[4m:]`,
|
||||
expected: []item{
|
||||
{ItemMetricIdentifier, 0, `test:name`},
|
||||
{ItemLeftBrace, 9, `{`},
|
||||
{ItemIdentifier, 10, `on`},
|
||||
{ItemNEQRegex, 12, `!~`},
|
||||
{ItemString, 14, `"b:ar"`},
|
||||
{ItemRightBrace, 20, `}`},
|
||||
{ItemLeftBracket, 21, `[`},
|
||||
{ItemDuration, 22, `4m`},
|
||||
{ItemColon, 24, `:`},
|
||||
{ItemRightBracket, 25, `]`},
|
||||
{METRIC_IDENTIFIER, 0, `test:name`},
|
||||
{LEFT_BRACE, 9, `{`},
|
||||
{IDENTIFIER, 10, `on`},
|
||||
{NEQ_REGEX, 12, `!~`},
|
||||
{STRING, 14, `"b:ar"`},
|
||||
{RIGHT_BRACE, 20, `}`},
|
||||
{LEFT_BRACKET, 21, `[`},
|
||||
{DURATION, 22, `4m`},
|
||||
{COLON, 24, `:`},
|
||||
{RIGHT_BRACKET, 25, `]`},
|
||||
},
|
||||
}, { // Nested Subquery.
|
||||
input: `min_over_time(rate(foo{bar="baz"}[2s])[5m:])[4m:3s]`,
|
||||
expected: []item{
|
||||
|
||||
{ItemIdentifier, 0, `min_over_time`},
|
||||
{ItemLeftParen, 13, `(`},
|
||||
{ItemIdentifier, 14, `rate`},
|
||||
{ItemLeftParen, 18, `(`},
|
||||
{ItemIdentifier, 19, `foo`},
|
||||
{ItemLeftBrace, 22, `{`},
|
||||
{ItemIdentifier, 23, `bar`},
|
||||
{ItemEQL, 26, `=`},
|
||||
{ItemString, 27, `"baz"`},
|
||||
{ItemRightBrace, 32, `}`},
|
||||
{ItemLeftBracket, 33, `[`},
|
||||
{ItemDuration, 34, `2s`},
|
||||
{ItemRightBracket, 36, `]`},
|
||||
{ItemRightParen, 37, `)`},
|
||||
{ItemLeftBracket, 38, `[`},
|
||||
{ItemDuration, 39, `5m`},
|
||||
{ItemColon, 41, `:`},
|
||||
{ItemRightBracket, 42, `]`},
|
||||
{ItemRightParen, 43, `)`},
|
||||
{ItemLeftBracket, 44, `[`},
|
||||
{ItemDuration, 45, `4m`},
|
||||
{ItemColon, 47, `:`},
|
||||
{ItemDuration, 48, `3s`},
|
||||
{ItemRightBracket, 50, `]`},
|
||||
{IDENTIFIER, 0, `min_over_time`},
|
||||
{LEFT_PAREN, 13, `(`},
|
||||
{IDENTIFIER, 14, `rate`},
|
||||
{LEFT_PAREN, 18, `(`},
|
||||
{IDENTIFIER, 19, `foo`},
|
||||
{LEFT_BRACE, 22, `{`},
|
||||
{IDENTIFIER, 23, `bar`},
|
||||
{EQL, 26, `=`},
|
||||
{STRING, 27, `"baz"`},
|
||||
{RIGHT_BRACE, 32, `}`},
|
||||
{LEFT_BRACKET, 33, `[`},
|
||||
{DURATION, 34, `2s`},
|
||||
{RIGHT_BRACKET, 36, `]`},
|
||||
{RIGHT_PAREN, 37, `)`},
|
||||
{LEFT_BRACKET, 38, `[`},
|
||||
{DURATION, 39, `5m`},
|
||||
{COLON, 41, `:`},
|
||||
{RIGHT_BRACKET, 42, `]`},
|
||||
{RIGHT_PAREN, 43, `)`},
|
||||
{LEFT_BRACKET, 44, `[`},
|
||||
{DURATION, 45, `4m`},
|
||||
{COLON, 47, `:`},
|
||||
{DURATION, 48, `3s`},
|
||||
{RIGHT_BRACKET, 50, `]`},
|
||||
},
|
||||
},
|
||||
// Subquery with offset.
|
||||
{
|
||||
input: `test:name{on!~"b:ar"}[4m:4s] offset 10m`,
|
||||
expected: []item{
|
||||
{ItemMetricIdentifier, 0, `test:name`},
|
||||
{ItemLeftBrace, 9, `{`},
|
||||
{ItemIdentifier, 10, `on`},
|
||||
{ItemNEQRegex, 12, `!~`},
|
||||
{ItemString, 14, `"b:ar"`},
|
||||
{ItemRightBrace, 20, `}`},
|
||||
{ItemLeftBracket, 21, `[`},
|
||||
{ItemDuration, 22, `4m`},
|
||||
{ItemColon, 24, `:`},
|
||||
{ItemDuration, 25, `4s`},
|
||||
{ItemRightBracket, 27, `]`},
|
||||
{ItemOffset, 29, "offset"},
|
||||
{ItemDuration, 36, "10m"},
|
||||
{METRIC_IDENTIFIER, 0, `test:name`},
|
||||
{LEFT_BRACE, 9, `{`},
|
||||
{IDENTIFIER, 10, `on`},
|
||||
{NEQ_REGEX, 12, `!~`},
|
||||
{STRING, 14, `"b:ar"`},
|
||||
{RIGHT_BRACE, 20, `}`},
|
||||
{LEFT_BRACKET, 21, `[`},
|
||||
{DURATION, 22, `4m`},
|
||||
{COLON, 24, `:`},
|
||||
{DURATION, 25, `4s`},
|
||||
{RIGHT_BRACKET, 27, `]`},
|
||||
{OFFSET, 29, "offset"},
|
||||
{DURATION, 36, "10m"},
|
||||
},
|
||||
}, {
|
||||
input: `min_over_time(rate(foo{bar="baz"}[2s])[5m:] offset 6m)[4m:3s]`,
|
||||
expected: []item{
|
||||
|
||||
{ItemIdentifier, 0, `min_over_time`},
|
||||
{ItemLeftParen, 13, `(`},
|
||||
{ItemIdentifier, 14, `rate`},
|
||||
{ItemLeftParen, 18, `(`},
|
||||
{ItemIdentifier, 19, `foo`},
|
||||
{ItemLeftBrace, 22, `{`},
|
||||
{ItemIdentifier, 23, `bar`},
|
||||
{ItemEQL, 26, `=`},
|
||||
{ItemString, 27, `"baz"`},
|
||||
{ItemRightBrace, 32, `}`},
|
||||
{ItemLeftBracket, 33, `[`},
|
||||
{ItemDuration, 34, `2s`},
|
||||
{ItemRightBracket, 36, `]`},
|
||||
{ItemRightParen, 37, `)`},
|
||||
{ItemLeftBracket, 38, `[`},
|
||||
{ItemDuration, 39, `5m`},
|
||||
{ItemColon, 41, `:`},
|
||||
{ItemRightBracket, 42, `]`},
|
||||
{ItemOffset, 44, `offset`},
|
||||
{ItemDuration, 51, `6m`},
|
||||
{ItemRightParen, 53, `)`},
|
||||
{ItemLeftBracket, 54, `[`},
|
||||
{ItemDuration, 55, `4m`},
|
||||
{ItemColon, 57, `:`},
|
||||
{ItemDuration, 58, `3s`},
|
||||
{ItemRightBracket, 60, `]`},
|
||||
{IDENTIFIER, 0, `min_over_time`},
|
||||
{LEFT_PAREN, 13, `(`},
|
||||
{IDENTIFIER, 14, `rate`},
|
||||
{LEFT_PAREN, 18, `(`},
|
||||
{IDENTIFIER, 19, `foo`},
|
||||
{LEFT_BRACE, 22, `{`},
|
||||
{IDENTIFIER, 23, `bar`},
|
||||
{EQL, 26, `=`},
|
||||
{STRING, 27, `"baz"`},
|
||||
{RIGHT_BRACE, 32, `}`},
|
||||
{LEFT_BRACKET, 33, `[`},
|
||||
{DURATION, 34, `2s`},
|
||||
{RIGHT_BRACKET, 36, `]`},
|
||||
{RIGHT_PAREN, 37, `)`},
|
||||
{LEFT_BRACKET, 38, `[`},
|
||||
{DURATION, 39, `5m`},
|
||||
{COLON, 41, `:`},
|
||||
{RIGHT_BRACKET, 42, `]`},
|
||||
{OFFSET, 44, `offset`},
|
||||
{DURATION, 51, `6m`},
|
||||
{RIGHT_PAREN, 53, `)`},
|
||||
{LEFT_BRACKET, 54, `[`},
|
||||
{DURATION, 55, `4m`},
|
||||
{COLON, 57, `:`},
|
||||
{DURATION, 58, `3s`},
|
||||
{RIGHT_BRACKET, 60, `]`},
|
||||
},
|
||||
},
|
||||
{
|
||||
input: `test:name[ 5m]`,
|
||||
expected: []item{
|
||||
{ItemMetricIdentifier, 0, `test:name`},
|
||||
{ItemLeftBracket, 9, `[`},
|
||||
{ItemDuration, 11, `5m`},
|
||||
{ItemRightBracket, 13, `]`},
|
||||
{METRIC_IDENTIFIER, 0, `test:name`},
|
||||
{LEFT_BRACKET, 9, `[`},
|
||||
{DURATION, 11, `5m`},
|
||||
{RIGHT_BRACKET, 13, `]`},
|
||||
},
|
||||
},
|
||||
{
|
||||
@ -703,18 +703,18 @@ func TestLexer(t *testing.T) {
|
||||
|
||||
lastItem := out[len(out)-1]
|
||||
if test.fail {
|
||||
if lastItem.typ != ItemError {
|
||||
if lastItem.typ != ERROR {
|
||||
t.Logf("%d: input %q", i, test.input)
|
||||
t.Fatalf("expected lexing error but did not fail")
|
||||
}
|
||||
continue
|
||||
}
|
||||
if lastItem.typ == ItemError {
|
||||
if lastItem.typ == ERROR {
|
||||
t.Logf("%d: input %q", i, test.input)
|
||||
t.Fatalf("unexpected lexing error at position %d: %s", lastItem.pos, lastItem)
|
||||
}
|
||||
|
||||
eofItem := item{ItemEOF, Pos(len(test.input)), ""}
|
||||
eofItem := item{EOF, Pos(len(test.input)), ""}
|
||||
testutil.Equals(t, lastItem, eofItem, "%d: input %q", i, test.input)
|
||||
|
||||
out = out[:len(out)-1]
|
||||
|
180
promql/parse.go
180
promql/parse.go
@ -70,7 +70,7 @@ func ParseMetric(input string) (m labels.Labels, err error) {
|
||||
defer p.recover(&err)
|
||||
|
||||
m = p.metric()
|
||||
if p.peek().typ != ItemEOF {
|
||||
if p.peek().typ != EOF {
|
||||
p.errorf("could not parse remaining input %.15q...", p.lex.input[p.lex.lastPos:])
|
||||
}
|
||||
return m, nil
|
||||
@ -83,11 +83,11 @@ func ParseMetricSelector(input string) (m []*labels.Matcher, err error) {
|
||||
defer p.recover(&err)
|
||||
|
||||
name := ""
|
||||
if t := p.peek().typ; t == ItemMetricIdentifier || t == ItemIdentifier {
|
||||
if t := p.peek().typ; t == METRIC_IDENTIFIER || t == IDENTIFIER {
|
||||
name = p.next().val
|
||||
}
|
||||
vs := p.VectorSelector(name)
|
||||
if p.peek().typ != ItemEOF {
|
||||
if p.peek().typ != EOF {
|
||||
p.errorf("could not parse remaining input %.15q...", p.lex.input[p.lex.lastPos:])
|
||||
}
|
||||
return vs.LabelMatchers, nil
|
||||
@ -105,7 +105,7 @@ func newParser(input string) *parser {
|
||||
func (p *parser) parseExpr() (expr Expr, err error) {
|
||||
defer p.recover(&err)
|
||||
|
||||
for p.peek().typ != ItemEOF {
|
||||
for p.peek().typ != EOF {
|
||||
if expr != nil {
|
||||
p.errorf("could not parse remaining input %.15q...", p.lex.input[p.lex.lastPos:])
|
||||
}
|
||||
@ -147,20 +147,20 @@ func (p *parser) parseSeriesDesc() (m labels.Labels, vals []sequenceValue, err e
|
||||
|
||||
const ctx = "series values"
|
||||
for {
|
||||
for p.peek().typ == ItemSpace {
|
||||
for p.peek().typ == SPACE {
|
||||
p.next()
|
||||
}
|
||||
if p.peek().typ == ItemEOF {
|
||||
if p.peek().typ == EOF {
|
||||
break
|
||||
}
|
||||
|
||||
// Extract blanks.
|
||||
if p.peek().typ == ItemBlank {
|
||||
if p.peek().typ == BLANK {
|
||||
p.next()
|
||||
times := uint64(1)
|
||||
if p.peek().typ == ItemTimes {
|
||||
if p.peek().typ == TIMES {
|
||||
p.next()
|
||||
times, err = strconv.ParseUint(p.expect(ItemNumber, ctx).val, 10, 64)
|
||||
times, err = strconv.ParseUint(p.expect(NUMBER, ctx).val, 10, 64)
|
||||
if err != nil {
|
||||
p.errorf("invalid repetition in %s: %s", ctx, err)
|
||||
}
|
||||
@ -170,7 +170,7 @@ func (p *parser) parseSeriesDesc() (m labels.Labels, vals []sequenceValue, err e
|
||||
}
|
||||
// This is to ensure that there is a space between this and the next number.
|
||||
// This is especially required if the next number is negative.
|
||||
if t := p.expectOneOf(ItemSpace, ItemEOF, ctx).typ; t == ItemEOF {
|
||||
if t := p.expectOneOf(SPACE, EOF, ctx).typ; t == EOF {
|
||||
break
|
||||
}
|
||||
continue
|
||||
@ -178,15 +178,15 @@ func (p *parser) parseSeriesDesc() (m labels.Labels, vals []sequenceValue, err e
|
||||
|
||||
// Extract values.
|
||||
sign := 1.0
|
||||
if t := p.peek().typ; t == ItemSUB || t == ItemADD {
|
||||
if p.next().typ == ItemSUB {
|
||||
if t := p.peek().typ; t == SUB || t == ADD {
|
||||
if p.next().typ == SUB {
|
||||
sign = -1
|
||||
}
|
||||
}
|
||||
var k float64
|
||||
if t := p.peek().typ; t == ItemNumber {
|
||||
k = sign * p.number(p.expect(ItemNumber, ctx).val)
|
||||
} else if t == ItemIdentifier && p.peek().val == "stale" {
|
||||
if t := p.peek().typ; t == NUMBER {
|
||||
k = sign * p.number(p.expect(NUMBER, ctx).val)
|
||||
} else if t == IDENTIFIER && p.peek().val == "stale" {
|
||||
p.next()
|
||||
k = math.Float64frombits(value.StaleNaN)
|
||||
} else {
|
||||
@ -197,24 +197,24 @@ func (p *parser) parseSeriesDesc() (m labels.Labels, vals []sequenceValue, err e
|
||||
})
|
||||
|
||||
// If there are no offset repetitions specified, proceed with the next value.
|
||||
if t := p.peek(); t.typ == ItemSpace {
|
||||
if t := p.peek(); t.typ == SPACE {
|
||||
// This ensures there is a space between every value.
|
||||
continue
|
||||
} else if t.typ == ItemEOF {
|
||||
} else if t.typ == EOF {
|
||||
break
|
||||
} else if t.typ != ItemADD && t.typ != ItemSUB {
|
||||
} else if t.typ != ADD && t.typ != SUB {
|
||||
p.errorf("expected next value or relative expansion in %s but got %s (value: %s)", ctx, t.desc(), p.peek())
|
||||
}
|
||||
|
||||
// Expand the repeated offsets into values.
|
||||
sign = 1.0
|
||||
if p.next().typ == ItemSUB {
|
||||
if p.next().typ == SUB {
|
||||
sign = -1.0
|
||||
}
|
||||
offset := sign * p.number(p.expect(ItemNumber, ctx).val)
|
||||
p.expect(ItemTimes, ctx)
|
||||
offset := sign * p.number(p.expect(NUMBER, ctx).val)
|
||||
p.expect(TIMES, ctx)
|
||||
|
||||
times, err := strconv.ParseUint(p.expect(ItemNumber, ctx).val, 10, 64)
|
||||
times, err := strconv.ParseUint(p.expect(NUMBER, ctx).val, 10, 64)
|
||||
if err != nil {
|
||||
p.errorf("invalid repetition in %s: %s", ctx, err)
|
||||
}
|
||||
@ -228,7 +228,7 @@ func (p *parser) parseSeriesDesc() (m labels.Labels, vals []sequenceValue, err e
|
||||
// This is to ensure that there is a space between this expanding notation
|
||||
// and the next number. This is especially required if the next number
|
||||
// is negative.
|
||||
if t := p.expectOneOf(ItemSpace, ItemEOF, ctx).typ; t == ItemEOF {
|
||||
if t := p.expectOneOf(SPACE, EOF, ctx).typ; t == EOF {
|
||||
break
|
||||
}
|
||||
}
|
||||
@ -248,7 +248,7 @@ func (p *parser) next() item {
|
||||
if !p.peeking {
|
||||
t := p.lex.nextItem()
|
||||
// Skip comments.
|
||||
for t.typ == ItemComment {
|
||||
for t.typ == COMMENT {
|
||||
t = p.lex.nextItem()
|
||||
}
|
||||
p.token = t
|
||||
@ -256,7 +256,7 @@ func (p *parser) next() item {
|
||||
|
||||
p.peeking = false
|
||||
|
||||
if p.token.typ == ItemError {
|
||||
if p.token.typ == ERROR {
|
||||
p.errorf("%s", p.token.val)
|
||||
}
|
||||
return p.token
|
||||
@ -271,7 +271,7 @@ func (p *parser) peek() item {
|
||||
|
||||
t := p.lex.nextItem()
|
||||
// Skip comments.
|
||||
for t.typ == ItemComment {
|
||||
for t.typ == COMMENT {
|
||||
t = p.lex.nextItem()
|
||||
}
|
||||
p.token = t
|
||||
@ -376,11 +376,11 @@ func (p *parser) expr() Expr {
|
||||
op := p.peek().typ
|
||||
if !op.isOperator() {
|
||||
// Check for subquery.
|
||||
if op == ItemLeftBracket {
|
||||
if op == LEFT_BRACKET {
|
||||
expr = p.subqueryOrRangeSelector(expr, false)
|
||||
if s, ok := expr.(*SubqueryExpr); ok {
|
||||
// Parse optional offset.
|
||||
if p.peek().typ == ItemOffset {
|
||||
if p.peek().typ == OFFSET {
|
||||
offset := p.offset()
|
||||
s.Offset = offset
|
||||
}
|
||||
@ -401,7 +401,7 @@ func (p *parser) expr() Expr {
|
||||
|
||||
returnBool := false
|
||||
// Parse bool modifier.
|
||||
if p.peek().typ == ItemBool {
|
||||
if p.peek().typ == BOOL {
|
||||
if !op.isComparisonOperator() {
|
||||
p.errorf("bool modifier can only be used on comparison operators")
|
||||
}
|
||||
@ -410,22 +410,22 @@ func (p *parser) expr() Expr {
|
||||
}
|
||||
|
||||
// Parse ON/IGNORING clause.
|
||||
if p.peek().typ == ItemOn || p.peek().typ == ItemIgnoring {
|
||||
if p.peek().typ == ItemOn {
|
||||
if p.peek().typ == ON || p.peek().typ == IGNORING {
|
||||
if p.peek().typ == ON {
|
||||
vecMatching.On = true
|
||||
}
|
||||
p.next()
|
||||
vecMatching.MatchingLabels = p.labels()
|
||||
|
||||
// Parse grouping.
|
||||
if t := p.peek().typ; t == ItemGroupLeft || t == ItemGroupRight {
|
||||
if t := p.peek().typ; t == GROUP_LEFT || t == GROUP_RIGHT {
|
||||
p.next()
|
||||
if t == ItemGroupLeft {
|
||||
if t == GROUP_LEFT {
|
||||
vecMatching.Card = CardManyToOne
|
||||
} else {
|
||||
vecMatching.Card = CardOneToMany
|
||||
}
|
||||
if p.peek().typ == ItemLeftParen {
|
||||
if p.peek().typ == LEFT_PAREN {
|
||||
vecMatching.Include = p.labels()
|
||||
}
|
||||
}
|
||||
@ -482,35 +482,35 @@ func (p *parser) balance(lhs Expr, op ItemType, rhs Expr, vecMatching *VectorMat
|
||||
//
|
||||
func (p *parser) unaryExpr() Expr {
|
||||
switch t := p.peek(); t.typ {
|
||||
case ItemADD, ItemSUB:
|
||||
case ADD, SUB:
|
||||
p.next()
|
||||
e := p.unaryExpr()
|
||||
|
||||
// Simplify unary expressions for number literals.
|
||||
if nl, ok := e.(*NumberLiteral); ok {
|
||||
if t.typ == ItemSUB {
|
||||
if t.typ == SUB {
|
||||
nl.Val *= -1
|
||||
}
|
||||
return nl
|
||||
}
|
||||
return &UnaryExpr{Op: t.typ, Expr: e}
|
||||
|
||||
case ItemLeftParen:
|
||||
case LEFT_PAREN:
|
||||
p.next()
|
||||
e := p.expr()
|
||||
p.expect(ItemRightParen, "paren expression")
|
||||
p.expect(RIGHT_PAREN, "paren expression")
|
||||
|
||||
return &ParenExpr{Expr: e}
|
||||
}
|
||||
e := p.primaryExpr()
|
||||
|
||||
// Expression might be followed by a range selector.
|
||||
if p.peek().typ == ItemLeftBracket {
|
||||
if p.peek().typ == LEFT_BRACKET {
|
||||
e = p.subqueryOrRangeSelector(e, true)
|
||||
}
|
||||
|
||||
// Parse optional offset.
|
||||
if p.peek().typ == ItemOffset {
|
||||
if p.peek().typ == OFFSET {
|
||||
offset := p.offset()
|
||||
|
||||
switch s := e.(type) {
|
||||
@ -544,7 +544,7 @@ func (p *parser) subqueryOrRangeSelector(expr Expr, checkRange bool) Expr {
|
||||
var erange time.Duration
|
||||
var err error
|
||||
|
||||
erangeStr := p.expect(ItemDuration, ctx).val
|
||||
erangeStr := p.expect(DURATION, ctx).val
|
||||
erange, err = parseDuration(erangeStr)
|
||||
if err != nil {
|
||||
p.error(err)
|
||||
@ -552,8 +552,8 @@ func (p *parser) subqueryOrRangeSelector(expr Expr, checkRange bool) Expr {
|
||||
|
||||
var itm item
|
||||
if checkRange {
|
||||
itm = p.expectOneOf(ItemRightBracket, ItemColon, ctx)
|
||||
if itm.typ == ItemRightBracket {
|
||||
itm = p.expectOneOf(RIGHT_BRACKET, COLON, ctx)
|
||||
if itm.typ == RIGHT_BRACKET {
|
||||
// Range selector.
|
||||
vs, ok := expr.(*VectorSelector)
|
||||
if !ok {
|
||||
@ -566,20 +566,20 @@ func (p *parser) subqueryOrRangeSelector(expr Expr, checkRange bool) Expr {
|
||||
}
|
||||
}
|
||||
} else {
|
||||
itm = p.expect(ItemColon, ctx)
|
||||
itm = p.expect(COLON, ctx)
|
||||
}
|
||||
|
||||
// Subquery.
|
||||
var estep time.Duration
|
||||
|
||||
itm = p.expectOneOf(ItemRightBracket, ItemDuration, ctx)
|
||||
if itm.typ == ItemDuration {
|
||||
itm = p.expectOneOf(RIGHT_BRACKET, DURATION, ctx)
|
||||
if itm.typ == DURATION {
|
||||
estepStr := itm.val
|
||||
estep, err = parseDuration(estepStr)
|
||||
if err != nil {
|
||||
p.error(err)
|
||||
}
|
||||
p.expect(ItemRightBracket, ctx)
|
||||
p.expect(RIGHT_BRACKET, ctx)
|
||||
}
|
||||
|
||||
return &SubqueryExpr{
|
||||
@ -608,26 +608,26 @@ func (p *parser) number(val string) float64 {
|
||||
//
|
||||
func (p *parser) primaryExpr() Expr {
|
||||
switch t := p.next(); {
|
||||
case t.typ == ItemNumber:
|
||||
case t.typ == NUMBER:
|
||||
f := p.number(t.val)
|
||||
return &NumberLiteral{f}
|
||||
|
||||
case t.typ == ItemString:
|
||||
case t.typ == STRING:
|
||||
return &StringLiteral{p.unquoteString(t.val)}
|
||||
|
||||
case t.typ == ItemLeftBrace:
|
||||
case t.typ == LEFT_BRACE:
|
||||
// Metric selector without metric name.
|
||||
p.backup()
|
||||
return p.VectorSelector("")
|
||||
|
||||
case t.typ == ItemIdentifier:
|
||||
case t.typ == IDENTIFIER:
|
||||
// Check for function call.
|
||||
if p.peek().typ == ItemLeftParen {
|
||||
if p.peek().typ == LEFT_PAREN {
|
||||
return p.call(t.val)
|
||||
}
|
||||
fallthrough // Else metric selector.
|
||||
|
||||
case t.typ == ItemMetricIdentifier:
|
||||
case t.typ == METRIC_IDENTIFIER:
|
||||
return p.VectorSelector(t.val)
|
||||
|
||||
case t.typ.isAggregator():
|
||||
@ -647,10 +647,10 @@ func (p *parser) primaryExpr() Expr {
|
||||
func (p *parser) labels() []string {
|
||||
const ctx = "grouping opts"
|
||||
|
||||
p.expect(ItemLeftParen, ctx)
|
||||
p.expect(LEFT_PAREN, ctx)
|
||||
|
||||
labels := []string{}
|
||||
if p.peek().typ != ItemRightParen {
|
||||
if p.peek().typ != RIGHT_PAREN {
|
||||
for {
|
||||
id := p.next()
|
||||
if !isLabel(id.val) {
|
||||
@ -658,13 +658,13 @@ func (p *parser) labels() []string {
|
||||
}
|
||||
labels = append(labels, id.val)
|
||||
|
||||
if p.peek().typ != ItemComma {
|
||||
if p.peek().typ != COMMA {
|
||||
break
|
||||
}
|
||||
p.next()
|
||||
}
|
||||
}
|
||||
p.expect(ItemRightParen, ctx)
|
||||
p.expect(RIGHT_PAREN, ctx)
|
||||
|
||||
return labels
|
||||
}
|
||||
@ -686,8 +686,8 @@ func (p *parser) aggrExpr() *AggregateExpr {
|
||||
|
||||
modifiersFirst := false
|
||||
|
||||
if t := p.peek().typ; t == ItemBy || t == ItemWithout {
|
||||
if t == ItemWithout {
|
||||
if t := p.peek().typ; t == BY || t == WITHOUT {
|
||||
if t == WITHOUT {
|
||||
without = true
|
||||
}
|
||||
p.next()
|
||||
@ -695,21 +695,21 @@ func (p *parser) aggrExpr() *AggregateExpr {
|
||||
modifiersFirst = true
|
||||
}
|
||||
|
||||
p.expect(ItemLeftParen, ctx)
|
||||
p.expect(LEFT_PAREN, ctx)
|
||||
var param Expr
|
||||
if agop.typ.isAggregatorWithParam() {
|
||||
param = p.expr()
|
||||
p.expect(ItemComma, ctx)
|
||||
p.expect(COMMA, ctx)
|
||||
}
|
||||
e := p.expr()
|
||||
p.expect(ItemRightParen, ctx)
|
||||
p.expect(RIGHT_PAREN, ctx)
|
||||
|
||||
if !modifiersFirst {
|
||||
if t := p.peek().typ; t == ItemBy || t == ItemWithout {
|
||||
if t := p.peek().typ; t == BY || t == WITHOUT {
|
||||
if len(grouping) > 0 {
|
||||
p.errorf("aggregation must only contain one grouping clause")
|
||||
}
|
||||
if t == ItemWithout {
|
||||
if t == WITHOUT {
|
||||
without = true
|
||||
}
|
||||
p.next()
|
||||
@ -738,9 +738,9 @@ func (p *parser) call(name string) *Call {
|
||||
p.errorf("unknown function with name %q", name)
|
||||
}
|
||||
|
||||
p.expect(ItemLeftParen, ctx)
|
||||
p.expect(LEFT_PAREN, ctx)
|
||||
// Might be call without args.
|
||||
if p.peek().typ == ItemRightParen {
|
||||
if p.peek().typ == RIGHT_PAREN {
|
||||
p.next() // Consume.
|
||||
return &Call{fn, nil}
|
||||
}
|
||||
@ -751,14 +751,14 @@ func (p *parser) call(name string) *Call {
|
||||
args = append(args, e)
|
||||
|
||||
// Terminate if no more arguments.
|
||||
if p.peek().typ != ItemComma {
|
||||
if p.peek().typ != COMMA {
|
||||
break
|
||||
}
|
||||
p.next()
|
||||
}
|
||||
|
||||
// Call must be closed.
|
||||
p.expect(ItemRightParen, ctx)
|
||||
p.expect(RIGHT_PAREN, ctx)
|
||||
|
||||
return &Call{Func: fn, Args: args}
|
||||
}
|
||||
@ -769,7 +769,7 @@ func (p *parser) call(name string) *Call {
|
||||
//
|
||||
func (p *parser) labelSet() labels.Labels {
|
||||
set := []labels.Label{}
|
||||
for _, lm := range p.labelMatchers(ItemEQL) {
|
||||
for _, lm := range p.labelMatchers(EQL) {
|
||||
set = append(set, labels.Label{Name: lm.Name, Value: lm.Value})
|
||||
}
|
||||
return labels.New(set...)
|
||||
@ -784,16 +784,16 @@ func (p *parser) labelMatchers(operators ...ItemType) []*labels.Matcher {
|
||||
|
||||
matchers := []*labels.Matcher{}
|
||||
|
||||
p.expect(ItemLeftBrace, ctx)
|
||||
p.expect(LEFT_BRACE, ctx)
|
||||
|
||||
// Check if no matchers are provided.
|
||||
if p.peek().typ == ItemRightBrace {
|
||||
if p.peek().typ == RIGHT_BRACE {
|
||||
p.next()
|
||||
return matchers
|
||||
}
|
||||
|
||||
for {
|
||||
label := p.expect(ItemIdentifier, ctx)
|
||||
label := p.expect(IDENTIFIER, ctx)
|
||||
|
||||
op := p.next().typ
|
||||
if !op.isOperator() {
|
||||
@ -809,18 +809,18 @@ func (p *parser) labelMatchers(operators ...ItemType) []*labels.Matcher {
|
||||
p.errorf("operator must be one of %q, is %q", operators, op)
|
||||
}
|
||||
|
||||
val := p.unquoteString(p.expect(ItemString, ctx).val)
|
||||
val := p.unquoteString(p.expect(STRING, ctx).val)
|
||||
|
||||
// Map the item to the respective match type.
|
||||
var matchType labels.MatchType
|
||||
switch op {
|
||||
case ItemEQL:
|
||||
case EQL:
|
||||
matchType = labels.MatchEqual
|
||||
case ItemNEQ:
|
||||
case NEQ:
|
||||
matchType = labels.MatchNotEqual
|
||||
case ItemEQLRegex:
|
||||
case EQL_REGEX:
|
||||
matchType = labels.MatchRegexp
|
||||
case ItemNEQRegex:
|
||||
case NEQ_REGEX:
|
||||
matchType = labels.MatchNotRegexp
|
||||
default:
|
||||
p.errorf("item %q is not a metric match type", op)
|
||||
@ -833,23 +833,23 @@ func (p *parser) labelMatchers(operators ...ItemType) []*labels.Matcher {
|
||||
|
||||
matchers = append(matchers, m)
|
||||
|
||||
if p.peek().typ == ItemIdentifier {
|
||||
if p.peek().typ == IDENTIFIER {
|
||||
p.errorf("missing comma before next identifier %q", p.peek().val)
|
||||
}
|
||||
|
||||
// Terminate list if last matcher.
|
||||
if p.peek().typ != ItemComma {
|
||||
if p.peek().typ != COMMA {
|
||||
break
|
||||
}
|
||||
p.next()
|
||||
|
||||
// Allow comma after each item in a multi-line listing.
|
||||
if p.peek().typ == ItemRightBrace {
|
||||
if p.peek().typ == RIGHT_BRACE {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
p.expect(ItemRightBrace, ctx)
|
||||
p.expect(RIGHT_BRACE, ctx)
|
||||
|
||||
return matchers
|
||||
}
|
||||
@ -864,14 +864,14 @@ func (p *parser) metric() labels.Labels {
|
||||
var m labels.Labels
|
||||
|
||||
t := p.peek().typ
|
||||
if t == ItemIdentifier || t == ItemMetricIdentifier {
|
||||
if t == IDENTIFIER || t == METRIC_IDENTIFIER {
|
||||
name = p.next().val
|
||||
t = p.peek().typ
|
||||
}
|
||||
if t != ItemLeftBrace && name == "" {
|
||||
if t != LEFT_BRACE && name == "" {
|
||||
p.errorf("missing metric name or metric selector")
|
||||
}
|
||||
if t == ItemLeftBrace {
|
||||
if t == LEFT_BRACE {
|
||||
m = p.labelSet()
|
||||
}
|
||||
if name != "" {
|
||||
@ -889,7 +889,7 @@ func (p *parser) offset() time.Duration {
|
||||
const ctx = "offset"
|
||||
|
||||
p.next()
|
||||
offi := p.expect(ItemDuration, ctx)
|
||||
offi := p.expect(DURATION, ctx)
|
||||
|
||||
offset, err := parseDuration(offi.val)
|
||||
if err != nil {
|
||||
@ -907,8 +907,8 @@ func (p *parser) offset() time.Duration {
|
||||
func (p *parser) VectorSelector(name string) *VectorSelector {
|
||||
var matchers []*labels.Matcher
|
||||
// Parse label matching if any.
|
||||
if t := p.peek(); t.typ == ItemLeftBrace {
|
||||
matchers = p.labelMatchers(ItemEQL, ItemNEQ, ItemEQLRegex, ItemNEQRegex)
|
||||
if t := p.peek(); t.typ == LEFT_BRACE {
|
||||
matchers = p.labelMatchers(EQL, NEQ, EQL_REGEX, NEQ_REGEX)
|
||||
}
|
||||
// Metric name must not be set in the label matchers and before at the same time.
|
||||
if name != "" {
|
||||
@ -994,10 +994,10 @@ func (p *parser) checkType(node Node) (typ ValueType) {
|
||||
p.errorf("aggregation operator expected in aggregation expression but got %q", n.Op)
|
||||
}
|
||||
p.expectType(n.Expr, ValueTypeVector, "aggregation expression")
|
||||
if n.Op == ItemTopK || n.Op == ItemBottomK || n.Op == ItemQuantile {
|
||||
if n.Op == TOPK || n.Op == BOTTOMK || n.Op == QUANTILE {
|
||||
p.expectType(n.Param, ValueTypeScalar, "aggregation parameter")
|
||||
}
|
||||
if n.Op == ItemCountValues {
|
||||
if n.Op == COUNT_VALUES {
|
||||
p.expectType(n.Param, ValueTypeString, "aggregation parameter")
|
||||
}
|
||||
|
||||
@ -1059,7 +1059,7 @@ func (p *parser) checkType(node Node) (typ ValueType) {
|
||||
p.checkType(n.Expr)
|
||||
|
||||
case *UnaryExpr:
|
||||
if n.Op != ItemADD && n.Op != ItemSUB {
|
||||
if n.Op != ADD && n.Op != SUB {
|
||||
p.errorf("only + and - operators allowed for unary expressions")
|
||||
}
|
||||
if t := p.checkType(n.Expr); t != ValueTypeScalar && t != ValueTypeVector {
|
||||
|
@ -71,77 +71,77 @@ var testExpr = []struct {
|
||||
expected: &NumberLiteral{-493},
|
||||
}, {
|
||||
input: "1 + 1",
|
||||
expected: &BinaryExpr{ItemADD, &NumberLiteral{1}, &NumberLiteral{1}, nil, false},
|
||||
expected: &BinaryExpr{ADD, &NumberLiteral{1}, &NumberLiteral{1}, nil, false},
|
||||
}, {
|
||||
input: "1 - 1",
|
||||
expected: &BinaryExpr{ItemSUB, &NumberLiteral{1}, &NumberLiteral{1}, nil, false},
|
||||
expected: &BinaryExpr{SUB, &NumberLiteral{1}, &NumberLiteral{1}, nil, false},
|
||||
}, {
|
||||
input: "1 * 1",
|
||||
expected: &BinaryExpr{ItemMUL, &NumberLiteral{1}, &NumberLiteral{1}, nil, false},
|
||||
expected: &BinaryExpr{MUL, &NumberLiteral{1}, &NumberLiteral{1}, nil, false},
|
||||
}, {
|
||||
input: "1 % 1",
|
||||
expected: &BinaryExpr{ItemMOD, &NumberLiteral{1}, &NumberLiteral{1}, nil, false},
|
||||
expected: &BinaryExpr{MOD, &NumberLiteral{1}, &NumberLiteral{1}, nil, false},
|
||||
}, {
|
||||
input: "1 / 1",
|
||||
expected: &BinaryExpr{ItemDIV, &NumberLiteral{1}, &NumberLiteral{1}, nil, false},
|
||||
expected: &BinaryExpr{DIV, &NumberLiteral{1}, &NumberLiteral{1}, nil, false},
|
||||
}, {
|
||||
input: "1 == bool 1",
|
||||
expected: &BinaryExpr{ItemEQL, &NumberLiteral{1}, &NumberLiteral{1}, nil, true},
|
||||
expected: &BinaryExpr{EQL, &NumberLiteral{1}, &NumberLiteral{1}, nil, true},
|
||||
}, {
|
||||
input: "1 != bool 1",
|
||||
expected: &BinaryExpr{ItemNEQ, &NumberLiteral{1}, &NumberLiteral{1}, nil, true},
|
||||
expected: &BinaryExpr{NEQ, &NumberLiteral{1}, &NumberLiteral{1}, nil, true},
|
||||
}, {
|
||||
input: "1 > bool 1",
|
||||
expected: &BinaryExpr{ItemGTR, &NumberLiteral{1}, &NumberLiteral{1}, nil, true},
|
||||
expected: &BinaryExpr{GTR, &NumberLiteral{1}, &NumberLiteral{1}, nil, true},
|
||||
}, {
|
||||
input: "1 >= bool 1",
|
||||
expected: &BinaryExpr{ItemGTE, &NumberLiteral{1}, &NumberLiteral{1}, nil, true},
|
||||
expected: &BinaryExpr{GTE, &NumberLiteral{1}, &NumberLiteral{1}, nil, true},
|
||||
}, {
|
||||
input: "1 < bool 1",
|
||||
expected: &BinaryExpr{ItemLSS, &NumberLiteral{1}, &NumberLiteral{1}, nil, true},
|
||||
expected: &BinaryExpr{LSS, &NumberLiteral{1}, &NumberLiteral{1}, nil, true},
|
||||
}, {
|
||||
input: "1 <= bool 1",
|
||||
expected: &BinaryExpr{ItemLTE, &NumberLiteral{1}, &NumberLiteral{1}, nil, true},
|
||||
expected: &BinaryExpr{LTE, &NumberLiteral{1}, &NumberLiteral{1}, nil, true},
|
||||
}, {
|
||||
input: "+1 + -2 * 1",
|
||||
expected: &BinaryExpr{
|
||||
Op: ItemADD,
|
||||
Op: ADD,
|
||||
LHS: &NumberLiteral{1},
|
||||
RHS: &BinaryExpr{
|
||||
Op: ItemMUL, LHS: &NumberLiteral{-2}, RHS: &NumberLiteral{1},
|
||||
Op: MUL, LHS: &NumberLiteral{-2}, RHS: &NumberLiteral{1},
|
||||
},
|
||||
},
|
||||
}, {
|
||||
input: "1 + 2/(3*1)",
|
||||
expected: &BinaryExpr{
|
||||
Op: ItemADD,
|
||||
Op: ADD,
|
||||
LHS: &NumberLiteral{1},
|
||||
RHS: &BinaryExpr{
|
||||
Op: ItemDIV,
|
||||
Op: DIV,
|
||||
LHS: &NumberLiteral{2},
|
||||
RHS: &ParenExpr{&BinaryExpr{
|
||||
Op: ItemMUL, LHS: &NumberLiteral{3}, RHS: &NumberLiteral{1},
|
||||
Op: MUL, LHS: &NumberLiteral{3}, RHS: &NumberLiteral{1},
|
||||
}},
|
||||
},
|
||||
},
|
||||
}, {
|
||||
input: "1 < bool 2 - 1 * 2",
|
||||
expected: &BinaryExpr{
|
||||
Op: ItemLSS,
|
||||
Op: LSS,
|
||||
ReturnBool: true,
|
||||
LHS: &NumberLiteral{1},
|
||||
RHS: &BinaryExpr{
|
||||
Op: ItemSUB,
|
||||
Op: SUB,
|
||||
LHS: &NumberLiteral{2},
|
||||
RHS: &BinaryExpr{
|
||||
Op: ItemMUL, LHS: &NumberLiteral{1}, RHS: &NumberLiteral{2},
|
||||
Op: MUL, LHS: &NumberLiteral{1}, RHS: &NumberLiteral{2},
|
||||
},
|
||||
},
|
||||
},
|
||||
}, {
|
||||
input: "-some_metric",
|
||||
expected: &UnaryExpr{
|
||||
Op: ItemSUB,
|
||||
Op: SUB,
|
||||
Expr: &VectorSelector{
|
||||
Name: "some_metric",
|
||||
LabelMatchers: []*labels.Matcher{
|
||||
@ -152,7 +152,7 @@ var testExpr = []struct {
|
||||
}, {
|
||||
input: "+some_metric",
|
||||
expected: &UnaryExpr{
|
||||
Op: ItemADD,
|
||||
Op: ADD,
|
||||
Expr: &VectorSelector{
|
||||
Name: "some_metric",
|
||||
LabelMatchers: []*labels.Matcher{
|
||||
@ -261,7 +261,7 @@ var testExpr = []struct {
|
||||
{
|
||||
input: "foo * bar",
|
||||
expected: &BinaryExpr{
|
||||
Op: ItemMUL,
|
||||
Op: MUL,
|
||||
LHS: &VectorSelector{
|
||||
Name: "foo",
|
||||
LabelMatchers: []*labels.Matcher{
|
||||
@ -279,7 +279,7 @@ var testExpr = []struct {
|
||||
}, {
|
||||
input: "foo == 1",
|
||||
expected: &BinaryExpr{
|
||||
Op: ItemEQL,
|
||||
Op: EQL,
|
||||
LHS: &VectorSelector{
|
||||
Name: "foo",
|
||||
LabelMatchers: []*labels.Matcher{
|
||||
@ -291,7 +291,7 @@ var testExpr = []struct {
|
||||
}, {
|
||||
input: "foo == bool 1",
|
||||
expected: &BinaryExpr{
|
||||
Op: ItemEQL,
|
||||
Op: EQL,
|
||||
LHS: &VectorSelector{
|
||||
Name: "foo",
|
||||
LabelMatchers: []*labels.Matcher{
|
||||
@ -304,7 +304,7 @@ var testExpr = []struct {
|
||||
}, {
|
||||
input: "2.5 / bar",
|
||||
expected: &BinaryExpr{
|
||||
Op: ItemDIV,
|
||||
Op: DIV,
|
||||
LHS: &NumberLiteral{2.5},
|
||||
RHS: &VectorSelector{
|
||||
Name: "bar",
|
||||
@ -316,7 +316,7 @@ var testExpr = []struct {
|
||||
}, {
|
||||
input: "foo and bar",
|
||||
expected: &BinaryExpr{
|
||||
Op: ItemLAND,
|
||||
Op: LAND,
|
||||
LHS: &VectorSelector{
|
||||
Name: "foo",
|
||||
LabelMatchers: []*labels.Matcher{
|
||||
@ -334,7 +334,7 @@ var testExpr = []struct {
|
||||
}, {
|
||||
input: "foo or bar",
|
||||
expected: &BinaryExpr{
|
||||
Op: ItemLOR,
|
||||
Op: LOR,
|
||||
LHS: &VectorSelector{
|
||||
Name: "foo",
|
||||
LabelMatchers: []*labels.Matcher{
|
||||
@ -352,7 +352,7 @@ var testExpr = []struct {
|
||||
}, {
|
||||
input: "foo unless bar",
|
||||
expected: &BinaryExpr{
|
||||
Op: ItemLUnless,
|
||||
Op: LUNLESS,
|
||||
LHS: &VectorSelector{
|
||||
Name: "foo",
|
||||
LabelMatchers: []*labels.Matcher{
|
||||
@ -371,9 +371,9 @@ var testExpr = []struct {
|
||||
// Test and/or precedence and reassigning of operands.
|
||||
input: "foo + bar or bla and blub",
|
||||
expected: &BinaryExpr{
|
||||
Op: ItemLOR,
|
||||
Op: LOR,
|
||||
LHS: &BinaryExpr{
|
||||
Op: ItemADD,
|
||||
Op: ADD,
|
||||
LHS: &VectorSelector{
|
||||
Name: "foo",
|
||||
LabelMatchers: []*labels.Matcher{
|
||||
@ -389,7 +389,7 @@ var testExpr = []struct {
|
||||
VectorMatching: &VectorMatching{Card: CardOneToOne},
|
||||
},
|
||||
RHS: &BinaryExpr{
|
||||
Op: ItemLAND,
|
||||
Op: LAND,
|
||||
LHS: &VectorSelector{
|
||||
Name: "bla",
|
||||
LabelMatchers: []*labels.Matcher{
|
||||
@ -410,11 +410,11 @@ var testExpr = []struct {
|
||||
// Test and/or/unless precedence.
|
||||
input: "foo and bar unless baz or qux",
|
||||
expected: &BinaryExpr{
|
||||
Op: ItemLOR,
|
||||
Op: LOR,
|
||||
LHS: &BinaryExpr{
|
||||
Op: ItemLUnless,
|
||||
Op: LUNLESS,
|
||||
LHS: &BinaryExpr{
|
||||
Op: ItemLAND,
|
||||
Op: LAND,
|
||||
LHS: &VectorSelector{
|
||||
Name: "foo",
|
||||
LabelMatchers: []*labels.Matcher{
|
||||
@ -449,7 +449,7 @@ var testExpr = []struct {
|
||||
// Test precedence and reassigning of operands.
|
||||
input: "bar + on(foo) bla / on(baz, buz) group_right(test) blub",
|
||||
expected: &BinaryExpr{
|
||||
Op: ItemADD,
|
||||
Op: ADD,
|
||||
LHS: &VectorSelector{
|
||||
Name: "bar",
|
||||
LabelMatchers: []*labels.Matcher{
|
||||
@ -457,7 +457,7 @@ var testExpr = []struct {
|
||||
},
|
||||
},
|
||||
RHS: &BinaryExpr{
|
||||
Op: ItemDIV,
|
||||
Op: DIV,
|
||||
LHS: &VectorSelector{
|
||||
Name: "bla",
|
||||
LabelMatchers: []*labels.Matcher{
|
||||
@ -486,7 +486,7 @@ var testExpr = []struct {
|
||||
}, {
|
||||
input: "foo * on(test,blub) bar",
|
||||
expected: &BinaryExpr{
|
||||
Op: ItemMUL,
|
||||
Op: MUL,
|
||||
LHS: &VectorSelector{
|
||||
Name: "foo",
|
||||
LabelMatchers: []*labels.Matcher{
|
||||
@ -508,7 +508,7 @@ var testExpr = []struct {
|
||||
}, {
|
||||
input: "foo * on(test,blub) group_left bar",
|
||||
expected: &BinaryExpr{
|
||||
Op: ItemMUL,
|
||||
Op: MUL,
|
||||
LHS: &VectorSelector{
|
||||
Name: "foo",
|
||||
LabelMatchers: []*labels.Matcher{
|
||||
@ -530,7 +530,7 @@ var testExpr = []struct {
|
||||
}, {
|
||||
input: "foo and on(test,blub) bar",
|
||||
expected: &BinaryExpr{
|
||||
Op: ItemLAND,
|
||||
Op: LAND,
|
||||
LHS: &VectorSelector{
|
||||
Name: "foo",
|
||||
LabelMatchers: []*labels.Matcher{
|
||||
@ -552,7 +552,7 @@ var testExpr = []struct {
|
||||
}, {
|
||||
input: "foo and on() bar",
|
||||
expected: &BinaryExpr{
|
||||
Op: ItemLAND,
|
||||
Op: LAND,
|
||||
LHS: &VectorSelector{
|
||||
Name: "foo",
|
||||
LabelMatchers: []*labels.Matcher{
|
||||
@ -574,7 +574,7 @@ var testExpr = []struct {
|
||||
}, {
|
||||
input: "foo and ignoring(test,blub) bar",
|
||||
expected: &BinaryExpr{
|
||||
Op: ItemLAND,
|
||||
Op: LAND,
|
||||
LHS: &VectorSelector{
|
||||
Name: "foo",
|
||||
LabelMatchers: []*labels.Matcher{
|
||||
@ -595,7 +595,7 @@ var testExpr = []struct {
|
||||
}, {
|
||||
input: "foo and ignoring() bar",
|
||||
expected: &BinaryExpr{
|
||||
Op: ItemLAND,
|
||||
Op: LAND,
|
||||
LHS: &VectorSelector{
|
||||
Name: "foo",
|
||||
LabelMatchers: []*labels.Matcher{
|
||||
@ -616,7 +616,7 @@ var testExpr = []struct {
|
||||
}, {
|
||||
input: "foo unless on(bar) baz",
|
||||
expected: &BinaryExpr{
|
||||
Op: ItemLUnless,
|
||||
Op: LUNLESS,
|
||||
LHS: &VectorSelector{
|
||||
Name: "foo",
|
||||
LabelMatchers: []*labels.Matcher{
|
||||
@ -638,7 +638,7 @@ var testExpr = []struct {
|
||||
}, {
|
||||
input: "foo / on(test,blub) group_left(bar) bar",
|
||||
expected: &BinaryExpr{
|
||||
Op: ItemDIV,
|
||||
Op: DIV,
|
||||
LHS: &VectorSelector{
|
||||
Name: "foo",
|
||||
LabelMatchers: []*labels.Matcher{
|
||||
@ -661,7 +661,7 @@ var testExpr = []struct {
|
||||
}, {
|
||||
input: "foo / ignoring(test,blub) group_left(blub) bar",
|
||||
expected: &BinaryExpr{
|
||||
Op: ItemDIV,
|
||||
Op: DIV,
|
||||
LHS: &VectorSelector{
|
||||
Name: "foo",
|
||||
LabelMatchers: []*labels.Matcher{
|
||||
@ -683,7 +683,7 @@ var testExpr = []struct {
|
||||
}, {
|
||||
input: "foo / ignoring(test,blub) group_left(bar) bar",
|
||||
expected: &BinaryExpr{
|
||||
Op: ItemDIV,
|
||||
Op: DIV,
|
||||
LHS: &VectorSelector{
|
||||
Name: "foo",
|
||||
LabelMatchers: []*labels.Matcher{
|
||||
@ -705,7 +705,7 @@ var testExpr = []struct {
|
||||
}, {
|
||||
input: "foo - on(test,blub) group_right(bar,foo) bar",
|
||||
expected: &BinaryExpr{
|
||||
Op: ItemSUB,
|
||||
Op: SUB,
|
||||
LHS: &VectorSelector{
|
||||
Name: "foo",
|
||||
LabelMatchers: []*labels.Matcher{
|
||||
@ -728,7 +728,7 @@ var testExpr = []struct {
|
||||
}, {
|
||||
input: "foo - ignoring(test,blub) group_right(bar,foo) bar",
|
||||
expected: &BinaryExpr{
|
||||
Op: ItemSUB,
|
||||
Op: SUB,
|
||||
LHS: &VectorSelector{
|
||||
Name: "foo",
|
||||
LabelMatchers: []*labels.Matcher{
|
||||
@ -1057,7 +1057,7 @@ var testExpr = []struct {
|
||||
{
|
||||
input: "sum by (foo)(some_metric)",
|
||||
expected: &AggregateExpr{
|
||||
Op: ItemSum,
|
||||
Op: SUM,
|
||||
Expr: &VectorSelector{
|
||||
Name: "some_metric",
|
||||
LabelMatchers: []*labels.Matcher{
|
||||
@ -1069,7 +1069,7 @@ var testExpr = []struct {
|
||||
}, {
|
||||
input: "avg by (foo)(some_metric)",
|
||||
expected: &AggregateExpr{
|
||||
Op: ItemAvg,
|
||||
Op: AVG,
|
||||
Expr: &VectorSelector{
|
||||
Name: "some_metric",
|
||||
LabelMatchers: []*labels.Matcher{
|
||||
@ -1081,7 +1081,7 @@ var testExpr = []struct {
|
||||
}, {
|
||||
input: "max by (foo)(some_metric)",
|
||||
expected: &AggregateExpr{
|
||||
Op: ItemMax,
|
||||
Op: MAX,
|
||||
Expr: &VectorSelector{
|
||||
Name: "some_metric",
|
||||
LabelMatchers: []*labels.Matcher{
|
||||
@ -1093,7 +1093,7 @@ var testExpr = []struct {
|
||||
}, {
|
||||
input: "sum without (foo) (some_metric)",
|
||||
expected: &AggregateExpr{
|
||||
Op: ItemSum,
|
||||
Op: SUM,
|
||||
Without: true,
|
||||
Expr: &VectorSelector{
|
||||
Name: "some_metric",
|
||||
@ -1106,7 +1106,7 @@ var testExpr = []struct {
|
||||
}, {
|
||||
input: "sum (some_metric) without (foo)",
|
||||
expected: &AggregateExpr{
|
||||
Op: ItemSum,
|
||||
Op: SUM,
|
||||
Without: true,
|
||||
Expr: &VectorSelector{
|
||||
Name: "some_metric",
|
||||
@ -1119,7 +1119,7 @@ var testExpr = []struct {
|
||||
}, {
|
||||
input: "stddev(some_metric)",
|
||||
expected: &AggregateExpr{
|
||||
Op: ItemStddev,
|
||||
Op: STDDEV,
|
||||
Expr: &VectorSelector{
|
||||
Name: "some_metric",
|
||||
LabelMatchers: []*labels.Matcher{
|
||||
@ -1130,7 +1130,7 @@ var testExpr = []struct {
|
||||
}, {
|
||||
input: "stdvar by (foo)(some_metric)",
|
||||
expected: &AggregateExpr{
|
||||
Op: ItemStdvar,
|
||||
Op: STDVAR,
|
||||
Expr: &VectorSelector{
|
||||
Name: "some_metric",
|
||||
LabelMatchers: []*labels.Matcher{
|
||||
@ -1142,7 +1142,7 @@ var testExpr = []struct {
|
||||
}, {
|
||||
input: "sum by ()(some_metric)",
|
||||
expected: &AggregateExpr{
|
||||
Op: ItemSum,
|
||||
Op: SUM,
|
||||
Expr: &VectorSelector{
|
||||
Name: "some_metric",
|
||||
LabelMatchers: []*labels.Matcher{
|
||||
@ -1154,7 +1154,7 @@ var testExpr = []struct {
|
||||
}, {
|
||||
input: "topk(5, some_metric)",
|
||||
expected: &AggregateExpr{
|
||||
Op: ItemTopK,
|
||||
Op: TOPK,
|
||||
Expr: &VectorSelector{
|
||||
Name: "some_metric",
|
||||
LabelMatchers: []*labels.Matcher{
|
||||
@ -1166,7 +1166,7 @@ var testExpr = []struct {
|
||||
}, {
|
||||
input: "count_values(\"value\", some_metric)",
|
||||
expected: &AggregateExpr{
|
||||
Op: ItemCountValues,
|
||||
Op: COUNT_VALUES,
|
||||
Expr: &VectorSelector{
|
||||
Name: "some_metric",
|
||||
LabelMatchers: []*labels.Matcher{
|
||||
@ -1179,7 +1179,7 @@ var testExpr = []struct {
|
||||
// Test usage of keywords as label names.
|
||||
input: "sum without(and, by, avg, count, alert, annotations)(some_metric)",
|
||||
expected: &AggregateExpr{
|
||||
Op: ItemSum,
|
||||
Op: SUM,
|
||||
Without: true,
|
||||
Expr: &VectorSelector{
|
||||
Name: "some_metric",
|
||||
@ -1494,7 +1494,7 @@ var testExpr = []struct {
|
||||
input: "sum without(and, by, avg, count, alert, annotations)(some_metric) [30m:10s]",
|
||||
expected: &SubqueryExpr{
|
||||
Expr: &AggregateExpr{
|
||||
Op: ItemSum,
|
||||
Op: SUM,
|
||||
Without: true,
|
||||
Expr: &VectorSelector{
|
||||
Name: "some_metric",
|
||||
@ -1525,7 +1525,7 @@ var testExpr = []struct {
|
||||
expected: &SubqueryExpr{
|
||||
Expr: &ParenExpr{
|
||||
Expr: &BinaryExpr{
|
||||
Op: ItemADD,
|
||||
Op: ADD,
|
||||
VectorMatching: &VectorMatching{
|
||||
Card: CardOneToOne,
|
||||
},
|
||||
@ -1551,7 +1551,7 @@ var testExpr = []struct {
|
||||
expected: &SubqueryExpr{
|
||||
Expr: &ParenExpr{
|
||||
Expr: &BinaryExpr{
|
||||
Op: ItemADD,
|
||||
Op: ADD,
|
||||
VectorMatching: &VectorMatching{
|
||||
Card: CardOneToOne,
|
||||
},
|
||||
|
Loading…
Reference in New Issue
Block a user