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.
|
||||
type MatrixSelector struct {
|
||||
Name string
|
||||
Range time.Duration
|
||||
Offset time.Duration
|
||||
LabelMatchers []*labels.Matcher
|
||||
|
||||
// The unexpanded seriesSet populated at query preparation time.
|
||||
unexpandedSeriesSet storage.SeriesSet
|
||||
series []storage.Series
|
||||
VectorSelector *VectorSelector
|
||||
Range time.Duration
|
||||
}
|
||||
|
||||
// SubqueryExpr represents a subquery.
|
||||
|
@ -316,7 +310,9 @@ func Children(node Node) []Node {
|
|||
return []Node{n.Expr}
|
||||
case *UnaryExpr:
|
||||
return []Node{n.Expr}
|
||||
case *MatrixSelector, *NumberLiteral, *StringLiteral, *VectorSelector:
|
||||
case *MatrixSelector:
|
||||
return []Node{n.VectorSelector}
|
||||
case *NumberLiteral, *StringLiteral, *VectorSelector:
|
||||
// nothing to do
|
||||
return []Node{}
|
||||
default:
|
||||
|
|
|
@ -623,8 +623,8 @@ func (ng *Engine) populateSeries(ctx context.Context, q storage.Queryable, s *Ev
|
|||
if maxOffset < n.Range+subqOffset {
|
||||
maxOffset = n.Range + subqOffset
|
||||
}
|
||||
if n.Offset+n.Range+subqOffset > maxOffset {
|
||||
maxOffset = n.Offset + n.Range + subqOffset
|
||||
if m := n.VectorSelector.Offset + n.Range + subqOffset; m > maxOffset {
|
||||
maxOffset = m
|
||||
}
|
||||
}
|
||||
return nil
|
||||
|
@ -639,6 +639,11 @@ func (ng *Engine) populateSeries(ctx context.Context, q storage.Queryable, s *Ev
|
|||
|
||||
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 {
|
||||
var set storage.SeriesSet
|
||||
var wrn storage.Warnings
|
||||
|
@ -658,7 +663,16 @@ func (ng *Engine) populateSeries(ctx context.Context, q storage.Queryable, s *Ev
|
|||
|
||||
switch n := node.(type) {
|
||||
case *VectorSelector:
|
||||
params.Start = params.Start - durationMilliseconds(LookbackDelta)
|
||||
if evalRange == 0 {
|
||||
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.By, params.Grouping = extractGroupsFromPath(path)
|
||||
if n.Offset > 0 {
|
||||
|
@ -676,24 +690,7 @@ func (ng *Engine) populateSeries(ctx context.Context, q storage.Queryable, s *Ev
|
|||
n.unexpandedSeriesSet = set
|
||||
|
||||
case *MatrixSelector:
|
||||
params.Func = extractFuncFromPath(path)
|
||||
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
|
||||
evalRange = n.Range
|
||||
}
|
||||
return nil
|
||||
})
|
||||
|
@ -734,14 +731,7 @@ func extractGroupsFromPath(p []Node) (bool, []string) {
|
|||
func checkForSeriesSetExpansion(ctx context.Context, expr Expr) {
|
||||
switch e := expr.(type) {
|
||||
case *MatrixSelector:
|
||||
if e.series == nil {
|
||||
series, err := expandSeriesSet(ctx, e.unexpandedSeriesSet)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
} else {
|
||||
e.series = series
|
||||
}
|
||||
}
|
||||
checkForSeriesSetExpansion(ctx, e.VectorSelector)
|
||||
case *VectorSelector:
|
||||
if e.series == nil {
|
||||
series, err := expandSeriesSet(ctx, e.unexpandedSeriesSet)
|
||||
|
@ -1000,12 +990,14 @@ func (ev *evaluator) rangeEval(f func([]Value, *EvalNodeHelper) Vector, exprs ..
|
|||
func (ev *evaluator) evalSubquery(subq *SubqueryExpr) *MatrixSelector {
|
||||
val := ev.eval(subq).(Matrix)
|
||||
ms := &MatrixSelector{
|
||||
Range: subq.Range,
|
||||
Offset: subq.Offset,
|
||||
series: make([]storage.Series, 0, len(val)),
|
||||
Range: subq.Range,
|
||||
VectorSelector: &VectorSelector{
|
||||
Offset: subq.Offset,
|
||||
series: make([]storage.Series, 0, len(val)),
|
||||
},
|
||||
}
|
||||
for _, s := range val {
|
||||
ms.series = append(ms.series, NewStorageSeries(s))
|
||||
ms.VectorSelector.series = append(ms.VectorSelector.series, NewStorageSeries(s))
|
||||
}
|
||||
return ms
|
||||
}
|
||||
|
@ -1085,9 +1077,11 @@ func (ev *evaluator) eval(expr Expr) Value {
|
|||
}
|
||||
|
||||
sel := e.Args[matrixArgIndex].(*MatrixSelector)
|
||||
selVS := sel.VectorSelector
|
||||
|
||||
checkForSeriesSetExpansion(ev.ctx, sel)
|
||||
mat := make(Matrix, 0, len(sel.series)) // Output matrix.
|
||||
offset := durationMilliseconds(sel.Offset)
|
||||
mat := make(Matrix, 0, len(selVS.series)) // Output matrix.
|
||||
offset := durationMilliseconds(selVS.Offset)
|
||||
selRange := durationMilliseconds(sel.Range)
|
||||
stepRange := selRange
|
||||
if stepRange > ev.interval {
|
||||
|
@ -1100,17 +1094,17 @@ func (ev *evaluator) eval(expr Expr) Value {
|
|||
enh := &EvalNodeHelper{out: make(Vector, 0, 1)}
|
||||
// Process all the calls for one time series at a time.
|
||||
it := storage.NewBuffer(selRange)
|
||||
for i, s := range sel.series {
|
||||
for i, s := range selVS.series {
|
||||
points = points[:0]
|
||||
it.Reset(s.Iterator())
|
||||
ss := Series{
|
||||
// For all range vector functions, the only change to the
|
||||
// output labels is dropping the metric name so just do
|
||||
// it once here.
|
||||
Metric: dropMetricName(sel.series[i].Labels()),
|
||||
Metric: dropMetricName(selVS.series[i].Labels()),
|
||||
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 {
|
||||
step++
|
||||
// Set the non-matrix arguments.
|
||||
|
@ -1409,20 +1403,22 @@ func (ev *evaluator) matrixSelector(node *MatrixSelector) Matrix {
|
|||
checkForSeriesSetExpansion(ev.ctx, node)
|
||||
|
||||
var (
|
||||
offset = durationMilliseconds(node.Offset)
|
||||
offset = durationMilliseconds(node.VectorSelector.Offset)
|
||||
maxt = ev.startTimestamp - offset
|
||||
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))
|
||||
for i, s := range node.series {
|
||||
series := node.VectorSelector.series
|
||||
|
||||
for i, s := range series {
|
||||
if err := contextDone(ev.ctx, "expression evaluation"); err != nil {
|
||||
ev.error(err)
|
||||
}
|
||||
it.Reset(s.Iterator())
|
||||
ss := Series{
|
||||
Metric: node.series[i].Labels(),
|
||||
Metric: series[i].Labels(),
|
||||
}
|
||||
|
||||
ss.Points = ev.matrixIterSlice(it, mint, maxt, getPointSlice(16))
|
||||
|
|
|
@ -67,8 +67,8 @@ func extrapolatedRate(vals []Value, args Expressions, enh *EvalNodeHelper, isCou
|
|||
|
||||
var (
|
||||
samples = vals[0].(Matrix)[0]
|
||||
rangeStart = enh.ts - durationMilliseconds(ms.Range+ms.Offset)
|
||||
rangeEnd = enh.ts - durationMilliseconds(ms.Offset)
|
||||
rangeStart = enh.ts - durationMilliseconds(ms.Range+ms.VectorSelector.Offset)
|
||||
rangeEnd = enh.ts - durationMilliseconds(ms.VectorSelector.Offset)
|
||||
)
|
||||
|
||||
// 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:
|
||||
lm = n.LabelMatchers
|
||||
case *MatrixSelector:
|
||||
lm = n.LabelMatchers
|
||||
lm = n.VectorSelector.LabelMatchers
|
||||
default:
|
||||
return m
|
||||
}
|
||||
|
|
|
@ -384,9 +384,7 @@ matrix_selector : expr LEFT_BRACKET duration RIGHT_BRACKET
|
|||
yylex.(*parser).errorf("no offset modifiers allowed before range")
|
||||
}
|
||||
$$ = &MatrixSelector{
|
||||
Name: vs.Name,
|
||||
Offset: vs.Offset,
|
||||
LabelMatchers: vs.LabelMatchers,
|
||||
VectorSelector: vs,
|
||||
Range: $3,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -184,7 +184,7 @@ const yyEofCode = 1
|
|||
const yyErrCode = 2
|
||||
const yyInitialStackSize = 16
|
||||
|
||||
//line promql/generated_parser.y:641
|
||||
//line promql/generated_parser.y:639
|
||||
|
||||
//line yacctab:1
|
||||
var yyExca = [...]int{
|
||||
|
@ -1119,15 +1119,13 @@ yydefault:
|
|||
yylex.(*parser).errorf("no offset modifiers allowed before range")
|
||||
}
|
||||
yyVAL.node = &MatrixSelector{
|
||||
Name: vs.Name,
|
||||
Offset: vs.Offset,
|
||||
LabelMatchers: vs.LabelMatchers,
|
||||
Range: yyDollar[3].duration,
|
||||
VectorSelector: vs,
|
||||
Range: yyDollar[3].duration,
|
||||
}
|
||||
}
|
||||
case 67:
|
||||
yyDollar = yyS[yypt-6 : yypt+1]
|
||||
//line promql/generated_parser.y:396
|
||||
//line promql/generated_parser.y:394
|
||||
{
|
||||
yyVAL.node = &SubqueryExpr{
|
||||
Expr: yyDollar[1].node.(Expr),
|
||||
|
@ -1137,31 +1135,31 @@ yydefault:
|
|||
}
|
||||
case 68:
|
||||
yyDollar = yyS[yypt-6 : yypt+1]
|
||||
//line promql/generated_parser.y:404
|
||||
//line promql/generated_parser.y:402
|
||||
{
|
||||
yylex.(*parser).unexpected("subquery selector", "\"]\"")
|
||||
}
|
||||
case 69:
|
||||
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 \"]\"")
|
||||
}
|
||||
case 70:
|
||||
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 \"]\"")
|
||||
}
|
||||
case 71:
|
||||
yyDollar = yyS[yypt-3 : yypt+1]
|
||||
//line promql/generated_parser.y:410
|
||||
//line promql/generated_parser.y:408
|
||||
{
|
||||
yylex.(*parser).unexpected("subquery selector", "duration")
|
||||
}
|
||||
case 72:
|
||||
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 yyDollar[1].item.Typ == SUB {
|
||||
|
@ -1174,164 +1172,164 @@ yydefault:
|
|||
}
|
||||
case 73:
|
||||
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)
|
||||
}
|
||||
case 74:
|
||||
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)
|
||||
}
|
||||
case 75:
|
||||
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)
|
||||
}
|
||||
case 76:
|
||||
yyDollar = yyS[yypt-3 : yypt+1]
|
||||
//line promql/generated_parser.y:445
|
||||
//line promql/generated_parser.y:443
|
||||
{
|
||||
yyVAL.matchers = yyDollar[2].matchers
|
||||
}
|
||||
case 77:
|
||||
yyDollar = yyS[yypt-4 : yypt+1]
|
||||
//line promql/generated_parser.y:447
|
||||
//line promql/generated_parser.y:445
|
||||
{
|
||||
yyVAL.matchers = yyDollar[2].matchers
|
||||
}
|
||||
case 78:
|
||||
yyDollar = yyS[yypt-2 : yypt+1]
|
||||
//line promql/generated_parser.y:449
|
||||
//line promql/generated_parser.y:447
|
||||
{
|
||||
yyVAL.matchers = []*labels.Matcher{}
|
||||
}
|
||||
case 79:
|
||||
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)
|
||||
}
|
||||
case 80:
|
||||
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}
|
||||
}
|
||||
case 81:
|
||||
yyDollar = yyS[yypt-2 : yypt+1]
|
||||
//line promql/generated_parser.y:458
|
||||
//line promql/generated_parser.y:456
|
||||
{
|
||||
yylex.(*parser).unexpected("label matching", "\",\" or \"}\"")
|
||||
}
|
||||
case 82:
|
||||
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)
|
||||
}
|
||||
case 83:
|
||||
yyDollar = yyS[yypt-3 : yypt+1]
|
||||
//line promql/generated_parser.y:464
|
||||
//line promql/generated_parser.y:462
|
||||
{
|
||||
yylex.(*parser).unexpected("label matching", "string")
|
||||
}
|
||||
case 84:
|
||||
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")
|
||||
}
|
||||
case 85:
|
||||
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 \"}\"")
|
||||
}
|
||||
case 86:
|
||||
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})
|
||||
sort.Sort(yyVAL.labels)
|
||||
}
|
||||
case 87:
|
||||
yyDollar = yyS[yypt-1 : yypt+1]
|
||||
//line promql/generated_parser.y:478
|
||||
//line promql/generated_parser.y:476
|
||||
{
|
||||
yyVAL.labels = yyDollar[1].labels
|
||||
}
|
||||
case 90:
|
||||
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...)
|
||||
}
|
||||
case 91:
|
||||
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...)
|
||||
}
|
||||
case 92:
|
||||
yyDollar = yyS[yypt-2 : yypt+1]
|
||||
//line promql/generated_parser.y:489
|
||||
//line promql/generated_parser.y:487
|
||||
{
|
||||
yyVAL.labels = labels.New()
|
||||
}
|
||||
case 93:
|
||||
yyDollar = yyS[yypt-0 : yypt+1]
|
||||
//line promql/generated_parser.y:491
|
||||
//line promql/generated_parser.y:489
|
||||
{
|
||||
yyVAL.labels = labels.New()
|
||||
}
|
||||
case 94:
|
||||
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)
|
||||
}
|
||||
case 95:
|
||||
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}
|
||||
}
|
||||
case 96:
|
||||
yyDollar = yyS[yypt-2 : yypt+1]
|
||||
//line promql/generated_parser.y:499
|
||||
//line promql/generated_parser.y:497
|
||||
{
|
||||
yylex.(*parser).unexpected("label set", "\",\" or \"}\"")
|
||||
}
|
||||
case 97:
|
||||
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)}
|
||||
}
|
||||
case 98:
|
||||
yyDollar = yyS[yypt-3 : yypt+1]
|
||||
//line promql/generated_parser.y:506
|
||||
//line promql/generated_parser.y:504
|
||||
{
|
||||
yylex.(*parser).unexpected("label set", "string")
|
||||
}
|
||||
case 99:
|
||||
yyDollar = yyS[yypt-2 : yypt+1]
|
||||
//line promql/generated_parser.y:508
|
||||
//line promql/generated_parser.y:506
|
||||
{
|
||||
yylex.(*parser).unexpected("label set", "\"=\"")
|
||||
}
|
||||
case 100:
|
||||
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 \"}\"")
|
||||
}
|
||||
case 101:
|
||||
yyDollar = yyS[yypt-2 : yypt+1]
|
||||
//line promql/generated_parser.y:518
|
||||
//line promql/generated_parser.y:516
|
||||
{
|
||||
yylex.(*parser).generatedParserResult = &seriesDescription{
|
||||
labels: yyDollar[1].labels,
|
||||
|
@ -1340,37 +1338,37 @@ yydefault:
|
|||
}
|
||||
case 102:
|
||||
yyDollar = yyS[yypt-0 : yypt+1]
|
||||
//line promql/generated_parser.y:527
|
||||
//line promql/generated_parser.y:525
|
||||
{
|
||||
yyVAL.series = []sequenceValue{}
|
||||
}
|
||||
case 103:
|
||||
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...)
|
||||
}
|
||||
case 104:
|
||||
yyDollar = yyS[yypt-2 : yypt+1]
|
||||
//line promql/generated_parser.y:531
|
||||
//line promql/generated_parser.y:529
|
||||
{
|
||||
yyVAL.series = yyDollar[1].series
|
||||
}
|
||||
case 105:
|
||||
yyDollar = yyS[yypt-1 : yypt+1]
|
||||
//line promql/generated_parser.y:533
|
||||
//line promql/generated_parser.y:531
|
||||
{
|
||||
yylex.(*parser).unexpected("series values", "")
|
||||
}
|
||||
case 106:
|
||||
yyDollar = yyS[yypt-1 : yypt+1]
|
||||
//line promql/generated_parser.y:537
|
||||
//line promql/generated_parser.y:535
|
||||
{
|
||||
yyVAL.series = []sequenceValue{{omitted: true}}
|
||||
}
|
||||
case 107:
|
||||
yyDollar = yyS[yypt-3 : yypt+1]
|
||||
//line promql/generated_parser.y:539
|
||||
//line promql/generated_parser.y:537
|
||||
{
|
||||
yyVAL.series = []sequenceValue{}
|
||||
for i := uint64(0); i < yyDollar[3].uint; i++ {
|
||||
|
@ -1379,13 +1377,13 @@ yydefault:
|
|||
}
|
||||
case 108:
|
||||
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}}
|
||||
}
|
||||
case 109:
|
||||
yyDollar = yyS[yypt-3 : yypt+1]
|
||||
//line promql/generated_parser.y:548
|
||||
//line promql/generated_parser.y:546
|
||||
{
|
||||
yyVAL.series = []sequenceValue{}
|
||||
for i := uint64(0); i <= yyDollar[3].uint; i++ {
|
||||
|
@ -1394,7 +1392,7 @@ yydefault:
|
|||
}
|
||||
case 110:
|
||||
yyDollar = yyS[yypt-4 : yypt+1]
|
||||
//line promql/generated_parser.y:555
|
||||
//line promql/generated_parser.y:553
|
||||
{
|
||||
yyVAL.series = []sequenceValue{}
|
||||
for i := uint64(0); i <= yyDollar[4].uint; i++ {
|
||||
|
@ -1404,7 +1402,7 @@ yydefault:
|
|||
}
|
||||
case 111:
|
||||
yyDollar = yyS[yypt-1 : yypt+1]
|
||||
//line promql/generated_parser.y:565
|
||||
//line promql/generated_parser.y:563
|
||||
{
|
||||
if yyDollar[1].item.Val != "stale" {
|
||||
yylex.(*parser).unexpected("series values", "number or \"stale\"")
|
||||
|
@ -1413,31 +1411,31 @@ yydefault:
|
|||
}
|
||||
case 154:
|
||||
yyDollar = yyS[yypt-1 : yypt+1]
|
||||
//line promql/generated_parser.y:595
|
||||
//line promql/generated_parser.y:593
|
||||
{
|
||||
yyVAL.node = &NumberLiteral{yyDollar[1].float}
|
||||
}
|
||||
case 155:
|
||||
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)
|
||||
}
|
||||
case 156:
|
||||
yyDollar = yyS[yypt-2 : yypt+1]
|
||||
//line promql/generated_parser.y:599
|
||||
//line promql/generated_parser.y:597
|
||||
{
|
||||
yyVAL.float = yyDollar[2].float
|
||||
}
|
||||
case 157:
|
||||
yyDollar = yyS[yypt-2 : yypt+1]
|
||||
//line promql/generated_parser.y:600
|
||||
//line promql/generated_parser.y:598
|
||||
{
|
||||
yyVAL.float = -yyDollar[2].float
|
||||
}
|
||||
case 158:
|
||||
yyDollar = yyS[yypt-1 : yypt+1]
|
||||
//line promql/generated_parser.y:604
|
||||
//line promql/generated_parser.y:602
|
||||
{
|
||||
var err error
|
||||
yyVAL.uint, err = strconv.ParseUint(yyDollar[1].item.Val, 10, 64)
|
||||
|
@ -1447,7 +1445,7 @@ yydefault:
|
|||
}
|
||||
case 159:
|
||||
yyDollar = yyS[yypt-1 : yypt+1]
|
||||
//line promql/generated_parser.y:614
|
||||
//line promql/generated_parser.y:612
|
||||
{
|
||||
var err error
|
||||
yyVAL.duration, err = parseDuration(yyDollar[1].item.Val)
|
||||
|
@ -1457,25 +1455,25 @@ yydefault:
|
|||
}
|
||||
case 160:
|
||||
yyDollar = yyS[yypt-1 : yypt+1]
|
||||
//line promql/generated_parser.y:624
|
||||
//line promql/generated_parser.y:622
|
||||
{
|
||||
yyVAL.node = &StringLiteral{yyDollar[1].string}
|
||||
}
|
||||
case 161:
|
||||
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)
|
||||
}
|
||||
case 162:
|
||||
yyDollar = yyS[yypt-0 : yypt+1]
|
||||
//line promql/generated_parser.y:633
|
||||
//line promql/generated_parser.y:631
|
||||
{
|
||||
yyVAL.duration = 0
|
||||
}
|
||||
case 164:
|
||||
yyDollar = yyS[yypt-0 : yypt+1]
|
||||
//line promql/generated_parser.y:637
|
||||
//line promql/generated_parser.y:635
|
||||
{
|
||||
yyVAL.strings = nil
|
||||
}
|
||||
|
|
|
@ -504,8 +504,10 @@ func (p *parser) checkType(node Node) (typ ValueType) {
|
|||
if ty != ValueTypeVector {
|
||||
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.
|
||||
|
||||
default:
|
||||
|
@ -581,7 +583,7 @@ func (p *parser) addOffset(e Node, offset time.Duration) {
|
|||
case *VectorSelector:
|
||||
offsetp = &s.Offset
|
||||
case *MatrixSelector:
|
||||
offsetp = &s.Offset
|
||||
offsetp = &s.VectorSelector.Offset
|
||||
case *SubqueryExpr:
|
||||
offsetp = &s.Offset
|
||||
default:
|
||||
|
|
|
@ -1028,63 +1028,76 @@ var testExpr = []struct {
|
|||
{
|
||||
input: "test[5s]",
|
||||
expected: &MatrixSelector{
|
||||
Name: "test",
|
||||
Offset: 0,
|
||||
Range: 5 * time.Second,
|
||||
LabelMatchers: []*labels.Matcher{
|
||||
mustLabelMatcher(labels.MatchEqual, string(model.MetricNameLabel), "test"),
|
||||
VectorSelector: &VectorSelector{
|
||||
Name: "test",
|
||||
Offset: 0,
|
||||
LabelMatchers: []*labels.Matcher{
|
||||
mustLabelMatcher(labels.MatchEqual, string(model.MetricNameLabel), "test"),
|
||||
},
|
||||
},
|
||||
|
||||
Range: 5 * time.Second,
|
||||
},
|
||||
}, {
|
||||
input: "test[5m]",
|
||||
expected: &MatrixSelector{
|
||||
Name: "test",
|
||||
Offset: 0,
|
||||
Range: 5 * time.Minute,
|
||||
LabelMatchers: []*labels.Matcher{
|
||||
mustLabelMatcher(labels.MatchEqual, string(model.MetricNameLabel), "test"),
|
||||
VectorSelector: &VectorSelector{
|
||||
Name: "test",
|
||||
Offset: 0,
|
||||
LabelMatchers: []*labels.Matcher{
|
||||
mustLabelMatcher(labels.MatchEqual, string(model.MetricNameLabel), "test"),
|
||||
},
|
||||
},
|
||||
Range: 5 * time.Minute,
|
||||
},
|
||||
}, {
|
||||
input: "test[5h] OFFSET 5m",
|
||||
expected: &MatrixSelector{
|
||||
Name: "test",
|
||||
Offset: 5 * time.Minute,
|
||||
Range: 5 * time.Hour,
|
||||
LabelMatchers: []*labels.Matcher{
|
||||
mustLabelMatcher(labels.MatchEqual, string(model.MetricNameLabel), "test"),
|
||||
VectorSelector: &VectorSelector{
|
||||
Name: "test",
|
||||
Offset: 5 * time.Minute,
|
||||
LabelMatchers: []*labels.Matcher{
|
||||
mustLabelMatcher(labels.MatchEqual, string(model.MetricNameLabel), "test"),
|
||||
},
|
||||
},
|
||||
Range: 5 * time.Hour,
|
||||
},
|
||||
}, {
|
||||
input: "test[5d] OFFSET 10s",
|
||||
expected: &MatrixSelector{
|
||||
Name: "test",
|
||||
Offset: 10 * time.Second,
|
||||
Range: 5 * 24 * time.Hour,
|
||||
LabelMatchers: []*labels.Matcher{
|
||||
mustLabelMatcher(labels.MatchEqual, string(model.MetricNameLabel), "test"),
|
||||
VectorSelector: &VectorSelector{
|
||||
Name: "test",
|
||||
Offset: 10 * time.Second,
|
||||
LabelMatchers: []*labels.Matcher{
|
||||
mustLabelMatcher(labels.MatchEqual, string(model.MetricNameLabel), "test"),
|
||||
},
|
||||
},
|
||||
Range: 5 * 24 * time.Hour,
|
||||
},
|
||||
}, {
|
||||
input: "test[5w] offset 2w",
|
||||
expected: &MatrixSelector{
|
||||
Name: "test",
|
||||
Offset: 14 * 24 * time.Hour,
|
||||
Range: 5 * 7 * 24 * time.Hour,
|
||||
LabelMatchers: []*labels.Matcher{
|
||||
mustLabelMatcher(labels.MatchEqual, string(model.MetricNameLabel), "test"),
|
||||
VectorSelector: &VectorSelector{
|
||||
Name: "test",
|
||||
Offset: 14 * 24 * time.Hour,
|
||||
LabelMatchers: []*labels.Matcher{
|
||||
mustLabelMatcher(labels.MatchEqual, string(model.MetricNameLabel), "test"),
|
||||
},
|
||||
},
|
||||
Range: 5 * 7 * 24 * time.Hour,
|
||||
},
|
||||
}, {
|
||||
input: `test{a="b"}[5y] OFFSET 3d`,
|
||||
expected: &MatrixSelector{
|
||||
Name: "test",
|
||||
Offset: 3 * 24 * time.Hour,
|
||||
Range: 5 * 365 * 24 * time.Hour,
|
||||
LabelMatchers: []*labels.Matcher{
|
||||
mustLabelMatcher(labels.MatchEqual, "a", "b"),
|
||||
mustLabelMatcher(labels.MatchEqual, string(model.MetricNameLabel), "test"),
|
||||
VectorSelector: &VectorSelector{
|
||||
Name: "test",
|
||||
Offset: 3 * 24 * time.Hour,
|
||||
LabelMatchers: []*labels.Matcher{
|
||||
mustLabelMatcher(labels.MatchEqual, "a", "b"),
|
||||
mustLabelMatcher(labels.MatchEqual, string(model.MetricNameLabel), "test"),
|
||||
},
|
||||
},
|
||||
Range: 5 * 365 * 24 * time.Hour,
|
||||
},
|
||||
}, {
|
||||
input: `foo[5mm]`,
|
||||
|
@ -1378,9 +1391,11 @@ var testExpr = []struct {
|
|||
Func: mustGetFunction("rate"),
|
||||
Args: Expressions{
|
||||
&MatrixSelector{
|
||||
Name: "some_metric",
|
||||
LabelMatchers: []*labels.Matcher{
|
||||
mustLabelMatcher(labels.MatchEqual, string(model.MetricNameLabel), "some_metric"),
|
||||
VectorSelector: &VectorSelector{
|
||||
Name: "some_metric",
|
||||
LabelMatchers: []*labels.Matcher{
|
||||
mustLabelMatcher(labels.MatchEqual, string(model.MetricNameLabel), "some_metric"),
|
||||
},
|
||||
},
|
||||
Range: 5 * time.Minute,
|
||||
},
|
||||
|
@ -1535,12 +1550,14 @@ var testExpr = []struct {
|
|||
Func: mustGetFunction("rate"),
|
||||
Args: Expressions{
|
||||
&MatrixSelector{
|
||||
Name: "foo",
|
||||
Range: 2 * time.Second,
|
||||
LabelMatchers: []*labels.Matcher{
|
||||
mustLabelMatcher(labels.MatchEqual, "bar", "baz"),
|
||||
mustLabelMatcher(labels.MatchEqual, string(model.MetricNameLabel), "foo"),
|
||||
VectorSelector: &VectorSelector{
|
||||
Name: "foo",
|
||||
LabelMatchers: []*labels.Matcher{
|
||||
mustLabelMatcher(labels.MatchEqual, "bar", "baz"),
|
||||
mustLabelMatcher(labels.MatchEqual, string(model.MetricNameLabel), "foo"),
|
||||
},
|
||||
},
|
||||
Range: 2 * time.Second,
|
||||
},
|
||||
},
|
||||
},
|
||||
|
@ -1560,12 +1577,14 @@ var testExpr = []struct {
|
|||
Func: mustGetFunction("rate"),
|
||||
Args: Expressions{
|
||||
&MatrixSelector{
|
||||
Name: "foo",
|
||||
Range: 2 * time.Second,
|
||||
LabelMatchers: []*labels.Matcher{
|
||||
mustLabelMatcher(labels.MatchEqual, "bar", "baz"),
|
||||
mustLabelMatcher(labels.MatchEqual, string(model.MetricNameLabel), "foo"),
|
||||
VectorSelector: &VectorSelector{
|
||||
Name: "foo",
|
||||
LabelMatchers: []*labels.Matcher{
|
||||
mustLabelMatcher(labels.MatchEqual, "bar", "baz"),
|
||||
mustLabelMatcher(labels.MatchEqual, string(model.MetricNameLabel), "foo"),
|
||||
},
|
||||
},
|
||||
Range: 2 * time.Second,
|
||||
},
|
||||
},
|
||||
},
|
||||
|
@ -1587,12 +1606,14 @@ var testExpr = []struct {
|
|||
Func: mustGetFunction("rate"),
|
||||
Args: Expressions{
|
||||
&MatrixSelector{
|
||||
Name: "foo",
|
||||
Range: 2 * time.Second,
|
||||
LabelMatchers: []*labels.Matcher{
|
||||
mustLabelMatcher(labels.MatchEqual, "bar", "baz"),
|
||||
mustLabelMatcher(labels.MatchEqual, string(model.MetricNameLabel), "foo"),
|
||||
VectorSelector: &VectorSelector{
|
||||
Name: "foo",
|
||||
LabelMatchers: []*labels.Matcher{
|
||||
mustLabelMatcher(labels.MatchEqual, "bar", "baz"),
|
||||
mustLabelMatcher(labels.MatchEqual, string(model.MetricNameLabel), "foo"),
|
||||
},
|
||||
},
|
||||
Range: 2 * time.Second,
|
||||
},
|
||||
},
|
||||
},
|
||||
|
|
|
@ -112,14 +112,16 @@ func (node *Call) String() string {
|
|||
}
|
||||
|
||||
func (node *MatrixSelector) String() string {
|
||||
vecSelector := &VectorSelector{
|
||||
Name: node.Name,
|
||||
LabelMatchers: node.LabelMatchers,
|
||||
}
|
||||
// Copy the Vector selector before changing the offset
|
||||
var vecSelector VectorSelector = *node.VectorSelector
|
||||
offset := ""
|
||||
if node.Offset != time.Duration(0) {
|
||||
offset = fmt.Sprintf(" offset %s", model.Duration(node.Offset))
|
||||
if vecSelector.Offset != time.Duration(0) {
|
||||
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)
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue