mirror of
https://github.com/prometheus/prometheus.git
synced 2025-01-12 06:17:27 -08:00
PromQL: AST: Make VectorSelector Children of MatrixSelector (#6590)
Make Vector selectors children of Matrix Selectors Signed-off-by: Tobias Guggenmos <tguggenm@redhat.com>
This commit is contained in:
parent
e7f7b6a06f
commit
64194f7d45
|
@ -107,14 +107,8 @@ type Call struct {
|
||||||
|
|
||||||
// MatrixSelector represents a Matrix selection.
|
// MatrixSelector represents a Matrix selection.
|
||||||
type MatrixSelector struct {
|
type MatrixSelector struct {
|
||||||
Name string
|
VectorSelector *VectorSelector
|
||||||
Range time.Duration
|
Range time.Duration
|
||||||
Offset time.Duration
|
|
||||||
LabelMatchers []*labels.Matcher
|
|
||||||
|
|
||||||
// The unexpanded seriesSet populated at query preparation time.
|
|
||||||
unexpandedSeriesSet storage.SeriesSet
|
|
||||||
series []storage.Series
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// SubqueryExpr represents a subquery.
|
// SubqueryExpr represents a subquery.
|
||||||
|
@ -316,7 +310,9 @@ func Children(node Node) []Node {
|
||||||
return []Node{n.Expr}
|
return []Node{n.Expr}
|
||||||
case *UnaryExpr:
|
case *UnaryExpr:
|
||||||
return []Node{n.Expr}
|
return []Node{n.Expr}
|
||||||
case *MatrixSelector, *NumberLiteral, *StringLiteral, *VectorSelector:
|
case *MatrixSelector:
|
||||||
|
return []Node{n.VectorSelector}
|
||||||
|
case *NumberLiteral, *StringLiteral, *VectorSelector:
|
||||||
// nothing to do
|
// nothing to do
|
||||||
return []Node{}
|
return []Node{}
|
||||||
default:
|
default:
|
||||||
|
|
|
@ -623,8 +623,8 @@ func (ng *Engine) populateSeries(ctx context.Context, q storage.Queryable, s *Ev
|
||||||
if maxOffset < n.Range+subqOffset {
|
if maxOffset < n.Range+subqOffset {
|
||||||
maxOffset = n.Range + subqOffset
|
maxOffset = n.Range + subqOffset
|
||||||
}
|
}
|
||||||
if n.Offset+n.Range+subqOffset > maxOffset {
|
if m := n.VectorSelector.Offset + n.Range + subqOffset; m > maxOffset {
|
||||||
maxOffset = n.Offset + n.Range + subqOffset
|
maxOffset = m
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
|
@ -639,6 +639,11 @@ func (ng *Engine) populateSeries(ctx context.Context, q storage.Queryable, s *Ev
|
||||||
|
|
||||||
var warnings storage.Warnings
|
var warnings storage.Warnings
|
||||||
|
|
||||||
|
// Whenever a MatrixSelector is evaluated this variable is set to the corresponding range.
|
||||||
|
// The evaluation of the VectorSelector inside then evaluates the given range and unsets
|
||||||
|
// the variable.
|
||||||
|
var evalRange time.Duration
|
||||||
|
|
||||||
Inspect(s.Expr, func(node Node, path []Node) error {
|
Inspect(s.Expr, func(node Node, path []Node) error {
|
||||||
var set storage.SeriesSet
|
var set storage.SeriesSet
|
||||||
var wrn storage.Warnings
|
var wrn storage.Warnings
|
||||||
|
@ -658,7 +663,16 @@ func (ng *Engine) populateSeries(ctx context.Context, q storage.Queryable, s *Ev
|
||||||
|
|
||||||
switch n := node.(type) {
|
switch n := node.(type) {
|
||||||
case *VectorSelector:
|
case *VectorSelector:
|
||||||
|
if evalRange == 0 {
|
||||||
params.Start = params.Start - durationMilliseconds(LookbackDelta)
|
params.Start = params.Start - durationMilliseconds(LookbackDelta)
|
||||||
|
} else {
|
||||||
|
params.Range = durationMilliseconds(evalRange)
|
||||||
|
// For all matrix queries we want to ensure that we have (end-start) + range selected
|
||||||
|
// this way we have `range` data before the start time
|
||||||
|
params.Start = params.Start - durationMilliseconds(evalRange)
|
||||||
|
evalRange = 0
|
||||||
|
}
|
||||||
|
|
||||||
params.Func = extractFuncFromPath(path)
|
params.Func = extractFuncFromPath(path)
|
||||||
params.By, params.Grouping = extractGroupsFromPath(path)
|
params.By, params.Grouping = extractGroupsFromPath(path)
|
||||||
if n.Offset > 0 {
|
if n.Offset > 0 {
|
||||||
|
@ -676,24 +690,7 @@ func (ng *Engine) populateSeries(ctx context.Context, q storage.Queryable, s *Ev
|
||||||
n.unexpandedSeriesSet = set
|
n.unexpandedSeriesSet = set
|
||||||
|
|
||||||
case *MatrixSelector:
|
case *MatrixSelector:
|
||||||
params.Func = extractFuncFromPath(path)
|
evalRange = n.Range
|
||||||
params.Range = durationMilliseconds(n.Range)
|
|
||||||
// For all matrix queries we want to ensure that we have (end-start) + range selected
|
|
||||||
// this way we have `range` data before the start time
|
|
||||||
params.Start = params.Start - durationMilliseconds(n.Range)
|
|
||||||
if n.Offset > 0 {
|
|
||||||
offsetMilliseconds := durationMilliseconds(n.Offset)
|
|
||||||
params.Start = params.Start - offsetMilliseconds
|
|
||||||
params.End = params.End - offsetMilliseconds
|
|
||||||
}
|
|
||||||
|
|
||||||
set, wrn, err = querier.Select(params, n.LabelMatchers...)
|
|
||||||
warnings = append(warnings, wrn...)
|
|
||||||
if err != nil {
|
|
||||||
level.Error(ng.logger).Log("msg", "error selecting series set", "err", err)
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
n.unexpandedSeriesSet = set
|
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
|
@ -734,14 +731,7 @@ func extractGroupsFromPath(p []Node) (bool, []string) {
|
||||||
func checkForSeriesSetExpansion(ctx context.Context, expr Expr) {
|
func checkForSeriesSetExpansion(ctx context.Context, expr Expr) {
|
||||||
switch e := expr.(type) {
|
switch e := expr.(type) {
|
||||||
case *MatrixSelector:
|
case *MatrixSelector:
|
||||||
if e.series == nil {
|
checkForSeriesSetExpansion(ctx, e.VectorSelector)
|
||||||
series, err := expandSeriesSet(ctx, e.unexpandedSeriesSet)
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
} else {
|
|
||||||
e.series = series
|
|
||||||
}
|
|
||||||
}
|
|
||||||
case *VectorSelector:
|
case *VectorSelector:
|
||||||
if e.series == nil {
|
if e.series == nil {
|
||||||
series, err := expandSeriesSet(ctx, e.unexpandedSeriesSet)
|
series, err := expandSeriesSet(ctx, e.unexpandedSeriesSet)
|
||||||
|
@ -1001,11 +991,13 @@ func (ev *evaluator) evalSubquery(subq *SubqueryExpr) *MatrixSelector {
|
||||||
val := ev.eval(subq).(Matrix)
|
val := ev.eval(subq).(Matrix)
|
||||||
ms := &MatrixSelector{
|
ms := &MatrixSelector{
|
||||||
Range: subq.Range,
|
Range: subq.Range,
|
||||||
|
VectorSelector: &VectorSelector{
|
||||||
Offset: subq.Offset,
|
Offset: subq.Offset,
|
||||||
series: make([]storage.Series, 0, len(val)),
|
series: make([]storage.Series, 0, len(val)),
|
||||||
|
},
|
||||||
}
|
}
|
||||||
for _, s := range val {
|
for _, s := range val {
|
||||||
ms.series = append(ms.series, NewStorageSeries(s))
|
ms.VectorSelector.series = append(ms.VectorSelector.series, NewStorageSeries(s))
|
||||||
}
|
}
|
||||||
return ms
|
return ms
|
||||||
}
|
}
|
||||||
|
@ -1085,9 +1077,11 @@ func (ev *evaluator) eval(expr Expr) Value {
|
||||||
}
|
}
|
||||||
|
|
||||||
sel := e.Args[matrixArgIndex].(*MatrixSelector)
|
sel := e.Args[matrixArgIndex].(*MatrixSelector)
|
||||||
|
selVS := sel.VectorSelector
|
||||||
|
|
||||||
checkForSeriesSetExpansion(ev.ctx, sel)
|
checkForSeriesSetExpansion(ev.ctx, sel)
|
||||||
mat := make(Matrix, 0, len(sel.series)) // Output matrix.
|
mat := make(Matrix, 0, len(selVS.series)) // Output matrix.
|
||||||
offset := durationMilliseconds(sel.Offset)
|
offset := durationMilliseconds(selVS.Offset)
|
||||||
selRange := durationMilliseconds(sel.Range)
|
selRange := durationMilliseconds(sel.Range)
|
||||||
stepRange := selRange
|
stepRange := selRange
|
||||||
if stepRange > ev.interval {
|
if stepRange > ev.interval {
|
||||||
|
@ -1100,17 +1094,17 @@ func (ev *evaluator) eval(expr Expr) Value {
|
||||||
enh := &EvalNodeHelper{out: make(Vector, 0, 1)}
|
enh := &EvalNodeHelper{out: make(Vector, 0, 1)}
|
||||||
// Process all the calls for one time series at a time.
|
// Process all the calls for one time series at a time.
|
||||||
it := storage.NewBuffer(selRange)
|
it := storage.NewBuffer(selRange)
|
||||||
for i, s := range sel.series {
|
for i, s := range selVS.series {
|
||||||
points = points[:0]
|
points = points[:0]
|
||||||
it.Reset(s.Iterator())
|
it.Reset(s.Iterator())
|
||||||
ss := Series{
|
ss := Series{
|
||||||
// For all range vector functions, the only change to the
|
// For all range vector functions, the only change to the
|
||||||
// output labels is dropping the metric name so just do
|
// output labels is dropping the metric name so just do
|
||||||
// it once here.
|
// it once here.
|
||||||
Metric: dropMetricName(sel.series[i].Labels()),
|
Metric: dropMetricName(selVS.series[i].Labels()),
|
||||||
Points: getPointSlice(numSteps),
|
Points: getPointSlice(numSteps),
|
||||||
}
|
}
|
||||||
inMatrix[0].Metric = sel.series[i].Labels()
|
inMatrix[0].Metric = selVS.series[i].Labels()
|
||||||
for ts, step := ev.startTimestamp, -1; ts <= ev.endTimestamp; ts += ev.interval {
|
for ts, step := ev.startTimestamp, -1; ts <= ev.endTimestamp; ts += ev.interval {
|
||||||
step++
|
step++
|
||||||
// Set the non-matrix arguments.
|
// Set the non-matrix arguments.
|
||||||
|
@ -1409,20 +1403,22 @@ func (ev *evaluator) matrixSelector(node *MatrixSelector) Matrix {
|
||||||
checkForSeriesSetExpansion(ev.ctx, node)
|
checkForSeriesSetExpansion(ev.ctx, node)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
offset = durationMilliseconds(node.Offset)
|
offset = durationMilliseconds(node.VectorSelector.Offset)
|
||||||
maxt = ev.startTimestamp - offset
|
maxt = ev.startTimestamp - offset
|
||||||
mint = maxt - durationMilliseconds(node.Range)
|
mint = maxt - durationMilliseconds(node.Range)
|
||||||
matrix = make(Matrix, 0, len(node.series))
|
matrix = make(Matrix, 0, len(node.VectorSelector.series))
|
||||||
)
|
)
|
||||||
|
|
||||||
it := storage.NewBuffer(durationMilliseconds(node.Range))
|
it := storage.NewBuffer(durationMilliseconds(node.Range))
|
||||||
for i, s := range node.series {
|
series := node.VectorSelector.series
|
||||||
|
|
||||||
|
for i, s := range series {
|
||||||
if err := contextDone(ev.ctx, "expression evaluation"); err != nil {
|
if err := contextDone(ev.ctx, "expression evaluation"); err != nil {
|
||||||
ev.error(err)
|
ev.error(err)
|
||||||
}
|
}
|
||||||
it.Reset(s.Iterator())
|
it.Reset(s.Iterator())
|
||||||
ss := Series{
|
ss := Series{
|
||||||
Metric: node.series[i].Labels(),
|
Metric: series[i].Labels(),
|
||||||
}
|
}
|
||||||
|
|
||||||
ss.Points = ev.matrixIterSlice(it, mint, maxt, getPointSlice(16))
|
ss.Points = ev.matrixIterSlice(it, mint, maxt, getPointSlice(16))
|
||||||
|
|
|
@ -67,8 +67,8 @@ func extrapolatedRate(vals []Value, args Expressions, enh *EvalNodeHelper, isCou
|
||||||
|
|
||||||
var (
|
var (
|
||||||
samples = vals[0].(Matrix)[0]
|
samples = vals[0].(Matrix)[0]
|
||||||
rangeStart = enh.ts - durationMilliseconds(ms.Range+ms.Offset)
|
rangeStart = enh.ts - durationMilliseconds(ms.Range+ms.VectorSelector.Offset)
|
||||||
rangeEnd = enh.ts - durationMilliseconds(ms.Offset)
|
rangeEnd = enh.ts - durationMilliseconds(ms.VectorSelector.Offset)
|
||||||
)
|
)
|
||||||
|
|
||||||
// No sense in trying to compute a rate without at least two points. Drop
|
// No sense in trying to compute a rate without at least two points. Drop
|
||||||
|
@ -1243,7 +1243,7 @@ func createLabelsForAbsentFunction(expr Expr) labels.Labels {
|
||||||
case *VectorSelector:
|
case *VectorSelector:
|
||||||
lm = n.LabelMatchers
|
lm = n.LabelMatchers
|
||||||
case *MatrixSelector:
|
case *MatrixSelector:
|
||||||
lm = n.LabelMatchers
|
lm = n.VectorSelector.LabelMatchers
|
||||||
default:
|
default:
|
||||||
return m
|
return m
|
||||||
}
|
}
|
||||||
|
|
|
@ -384,9 +384,7 @@ matrix_selector : expr LEFT_BRACKET duration RIGHT_BRACKET
|
||||||
yylex.(*parser).errorf("no offset modifiers allowed before range")
|
yylex.(*parser).errorf("no offset modifiers allowed before range")
|
||||||
}
|
}
|
||||||
$$ = &MatrixSelector{
|
$$ = &MatrixSelector{
|
||||||
Name: vs.Name,
|
VectorSelector: vs,
|
||||||
Offset: vs.Offset,
|
|
||||||
LabelMatchers: vs.LabelMatchers,
|
|
||||||
Range: $3,
|
Range: $3,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -184,7 +184,7 @@ const yyEofCode = 1
|
||||||
const yyErrCode = 2
|
const yyErrCode = 2
|
||||||
const yyInitialStackSize = 16
|
const yyInitialStackSize = 16
|
||||||
|
|
||||||
//line promql/generated_parser.y:641
|
//line promql/generated_parser.y:639
|
||||||
|
|
||||||
//line yacctab:1
|
//line yacctab:1
|
||||||
var yyExca = [...]int{
|
var yyExca = [...]int{
|
||||||
|
@ -1119,15 +1119,13 @@ yydefault:
|
||||||
yylex.(*parser).errorf("no offset modifiers allowed before range")
|
yylex.(*parser).errorf("no offset modifiers allowed before range")
|
||||||
}
|
}
|
||||||
yyVAL.node = &MatrixSelector{
|
yyVAL.node = &MatrixSelector{
|
||||||
Name: vs.Name,
|
VectorSelector: vs,
|
||||||
Offset: vs.Offset,
|
|
||||||
LabelMatchers: vs.LabelMatchers,
|
|
||||||
Range: yyDollar[3].duration,
|
Range: yyDollar[3].duration,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
case 67:
|
case 67:
|
||||||
yyDollar = yyS[yypt-6 : yypt+1]
|
yyDollar = yyS[yypt-6 : yypt+1]
|
||||||
//line promql/generated_parser.y:396
|
//line promql/generated_parser.y:394
|
||||||
{
|
{
|
||||||
yyVAL.node = &SubqueryExpr{
|
yyVAL.node = &SubqueryExpr{
|
||||||
Expr: yyDollar[1].node.(Expr),
|
Expr: yyDollar[1].node.(Expr),
|
||||||
|
@ -1137,31 +1135,31 @@ yydefault:
|
||||||
}
|
}
|
||||||
case 68:
|
case 68:
|
||||||
yyDollar = yyS[yypt-6 : yypt+1]
|
yyDollar = yyS[yypt-6 : yypt+1]
|
||||||
//line promql/generated_parser.y:404
|
//line promql/generated_parser.y:402
|
||||||
{
|
{
|
||||||
yylex.(*parser).unexpected("subquery selector", "\"]\"")
|
yylex.(*parser).unexpected("subquery selector", "\"]\"")
|
||||||
}
|
}
|
||||||
case 69:
|
case 69:
|
||||||
yyDollar = yyS[yypt-5 : yypt+1]
|
yyDollar = yyS[yypt-5 : yypt+1]
|
||||||
//line promql/generated_parser.y:406
|
//line promql/generated_parser.y:404
|
||||||
{
|
{
|
||||||
yylex.(*parser).unexpected("subquery selector", "duration or \"]\"")
|
yylex.(*parser).unexpected("subquery selector", "duration or \"]\"")
|
||||||
}
|
}
|
||||||
case 70:
|
case 70:
|
||||||
yyDollar = yyS[yypt-4 : yypt+1]
|
yyDollar = yyS[yypt-4 : yypt+1]
|
||||||
//line promql/generated_parser.y:408
|
//line promql/generated_parser.y:406
|
||||||
{
|
{
|
||||||
yylex.(*parser).unexpected("subquery or range", "\":\" or \"]\"")
|
yylex.(*parser).unexpected("subquery or range", "\":\" or \"]\"")
|
||||||
}
|
}
|
||||||
case 71:
|
case 71:
|
||||||
yyDollar = yyS[yypt-3 : yypt+1]
|
yyDollar = yyS[yypt-3 : yypt+1]
|
||||||
//line promql/generated_parser.y:410
|
//line promql/generated_parser.y:408
|
||||||
{
|
{
|
||||||
yylex.(*parser).unexpected("subquery selector", "duration")
|
yylex.(*parser).unexpected("subquery selector", "duration")
|
||||||
}
|
}
|
||||||
case 72:
|
case 72:
|
||||||
yyDollar = yyS[yypt-2 : yypt+1]
|
yyDollar = yyS[yypt-2 : yypt+1]
|
||||||
//line promql/generated_parser.y:420
|
//line promql/generated_parser.y:418
|
||||||
{
|
{
|
||||||
if nl, ok := yyDollar[2].node.(*NumberLiteral); ok {
|
if nl, ok := yyDollar[2].node.(*NumberLiteral); ok {
|
||||||
if yyDollar[1].item.Typ == SUB {
|
if yyDollar[1].item.Typ == SUB {
|
||||||
|
@ -1174,164 +1172,164 @@ yydefault:
|
||||||
}
|
}
|
||||||
case 73:
|
case 73:
|
||||||
yyDollar = yyS[yypt-2 : yypt+1]
|
yyDollar = yyS[yypt-2 : yypt+1]
|
||||||
//line promql/generated_parser.y:437
|
//line promql/generated_parser.y:435
|
||||||
{
|
{
|
||||||
yyVAL.node = yylex.(*parser).newVectorSelector(yyDollar[1].item.Val, yyDollar[2].matchers)
|
yyVAL.node = yylex.(*parser).newVectorSelector(yyDollar[1].item.Val, yyDollar[2].matchers)
|
||||||
}
|
}
|
||||||
case 74:
|
case 74:
|
||||||
yyDollar = yyS[yypt-1 : yypt+1]
|
yyDollar = yyS[yypt-1 : yypt+1]
|
||||||
//line promql/generated_parser.y:439
|
//line promql/generated_parser.y:437
|
||||||
{
|
{
|
||||||
yyVAL.node = yylex.(*parser).newVectorSelector(yyDollar[1].item.Val, nil)
|
yyVAL.node = yylex.(*parser).newVectorSelector(yyDollar[1].item.Val, nil)
|
||||||
}
|
}
|
||||||
case 75:
|
case 75:
|
||||||
yyDollar = yyS[yypt-1 : yypt+1]
|
yyDollar = yyS[yypt-1 : yypt+1]
|
||||||
//line promql/generated_parser.y:441
|
//line promql/generated_parser.y:439
|
||||||
{
|
{
|
||||||
yyVAL.node = yylex.(*parser).newVectorSelector("", yyDollar[1].matchers)
|
yyVAL.node = yylex.(*parser).newVectorSelector("", yyDollar[1].matchers)
|
||||||
}
|
}
|
||||||
case 76:
|
case 76:
|
||||||
yyDollar = yyS[yypt-3 : yypt+1]
|
yyDollar = yyS[yypt-3 : yypt+1]
|
||||||
//line promql/generated_parser.y:445
|
//line promql/generated_parser.y:443
|
||||||
{
|
{
|
||||||
yyVAL.matchers = yyDollar[2].matchers
|
yyVAL.matchers = yyDollar[2].matchers
|
||||||
}
|
}
|
||||||
case 77:
|
case 77:
|
||||||
yyDollar = yyS[yypt-4 : yypt+1]
|
yyDollar = yyS[yypt-4 : yypt+1]
|
||||||
//line promql/generated_parser.y:447
|
//line promql/generated_parser.y:445
|
||||||
{
|
{
|
||||||
yyVAL.matchers = yyDollar[2].matchers
|
yyVAL.matchers = yyDollar[2].matchers
|
||||||
}
|
}
|
||||||
case 78:
|
case 78:
|
||||||
yyDollar = yyS[yypt-2 : yypt+1]
|
yyDollar = yyS[yypt-2 : yypt+1]
|
||||||
//line promql/generated_parser.y:449
|
//line promql/generated_parser.y:447
|
||||||
{
|
{
|
||||||
yyVAL.matchers = []*labels.Matcher{}
|
yyVAL.matchers = []*labels.Matcher{}
|
||||||
}
|
}
|
||||||
case 79:
|
case 79:
|
||||||
yyDollar = yyS[yypt-3 : yypt+1]
|
yyDollar = yyS[yypt-3 : yypt+1]
|
||||||
//line promql/generated_parser.y:454
|
//line promql/generated_parser.y:452
|
||||||
{
|
{
|
||||||
yyVAL.matchers = append(yyDollar[1].matchers, yyDollar[3].matcher)
|
yyVAL.matchers = append(yyDollar[1].matchers, yyDollar[3].matcher)
|
||||||
}
|
}
|
||||||
case 80:
|
case 80:
|
||||||
yyDollar = yyS[yypt-1 : yypt+1]
|
yyDollar = yyS[yypt-1 : yypt+1]
|
||||||
//line promql/generated_parser.y:456
|
//line promql/generated_parser.y:454
|
||||||
{
|
{
|
||||||
yyVAL.matchers = []*labels.Matcher{yyDollar[1].matcher}
|
yyVAL.matchers = []*labels.Matcher{yyDollar[1].matcher}
|
||||||
}
|
}
|
||||||
case 81:
|
case 81:
|
||||||
yyDollar = yyS[yypt-2 : yypt+1]
|
yyDollar = yyS[yypt-2 : yypt+1]
|
||||||
//line promql/generated_parser.y:458
|
//line promql/generated_parser.y:456
|
||||||
{
|
{
|
||||||
yylex.(*parser).unexpected("label matching", "\",\" or \"}\"")
|
yylex.(*parser).unexpected("label matching", "\",\" or \"}\"")
|
||||||
}
|
}
|
||||||
case 82:
|
case 82:
|
||||||
yyDollar = yyS[yypt-3 : yypt+1]
|
yyDollar = yyS[yypt-3 : yypt+1]
|
||||||
//line promql/generated_parser.y:462
|
//line promql/generated_parser.y:460
|
||||||
{
|
{
|
||||||
yyVAL.matcher = yylex.(*parser).newLabelMatcher(yyDollar[1].item, yyDollar[2].item, yyDollar[3].item)
|
yyVAL.matcher = yylex.(*parser).newLabelMatcher(yyDollar[1].item, yyDollar[2].item, yyDollar[3].item)
|
||||||
}
|
}
|
||||||
case 83:
|
case 83:
|
||||||
yyDollar = yyS[yypt-3 : yypt+1]
|
yyDollar = yyS[yypt-3 : yypt+1]
|
||||||
//line promql/generated_parser.y:464
|
//line promql/generated_parser.y:462
|
||||||
{
|
{
|
||||||
yylex.(*parser).unexpected("label matching", "string")
|
yylex.(*parser).unexpected("label matching", "string")
|
||||||
}
|
}
|
||||||
case 84:
|
case 84:
|
||||||
yyDollar = yyS[yypt-2 : yypt+1]
|
yyDollar = yyS[yypt-2 : yypt+1]
|
||||||
//line promql/generated_parser.y:466
|
//line promql/generated_parser.y:464
|
||||||
{
|
{
|
||||||
yylex.(*parser).unexpected("label matching", "label matching operator")
|
yylex.(*parser).unexpected("label matching", "label matching operator")
|
||||||
}
|
}
|
||||||
case 85:
|
case 85:
|
||||||
yyDollar = yyS[yypt-1 : yypt+1]
|
yyDollar = yyS[yypt-1 : yypt+1]
|
||||||
//line promql/generated_parser.y:468
|
//line promql/generated_parser.y:466
|
||||||
{
|
{
|
||||||
yylex.(*parser).unexpected("label matching", "identifier or \"}\"")
|
yylex.(*parser).unexpected("label matching", "identifier or \"}\"")
|
||||||
}
|
}
|
||||||
case 86:
|
case 86:
|
||||||
yyDollar = yyS[yypt-2 : yypt+1]
|
yyDollar = yyS[yypt-2 : yypt+1]
|
||||||
//line promql/generated_parser.y:476
|
//line promql/generated_parser.y:474
|
||||||
{
|
{
|
||||||
yyVAL.labels = append(yyDollar[2].labels, labels.Label{Name: labels.MetricName, Value: yyDollar[1].item.Val})
|
yyVAL.labels = append(yyDollar[2].labels, labels.Label{Name: labels.MetricName, Value: yyDollar[1].item.Val})
|
||||||
sort.Sort(yyVAL.labels)
|
sort.Sort(yyVAL.labels)
|
||||||
}
|
}
|
||||||
case 87:
|
case 87:
|
||||||
yyDollar = yyS[yypt-1 : yypt+1]
|
yyDollar = yyS[yypt-1 : yypt+1]
|
||||||
//line promql/generated_parser.y:478
|
//line promql/generated_parser.y:476
|
||||||
{
|
{
|
||||||
yyVAL.labels = yyDollar[1].labels
|
yyVAL.labels = yyDollar[1].labels
|
||||||
}
|
}
|
||||||
case 90:
|
case 90:
|
||||||
yyDollar = yyS[yypt-3 : yypt+1]
|
yyDollar = yyS[yypt-3 : yypt+1]
|
||||||
//line promql/generated_parser.y:485
|
//line promql/generated_parser.y:483
|
||||||
{
|
{
|
||||||
yyVAL.labels = labels.New(yyDollar[2].labels...)
|
yyVAL.labels = labels.New(yyDollar[2].labels...)
|
||||||
}
|
}
|
||||||
case 91:
|
case 91:
|
||||||
yyDollar = yyS[yypt-4 : yypt+1]
|
yyDollar = yyS[yypt-4 : yypt+1]
|
||||||
//line promql/generated_parser.y:487
|
//line promql/generated_parser.y:485
|
||||||
{
|
{
|
||||||
yyVAL.labels = labels.New(yyDollar[2].labels...)
|
yyVAL.labels = labels.New(yyDollar[2].labels...)
|
||||||
}
|
}
|
||||||
case 92:
|
case 92:
|
||||||
yyDollar = yyS[yypt-2 : yypt+1]
|
yyDollar = yyS[yypt-2 : yypt+1]
|
||||||
//line promql/generated_parser.y:489
|
//line promql/generated_parser.y:487
|
||||||
{
|
{
|
||||||
yyVAL.labels = labels.New()
|
yyVAL.labels = labels.New()
|
||||||
}
|
}
|
||||||
case 93:
|
case 93:
|
||||||
yyDollar = yyS[yypt-0 : yypt+1]
|
yyDollar = yyS[yypt-0 : yypt+1]
|
||||||
//line promql/generated_parser.y:491
|
//line promql/generated_parser.y:489
|
||||||
{
|
{
|
||||||
yyVAL.labels = labels.New()
|
yyVAL.labels = labels.New()
|
||||||
}
|
}
|
||||||
case 94:
|
case 94:
|
||||||
yyDollar = yyS[yypt-3 : yypt+1]
|
yyDollar = yyS[yypt-3 : yypt+1]
|
||||||
//line promql/generated_parser.y:495
|
//line promql/generated_parser.y:493
|
||||||
{
|
{
|
||||||
yyVAL.labels = append(yyDollar[1].labels, yyDollar[3].label)
|
yyVAL.labels = append(yyDollar[1].labels, yyDollar[3].label)
|
||||||
}
|
}
|
||||||
case 95:
|
case 95:
|
||||||
yyDollar = yyS[yypt-1 : yypt+1]
|
yyDollar = yyS[yypt-1 : yypt+1]
|
||||||
//line promql/generated_parser.y:497
|
//line promql/generated_parser.y:495
|
||||||
{
|
{
|
||||||
yyVAL.labels = []labels.Label{yyDollar[1].label}
|
yyVAL.labels = []labels.Label{yyDollar[1].label}
|
||||||
}
|
}
|
||||||
case 96:
|
case 96:
|
||||||
yyDollar = yyS[yypt-2 : yypt+1]
|
yyDollar = yyS[yypt-2 : yypt+1]
|
||||||
//line promql/generated_parser.y:499
|
//line promql/generated_parser.y:497
|
||||||
{
|
{
|
||||||
yylex.(*parser).unexpected("label set", "\",\" or \"}\"")
|
yylex.(*parser).unexpected("label set", "\",\" or \"}\"")
|
||||||
}
|
}
|
||||||
case 97:
|
case 97:
|
||||||
yyDollar = yyS[yypt-3 : yypt+1]
|
yyDollar = yyS[yypt-3 : yypt+1]
|
||||||
//line promql/generated_parser.y:504
|
//line promql/generated_parser.y:502
|
||||||
{
|
{
|
||||||
yyVAL.label = labels.Label{Name: yyDollar[1].item.Val, Value: yylex.(*parser).unquoteString(yyDollar[3].item.Val)}
|
yyVAL.label = labels.Label{Name: yyDollar[1].item.Val, Value: yylex.(*parser).unquoteString(yyDollar[3].item.Val)}
|
||||||
}
|
}
|
||||||
case 98:
|
case 98:
|
||||||
yyDollar = yyS[yypt-3 : yypt+1]
|
yyDollar = yyS[yypt-3 : yypt+1]
|
||||||
//line promql/generated_parser.y:506
|
//line promql/generated_parser.y:504
|
||||||
{
|
{
|
||||||
yylex.(*parser).unexpected("label set", "string")
|
yylex.(*parser).unexpected("label set", "string")
|
||||||
}
|
}
|
||||||
case 99:
|
case 99:
|
||||||
yyDollar = yyS[yypt-2 : yypt+1]
|
yyDollar = yyS[yypt-2 : yypt+1]
|
||||||
//line promql/generated_parser.y:508
|
//line promql/generated_parser.y:506
|
||||||
{
|
{
|
||||||
yylex.(*parser).unexpected("label set", "\"=\"")
|
yylex.(*parser).unexpected("label set", "\"=\"")
|
||||||
}
|
}
|
||||||
case 100:
|
case 100:
|
||||||
yyDollar = yyS[yypt-1 : yypt+1]
|
yyDollar = yyS[yypt-1 : yypt+1]
|
||||||
//line promql/generated_parser.y:510
|
//line promql/generated_parser.y:508
|
||||||
{
|
{
|
||||||
yylex.(*parser).unexpected("label set", "identifier or \"}\"")
|
yylex.(*parser).unexpected("label set", "identifier or \"}\"")
|
||||||
}
|
}
|
||||||
case 101:
|
case 101:
|
||||||
yyDollar = yyS[yypt-2 : yypt+1]
|
yyDollar = yyS[yypt-2 : yypt+1]
|
||||||
//line promql/generated_parser.y:518
|
//line promql/generated_parser.y:516
|
||||||
{
|
{
|
||||||
yylex.(*parser).generatedParserResult = &seriesDescription{
|
yylex.(*parser).generatedParserResult = &seriesDescription{
|
||||||
labels: yyDollar[1].labels,
|
labels: yyDollar[1].labels,
|
||||||
|
@ -1340,37 +1338,37 @@ yydefault:
|
||||||
}
|
}
|
||||||
case 102:
|
case 102:
|
||||||
yyDollar = yyS[yypt-0 : yypt+1]
|
yyDollar = yyS[yypt-0 : yypt+1]
|
||||||
//line promql/generated_parser.y:527
|
//line promql/generated_parser.y:525
|
||||||
{
|
{
|
||||||
yyVAL.series = []sequenceValue{}
|
yyVAL.series = []sequenceValue{}
|
||||||
}
|
}
|
||||||
case 103:
|
case 103:
|
||||||
yyDollar = yyS[yypt-3 : yypt+1]
|
yyDollar = yyS[yypt-3 : yypt+1]
|
||||||
//line promql/generated_parser.y:529
|
//line promql/generated_parser.y:527
|
||||||
{
|
{
|
||||||
yyVAL.series = append(yyDollar[1].series, yyDollar[3].series...)
|
yyVAL.series = append(yyDollar[1].series, yyDollar[3].series...)
|
||||||
}
|
}
|
||||||
case 104:
|
case 104:
|
||||||
yyDollar = yyS[yypt-2 : yypt+1]
|
yyDollar = yyS[yypt-2 : yypt+1]
|
||||||
//line promql/generated_parser.y:531
|
//line promql/generated_parser.y:529
|
||||||
{
|
{
|
||||||
yyVAL.series = yyDollar[1].series
|
yyVAL.series = yyDollar[1].series
|
||||||
}
|
}
|
||||||
case 105:
|
case 105:
|
||||||
yyDollar = yyS[yypt-1 : yypt+1]
|
yyDollar = yyS[yypt-1 : yypt+1]
|
||||||
//line promql/generated_parser.y:533
|
//line promql/generated_parser.y:531
|
||||||
{
|
{
|
||||||
yylex.(*parser).unexpected("series values", "")
|
yylex.(*parser).unexpected("series values", "")
|
||||||
}
|
}
|
||||||
case 106:
|
case 106:
|
||||||
yyDollar = yyS[yypt-1 : yypt+1]
|
yyDollar = yyS[yypt-1 : yypt+1]
|
||||||
//line promql/generated_parser.y:537
|
//line promql/generated_parser.y:535
|
||||||
{
|
{
|
||||||
yyVAL.series = []sequenceValue{{omitted: true}}
|
yyVAL.series = []sequenceValue{{omitted: true}}
|
||||||
}
|
}
|
||||||
case 107:
|
case 107:
|
||||||
yyDollar = yyS[yypt-3 : yypt+1]
|
yyDollar = yyS[yypt-3 : yypt+1]
|
||||||
//line promql/generated_parser.y:539
|
//line promql/generated_parser.y:537
|
||||||
{
|
{
|
||||||
yyVAL.series = []sequenceValue{}
|
yyVAL.series = []sequenceValue{}
|
||||||
for i := uint64(0); i < yyDollar[3].uint; i++ {
|
for i := uint64(0); i < yyDollar[3].uint; i++ {
|
||||||
|
@ -1379,13 +1377,13 @@ yydefault:
|
||||||
}
|
}
|
||||||
case 108:
|
case 108:
|
||||||
yyDollar = yyS[yypt-1 : yypt+1]
|
yyDollar = yyS[yypt-1 : yypt+1]
|
||||||
//line promql/generated_parser.y:546
|
//line promql/generated_parser.y:544
|
||||||
{
|
{
|
||||||
yyVAL.series = []sequenceValue{{value: yyDollar[1].float}}
|
yyVAL.series = []sequenceValue{{value: yyDollar[1].float}}
|
||||||
}
|
}
|
||||||
case 109:
|
case 109:
|
||||||
yyDollar = yyS[yypt-3 : yypt+1]
|
yyDollar = yyS[yypt-3 : yypt+1]
|
||||||
//line promql/generated_parser.y:548
|
//line promql/generated_parser.y:546
|
||||||
{
|
{
|
||||||
yyVAL.series = []sequenceValue{}
|
yyVAL.series = []sequenceValue{}
|
||||||
for i := uint64(0); i <= yyDollar[3].uint; i++ {
|
for i := uint64(0); i <= yyDollar[3].uint; i++ {
|
||||||
|
@ -1394,7 +1392,7 @@ yydefault:
|
||||||
}
|
}
|
||||||
case 110:
|
case 110:
|
||||||
yyDollar = yyS[yypt-4 : yypt+1]
|
yyDollar = yyS[yypt-4 : yypt+1]
|
||||||
//line promql/generated_parser.y:555
|
//line promql/generated_parser.y:553
|
||||||
{
|
{
|
||||||
yyVAL.series = []sequenceValue{}
|
yyVAL.series = []sequenceValue{}
|
||||||
for i := uint64(0); i <= yyDollar[4].uint; i++ {
|
for i := uint64(0); i <= yyDollar[4].uint; i++ {
|
||||||
|
@ -1404,7 +1402,7 @@ yydefault:
|
||||||
}
|
}
|
||||||
case 111:
|
case 111:
|
||||||
yyDollar = yyS[yypt-1 : yypt+1]
|
yyDollar = yyS[yypt-1 : yypt+1]
|
||||||
//line promql/generated_parser.y:565
|
//line promql/generated_parser.y:563
|
||||||
{
|
{
|
||||||
if yyDollar[1].item.Val != "stale" {
|
if yyDollar[1].item.Val != "stale" {
|
||||||
yylex.(*parser).unexpected("series values", "number or \"stale\"")
|
yylex.(*parser).unexpected("series values", "number or \"stale\"")
|
||||||
|
@ -1413,31 +1411,31 @@ yydefault:
|
||||||
}
|
}
|
||||||
case 154:
|
case 154:
|
||||||
yyDollar = yyS[yypt-1 : yypt+1]
|
yyDollar = yyS[yypt-1 : yypt+1]
|
||||||
//line promql/generated_parser.y:595
|
//line promql/generated_parser.y:593
|
||||||
{
|
{
|
||||||
yyVAL.node = &NumberLiteral{yyDollar[1].float}
|
yyVAL.node = &NumberLiteral{yyDollar[1].float}
|
||||||
}
|
}
|
||||||
case 155:
|
case 155:
|
||||||
yyDollar = yyS[yypt-1 : yypt+1]
|
yyDollar = yyS[yypt-1 : yypt+1]
|
||||||
//line promql/generated_parser.y:597
|
//line promql/generated_parser.y:595
|
||||||
{
|
{
|
||||||
yyVAL.float = yylex.(*parser).number(yyDollar[1].item.Val)
|
yyVAL.float = yylex.(*parser).number(yyDollar[1].item.Val)
|
||||||
}
|
}
|
||||||
case 156:
|
case 156:
|
||||||
yyDollar = yyS[yypt-2 : yypt+1]
|
yyDollar = yyS[yypt-2 : yypt+1]
|
||||||
//line promql/generated_parser.y:599
|
//line promql/generated_parser.y:597
|
||||||
{
|
{
|
||||||
yyVAL.float = yyDollar[2].float
|
yyVAL.float = yyDollar[2].float
|
||||||
}
|
}
|
||||||
case 157:
|
case 157:
|
||||||
yyDollar = yyS[yypt-2 : yypt+1]
|
yyDollar = yyS[yypt-2 : yypt+1]
|
||||||
//line promql/generated_parser.y:600
|
//line promql/generated_parser.y:598
|
||||||
{
|
{
|
||||||
yyVAL.float = -yyDollar[2].float
|
yyVAL.float = -yyDollar[2].float
|
||||||
}
|
}
|
||||||
case 158:
|
case 158:
|
||||||
yyDollar = yyS[yypt-1 : yypt+1]
|
yyDollar = yyS[yypt-1 : yypt+1]
|
||||||
//line promql/generated_parser.y:604
|
//line promql/generated_parser.y:602
|
||||||
{
|
{
|
||||||
var err error
|
var err error
|
||||||
yyVAL.uint, err = strconv.ParseUint(yyDollar[1].item.Val, 10, 64)
|
yyVAL.uint, err = strconv.ParseUint(yyDollar[1].item.Val, 10, 64)
|
||||||
|
@ -1447,7 +1445,7 @@ yydefault:
|
||||||
}
|
}
|
||||||
case 159:
|
case 159:
|
||||||
yyDollar = yyS[yypt-1 : yypt+1]
|
yyDollar = yyS[yypt-1 : yypt+1]
|
||||||
//line promql/generated_parser.y:614
|
//line promql/generated_parser.y:612
|
||||||
{
|
{
|
||||||
var err error
|
var err error
|
||||||
yyVAL.duration, err = parseDuration(yyDollar[1].item.Val)
|
yyVAL.duration, err = parseDuration(yyDollar[1].item.Val)
|
||||||
|
@ -1457,25 +1455,25 @@ yydefault:
|
||||||
}
|
}
|
||||||
case 160:
|
case 160:
|
||||||
yyDollar = yyS[yypt-1 : yypt+1]
|
yyDollar = yyS[yypt-1 : yypt+1]
|
||||||
//line promql/generated_parser.y:624
|
//line promql/generated_parser.y:622
|
||||||
{
|
{
|
||||||
yyVAL.node = &StringLiteral{yyDollar[1].string}
|
yyVAL.node = &StringLiteral{yyDollar[1].string}
|
||||||
}
|
}
|
||||||
case 161:
|
case 161:
|
||||||
yyDollar = yyS[yypt-1 : yypt+1]
|
yyDollar = yyS[yypt-1 : yypt+1]
|
||||||
//line promql/generated_parser.y:626
|
//line promql/generated_parser.y:624
|
||||||
{
|
{
|
||||||
yyVAL.string = yylex.(*parser).unquoteString(yyDollar[1].item.Val)
|
yyVAL.string = yylex.(*parser).unquoteString(yyDollar[1].item.Val)
|
||||||
}
|
}
|
||||||
case 162:
|
case 162:
|
||||||
yyDollar = yyS[yypt-0 : yypt+1]
|
yyDollar = yyS[yypt-0 : yypt+1]
|
||||||
//line promql/generated_parser.y:633
|
//line promql/generated_parser.y:631
|
||||||
{
|
{
|
||||||
yyVAL.duration = 0
|
yyVAL.duration = 0
|
||||||
}
|
}
|
||||||
case 164:
|
case 164:
|
||||||
yyDollar = yyS[yypt-0 : yypt+1]
|
yyDollar = yyS[yypt-0 : yypt+1]
|
||||||
//line promql/generated_parser.y:637
|
//line promql/generated_parser.y:635
|
||||||
{
|
{
|
||||||
yyVAL.strings = nil
|
yyVAL.strings = nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -504,8 +504,10 @@ func (p *parser) checkType(node Node) (typ ValueType) {
|
||||||
if ty != ValueTypeVector {
|
if ty != ValueTypeVector {
|
||||||
p.errorf("subquery is only allowed on instant vector, got %s in %q instead", ty, n.String())
|
p.errorf("subquery is only allowed on instant vector, got %s in %q instead", ty, n.String())
|
||||||
}
|
}
|
||||||
|
case *MatrixSelector:
|
||||||
|
p.checkType(n.VectorSelector)
|
||||||
|
|
||||||
case *NumberLiteral, *MatrixSelector, *StringLiteral, *VectorSelector:
|
case *NumberLiteral, *StringLiteral, *VectorSelector:
|
||||||
// Nothing to do for terminals.
|
// Nothing to do for terminals.
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
@ -581,7 +583,7 @@ func (p *parser) addOffset(e Node, offset time.Duration) {
|
||||||
case *VectorSelector:
|
case *VectorSelector:
|
||||||
offsetp = &s.Offset
|
offsetp = &s.Offset
|
||||||
case *MatrixSelector:
|
case *MatrixSelector:
|
||||||
offsetp = &s.Offset
|
offsetp = &s.VectorSelector.Offset
|
||||||
case *SubqueryExpr:
|
case *SubqueryExpr:
|
||||||
offsetp = &s.Offset
|
offsetp = &s.Offset
|
||||||
default:
|
default:
|
||||||
|
|
|
@ -1028,64 +1028,77 @@ var testExpr = []struct {
|
||||||
{
|
{
|
||||||
input: "test[5s]",
|
input: "test[5s]",
|
||||||
expected: &MatrixSelector{
|
expected: &MatrixSelector{
|
||||||
|
VectorSelector: &VectorSelector{
|
||||||
Name: "test",
|
Name: "test",
|
||||||
Offset: 0,
|
Offset: 0,
|
||||||
Range: 5 * time.Second,
|
|
||||||
LabelMatchers: []*labels.Matcher{
|
LabelMatchers: []*labels.Matcher{
|
||||||
mustLabelMatcher(labels.MatchEqual, string(model.MetricNameLabel), "test"),
|
mustLabelMatcher(labels.MatchEqual, string(model.MetricNameLabel), "test"),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
|
Range: 5 * time.Second,
|
||||||
|
},
|
||||||
}, {
|
}, {
|
||||||
input: "test[5m]",
|
input: "test[5m]",
|
||||||
expected: &MatrixSelector{
|
expected: &MatrixSelector{
|
||||||
|
VectorSelector: &VectorSelector{
|
||||||
Name: "test",
|
Name: "test",
|
||||||
Offset: 0,
|
Offset: 0,
|
||||||
Range: 5 * time.Minute,
|
|
||||||
LabelMatchers: []*labels.Matcher{
|
LabelMatchers: []*labels.Matcher{
|
||||||
mustLabelMatcher(labels.MatchEqual, string(model.MetricNameLabel), "test"),
|
mustLabelMatcher(labels.MatchEqual, string(model.MetricNameLabel), "test"),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
Range: 5 * time.Minute,
|
||||||
|
},
|
||||||
}, {
|
}, {
|
||||||
input: "test[5h] OFFSET 5m",
|
input: "test[5h] OFFSET 5m",
|
||||||
expected: &MatrixSelector{
|
expected: &MatrixSelector{
|
||||||
|
VectorSelector: &VectorSelector{
|
||||||
Name: "test",
|
Name: "test",
|
||||||
Offset: 5 * time.Minute,
|
Offset: 5 * time.Minute,
|
||||||
Range: 5 * time.Hour,
|
|
||||||
LabelMatchers: []*labels.Matcher{
|
LabelMatchers: []*labels.Matcher{
|
||||||
mustLabelMatcher(labels.MatchEqual, string(model.MetricNameLabel), "test"),
|
mustLabelMatcher(labels.MatchEqual, string(model.MetricNameLabel), "test"),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
Range: 5 * time.Hour,
|
||||||
|
},
|
||||||
}, {
|
}, {
|
||||||
input: "test[5d] OFFSET 10s",
|
input: "test[5d] OFFSET 10s",
|
||||||
expected: &MatrixSelector{
|
expected: &MatrixSelector{
|
||||||
|
VectorSelector: &VectorSelector{
|
||||||
Name: "test",
|
Name: "test",
|
||||||
Offset: 10 * time.Second,
|
Offset: 10 * time.Second,
|
||||||
Range: 5 * 24 * time.Hour,
|
|
||||||
LabelMatchers: []*labels.Matcher{
|
LabelMatchers: []*labels.Matcher{
|
||||||
mustLabelMatcher(labels.MatchEqual, string(model.MetricNameLabel), "test"),
|
mustLabelMatcher(labels.MatchEqual, string(model.MetricNameLabel), "test"),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
Range: 5 * 24 * time.Hour,
|
||||||
|
},
|
||||||
}, {
|
}, {
|
||||||
input: "test[5w] offset 2w",
|
input: "test[5w] offset 2w",
|
||||||
expected: &MatrixSelector{
|
expected: &MatrixSelector{
|
||||||
|
VectorSelector: &VectorSelector{
|
||||||
Name: "test",
|
Name: "test",
|
||||||
Offset: 14 * 24 * time.Hour,
|
Offset: 14 * 24 * time.Hour,
|
||||||
Range: 5 * 7 * 24 * time.Hour,
|
|
||||||
LabelMatchers: []*labels.Matcher{
|
LabelMatchers: []*labels.Matcher{
|
||||||
mustLabelMatcher(labels.MatchEqual, string(model.MetricNameLabel), "test"),
|
mustLabelMatcher(labels.MatchEqual, string(model.MetricNameLabel), "test"),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
Range: 5 * 7 * 24 * time.Hour,
|
||||||
|
},
|
||||||
}, {
|
}, {
|
||||||
input: `test{a="b"}[5y] OFFSET 3d`,
|
input: `test{a="b"}[5y] OFFSET 3d`,
|
||||||
expected: &MatrixSelector{
|
expected: &MatrixSelector{
|
||||||
|
VectorSelector: &VectorSelector{
|
||||||
Name: "test",
|
Name: "test",
|
||||||
Offset: 3 * 24 * time.Hour,
|
Offset: 3 * 24 * time.Hour,
|
||||||
Range: 5 * 365 * 24 * time.Hour,
|
|
||||||
LabelMatchers: []*labels.Matcher{
|
LabelMatchers: []*labels.Matcher{
|
||||||
mustLabelMatcher(labels.MatchEqual, "a", "b"),
|
mustLabelMatcher(labels.MatchEqual, "a", "b"),
|
||||||
mustLabelMatcher(labels.MatchEqual, string(model.MetricNameLabel), "test"),
|
mustLabelMatcher(labels.MatchEqual, string(model.MetricNameLabel), "test"),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
Range: 5 * 365 * 24 * time.Hour,
|
||||||
|
},
|
||||||
}, {
|
}, {
|
||||||
input: `foo[5mm]`,
|
input: `foo[5mm]`,
|
||||||
fail: true,
|
fail: true,
|
||||||
|
@ -1378,10 +1391,12 @@ var testExpr = []struct {
|
||||||
Func: mustGetFunction("rate"),
|
Func: mustGetFunction("rate"),
|
||||||
Args: Expressions{
|
Args: Expressions{
|
||||||
&MatrixSelector{
|
&MatrixSelector{
|
||||||
|
VectorSelector: &VectorSelector{
|
||||||
Name: "some_metric",
|
Name: "some_metric",
|
||||||
LabelMatchers: []*labels.Matcher{
|
LabelMatchers: []*labels.Matcher{
|
||||||
mustLabelMatcher(labels.MatchEqual, string(model.MetricNameLabel), "some_metric"),
|
mustLabelMatcher(labels.MatchEqual, string(model.MetricNameLabel), "some_metric"),
|
||||||
},
|
},
|
||||||
|
},
|
||||||
Range: 5 * time.Minute,
|
Range: 5 * time.Minute,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -1535,13 +1550,15 @@ var testExpr = []struct {
|
||||||
Func: mustGetFunction("rate"),
|
Func: mustGetFunction("rate"),
|
||||||
Args: Expressions{
|
Args: Expressions{
|
||||||
&MatrixSelector{
|
&MatrixSelector{
|
||||||
|
VectorSelector: &VectorSelector{
|
||||||
Name: "foo",
|
Name: "foo",
|
||||||
Range: 2 * time.Second,
|
|
||||||
LabelMatchers: []*labels.Matcher{
|
LabelMatchers: []*labels.Matcher{
|
||||||
mustLabelMatcher(labels.MatchEqual, "bar", "baz"),
|
mustLabelMatcher(labels.MatchEqual, "bar", "baz"),
|
||||||
mustLabelMatcher(labels.MatchEqual, string(model.MetricNameLabel), "foo"),
|
mustLabelMatcher(labels.MatchEqual, string(model.MetricNameLabel), "foo"),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
Range: 2 * time.Second,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Range: 5 * time.Minute,
|
Range: 5 * time.Minute,
|
||||||
|
@ -1560,13 +1577,15 @@ var testExpr = []struct {
|
||||||
Func: mustGetFunction("rate"),
|
Func: mustGetFunction("rate"),
|
||||||
Args: Expressions{
|
Args: Expressions{
|
||||||
&MatrixSelector{
|
&MatrixSelector{
|
||||||
|
VectorSelector: &VectorSelector{
|
||||||
Name: "foo",
|
Name: "foo",
|
||||||
Range: 2 * time.Second,
|
|
||||||
LabelMatchers: []*labels.Matcher{
|
LabelMatchers: []*labels.Matcher{
|
||||||
mustLabelMatcher(labels.MatchEqual, "bar", "baz"),
|
mustLabelMatcher(labels.MatchEqual, "bar", "baz"),
|
||||||
mustLabelMatcher(labels.MatchEqual, string(model.MetricNameLabel), "foo"),
|
mustLabelMatcher(labels.MatchEqual, string(model.MetricNameLabel), "foo"),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
Range: 2 * time.Second,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Range: 5 * time.Minute,
|
Range: 5 * time.Minute,
|
||||||
|
@ -1587,13 +1606,15 @@ var testExpr = []struct {
|
||||||
Func: mustGetFunction("rate"),
|
Func: mustGetFunction("rate"),
|
||||||
Args: Expressions{
|
Args: Expressions{
|
||||||
&MatrixSelector{
|
&MatrixSelector{
|
||||||
|
VectorSelector: &VectorSelector{
|
||||||
Name: "foo",
|
Name: "foo",
|
||||||
Range: 2 * time.Second,
|
|
||||||
LabelMatchers: []*labels.Matcher{
|
LabelMatchers: []*labels.Matcher{
|
||||||
mustLabelMatcher(labels.MatchEqual, "bar", "baz"),
|
mustLabelMatcher(labels.MatchEqual, "bar", "baz"),
|
||||||
mustLabelMatcher(labels.MatchEqual, string(model.MetricNameLabel), "foo"),
|
mustLabelMatcher(labels.MatchEqual, string(model.MetricNameLabel), "foo"),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
Range: 2 * time.Second,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Range: 5 * time.Minute,
|
Range: 5 * time.Minute,
|
||||||
|
|
|
@ -112,14 +112,16 @@ func (node *Call) String() string {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (node *MatrixSelector) String() string {
|
func (node *MatrixSelector) String() string {
|
||||||
vecSelector := &VectorSelector{
|
// Copy the Vector selector before changing the offset
|
||||||
Name: node.Name,
|
var vecSelector VectorSelector = *node.VectorSelector
|
||||||
LabelMatchers: node.LabelMatchers,
|
|
||||||
}
|
|
||||||
offset := ""
|
offset := ""
|
||||||
if node.Offset != time.Duration(0) {
|
if vecSelector.Offset != time.Duration(0) {
|
||||||
offset = fmt.Sprintf(" offset %s", model.Duration(node.Offset))
|
offset = fmt.Sprintf(" offset %s", model.Duration(vecSelector.Offset))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Do not print the offset twice.
|
||||||
|
vecSelector.Offset = 0
|
||||||
|
|
||||||
return fmt.Sprintf("%s[%s]%s", vecSelector.String(), model.Duration(node.Range), offset)
|
return fmt.Sprintf("%s[%s]%s", vecSelector.String(), model.Duration(node.Range), offset)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue