From 17fb65176ef7ad4b6c32048f69a28ae41518c1ec Mon Sep 17 00:00:00 2001 From: Lukasz Mierzwa Date: Tue, 11 Feb 2025 09:37:42 +0000 Subject: [PATCH 1/3] Improve logic of promql/series --- docs/changelog.md | 7 + docs/checks/promql/series.md | 15 + internal/checks/alerts_template.go | 2 +- internal/checks/promql_series.go | 91 +- internal/checks/promql_series_test.go | 39 + internal/parser/utils/source.go | 194 +-- internal/parser/utils/source_test.go | 1596 ++++++++++++------------- 7 files changed, 1020 insertions(+), 924 deletions(-) diff --git a/docs/changelog.md b/docs/changelog.md index 923ad360..b00b979f 100644 --- a/docs/changelog.md +++ b/docs/changelog.md @@ -7,6 +7,13 @@ - Added `names` option to the `parser` block, which controls how does Prometheus validates label names. +### Fixed + +- Improved the logic of [promql/series](checks/promql/series.md) check to skip checks on some selectors + which absence might be expected. For example using `foo unless bar` will now only have `foo` + tested while `bar` is ignored by this check. This is because the query implies that `bar` + might be present or missing and depending on that `foo` is evaluated. + ## v0.70.0 ### Added diff --git a/docs/checks/promql/series.md b/docs/checks/promql/series.md index 34336b4b..66bdb489 100644 --- a/docs/checks/promql/series.md +++ b/docs/checks/promql/series.md @@ -21,6 +21,10 @@ to determine why, by checking if: - `my_metric` has any series with `foo` label - `my_metric` has any series matching `foo="bar"` +## Ignored cases + +### vector() fallback + Metrics that are wrapped in `... or vector(0)` won't be checked, since the intention of adding `or vector(0)` is to provide a fallback value when there are no matching time series. @@ -31,6 +35,17 @@ Example: expr: sum(my_metric or vector(0)) > 1 ``` +### foo unless bar + +In a query using `foo unless bar` only `foo` selector will be tested, since +this query implies that the presence of `bar` is not guaranteed. +`bar` is only tested for being present and so it's likely that it might be missing. + +Note that using `foo unless bar > 5` doesn't follow the same pattern and will have +both `foo` and `bar` tested by this check +Having `bar > 5` means it's assumed to be always present as we're testing it's value, +rather than it's existence. + ## Common problems If you see this check complaining about some metric it's might due to a number diff --git a/internal/checks/alerts_template.go b/internal/checks/alerts_template.go index 6900f0a0..9efdb8da 100644 --- a/internal/checks/alerts_template.go +++ b/internal/checks/alerts_template.go @@ -443,7 +443,7 @@ func checkQueryLabels(query, labelName, labelValue string, src []utils.Source) ( if s.IsDead { continue } - if s.FixedLabels && !slices.Contains(s.IncludedLabels, v[1]) { + if s.FixedLabels && !slices.Contains(s.IncludedLabels, v[1]) && !slices.Contains(s.GuaranteedLabels, v[1]) { problems = append(problems, textForProblem(query, v[1], "", s, Bug)) goto NEXT } diff --git a/internal/checks/promql_series.go b/internal/checks/promql_series.go index afa13973..6098a479 100644 --- a/internal/checks/promql_series.go +++ b/internal/checks/promql_series.go @@ -143,7 +143,7 @@ func (c SeriesCheck) Check(ctx context.Context, _ discovery.Path, rule parser.Ru selectors := utils.HasVectorSelector(expr.Query) done := map[string]bool{} - for _, selector := range getNonFallbackSelectors(expr.Query) { + for _, selector := range getNonFallbackSelectors(expr) { if _, ok := done[selector.String()]; ok { continue } @@ -186,7 +186,7 @@ func (c SeriesCheck) Check(ctx context.Context, _ discovery.Path, rule parser.Ru if arEntry != nil { slog.Debug( "Metric is provided by alerting rule", - slog.String("selector", (&selector).String()), + slog.String("selector", selector.String()), slog.String("path", arEntry.Path.Name), ) } else { @@ -218,14 +218,14 @@ func (c SeriesCheck) Check(ctx context.Context, _ discovery.Path, rule parser.Ru } // 1. If foo{bar, baz} is there -> GOOD - slog.Debug("Checking if selector returns anything", slog.String("check", c.Reporter()), slog.String("selector", (&selector).String())) + slog.Debug("Checking if selector returns anything", slog.String("check", c.Reporter()), slog.String("selector", selector.String())) count, err := c.instantSeriesCount(ctx, fmt.Sprintf("count(%s)", selector.String())) if err != nil { problems = append(problems, c.queryProblem(err, expr)) continue } if count > 0 { - slog.Debug("Found series, skipping further checks", slog.String("check", c.Reporter()), slog.String("selector", (&selector).String())) + slog.Debug("Found series, skipping further checks", slog.String("check", c.Reporter()), slog.String("selector", selector.String())) continue } @@ -376,7 +376,7 @@ func (c SeriesCheck) Check(ctx context.Context, _ discovery.Path, rule parser.Ru slog.Debug( "Series disappeared from prometheus but for less then configured min-age", slog.String("check", c.Reporter()), - slog.String("selector", (&selector).String()), + slog.String("selector", selector.String()), slog.String("min-age", output.HumanizeDuration(minAge)), slog.String("last-seen", sinceDesc(newest(trs.Series.Ranges))), ) @@ -444,7 +444,7 @@ func (c SeriesCheck) Check(ctx context.Context, _ discovery.Path, rule parser.Ru Severity: severity, }) slog.Debug("No historical series matching filter used in the query", - slog.String("check", c.Reporter()), slog.String("selector", (&selector).String()), slog.String("matcher", lm.String())) + slog.String("check", c.Reporter()), slog.String("selector", selector.String()), slog.String("matcher", lm.String())) continue } @@ -482,7 +482,7 @@ func (c SeriesCheck) Check(ctx context.Context, _ discovery.Path, rule parser.Ru slog.Debug( "Series disappeared from prometheus but for less then configured min-age", slog.String("check", c.Reporter()), - slog.String("selector", (&selector).String()), + slog.String("selector", selector.String()), slog.String("min-age", output.HumanizeDuration(minAge)), slog.String("last-seen", sinceDesc(newest(trsLabel.Series.Ranges))), ) @@ -507,7 +507,7 @@ func (c SeriesCheck) Check(ctx context.Context, _ discovery.Path, rule parser.Ru slog.Debug( "Series matching filter disappeared from prometheus", slog.String("check", c.Reporter()), - slog.String("selector", (&selector).String()), + slog.String("selector", selector.String()), slog.String("matcher", lm.String()), ) continue @@ -528,7 +528,7 @@ func (c SeriesCheck) Check(ctx context.Context, _ discovery.Path, rule parser.Ru slog.Debug( "Series matching filter are only sometimes present", slog.String("check", c.Reporter()), - slog.String("selector", (&selector).String()), + slog.String("selector", selector.String()), slog.String("matcher", lm.String()), ) } @@ -686,7 +686,7 @@ func (c SeriesCheck) instantSeriesCount(ctx context.Context, query string) (int, return series, nil } -func (c SeriesCheck) getMinAge(rule parser.Rule, selector promParser.VectorSelector) (minAge time.Duration, problems []Problem) { +func (c SeriesCheck) getMinAge(rule parser.Rule, selector *promParser.VectorSelector) (minAge time.Duration, problems []Problem) { minAge = time.Hour * 2 for _, ruleSet := range comments.Only[comments.RuleSet](rule.Comments, comments.RuleSetType) { matcher, key, value := parseRuleSet(ruleSet.Value) @@ -716,7 +716,7 @@ func (c SeriesCheck) getMinAge(rule parser.Rule, selector promParser.VectorSelec return minAge, problems } -func (c SeriesCheck) isLabelValueIgnored(settings *PromqlSeriesSettings, rule parser.Rule, selector promParser.VectorSelector, labelName string) bool { +func (c SeriesCheck) isLabelValueIgnored(settings *PromqlSeriesSettings, rule parser.Rule, selector *promParser.VectorSelector, labelName string) bool { for matcher, names := range settings.IgnoreLabelsValue { isMatch, _ := matchSelectorToMetric(selector, matcher) if !isMatch { @@ -739,7 +739,7 @@ func (c SeriesCheck) isLabelValueIgnored(settings *PromqlSeriesSettings, rule pa } } if labelName == value { - slog.Debug("Label check disabled by comment", slog.String("selector", (&selector).String()), slog.String("label", labelName)) + slog.Debug("Label check disabled by comment", slog.String("selector", selector.String()), slog.String("label", labelName)) return true } } @@ -760,36 +760,51 @@ func (c SeriesCheck) textAndSeverity(settings *PromqlSeriesSettings, name, text return text, s } -func getNonFallbackSelectors(n *parser.PromQLNode) (selectors []promParser.VectorSelector) { -LOOP: - for _, vs := range parser.WalkDownExpr[*promParser.VectorSelector](n) { - for _, bin := range parser.WalkUpExpr[*promParser.BinaryExpr](vs.Parent) { - if binExp := bin.Expr.(*promParser.BinaryExpr); binExp.Op != promParser.LOR { - continue +func selectorWithoutOffset(vs *promParser.VectorSelector) *promParser.VectorSelector { + if vs.OriginalOffset == 0 { + return vs + } + + s := &promParser.VectorSelector{} + *s = *vs + s.Offset = 0 + s.OriginalOffset = 0 + return s +} + +func getNonFallbackSelectors(n parser.PromQLExpr) (selectors []*promParser.VectorSelector) { + var hasVectorFallback bool + sources := utils.LabelsSource(n.Value.Value, n.Query.Expr) + for _, ls := range sources { + if ls.AlwaysReturns && len(ls.ReturnedNumbers) > 0 { + hasVectorFallback = true + break + } + } + for _, ls := range sources { + if !hasVectorFallback { + for _, s := range ls.Selectors { + selectors = append(selectors, selectorWithoutOffset(s)) } - for _, vec := range parser.WalkDownExpr[*promParser.Call](bin) { - if vecCall := vec.Expr.(*promParser.Call); vecCall.Func.Name == "vector" { - // vector seletor is under (...) OR vector() - // ignore it - slog.Debug( - "Metric uses vector() fallback value, ignore", - slog.String("selector", (vs.Expr.String())), - ) - continue LOOP - } + } + for _, js := range ls.Joins { + for _, s := range js.Selectors { + selectors = append(selectors, selectorWithoutOffset(s)) } } - // copy node without offset - nc := promParser.VectorSelector{ - Name: vs.Expr.(*promParser.VectorSelector).Name, - LabelMatchers: vs.Expr.(*promParser.VectorSelector).LabelMatchers, + for _, us := range ls.Unless { + if !us.IsConditional { + continue + } + for _, s := range us.Selectors { + selectors = append(selectors, selectorWithoutOffset(s)) + } } - selectors = append(selectors, nc) } return selectors } -func stripLabels(selector promParser.VectorSelector) promParser.VectorSelector { +func stripLabels(selector *promParser.VectorSelector) promParser.VectorSelector { s := promParser.VectorSelector{ Name: selector.Name, LabelMatchers: []*labels.Matcher{}, @@ -805,7 +820,7 @@ func stripLabels(selector promParser.VectorSelector) promParser.VectorSelector { return s } -func isDisabled(rule parser.Rule, selector promParser.VectorSelector) bool { +func isDisabled(rule parser.Rule, selector *promParser.VectorSelector) bool { for _, disable := range comments.Only[comments.Disable](rule.Comments, comments.DisableType) { if strings.HasPrefix(disable.Match, SeriesCheckName+"(") && strings.HasSuffix(disable.Match, ")") { cs := strings.TrimSuffix(strings.TrimPrefix(disable.Match, SeriesCheckName+"("), ")") @@ -823,7 +838,7 @@ func isDisabled(rule parser.Rule, selector promParser.VectorSelector) bool { return false } -func matchSelectorToMetric(selector promParser.VectorSelector, metric string) (bool, bool) { +func matchSelectorToMetric(selector *promParser.VectorSelector, metric string) (bool, bool) { // Try full string or name match first. if metric == selector.String() || metric == selector.Name { return true, true @@ -889,7 +904,7 @@ func orphanedDisableComments(ctx context.Context, rule parser.Rule, selectors [] continue } for _, selector := range selectors { - isMatch, ok := matchSelectorToMetric(selector, match) + isMatch, ok := matchSelectorToMetric(&selector, match) if !ok { continue } @@ -912,7 +927,7 @@ func orphanedRuleSetComments(rule parser.Rule, selectors []promParser.VectorSele matcher, key, value := parseRuleSet(ruleSet.Value) for _, selector := range selectors { if matcher != "" { - isMatch, _ := matchSelectorToMetric(selector, matcher) + isMatch, _ := matchSelectorToMetric(&selector, matcher) if !isMatch { continue } diff --git a/internal/checks/promql_series_test.go b/internal/checks/promql_series_test.go index 878a0a8a..53d8b4b0 100644 --- a/internal/checks/promql_series_test.go +++ b/internal/checks/promql_series_test.go @@ -4234,6 +4234,45 @@ func TestSeriesCheck(t *testing.T) { }, }, }, + { + description: "foo unless bar", + content: "- record: foo\n expr: foo unless bar\n", + checker: newSeriesCheck, + prometheus: newSimpleProm, + problems: noProblems, + mocks: []*prometheusMock{ + { + conds: []requestCondition{ + requireQueryPath, + formCond{key: "query", value: "count(foo)"}, + }, + resp: respondWithSingleInstantVector(), + }, + }, + }, + { + description: "foo unless bar > 5", + content: "- record: foo\n expr: foo unless bar > 5\n", + checker: newSeriesCheck, + prometheus: newSimpleProm, + problems: noProblems, + mocks: []*prometheusMock{ + { + conds: []requestCondition{ + requireQueryPath, + formCond{key: "query", value: "count(foo)"}, + }, + resp: respondWithSingleInstantVector(), + }, + { + conds: []requestCondition{ + requireQueryPath, + formCond{key: "query", value: "count(bar)"}, + }, + resp: respondWithSingleInstantVector(), + }, + }, + }, } runTests(t, testCases) } diff --git a/internal/parser/utils/source.go b/internal/parser/utils/source.go index 0c0c0a68..f55f4d84 100644 --- a/internal/parser/utils/source.go +++ b/internal/parser/utils/source.go @@ -28,6 +28,8 @@ type ExcludedLabel struct { } type Source struct { + Joins []Source // Any other sources this source joins with. + Unless []Source // Any other sources this source is suppressed by. Selectors []*promParser.VectorSelector Call *promParser.Call ExcludeReason map[string]ExcludedLabel // Reason why a label was excluded @@ -41,6 +43,7 @@ type Source struct { FixedLabels bool // Labels are fixed and only allowed labels can be present. IsDead bool // True if this source cannot be reached and is dead code. AlwaysReturns bool // True if this source always returns results. + IsConditional bool // True if this source is guarded by 'foo > 5' or other condition. } func LabelsSource(expr string, node promParser.Node) (src []Source) { @@ -57,8 +60,7 @@ func walkNode(expr string, node promParser.Node) (src []Source) { src = append(src, parseBinOps(expr, n)...) case *promParser.Call: - s = parseCall(expr, n) - src = append(src, s) + src = append(src, parseCall(expr, n)...) case *promParser.MatrixSelector: src = append(src, walkNode(expr, n.VectorSelector)...) @@ -114,7 +116,7 @@ func walkNode(expr string, node promParser.Node) (src []Source) { s.Type = SelectorSource s.Returns = promParser.ValueTypeVector s.Selectors = append(s.Selectors, n) - s.GuaranteedLabels = appendToSlice(s.GuaranteedLabels, labelsFromSelectors(guaranteedLabelsMatches, n)...) + s = guaranteeLabel(s, labelsFromSelectors(guaranteedLabelsMatches, n)...) src = append(src, s) default: @@ -145,6 +147,31 @@ func appendToSlice(dst []string, values ...string) []string { return dst } +func includeLabel(s Source, names ...string) Source { + s.ExcludedLabels = removeFromSlice(s.ExcludedLabels, names...) + for _, name := range names { + delete(s.ExcludeReason, name) + } + s.IncludedLabels = appendToSlice(s.IncludedLabels, names...) + return s +} + +func guaranteeLabel(s Source, names ...string) Source { + s.ExcludedLabels = removeFromSlice(s.ExcludedLabels, names...) + for _, name := range names { + delete(s.ExcludeReason, name) + } + s.GuaranteedLabels = appendToSlice(s.GuaranteedLabels, names...) + return s +} + +func excludeLabel(s Source, names ...string) Source { + s.ExcludedLabels = appendToSlice(s.ExcludedLabels, names...) + s.IncludedLabels = removeFromSlice(s.IncludedLabels, names...) + s.GuaranteedLabels = removeFromSlice(s.GuaranteedLabels, names...) + return s +} + func setInMap(dst map[string]ExcludedLabel, key string, val ExcludedLabel) map[string]ExcludedLabel { if dst == nil { dst = map[string]ExcludedLabel{} @@ -236,10 +263,8 @@ func walkAggregation(expr string, n *promParser.AggregateExpr) (src []Source) { for _, s = range parseAggregation(expr, n) { s.Operation = "count_values" // Param is the label to store the count value in. - s.GuaranteedLabels = appendToSlice(s.GuaranteedLabels, n.Param.(*promParser.StringLiteral).Val) - s.IncludedLabels = appendToSlice(s.IncludedLabels, n.Param.(*promParser.StringLiteral).Val) - s.ExcludedLabels = removeFromSlice(s.ExcludedLabels, n.Param.(*promParser.StringLiteral).Val) - delete(s.ExcludeReason, n.Param.(*promParser.StringLiteral).Val) + s = includeLabel(s, n.Param.(*promParser.StringLiteral).Val) + s = guaranteeLabel(s, n.Param.(*promParser.StringLiteral).Val) src = append(src, s) } case promParser.QUANTILE: @@ -278,9 +303,7 @@ func parseAggregation(expr string, n *promParser.AggregateExpr) (src []Source) { var s Source for _, s = range walkNode(expr, n.Expr) { if n.Without { - s.ExcludedLabels = appendToSlice(s.ExcludedLabels, n.Grouping...) - s.IncludedLabels = removeFromSlice(s.IncludedLabels, n.Grouping...) - s.GuaranteedLabels = removeFromSlice(s.GuaranteedLabels, n.Grouping...) + s = excludeLabel(s, n.Grouping...) for _, name := range n.Grouping { s.ExcludeReason = setInMap( s.ExcludeReason, @@ -307,10 +330,7 @@ func parseAggregation(expr string, n *promParser.AggregateExpr) (src []Source) { } else { // Check if source of labels already fixes them. if !s.FixedLabels { - s.IncludedLabels = appendToSlice(s.IncludedLabels, n.Grouping...) - for _, name := range n.Grouping { - s.ExcludedLabels = removeFromSlice(s.ExcludedLabels, name) - } + s = includeLabel(s, n.Grouping...) s.ExcludeReason = setInMap( s.ExcludeReason, "", @@ -337,55 +357,36 @@ func parseAggregation(expr string, n *promParser.AggregateExpr) (src []Source) { return src } -func parseCall(expr string, n *promParser.Call) (s Source) { - s.Type = FuncSource - s.Operation = n.Func.Name - s.Call = n - - var vt promParser.ValueType - for i, e := range n.Args { - if i >= len(n.Func.ArgTypes) { - vt = n.Func.ArgTypes[len(n.Func.ArgTypes)-1] - } else { - vt = n.Func.ArgTypes[i] - } - - // nolint: exhaustive - switch vt { - case promParser.ValueTypeVector, promParser.ValueTypeMatrix: - for _, es := range walkNode(expr, e) { - s.Selectors = append(s.Selectors, es.Selectors...) - } - } - } - +func parsePromQLFunc(s Source, expr string, n *promParser.Call) Source { switch n.Func.Name { case "abs", "sgn", "acos", "acosh", "asin", "asinh", "atan", "atanh", "cos", "cosh", "sin", "sinh", "tan", "tanh": // No change to labels. s.Returns = promParser.ValueTypeVector - s.GuaranteedLabels = appendToSlice(s.GuaranteedLabels, labelsFromSelectors(guaranteedLabelsMatches, s.Selectors...)...) + s = guaranteeLabel(s, labelsFromSelectors(guaranteedLabelsMatches, s.Selectors...)...) case "ceil", "floor", "round": // No change to labels. s.Returns = promParser.ValueTypeVector - s.GuaranteedLabels = appendToSlice(s.GuaranteedLabels, labelsFromSelectors(guaranteedLabelsMatches, s.Selectors...)...) + s = guaranteeLabel(s, labelsFromSelectors(guaranteedLabelsMatches, s.Selectors...)...) case "changes", "resets": // No change to labels. s.Returns = promParser.ValueTypeVector - s.GuaranteedLabels = appendToSlice(s.GuaranteedLabels, labelsFromSelectors(guaranteedLabelsMatches, s.Selectors...)...) + s = guaranteeLabel(s, labelsFromSelectors(guaranteedLabelsMatches, s.Selectors...)...) case "clamp", "clamp_max", "clamp_min": // No change to labels. s.Returns = promParser.ValueTypeVector - s.GuaranteedLabels = appendToSlice(s.GuaranteedLabels, labelsFromSelectors(guaranteedLabelsMatches, s.Selectors...)...) + s = guaranteeLabel(s, labelsFromSelectors(guaranteedLabelsMatches, s.Selectors...)...) case "absent", "absent_over_time": s.Returns = promParser.ValueTypeVector s.FixedLabels = true + s.IncludedLabels = nil + s.GuaranteedLabels = nil for _, name := range labelsFromSelectors([]labels.MatchType{labels.MatchEqual}, s.Selectors...) { - s.IncludedLabels = appendToSlice(s.IncludedLabels, name) - s.GuaranteedLabels = appendToSlice(s.GuaranteedLabels, name) + s = includeLabel(s, name) + s = guaranteeLabel(s, name) } s.ExcludeReason = setInMap( s.ExcludeReason, @@ -404,7 +405,7 @@ If you're hoping to get instance specific labels this way and alert when some ta case "avg_over_time", "count_over_time", "last_over_time", "max_over_time", "min_over_time", "present_over_time", "quantile_over_time", "stddev_over_time", "stdvar_over_time", "sum_over_time": // No change to labels. s.Returns = promParser.ValueTypeVector - s.GuaranteedLabels = appendToSlice(s.GuaranteedLabels, labelsFromSelectors(guaranteedLabelsMatches, s.Selectors...)...) + s = guaranteeLabel(s, labelsFromSelectors(guaranteedLabelsMatches, s.Selectors...)...) case "days_in_month", "day_of_month", "day_of_week", "day_of_year", "hour", "minute", "month", "year": s.Returns = promParser.ValueTypeVector @@ -425,34 +426,34 @@ If you're hoping to get instance specific labels this way and alert when some ta }, ) } else { - s.GuaranteedLabels = appendToSlice(s.GuaranteedLabels, labelsFromSelectors(guaranteedLabelsMatches, s.Selectors...)...) + s = guaranteeLabel(s, labelsFromSelectors(guaranteedLabelsMatches, s.Selectors...)...) } case "deg", "rad", "ln", "log10", "log2", "sqrt", "exp": // No change to labels. s.Returns = promParser.ValueTypeVector - s.GuaranteedLabels = appendToSlice(s.GuaranteedLabels, labelsFromSelectors(guaranteedLabelsMatches, s.Selectors...)...) + s = guaranteeLabel(s, labelsFromSelectors(guaranteedLabelsMatches, s.Selectors...)...) case "delta", "idelta", "increase", "deriv", "irate", "rate": // No change to labels. s.Returns = promParser.ValueTypeVector - s.GuaranteedLabels = appendToSlice(s.GuaranteedLabels, labelsFromSelectors(guaranteedLabelsMatches, s.Selectors...)...) + s = guaranteeLabel(s, labelsFromSelectors(guaranteedLabelsMatches, s.Selectors...)...) case "histogram_avg", "histogram_count", "histogram_sum", "histogram_stddev", "histogram_stdvar", "histogram_fraction", "histogram_quantile": // No change to labels. s.Returns = promParser.ValueTypeVector - s.GuaranteedLabels = appendToSlice(s.GuaranteedLabels, labelsFromSelectors(guaranteedLabelsMatches, s.Selectors...)...) + s = guaranteeLabel(s, labelsFromSelectors(guaranteedLabelsMatches, s.Selectors...)...) case "holt_winters", "predict_linear": // No change to labels. s.Returns = promParser.ValueTypeVector - s.GuaranteedLabels = appendToSlice(s.GuaranteedLabels, labelsFromSelectors(guaranteedLabelsMatches, s.Selectors...)...) + s = guaranteeLabel(s, labelsFromSelectors(guaranteedLabelsMatches, s.Selectors...)...) case "label_replace", "label_join": // One label added to the results. s.Returns = promParser.ValueTypeVector - s.GuaranteedLabels = appendToSlice(s.GuaranteedLabels, labelsFromSelectors(guaranteedLabelsMatches, s.Selectors...)...) - s.GuaranteedLabels = appendToSlice(s.GuaranteedLabels, s.Call.Args[1].(*promParser.StringLiteral).Val) + s = guaranteeLabel(s, labelsFromSelectors(guaranteedLabelsMatches, s.Selectors...)...) + s = guaranteeLabel(s, s.Call.Args[1].(*promParser.StringLiteral).Val) case "pi": s.Returns = promParser.ValueTypeScalar @@ -506,7 +507,7 @@ If you're hoping to get instance specific labels this way and alert when some ta case "timestamp": // No change to labels. s.Returns = promParser.ValueTypeVector - s.GuaranteedLabels = appendToSlice(s.GuaranteedLabels, labelsFromSelectors(guaranteedLabelsMatches, s.Selectors...)...) + s = guaranteeLabel(s, labelsFromSelectors(guaranteedLabelsMatches, s.Selectors...)...) case "vector": s.Returns = promParser.ValueTypeVector @@ -534,6 +535,38 @@ If you're hoping to get instance specific labels this way and alert when some ta return s } +func parseCall(expr string, n *promParser.Call) (src []Source) { + var vt promParser.ValueType + for i, e := range n.Args { + if i >= len(n.Func.ArgTypes) { + vt = n.Func.ArgTypes[len(n.Func.ArgTypes)-1] + } else { + vt = n.Func.ArgTypes[i] + } + + switch vt { + case promParser.ValueTypeVector, promParser.ValueTypeMatrix: + for _, es := range walkNode(expr, e) { + es.Type = FuncSource + es.Operation = n.Func.Name + es.Call = n + src = append(src, parsePromQLFunc(es, expr, n)) + } + case promParser.ValueTypeNone, promParser.ValueTypeScalar, promParser.ValueTypeString: + } + } + + if len(src) == 0 { + var s Source + s.Type = FuncSource + s.Operation = n.Func.Name + s.Call = n + src = append(src, parsePromQLFunc(s, expr, n)) + } + + return src +} + func parseBinOps(expr string, n *promParser.BinaryExpr) (src []Source) { var s Source switch { @@ -546,7 +579,9 @@ func parseBinOps(expr string, n *promParser.BinaryExpr) (src []Source) { lhs := walkNode(expr, n.LHS) rhs := walkNode(expr, n.RHS) for _, ls := range lhs { + ls.IsConditional = n.Op.IsComparisonOperator() for _, rs := range rhs { + rs.IsConditional = n.Op.IsComparisonOperator() switch { case ls.AlwaysReturns && rs.AlwaysReturns: // Both sides always return something @@ -569,15 +604,13 @@ func parseBinOps(expr string, n *promParser.BinaryExpr) (src []Source) { // foo{} + bar{} // foo{} + on(...) bar{} // foo{} + ignoring(...) bar{} + // foo{} / bar{} case n.VectorMatching.Card == promParser.CardOneToOne: + rhs := walkNode(expr, n.RHS) for _, s = range walkNode(expr, n.LHS) { if n.VectorMatching.On { s.FixedLabels = true - s.IncludedLabels = appendToSlice(s.IncludedLabels, n.VectorMatching.MatchingLabels...) - s.ExcludedLabels = removeFromSlice(s.ExcludedLabels, n.VectorMatching.MatchingLabels...) - for _, name := range n.VectorMatching.MatchingLabels { - delete(s.ExcludeReason, name) - } + s = includeLabel(s, n.VectorMatching.MatchingLabels...) s.ExcludeReason = setInMap( s.ExcludeReason, "", @@ -596,9 +629,7 @@ func parseBinOps(expr string, n *promParser.BinaryExpr) (src []Source) { }, ) } else { - s.IncludedLabels = removeFromSlice(s.IncludedLabels, n.VectorMatching.MatchingLabels...) - s.GuaranteedLabels = removeFromSlice(s.GuaranteedLabels, n.VectorMatching.MatchingLabels...) - s.ExcludedLabels = appendToSlice(s.ExcludedLabels, n.VectorMatching.MatchingLabels...) + s = excludeLabel(s, n.VectorMatching.MatchingLabels...) for _, name := range n.VectorMatching.MatchingLabels { s.ExcludeReason = setInMap( s.ExcludeReason, @@ -622,61 +653,54 @@ func parseBinOps(expr string, n *promParser.BinaryExpr) (src []Source) { if s.Operation == "" { s.Operation = n.VectorMatching.Card.String() } + s.Joins = append(s.Joins, rhs...) + s.IsConditional = n.Op.IsComparisonOperator() src = append(src, s) } // foo{} + on(...) group_left(...) bar{} // foo{} + ignoring(...) group_left(...) bar{} case n.VectorMatching.Card == promParser.CardOneToMany: + lhs := walkNode(expr, n.LHS) for _, s = range walkNode(expr, n.RHS) { - s.IncludedLabels = appendToSlice(s.IncludedLabels, n.VectorMatching.Include...) + s = includeLabel(s, n.VectorMatching.Include...) if n.VectorMatching.On { - s.IncludedLabels = appendToSlice(s.IncludedLabels, n.VectorMatching.MatchingLabels...) - for _, name := range n.VectorMatching.MatchingLabels { - delete(s.ExcludeReason, name) - } - } - s.ExcludedLabels = removeFromSlice(s.ExcludedLabels, n.VectorMatching.Include...) - for _, name := range n.VectorMatching.Include { - delete(s.ExcludeReason, name) + s = includeLabel(s, n.VectorMatching.MatchingLabels...) } if s.Operation == "" { s.Operation = n.VectorMatching.Card.String() } + s.Joins = append(s.Joins, lhs...) + s.IsConditional = n.Op.IsComparisonOperator() src = append(src, s) } // foo{} + on(...) group_right(...) bar{} // foo{} + ignoring(...) group_right(...) bar{} case n.VectorMatching.Card == promParser.CardManyToOne: + rhs := walkNode(expr, n.RHS) for _, s = range walkNode(expr, n.LHS) { - s.IncludedLabels = appendToSlice(s.IncludedLabels, n.VectorMatching.Include...) + s = includeLabel(s, n.VectorMatching.Include...) if n.VectorMatching.On { - s.IncludedLabels = appendToSlice(s.IncludedLabels, n.VectorMatching.MatchingLabels...) - for _, name := range n.VectorMatching.MatchingLabels { - delete(s.ExcludeReason, name) - } - } - s.ExcludedLabels = removeFromSlice(s.ExcludedLabels, n.VectorMatching.Include...) - for _, name := range n.VectorMatching.Include { - delete(s.ExcludeReason, name) + s = includeLabel(s, n.VectorMatching.MatchingLabels...) } if s.Operation == "" { s.Operation = n.VectorMatching.Card.String() } + s.Joins = append(s.Joins, rhs...) + s.IsConditional = n.Op.IsComparisonOperator() src = append(src, s) } // foo{} and on(...) bar{} // foo{} and ignoring(...) bar{} + // foo{} unless bar{} case n.VectorMatching.Card == promParser.CardManyToMany: var lhsCanBeEmpty bool // true if any of the LHS query can produce empty results. + rhs := walkNode(expr, n.RHS) for _, s = range walkNode(expr, n.LHS) { if n.VectorMatching.On { - s.IncludedLabels = appendToSlice(s.IncludedLabels, n.VectorMatching.MatchingLabels...) - for _, name := range n.VectorMatching.MatchingLabels { - delete(s.ExcludeReason, name) - } + s = includeLabel(s, n.VectorMatching.MatchingLabels...) } if s.Operation == "" { s.Operation = n.VectorMatching.Card.String() @@ -684,10 +708,16 @@ func parseBinOps(expr string, n *promParser.BinaryExpr) (src []Source) { if !s.AlwaysReturns { lhsCanBeEmpty = true } + switch { + case n.Op == promParser.LUNLESS: + s.Unless = append(s.Unless, rhs...) + case n.Op != promParser.LOR: + s.Joins = append(s.Joins, rhs...) + } src = append(src, s) } if n.Op == promParser.LOR { - for _, s = range walkNode(expr, n.RHS) { + for _, s = range rhs { if s.Operation == "" { s.Operation = n.VectorMatching.Card.String() } diff --git a/internal/parser/utils/source_test.go b/internal/parser/utils/source_test.go index 5564128a..796341fb 100644 --- a/internal/parser/utils/source_test.go +++ b/internal/parser/utils/source_test.go @@ -3,7 +3,6 @@ package utils_test import ( "strings" "testing" - "time" "github.com/stretchr/testify/require" @@ -11,33 +10,22 @@ import ( "github.com/cloudflare/pint/internal/parser/utils" promParser "github.com/prometheus/prometheus/promql/parser" - "github.com/prometheus/prometheus/promql/parser/posrange" ) +func mustParse[T any](t *testing.T, s string, offset int) T { + m, err := promParser.ParseExpr(strings.Repeat(" ", offset) + s) + require.NoErrorf(t, err, "failed to parse vector selector: %s", s) + n, ok := m.(T) + require.True(t, ok, "failed to convert %q to %t\n", s, n) + return n +} + func TestLabelsSource(t *testing.T) { type testCaseT struct { expr string output []utils.Source } - mustParseVector := func(s string, offset int) *promParser.VectorSelector { - m, err := promParser.ParseExpr(s) - require.NoErrorf(t, err, "failed to parse vector selector: %s", s) - v := m.(*promParser.VectorSelector) - v.PosRange.Start += posrange.Pos(offset) - v.PosRange.End += posrange.Pos(offset) - return v - } - - mustParseMatrix := func(s string, offset int) *promParser.MatrixSelector { - e, err := promParser.ParseExpr(s) - require.NoErrorf(t, err, "failed to parse matrix selector: %s", s) - m := e.(*promParser.MatrixSelector) - m.VectorSelector = mustParseVector(m.VectorSelector.String(), offset) - m.EndPos += posrange.Pos(offset) - return m - } - testCases := []testCaseT{ { expr: "1", @@ -91,6 +79,7 @@ func TestLabelsSource(t *testing.T) { Fragment: "2", }, }, + IsConditional: true, }, }, }, @@ -110,6 +99,7 @@ func TestLabelsSource(t *testing.T) { Fragment: "2", }, }, + IsConditional: true, }, }, }, @@ -129,6 +119,7 @@ func TestLabelsSource(t *testing.T) { Fragment: "2", }, }, + IsConditional: true, }, }, }, @@ -147,6 +138,7 @@ func TestLabelsSource(t *testing.T) { Fragment: "2", }, }, + IsConditional: true, }, }, }, @@ -166,6 +158,7 @@ func TestLabelsSource(t *testing.T) { Fragment: "2", }, }, + IsConditional: true, }, }, }, @@ -185,6 +178,7 @@ func TestLabelsSource(t *testing.T) { Fragment: "20", }, }, + IsConditional: true, }, }, }, @@ -214,7 +208,7 @@ func TestLabelsSource(t *testing.T) { Returns: promParser.ValueTypeVector, Operation: promParser.CardManyToMany.String(), Selectors: []*promParser.VectorSelector{ - mustParseVector("foo", 1), + mustParse[*promParser.VectorSelector](t, "foo", 1), }, }, { @@ -222,7 +216,7 @@ func TestLabelsSource(t *testing.T) { Returns: promParser.ValueTypeVector, Operation: promParser.CardManyToMany.String(), Selectors: []*promParser.VectorSelector{ - mustParseVector("bar", 8), + mustParse[*promParser.VectorSelector](t, "bar", 8), }, }, }, @@ -235,7 +229,7 @@ func TestLabelsSource(t *testing.T) { Returns: promParser.ValueTypeVector, Operation: promParser.CardManyToMany.String(), Selectors: []*promParser.VectorSelector{ - mustParseVector("foo", 1), + mustParse[*promParser.VectorSelector](t, "foo", 1), }, }, { @@ -251,29 +245,7 @@ func TestLabelsSource(t *testing.T) { Fragment: "vector(2)", }, }, - Call: &promParser.Call{ - Func: &promParser.Function{ - Name: "vector", - ArgTypes: []promParser.ValueType{ - promParser.ValueTypeScalar, - }, - Variadic: 0, - ReturnType: promParser.ValueTypeVector, - }, - Args: promParser.Expressions{ - &promParser.NumberLiteral{ - Val: 2, - PosRange: posrange.PositionRange{ - Start: 15, - End: 16, - }, - }, - }, - PosRange: posrange.PositionRange{ - Start: 8, - End: 17, - }, - }, + Call: mustParse[*promParser.Call](t, "vector(2)", 8), }, }, }, @@ -285,7 +257,33 @@ func TestLabelsSource(t *testing.T) { Returns: promParser.ValueTypeVector, Operation: promParser.CardManyToMany.String(), Selectors: []*promParser.VectorSelector{ - mustParseVector("foo", 1), + mustParse[*promParser.VectorSelector](t, "foo", 1), + }, + Joins: []utils.Source{ + { + Type: utils.FuncSource, + Returns: promParser.ValueTypeVector, + Operation: "vector", + FixedLabels: true, + AlwaysReturns: true, + ReturnedNumbers: []float64{2}, + Call: mustParse[*promParser.Call](t, "vector(2)", 22), + ExcludeReason: map[string]utils.ExcludedLabel{ + "": { + Reason: "Calling `vector()` will return a vector value with no labels.", + Fragment: "vector(2)", + }, + }, + }, + { + Type: utils.SelectorSource, + Returns: promParser.ValueTypeVector, + Operation: promParser.CardManyToMany.String(), + Selectors: []*promParser.VectorSelector{ + mustParse[*promParser.VectorSelector](t, "bar", 35), + }, + IsDead: true, + }, }, }, { @@ -301,27 +299,31 @@ func TestLabelsSource(t *testing.T) { Fragment: "vector(5)", }, }, - Call: &promParser.Call{ - Func: &promParser.Function{ - Name: "vector", - ArgTypes: []promParser.ValueType{ - promParser.ValueTypeScalar, - }, - Variadic: 0, - ReturnType: promParser.ValueTypeVector, - }, - Args: promParser.Expressions{ - &promParser.NumberLiteral{ - Val: 5, - PosRange: posrange.PositionRange{ - Start: 15, - End: 16, + Call: mustParse[*promParser.Call](t, "vector(5)", 8), + Joins: []utils.Source{ + { + Type: utils.FuncSource, + Returns: promParser.ValueTypeVector, + Operation: "vector", + FixedLabels: true, + AlwaysReturns: true, + ReturnedNumbers: []float64{2}, + Call: mustParse[*promParser.Call](t, "vector(2)", 22), + ExcludeReason: map[string]utils.ExcludedLabel{ + "": { + Reason: "Calling `vector()` will return a vector value with no labels.", + Fragment: "vector(2)", }, }, }, - PosRange: posrange.PositionRange{ - Start: 8, - End: 17, + { + Type: utils.SelectorSource, + Returns: promParser.ValueTypeVector, + Operation: promParser.CardManyToMany.String(), + Selectors: []*promParser.VectorSelector{ + mustParse[*promParser.VectorSelector](t, "bar", 35), + }, + IsDead: true, }, }, }, @@ -342,6 +344,7 @@ func TestLabelsSource(t *testing.T) { Fragment: "1", }, }, + IsConditional: true, }, }, }, @@ -360,6 +363,7 @@ func TestLabelsSource(t *testing.T) { Fragment: "20", }, }, + IsConditional: true, }, }, }, @@ -387,7 +391,19 @@ func TestLabelsSource(t *testing.T) { Type: utils.SelectorSource, Returns: promParser.ValueTypeVector, Selectors: []*promParser.VectorSelector{ - mustParseVector("foo", 0), + mustParse[*promParser.VectorSelector](t, "foo", 0), + }, + }, + }, + }, + { + expr: "foo offset 5m", + output: []utils.Source{ + { + Type: utils.SelectorSource, + Returns: promParser.ValueTypeVector, + Selectors: []*promParser.VectorSelector{ + mustParse[*promParser.VectorSelector](t, "foo offset 5m", 0), }, }, }, @@ -399,7 +415,7 @@ func TestLabelsSource(t *testing.T) { Type: utils.SelectorSource, Returns: promParser.ValueTypeVector, Selectors: []*promParser.VectorSelector{ - mustParseVector(`foo{job="bar"}`, 0), + mustParse[*promParser.VectorSelector](t, `foo{job="bar"}`, 0), }, GuaranteedLabels: []string{"job"}, }, @@ -412,7 +428,7 @@ func TestLabelsSource(t *testing.T) { Type: utils.SelectorSource, Returns: promParser.ValueTypeVector, Selectors: []*promParser.VectorSelector{ - mustParseVector(`foo{job="bar"}`, 0), + mustParse[*promParser.VectorSelector](t, `foo{job="bar"}`, 0), }, Operation: promParser.CardManyToMany.String(), GuaranteedLabels: []string{"job"}, @@ -421,7 +437,7 @@ func TestLabelsSource(t *testing.T) { Type: utils.SelectorSource, Returns: promParser.ValueTypeVector, Selectors: []*promParser.VectorSelector{ - mustParseVector(`bar{job="foo"}`, 18), + mustParse[*promParser.VectorSelector](t, `bar{job="foo"}`, 18), }, Operation: promParser.CardManyToMany.String(), GuaranteedLabels: []string{"job"}, @@ -435,7 +451,7 @@ func TestLabelsSource(t *testing.T) { Type: utils.SelectorSource, Returns: promParser.ValueTypeVector, Selectors: []*promParser.VectorSelector{ - mustParseVector(`foo{a="bar"}`, 0), + mustParse[*promParser.VectorSelector](t, `foo{a="bar"}`, 0), }, Operation: promParser.CardManyToMany.String(), GuaranteedLabels: []string{"a"}, @@ -444,7 +460,7 @@ func TestLabelsSource(t *testing.T) { Type: utils.SelectorSource, Returns: promParser.ValueTypeVector, Selectors: []*promParser.VectorSelector{ - mustParseVector(`bar{b="foo"}`, 16), + mustParse[*promParser.VectorSelector](t, `bar{b="foo"}`, 16), }, Operation: promParser.CardManyToMany.String(), GuaranteedLabels: []string{"b"}, @@ -458,7 +474,7 @@ func TestLabelsSource(t *testing.T) { Type: utils.SelectorSource, Returns: promParser.ValueTypeVector, Selectors: []*promParser.VectorSelector{ - mustParseVector("foo", 0), + mustParse[*promParser.VectorSelector](t, "foo", 0), }, }, }, @@ -470,7 +486,7 @@ func TestLabelsSource(t *testing.T) { Type: utils.SelectorSource, Returns: promParser.ValueTypeVector, Selectors: []*promParser.VectorSelector{ - mustParseVector("prometheus_build_info", 0), + mustParse[*promParser.VectorSelector](t, "prometheus_build_info", 0), }, }, }, @@ -483,46 +499,9 @@ func TestLabelsSource(t *testing.T) { Returns: promParser.ValueTypeVector, Operation: "deriv", Selectors: []*promParser.VectorSelector{ - mustParseVector("distance_covered_meters_total", 11), - }, - Call: &promParser.Call{ - Func: &promParser.Function{ - Name: "deriv", - ArgTypes: []promParser.ValueType{ - promParser.ValueTypeMatrix, - }, - Variadic: 0, - ReturnType: promParser.ValueTypeVector, - }, - Args: promParser.Expressions{ - &promParser.SubqueryExpr{ - Expr: &promParser.Call{ - Func: &promParser.Function{ - Name: "rate", - ArgTypes: []promParser.ValueType{ - promParser.ValueTypeMatrix, - }, - Variadic: 0, - ReturnType: promParser.ValueTypeVector, - }, - Args: promParser.Expressions{ - mustParseMatrix(`distance_covered_meters_total[1m]`, 11), - }, - PosRange: posrange.PositionRange{ - Start: 6, - End: 45, - }, - }, - Range: time.Minute * 5, - Step: time.Minute, - EndPos: posrange.Pos(52), - }, - }, - PosRange: posrange.PositionRange{ - Start: 0, - End: 53, - }, + mustParse[*promParser.VectorSelector](t, "distance_covered_meters_total", 11), }, + Call: mustParse[*promParser.Call](t, "deriv(rate(distance_covered_meters_total[1m])[5m:1m])", 0), }, }, }, @@ -533,7 +512,7 @@ func TestLabelsSource(t *testing.T) { Type: utils.SelectorSource, Returns: promParser.ValueTypeVector, Selectors: []*promParser.VectorSelector{ - mustParseVector("foo", 0), + mustParse[*promParser.VectorSelector](t, "foo", 0), }, }, }, @@ -545,7 +524,7 @@ func TestLabelsSource(t *testing.T) { Type: utils.SelectorSource, Returns: promParser.ValueTypeVector, Selectors: []*promParser.VectorSelector{ - mustParseVector("foo", 0), + mustParse[*promParser.VectorSelector](t, "foo", 0), }, }, }, @@ -557,7 +536,7 @@ func TestLabelsSource(t *testing.T) { Type: utils.SelectorSource, Returns: promParser.ValueTypeVector, Selectors: []*promParser.VectorSelector{ - mustParseVector("foo", 1), + mustParse[*promParser.VectorSelector](t, "foo", 1), }, }, }, @@ -570,7 +549,7 @@ func TestLabelsSource(t *testing.T) { Returns: promParser.ValueTypeVector, Operation: "sum", Selectors: []*promParser.VectorSelector{ - mustParseVector(`foo{job="myjob"}`, 4), + mustParse[*promParser.VectorSelector](t, `foo{job="myjob"}`, 4), }, FixedLabels: true, ExcludeReason: map[string]utils.ExcludedLabel{ @@ -582,6 +561,27 @@ func TestLabelsSource(t *testing.T) { }, }, }, + { + expr: `sum(foo{job="myjob"}) > 20`, + output: []utils.Source{ + { + Type: utils.AggregateSource, + Returns: promParser.ValueTypeVector, + Operation: "sum", + Selectors: []*promParser.VectorSelector{ + mustParse[*promParser.VectorSelector](t, `foo{job="myjob"}`, 4), + }, + FixedLabels: true, + ExcludeReason: map[string]utils.ExcludedLabel{ + "": { + Reason: "Query is using aggregation that removes all labels.", + Fragment: `sum(foo{job="myjob"})`, + }, + }, + IsConditional: true, + }, + }, + }, { expr: `sum(foo{job="myjob"}) without(job)`, output: []utils.Source{ @@ -590,7 +590,7 @@ func TestLabelsSource(t *testing.T) { Returns: promParser.ValueTypeVector, Operation: "sum", Selectors: []*promParser.VectorSelector{ - mustParseVector(`foo{job="myjob"}`, 4), + mustParse[*promParser.VectorSelector](t, `foo{job="myjob"}`, 4), }, ExcludedLabels: []string{"job"}, ExcludeReason: map[string]utils.ExcludedLabel{ @@ -610,7 +610,7 @@ func TestLabelsSource(t *testing.T) { Returns: promParser.ValueTypeVector, Operation: "sum", Selectors: []*promParser.VectorSelector{ - mustParseVector(`foo`, 4), + mustParse[*promParser.VectorSelector](t, `foo`, 4), }, IncludedLabels: []string{"job"}, FixedLabels: true, @@ -631,7 +631,7 @@ func TestLabelsSource(t *testing.T) { Returns: promParser.ValueTypeVector, Operation: "sum", Selectors: []*promParser.VectorSelector{ - mustParseVector(`foo{job="myjob"}`, 4), + mustParse[*promParser.VectorSelector](t, `foo{job="myjob"}`, 4), }, IncludedLabels: []string{"job"}, GuaranteedLabels: []string{"job"}, @@ -645,6 +645,21 @@ func TestLabelsSource(t *testing.T) { }, }, }, + { + expr: `abs(foo{job="myjob"} offset 5m)`, + output: []utils.Source{ + { + Type: utils.FuncSource, + Returns: promParser.ValueTypeVector, + Operation: "abs", + Selectors: []*promParser.VectorSelector{ + mustParse[*promParser.VectorSelector](t, `foo{job="myjob"} offset 5m`, 4), + }, + Call: mustParse[*promParser.Call](t, `abs(foo{job="myjob"} offset 5m)`, 0), + GuaranteedLabels: []string{"job"}, + }, + }, + }, { expr: `abs(foo{job="myjob"} or bar{cluster="dev"})`, output: []utils.Source{ @@ -653,33 +668,20 @@ func TestLabelsSource(t *testing.T) { Returns: promParser.ValueTypeVector, Operation: "abs", Selectors: []*promParser.VectorSelector{ - mustParseVector(`foo{job="myjob"}`, 4), - mustParseVector(`bar{cluster="dev"}`, 24), + mustParse[*promParser.VectorSelector](t, `foo{job="myjob"}`, 4), }, - Call: &promParser.Call{ - Func: &promParser.Function{ - Name: "abs", - ArgTypes: []promParser.ValueType{ - promParser.ValueTypeVector, - }, - Variadic: 0, - ReturnType: promParser.ValueTypeVector, - }, - Args: promParser.Expressions{ - &promParser.BinaryExpr{ - Op: promParser.LOR, - LHS: mustParseVector(`foo{job="myjob"}`, 4), - RHS: mustParseVector(`bar{cluster="dev"}`, 24), - VectorMatching: &promParser.VectorMatching{ - Card: promParser.CardManyToMany, - }, - }, - }, - PosRange: posrange.PositionRange{ - Start: 0, - End: 43, - }, + GuaranteedLabels: []string{"job"}, + Call: mustParse[*promParser.Call](t, `abs(foo{job="myjob"} or bar{cluster="dev"})`, 0), + }, + { + Type: utils.FuncSource, + Returns: promParser.ValueTypeVector, + Operation: "abs", + Selectors: []*promParser.VectorSelector{ + mustParse[*promParser.VectorSelector](t, `bar{cluster="dev"}`, 24), }, + Call: mustParse[*promParser.Call](t, `abs(foo{job="myjob"} or bar{cluster="dev"})`, 0), + GuaranteedLabels: []string{"cluster"}, }, }, }, @@ -691,7 +693,7 @@ func TestLabelsSource(t *testing.T) { Returns: promParser.ValueTypeVector, Operation: "sum", Selectors: []*promParser.VectorSelector{ - mustParseVector(`foo{job="myjob"}`, 4), + mustParse[*promParser.VectorSelector](t, `foo{job="myjob"}`, 4), }, GuaranteedLabels: []string{"job"}, ExcludedLabels: []string{"instance"}, @@ -707,7 +709,7 @@ func TestLabelsSource(t *testing.T) { Returns: promParser.ValueTypeVector, Operation: "sum", Selectors: []*promParser.VectorSelector{ - mustParseVector(`bar{cluster="dev"}`, 24), + mustParse[*promParser.VectorSelector](t, `bar{cluster="dev"}`, 24), }, GuaranteedLabels: []string{"cluster"}, ExcludedLabels: []string{"instance"}, @@ -728,7 +730,7 @@ func TestLabelsSource(t *testing.T) { Returns: promParser.ValueTypeVector, Operation: "sum", Selectors: []*promParser.VectorSelector{ - mustParseVector(`foo{job="myjob"}`, 4), + mustParse[*promParser.VectorSelector](t, `foo{job="myjob"}`, 4), }, GuaranteedLabels: []string{"job"}, ExcludedLabels: []string{"instance"}, @@ -749,7 +751,7 @@ func TestLabelsSource(t *testing.T) { Returns: promParser.ValueTypeVector, Operation: "min", Selectors: []*promParser.VectorSelector{ - mustParseVector(`foo{job="myjob"}`, 4), + mustParse[*promParser.VectorSelector](t, `foo{job="myjob"}`, 4), }, FixedLabels: true, ExcludeReason: map[string]utils.ExcludedLabel{ @@ -758,6 +760,23 @@ func TestLabelsSource(t *testing.T) { Fragment: `min(foo{job="myjob"})`, }, }, + Joins: []utils.Source{ + { + Type: utils.AggregateSource, + Operation: "max", + Returns: promParser.ValueTypeVector, + Selectors: []*promParser.VectorSelector{ + mustParse[*promParser.VectorSelector](t, `foo{job="myjob"}`, 28), + }, + FixedLabels: true, + ExcludeReason: map[string]utils.ExcludedLabel{ + "": { + Reason: "Query is using aggregation that removes all labels.", + Fragment: `max(foo{job="myjob"})`, + }, + }, + }, + }, }, }, }, @@ -769,7 +788,7 @@ func TestLabelsSource(t *testing.T) { Returns: promParser.ValueTypeVector, Operation: "max", Selectors: []*promParser.VectorSelector{ - mustParseVector(`foo{job="myjob"}`, 4), + mustParse[*promParser.VectorSelector](t, `foo{job="myjob"}`, 4), }, FixedLabels: true, ExcludeReason: map[string]utils.ExcludedLabel{ @@ -778,6 +797,23 @@ func TestLabelsSource(t *testing.T) { Fragment: `max(foo{job="myjob"})`, }, }, + Joins: []utils.Source{ + { + Type: utils.AggregateSource, + Operation: "min", + Returns: promParser.ValueTypeVector, + Selectors: []*promParser.VectorSelector{ + mustParse[*promParser.VectorSelector](t, `foo{job="myjob"}`, 28), + }, + FixedLabels: true, + ExcludeReason: map[string]utils.ExcludedLabel{ + "": { + Reason: "Query is using aggregation that removes all labels.", + Fragment: `min(foo{job="myjob"})`, + }, + }, + }, + }, }, }, }, @@ -789,7 +825,7 @@ func TestLabelsSource(t *testing.T) { Returns: promParser.ValueTypeVector, Operation: "avg", Selectors: []*promParser.VectorSelector{ - mustParseVector(`foo{job="myjob"}`, 4), + mustParse[*promParser.VectorSelector](t, `foo{job="myjob"}`, 4), }, GuaranteedLabels: []string{"job"}, IncludedLabels: []string{"job"}, @@ -811,7 +847,7 @@ func TestLabelsSource(t *testing.T) { Returns: promParser.ValueTypeVector, Operation: "group", Selectors: []*promParser.VectorSelector{ - mustParseVector(`foo`, 6), + mustParse[*promParser.VectorSelector](t, `foo`, 6), }, IncludedLabels: []string{"job"}, FixedLabels: true, @@ -832,7 +868,7 @@ func TestLabelsSource(t *testing.T) { Returns: promParser.ValueTypeVector, Operation: "stddev", Selectors: []*promParser.VectorSelector{ - mustParseVector(`foo`, 12), + mustParse[*promParser.VectorSelector](t, `foo`, 12), }, FixedLabels: true, ExcludeReason: map[string]utils.ExcludedLabel{ @@ -852,7 +888,7 @@ func TestLabelsSource(t *testing.T) { Returns: promParser.ValueTypeVector, Operation: "stdvar", Selectors: []*promParser.VectorSelector{ - mustParseVector(`foo`, 12), + mustParse[*promParser.VectorSelector](t, `foo`, 12), }, FixedLabels: true, ExcludeReason: map[string]utils.ExcludedLabel{ @@ -872,25 +908,9 @@ func TestLabelsSource(t *testing.T) { Returns: promParser.ValueTypeVector, Operation: "stddev_over_time", Selectors: []*promParser.VectorSelector{ - mustParseVector(`foo`, 17), - }, - Call: &promParser.Call{ - Func: &promParser.Function{ - Name: "stddev_over_time", - ArgTypes: []promParser.ValueType{ - promParser.ValueTypeMatrix, - }, - Variadic: 0, - ReturnType: promParser.ValueTypeVector, - }, - Args: promParser.Expressions{ - mustParseMatrix(`foo[5m]`, 17), - }, - PosRange: posrange.PositionRange{ - Start: 0, - End: 25, - }, + mustParse[*promParser.VectorSelector](t, `foo`, 17), }, + Call: mustParse[*promParser.Call](t, `stddev_over_time(foo[5m])`, 0), }, }, }, @@ -902,25 +922,9 @@ func TestLabelsSource(t *testing.T) { Returns: promParser.ValueTypeVector, Operation: "stdvar_over_time", Selectors: []*promParser.VectorSelector{ - mustParseVector(`foo`, 17), - }, - Call: &promParser.Call{ - Func: &promParser.Function{ - Name: "stdvar_over_time", - ArgTypes: []promParser.ValueType{ - promParser.ValueTypeMatrix, - }, - Variadic: 0, - ReturnType: promParser.ValueTypeVector, - }, - Args: promParser.Expressions{ - mustParseMatrix(`foo[5m]`, 17), - }, - PosRange: posrange.PositionRange{ - Start: 0, - End: 25, - }, + mustParse[*promParser.VectorSelector](t, `foo`, 17), }, + Call: mustParse[*promParser.Call](t, `stdvar_over_time(foo[5m])`, 0), }, }, }, @@ -932,7 +936,7 @@ func TestLabelsSource(t *testing.T) { Returns: promParser.ValueTypeVector, Operation: "quantile", Selectors: []*promParser.VectorSelector{ - mustParseVector(`foo`, 19), + mustParse[*promParser.VectorSelector](t, `foo`, 19), }, FixedLabels: true, ExcludeReason: map[string]utils.ExcludedLabel{ @@ -952,7 +956,7 @@ func TestLabelsSource(t *testing.T) { Returns: promParser.ValueTypeVector, Operation: "count_values", Selectors: []*promParser.VectorSelector{ - mustParseVector(`build_version`, 24), + mustParse[*promParser.VectorSelector](t, `build_version`, 24), }, GuaranteedLabels: []string{"version"}, IncludedLabels: []string{"version"}, @@ -974,7 +978,7 @@ func TestLabelsSource(t *testing.T) { Returns: promParser.ValueTypeVector, Operation: "count_values", Selectors: []*promParser.VectorSelector{ - mustParseVector(`build_version`, 24), + mustParse[*promParser.VectorSelector](t, `build_version`, 24), }, IncludedLabels: []string{"version"}, GuaranteedLabels: []string{"version"}, @@ -996,7 +1000,7 @@ func TestLabelsSource(t *testing.T) { Returns: promParser.ValueTypeVector, Operation: "count_values", Selectors: []*promParser.VectorSelector{ - mustParseVector(`build_version{job="foo"}`, 24), + mustParse[*promParser.VectorSelector](t, `build_version{job="foo"}`, 24), }, IncludedLabels: []string{"version"}, GuaranteedLabels: []string{"version"}, @@ -1018,7 +1022,7 @@ func TestLabelsSource(t *testing.T) { Returns: promParser.ValueTypeVector, Operation: "count_values", Selectors: []*promParser.VectorSelector{ - mustParseVector(`build_version`, 24), + mustParse[*promParser.VectorSelector](t, `build_version`, 24), }, GuaranteedLabels: []string{"version"}, IncludedLabels: []string{"job", "version"}, @@ -1040,9 +1044,10 @@ func TestLabelsSource(t *testing.T) { Returns: promParser.ValueTypeVector, Operation: "topk", Selectors: []*promParser.VectorSelector{ - mustParseVector(`foo{job="myjob"}`, 9), + mustParse[*promParser.VectorSelector](t, `foo{job="myjob"}`, 9), }, GuaranteedLabels: []string{"job"}, + IsConditional: true, }, }, }, @@ -1054,7 +1059,7 @@ func TestLabelsSource(t *testing.T) { Returns: promParser.ValueTypeVector, Operation: "topk", Selectors: []*promParser.VectorSelector{ - mustParseVector(`foo`, 9), + mustParse[*promParser.VectorSelector](t, `foo`, 9), }, }, { @@ -1062,7 +1067,7 @@ func TestLabelsSource(t *testing.T) { Operation: "topk", Returns: promParser.ValueTypeVector, Selectors: []*promParser.VectorSelector{ - mustParseVector(`bar`, 16), + mustParse[*promParser.VectorSelector](t, `bar`, 16), }, }, }, @@ -1075,25 +1080,9 @@ func TestLabelsSource(t *testing.T) { Returns: promParser.ValueTypeVector, Operation: "rate", Selectors: []*promParser.VectorSelector{ - mustParseVector(`foo`, 5), - }, - Call: &promParser.Call{ - Func: &promParser.Function{ - Name: "rate", - ArgTypes: []promParser.ValueType{ - promParser.ValueTypeMatrix, - }, - Variadic: 0, - ReturnType: promParser.ValueTypeVector, - }, - Args: promParser.Expressions{ - mustParseMatrix(`foo[10m]`, 5), - }, - PosRange: posrange.PositionRange{ - Start: 0, - End: 14, - }, + mustParse[*promParser.VectorSelector](t, `foo`, 5), }, + Call: mustParse[*promParser.Call](t, `rate(foo[10m])`, 0), }, }, }, @@ -1105,7 +1094,7 @@ func TestLabelsSource(t *testing.T) { Returns: promParser.ValueTypeVector, Operation: "sum", Selectors: []*promParser.VectorSelector{ - mustParseVector(`foo`, 9), + mustParse[*promParser.VectorSelector](t, `foo`, 9), }, ExcludedLabels: []string{"instance"}, ExcludeReason: map[string]utils.ExcludedLabel{ @@ -1125,9 +1114,18 @@ func TestLabelsSource(t *testing.T) { Returns: promParser.ValueTypeVector, Operation: promParser.CardOneToOne.String(), Selectors: []*promParser.VectorSelector{ - mustParseVector(`foo{job="foo"}`, 0), + mustParse[*promParser.VectorSelector](t, `foo{job="foo"}`, 0), }, GuaranteedLabels: []string{"job"}, + Joins: []utils.Source{ + { + Type: utils.SelectorSource, + Returns: promParser.ValueTypeVector, + Selectors: []*promParser.VectorSelector{ + mustParse[*promParser.VectorSelector](t, `bar`, 17), + }, + }, + }, }, }, }, @@ -1139,7 +1137,7 @@ func TestLabelsSource(t *testing.T) { Returns: promParser.ValueTypeVector, Operation: promParser.CardOneToOne.String(), Selectors: []*promParser.VectorSelector{ - mustParseVector(`foo{job="foo"}`, 0), + mustParse[*promParser.VectorSelector](t, `foo{job="foo"}`, 0), }, GuaranteedLabels: []string{"job"}, IncludedLabels: []string{"instance"}, @@ -1150,6 +1148,15 @@ func TestLabelsSource(t *testing.T) { Fragment: `foo{job="foo"} * on(instance) bar`, }, }, + Joins: []utils.Source{ + { + Type: utils.SelectorSource, + Returns: promParser.ValueTypeVector, + Selectors: []*promParser.VectorSelector{ + mustParse[*promParser.VectorSelector](t, `bar`, 30), + }, + }, + }, }, }, }, @@ -1161,10 +1168,19 @@ func TestLabelsSource(t *testing.T) { Returns: promParser.ValueTypeVector, Operation: promParser.CardManyToOne.String(), Selectors: []*promParser.VectorSelector{ - mustParseVector(`foo{job="foo"}`, 0), + mustParse[*promParser.VectorSelector](t, `foo{job="foo"}`, 0), }, IncludedLabels: []string{"bar", "instance"}, GuaranteedLabels: []string{"job"}, + Joins: []utils.Source{ + { + Type: utils.SelectorSource, + Returns: promParser.ValueTypeVector, + Selectors: []*promParser.VectorSelector{ + mustParse[*promParser.VectorSelector](t, `bar`, 46), + }, + }, + }, }, }, }, @@ -1176,10 +1192,20 @@ func TestLabelsSource(t *testing.T) { Returns: promParser.ValueTypeVector, Operation: promParser.CardManyToOne.String(), Selectors: []*promParser.VectorSelector{ - mustParseVector(`foo{job="foo"}`, 0), + mustParse[*promParser.VectorSelector](t, `foo{job="foo"}`, 0), }, IncludedLabels: []string{"cluster", "instance"}, GuaranteedLabels: []string{"job"}, + Joins: []utils.Source{ + { + Type: utils.SelectorSource, + Returns: promParser.ValueTypeVector, + Selectors: []*promParser.VectorSelector{ + mustParse[*promParser.VectorSelector](t, `bar{cluster="bar", ignored="true"}`, 50), + }, + GuaranteedLabels: []string{"cluster", "ignored"}, + }, + }, }, }, }, @@ -1191,10 +1217,20 @@ func TestLabelsSource(t *testing.T) { Returns: promParser.ValueTypeVector, Operation: promParser.CardOneToMany.String(), Selectors: []*promParser.VectorSelector{ - mustParseVector(`bar{cluster="bar"}`, 63), + mustParse[*promParser.VectorSelector](t, `bar{cluster="bar"}`, 63), }, IncludedLabels: []string{"job", "instance"}, GuaranteedLabels: []string{"cluster"}, + Joins: []utils.Source{ + { + Type: utils.SelectorSource, + Returns: promParser.ValueTypeVector, + Selectors: []*promParser.VectorSelector{ + mustParse[*promParser.VectorSelector](t, `foo{job="foo", ignored="true"}`, 0), + }, + GuaranteedLabels: []string{"job", "ignored"}, + }, + }, }, }, }, @@ -1206,7 +1242,7 @@ func TestLabelsSource(t *testing.T) { Returns: promParser.ValueTypeVector, Operation: "count", Selectors: []*promParser.VectorSelector{ - mustParseVector(`foo`, 6), + mustParse[*promParser.VectorSelector](t, `foo`, 6), }, FixedLabels: true, ExcludeReason: map[string]utils.ExcludedLabel{ @@ -1215,6 +1251,15 @@ func TestLabelsSource(t *testing.T) { Fragment: `count(foo / bar)`, }, }, + Joins: []utils.Source{ + { + Type: utils.SelectorSource, + Returns: promParser.ValueTypeVector, + Selectors: []*promParser.VectorSelector{ + mustParse[*promParser.VectorSelector](t, `bar`, 12), + }, + }, + }, }, }, }, @@ -1226,7 +1271,7 @@ func TestLabelsSource(t *testing.T) { Returns: promParser.ValueTypeVector, Operation: "count", Selectors: []*promParser.VectorSelector{ - mustParseVector(`up{job="a"}`, 6), + mustParse[*promParser.VectorSelector](t, `up{job="a"}`, 6), }, FixedLabels: true, ExcludeReason: map[string]utils.ExcludedLabel{ @@ -1235,6 +1280,16 @@ func TestLabelsSource(t *testing.T) { Fragment: `count(up{job="a"} / on () up{job="b"})`, }, }, + Joins: []utils.Source{ + { + Type: utils.SelectorSource, + Returns: promParser.ValueTypeVector, + Selectors: []*promParser.VectorSelector{ + mustParse[*promParser.VectorSelector](t, `up{job="b"}`, 26), + }, + GuaranteedLabels: []string{"job"}, + }, + }, }, }, }, @@ -1246,7 +1301,7 @@ func TestLabelsSource(t *testing.T) { Returns: promParser.ValueTypeVector, Operation: "count", Selectors: []*promParser.VectorSelector{ - mustParseVector(`up{job="a"}`, 6), + mustParse[*promParser.VectorSelector](t, `up{job="a"}`, 6), }, FixedLabels: true, ExcludeReason: map[string]utils.ExcludedLabel{ @@ -1255,6 +1310,16 @@ func TestLabelsSource(t *testing.T) { Fragment: `count(up{job="a"} / on (env) up{job="b"})`, }, }, + Joins: []utils.Source{ + { + Type: utils.SelectorSource, + Returns: promParser.ValueTypeVector, + Selectors: []*promParser.VectorSelector{ + mustParse[*promParser.VectorSelector](t, `up{job="b"}`, 29), + }, + GuaranteedLabels: []string{"job"}, + }, + }, }, }, }, @@ -1266,9 +1331,18 @@ func TestLabelsSource(t *testing.T) { Returns: promParser.ValueTypeVector, Operation: promParser.CardManyToMany.String(), Selectors: []*promParser.VectorSelector{ - mustParseVector(`foo{job="foo", instance="1"}`, 0), + mustParse[*promParser.VectorSelector](t, `foo{job="foo", instance="1"}`, 0), }, GuaranteedLabels: []string{"job", "instance"}, + Joins: []utils.Source{ + { + Type: utils.SelectorSource, + Returns: promParser.ValueTypeVector, + Selectors: []*promParser.VectorSelector{ + mustParse[*promParser.VectorSelector](t, `bar`, 33), + }, + }, + }, }, }, }, @@ -1280,10 +1354,19 @@ func TestLabelsSource(t *testing.T) { Returns: promParser.ValueTypeVector, Operation: promParser.CardManyToMany.String(), Selectors: []*promParser.VectorSelector{ - mustParseVector(`foo{job="foo", instance="1"}`, 0), + mustParse[*promParser.VectorSelector](t, `foo{job="foo", instance="1"}`, 0), }, IncludedLabels: []string{"cluster"}, GuaranteedLabels: []string{"job", "instance"}, + Joins: []utils.Source{ + { + Type: utils.SelectorSource, + Returns: promParser.ValueTypeVector, + Selectors: []*promParser.VectorSelector{ + mustParse[*promParser.VectorSelector](t, `bar`, 45), + }, + }, + }, }, }, }, @@ -1295,7 +1378,7 @@ func TestLabelsSource(t *testing.T) { Returns: promParser.ValueTypeVector, Operation: "topk", Selectors: []*promParser.VectorSelector{ - mustParseVector(`foo`, 9), + mustParse[*promParser.VectorSelector](t, `foo`, 9), }, }, }, @@ -1308,7 +1391,7 @@ func TestLabelsSource(t *testing.T) { Returns: promParser.ValueTypeVector, Operation: "topk", Selectors: []*promParser.VectorSelector{ - mustParseVector(`foo`, 9), + mustParse[*promParser.VectorSelector](t, `foo`, 9), }, }, }, @@ -1321,7 +1404,7 @@ func TestLabelsSource(t *testing.T) { Returns: promParser.ValueTypeVector, Operation: "topk", Selectors: []*promParser.VectorSelector{ - mustParseVector(`foo`, 9), + mustParse[*promParser.VectorSelector](t, `foo`, 9), }, }, }, @@ -1334,7 +1417,7 @@ func TestLabelsSource(t *testing.T) { Returns: promParser.ValueTypeVector, Operation: "bottomk", Selectors: []*promParser.VectorSelector{ - mustParseVector(`foo`, 21), + mustParse[*promParser.VectorSelector](t, `foo`, 21), }, ExcludedLabels: []string{"job"}, ExcludeReason: map[string]utils.ExcludedLabel{ @@ -1354,7 +1437,7 @@ func TestLabelsSource(t *testing.T) { Returns: promParser.ValueTypeVector, Operation: promParser.CardManyToMany.String(), Selectors: []*promParser.VectorSelector{ - mustParseVector(`foo`, 0), + mustParse[*promParser.VectorSelector](t, `foo`, 0), }, }, { @@ -1362,7 +1445,7 @@ func TestLabelsSource(t *testing.T) { Returns: promParser.ValueTypeVector, Operation: promParser.CardManyToMany.String(), Selectors: []*promParser.VectorSelector{ - mustParseVector(`bar`, 7), + mustParse[*promParser.VectorSelector](t, `bar`, 7), }, }, }, @@ -1375,7 +1458,7 @@ func TestLabelsSource(t *testing.T) { Returns: promParser.ValueTypeVector, Operation: promParser.CardManyToMany.String(), Selectors: []*promParser.VectorSelector{ - mustParseVector(`foo`, 0), + mustParse[*promParser.VectorSelector](t, `foo`, 0), }, }, { @@ -1383,7 +1466,7 @@ func TestLabelsSource(t *testing.T) { Returns: promParser.ValueTypeVector, Operation: promParser.CardManyToMany.String(), Selectors: []*promParser.VectorSelector{ - mustParseVector(`bar`, 7), + mustParse[*promParser.VectorSelector](t, `bar`, 7), }, }, { @@ -1391,7 +1474,7 @@ func TestLabelsSource(t *testing.T) { Returns: promParser.ValueTypeVector, Operation: promParser.CardManyToMany.String(), Selectors: []*promParser.VectorSelector{ - mustParseVector(`baz`, 14), + mustParse[*promParser.VectorSelector](t, `baz`, 14), }, }, }, @@ -1404,7 +1487,7 @@ func TestLabelsSource(t *testing.T) { Returns: promParser.ValueTypeVector, Operation: promParser.CardManyToMany.String(), Selectors: []*promParser.VectorSelector{ - mustParseVector(`foo`, 1), + mustParse[*promParser.VectorSelector](t, `foo`, 1), }, }, { @@ -1412,7 +1495,7 @@ func TestLabelsSource(t *testing.T) { Returns: promParser.ValueTypeVector, Operation: promParser.CardManyToMany.String(), Selectors: []*promParser.VectorSelector{ - mustParseVector(`bar`, 8), + mustParse[*promParser.VectorSelector](t, `bar`, 8), }, }, { @@ -1420,7 +1503,7 @@ func TestLabelsSource(t *testing.T) { Returns: promParser.ValueTypeVector, Operation: promParser.CardManyToMany.String(), Selectors: []*promParser.VectorSelector{ - mustParseVector(`baz`, 16), + mustParse[*promParser.VectorSelector](t, `baz`, 16), }, }, }, @@ -1433,7 +1516,68 @@ func TestLabelsSource(t *testing.T) { Returns: promParser.ValueTypeVector, Operation: promParser.CardManyToMany.String(), Selectors: []*promParser.VectorSelector{ - mustParseVector(`foo`, 0), + mustParse[*promParser.VectorSelector](t, `foo`, 0), + }, + Unless: []utils.Source{ + { + Type: utils.SelectorSource, + Returns: promParser.ValueTypeVector, + Selectors: []*promParser.VectorSelector{ + mustParse[*promParser.VectorSelector](t, `bar`, 11), + }, + }, + }, + }, + }, + }, + { + expr: `foo unless bar > 5`, + output: []utils.Source{ + { + Type: utils.SelectorSource, + Returns: promParser.ValueTypeVector, + Operation: promParser.CardManyToMany.String(), + Selectors: []*promParser.VectorSelector{ + mustParse[*promParser.VectorSelector](t, `foo`, 0), + }, + Unless: []utils.Source{ + { + Type: utils.SelectorSource, + Returns: promParser.ValueTypeVector, + Selectors: []*promParser.VectorSelector{ + mustParse[*promParser.VectorSelector](t, `bar`, 11), + }, + IsConditional: true, + }, + }, + }, + }, + }, + { + expr: `foo unless bar unless baz`, + output: []utils.Source{ + { + Type: utils.SelectorSource, + Returns: promParser.ValueTypeVector, + Operation: promParser.CardManyToMany.String(), + Selectors: []*promParser.VectorSelector{ + mustParse[*promParser.VectorSelector](t, `foo`, 0), + }, + Unless: []utils.Source{ + { + Type: utils.SelectorSource, + Returns: promParser.ValueTypeVector, + Selectors: []*promParser.VectorSelector{ + mustParse[*promParser.VectorSelector](t, `bar`, 11), + }, + }, + { + Type: utils.SelectorSource, + Returns: promParser.ValueTypeVector, + Selectors: []*promParser.VectorSelector{ + mustParse[*promParser.VectorSelector](t, `baz`, 22), + }, + }, }, }, }, @@ -1446,7 +1590,7 @@ func TestLabelsSource(t *testing.T) { Returns: promParser.ValueTypeVector, Operation: "count", Selectors: []*promParser.VectorSelector{ - mustParseVector(`up{job="foo", cluster="dev"}`, 10), + mustParse[*promParser.VectorSelector](t, `up{job="foo", cluster="dev"}`, 10), }, ExcludedLabels: []string{"job", "cluster"}, // FIXME empty FixedLabels: true, @@ -1464,6 +1608,7 @@ func TestLabelsSource(t *testing.T) { Fragment: `count(sum(up{job="foo", cluster="dev"}) by(job, cluster) == 0) without(job, cluster)`, }, }, + IsConditional: true, }, }, }, @@ -1482,21 +1627,7 @@ func TestLabelsSource(t *testing.T) { Fragment: `year()`, }, }, - Call: &promParser.Call{ - Func: &promParser.Function{ - Name: "year", - ArgTypes: []promParser.ValueType{ - promParser.ValueTypeVector, - }, - Variadic: 1, - ReturnType: promParser.ValueTypeVector, - }, - Args: promParser.Expressions{}, - PosRange: posrange.PositionRange{ - Start: 0, - End: 6, - }, - }, + Call: mustParse[*promParser.Call](t, `year()`, 0), }, }, }, @@ -1508,25 +1639,9 @@ func TestLabelsSource(t *testing.T) { Returns: promParser.ValueTypeVector, Operation: "year", Selectors: []*promParser.VectorSelector{ - mustParseVector("foo", 5), - }, - Call: &promParser.Call{ - Func: &promParser.Function{ - Name: "year", - ArgTypes: []promParser.ValueType{ - promParser.ValueTypeVector, - }, - Variadic: 1, - ReturnType: promParser.ValueTypeVector, - }, - Args: promParser.Expressions{ - mustParseVector("foo", 5), - }, - PosRange: posrange.PositionRange{ - Start: 0, - End: 9, - }, + mustParse[*promParser.VectorSelector](t, "foo", 5), }, + Call: mustParse[*promParser.Call](t, `year(foo)`, 0), }, }, }, @@ -1538,49 +1653,10 @@ func TestLabelsSource(t *testing.T) { Returns: promParser.ValueTypeVector, Operation: "label_join", Selectors: []*promParser.VectorSelector{ - mustParseVector(`up{job="api-server",src1="a",src2="b",src3="c"}`, 11), + mustParse[*promParser.VectorSelector](t, `up{job="api-server",src1="a",src2="b",src3="c"}`, 11), }, GuaranteedLabels: []string{"job", "src1", "src2", "src3", "foo"}, - Call: &promParser.Call{ - Func: &promParser.Function{ - Name: "label_join", - ArgTypes: []promParser.ValueType{ - promParser.ValueTypeVector, - promParser.ValueTypeString, - promParser.ValueTypeString, - promParser.ValueTypeString, - }, - Variadic: -1, - ReturnType: promParser.ValueTypeVector, - }, - Args: promParser.Expressions{ - mustParseVector(`up{job="api-server",src1="a",src2="b",src3="c"}`, 11), - &promParser.StringLiteral{ - Val: "foo", - PosRange: posrange.PositionRange{Start: 60, End: 65}, - }, - &promParser.StringLiteral{ - Val: ",", - PosRange: posrange.PositionRange{Start: 67, End: 70}, - }, - &promParser.StringLiteral{ - Val: "src1", - PosRange: posrange.PositionRange{Start: 72, End: 78}, - }, - &promParser.StringLiteral{ - Val: "src2", - PosRange: posrange.PositionRange{Start: 80, End: 86}, - }, - &promParser.StringLiteral{ - Val: "src3", - PosRange: posrange.PositionRange{Start: 88, End: 94}, - }, - }, - PosRange: posrange.PositionRange{ - Start: 0, - End: 95, - }, - }, + Call: mustParse[*promParser.Call](t, `label_join(up{job="api-server",src1="a",src2="b",src3="c"}, "foo", ",", "src1", "src2", "src3")`, 0), }, }, }, @@ -1599,10 +1675,37 @@ sum(foo:count) by(job) > 20`, Returns: promParser.ValueTypeVector, Operation: "sum", Selectors: []*promParser.VectorSelector{ - mustParseVector(`foo:sum`, 8), + mustParse[*promParser.VectorSelector](t, `foo:sum`, 8), }, IncludedLabels: []string{"notify", "job"}, ExcludeReason: map[string]utils.ExcludedLabel{}, + IsConditional: false, // FIXME should be true + Joins: []utils.Source{ + { + Type: utils.SelectorSource, + Returns: promParser.ValueTypeVector, + Selectors: []*promParser.VectorSelector{ + mustParse[*promParser.VectorSelector](t, `job:notify`, 68), + }, + }, + { + Type: utils.AggregateSource, + Returns: promParser.ValueTypeVector, + Operation: "sum", + Selectors: []*promParser.VectorSelector{ + mustParse[*promParser.VectorSelector](t, `foo:count`, 97), + }, + IncludedLabels: []string{"job"}, + FixedLabels: true, + ExcludeReason: map[string]utils.ExcludedLabel{ + "": { + Reason: "Query is using aggregation with `by(job)`, only labels included inside `by(...)` will be present on the results.", + Fragment: `sum(foo:count) by(job)`, + }, + }, + IsConditional: true, + }, + }, }, }, }, @@ -1614,7 +1717,7 @@ sum(foo:count) by(job) > 20`, Returns: promParser.ValueTypeVector, Operation: promParser.CardOneToOne.String(), Selectors: []*promParser.VectorSelector{ - mustParseVector(`container_file_descriptors`, 0), + mustParse[*promParser.VectorSelector](t, `container_file_descriptors`, 0), }, IncludedLabels: []string{"instance", "app_name"}, FixedLabels: true, @@ -1624,6 +1727,16 @@ sum(foo:count) by(job) > 20`, Fragment: `container_file_descriptors / on (instance, app_name) container_ulimits_soft{ulimit="max_open_files"}`, }, }, + Joins: []utils.Source{ + { + Type: utils.SelectorSource, + Returns: promParser.ValueTypeVector, + Selectors: []*promParser.VectorSelector{ + mustParse[*promParser.VectorSelector](t, `container_ulimits_soft{ulimit="max_open_files"}`, 53), + }, + GuaranteedLabels: []string{"ulimit"}, + }, + }, }, }, }, @@ -1635,9 +1748,19 @@ sum(foo:count) by(job) > 20`, Returns: promParser.ValueTypeVector, Operation: promParser.CardManyToOne.String(), Selectors: []*promParser.VectorSelector{ - mustParseVector(`container_file_descriptors`, 0), + mustParse[*promParser.VectorSelector](t, `container_file_descriptors`, 0), }, IncludedLabels: []string{"instance", "app_name"}, + Joins: []utils.Source{ + { + Type: utils.SelectorSource, + Returns: promParser.ValueTypeVector, + Selectors: []*promParser.VectorSelector{ + mustParse[*promParser.VectorSelector](t, `container_ulimits_soft{ulimit="max_open_files"}`, 66), + }, + GuaranteedLabels: []string{"ulimit"}, + }, + }, }, }, }, @@ -1649,7 +1772,7 @@ sum(foo:count) by(job) > 20`, Returns: promParser.ValueTypeVector, Operation: "absent", Selectors: []*promParser.VectorSelector{ - mustParseVector(`foo{job="bar"}`, 7), + mustParse[*promParser.VectorSelector](t, `foo{job="bar"}`, 7), }, IncludedLabels: []string{"job"}, GuaranteedLabels: []string{"job"}, @@ -1660,23 +1783,7 @@ sum(foo:count) by(job) > 20`, Fragment: `absent(foo{job="bar"})`, }, }, - Call: &promParser.Call{ - Func: &promParser.Function{ - Name: "absent", - ArgTypes: []promParser.ValueType{ - promParser.ValueTypeVector, - }, - Variadic: 0, - ReturnType: promParser.ValueTypeVector, - }, - Args: promParser.Expressions{ - mustParseVector(`foo{job="bar"}`, 7), - }, - PosRange: posrange.PositionRange{ - Start: 0, - End: 22, - }, - }, + Call: mustParse[*promParser.Call](t, `absent(foo{job="bar"})`, 0), }, }, }, @@ -1688,7 +1795,7 @@ sum(foo:count) by(job) > 20`, Returns: promParser.ValueTypeVector, Operation: "absent", Selectors: []*promParser.VectorSelector{ - mustParseVector(`foo{job="bar", cluster!="dev", instance=~".+", env="prod"}`, 7), + mustParse[*promParser.VectorSelector](t, `foo{job="bar", cluster!="dev", instance=~".+", env="prod"}`, 7), }, IncludedLabels: []string{"job", "env"}, GuaranteedLabels: []string{"job", "env"}, @@ -1699,23 +1806,7 @@ sum(foo:count) by(job) > 20`, Fragment: `absent(foo{job="bar", cluster!="dev", instance=~".+", env="prod"})`, }, }, - Call: &promParser.Call{ - Func: &promParser.Function{ - Name: "absent", - ArgTypes: []promParser.ValueType{ - promParser.ValueTypeVector, - }, - Variadic: 0, - ReturnType: promParser.ValueTypeVector, - }, - Args: promParser.Expressions{ - mustParseVector(`foo{job="bar", cluster!="dev", instance=~".+", env="prod"}`, 7), - }, - PosRange: posrange.PositionRange{ - Start: 0, - End: 66, - }, - }, + Call: mustParse[*promParser.Call](t, `absent(foo{job="bar", cluster!="dev", instance=~".+", env="prod"})`, 0), }, }, }, @@ -1727,7 +1818,7 @@ sum(foo:count) by(job) > 20`, Returns: promParser.ValueTypeVector, Operation: "absent", Selectors: []*promParser.VectorSelector{ - mustParseVector(`foo`, 11), + mustParse[*promParser.VectorSelector](t, `foo`, 11), }, FixedLabels: true, ExcludeReason: map[string]utils.ExcludedLabel{ @@ -1736,31 +1827,7 @@ sum(foo:count) by(job) > 20`, Fragment: `absent(sum(foo) by(job, instance))`, }, }, - Call: &promParser.Call{ - Func: &promParser.Function{ - Name: "absent", - ArgTypes: []promParser.ValueType{ - promParser.ValueTypeVector, - }, - Variadic: 0, - ReturnType: promParser.ValueTypeVector, - }, - Args: promParser.Expressions{ - &promParser.AggregateExpr{ - Op: promParser.SUM, - Expr: mustParseVector("foo", 11), - Grouping: []string{"job", "instance"}, - PosRange: posrange.PositionRange{ - Start: 7, - End: 33, - }, - }, - }, - PosRange: posrange.PositionRange{ - Start: 0, - End: 34, - }, - }, + Call: mustParse[*promParser.Call](t, `absent(sum(foo) by(job, instance))`, 0), }, }, }, @@ -1772,7 +1839,7 @@ sum(foo:count) by(job) > 20`, Returns: promParser.ValueTypeVector, Operation: "absent", Selectors: []*promParser.VectorSelector{ - mustParseVector(`foo{job="prometheus", xxx="1"}`, 7), + mustParse[*promParser.VectorSelector](t, `foo{job="prometheus", xxx="1"}`, 7), }, IncludedLabels: []string{"job", "xxx"}, GuaranteedLabels: []string{"job", "xxx"}, @@ -1783,21 +1850,14 @@ sum(foo:count) by(job) > 20`, Fragment: `absent(foo{job="prometheus", xxx="1"})`, }, }, - Call: &promParser.Call{ - Func: &promParser.Function{ - Name: "absent", - ArgTypes: []promParser.ValueType{ - promParser.ValueTypeVector, + Call: mustParse[*promParser.Call](t, `absent(foo{job="prometheus", xxx="1"})`, 0), + Joins: []utils.Source{ + { + Type: utils.SelectorSource, + Returns: promParser.ValueTypeVector, + Selectors: []*promParser.VectorSelector{ + mustParse[*promParser.VectorSelector](t, "prometheus_build_info", 51), }, - Variadic: 0, - ReturnType: promParser.ValueTypeVector, - }, - Args: promParser.Expressions{ - mustParseVector(`foo{job="prometheus", xxx="1"}`, 7), - }, - PosRange: posrange.PositionRange{ - Start: 0, - End: 38, }, }, }, @@ -1811,7 +1871,7 @@ sum(foo:count) by(job) > 20`, Returns: promParser.ValueTypeVector, Operation: "sum", Selectors: []*promParser.VectorSelector{ - mustParseVector(`foo`, 8), + mustParse[*promParser.VectorSelector](t, `foo`, 8), }, IncludedLabels: []string{"notjob"}, FixedLabels: true, @@ -1832,7 +1892,7 @@ sum(foo:count) by(job) > 20`, Returns: promParser.ValueTypeVector, Operation: "count", Selectors: []*promParser.VectorSelector{ - mustParseVector(`node_exporter_build_info`, 6), + mustParse[*promParser.VectorSelector](t, `node_exporter_build_info`, 6), }, IncludedLabels: []string{"instance", "version", "foo"}, // FIXME foo shouldn't be there because count() doesn't produce it FixedLabels: true, @@ -1842,6 +1902,25 @@ sum(foo:count) by(job) > 20`, Fragment: `count(node_exporter_build_info) by (instance, version)`, }, }, + IsConditional: true, + Joins: []utils.Source{ + { + Type: utils.AggregateSource, + Returns: promParser.ValueTypeVector, + Operation: "count", + Selectors: []*promParser.VectorSelector{ + mustParse[*promParser.VectorSelector](t, "deb_package_version", 106), + }, + IncludedLabels: []string{"instance", "version", "package"}, + FixedLabels: true, + ExcludeReason: map[string]utils.ExcludedLabel{ + "": { + Reason: "Query is using aggregation with `by(instance, version, package)`, only labels included inside `by(...)` will be present on the results.", + Fragment: `count(deb_package_version) by (instance, version, package)`, + }, + }, + }, + }, }, }, }, @@ -1853,7 +1932,7 @@ sum(foo:count) by(job) > 20`, Returns: promParser.ValueTypeVector, Operation: "absent", Selectors: []*promParser.VectorSelector{ - mustParseVector(`foo`, 7), + mustParse[*promParser.VectorSelector](t, `foo`, 7), }, FixedLabels: true, ExcludeReason: map[string]utils.ExcludedLabel{ @@ -1862,30 +1941,14 @@ sum(foo:count) by(job) > 20`, Fragment: `absent(foo)`, }, }, - Call: &promParser.Call{ - Func: &promParser.Function{ - Name: "absent", - ArgTypes: []promParser.ValueType{ - promParser.ValueTypeVector, - }, - Variadic: 0, - ReturnType: promParser.ValueTypeVector, - }, - Args: promParser.Expressions{ - mustParseVector(`foo`, 7), - }, - PosRange: posrange.PositionRange{ - Start: 0, - End: 11, - }, - }, + Call: mustParse[*promParser.Call](t, `absent(foo)`, 0), }, { Type: utils.FuncSource, Returns: promParser.ValueTypeVector, Operation: "absent", Selectors: []*promParser.VectorSelector{ - mustParseVector(`bar`, 22), + mustParse[*promParser.VectorSelector](t, `bar`, 22), }, FixedLabels: true, ExcludeReason: map[string]utils.ExcludedLabel{ @@ -1894,23 +1957,7 @@ sum(foo:count) by(job) > 20`, Fragment: `absent(bar)`, }, }, - Call: &promParser.Call{ - Func: &promParser.Function{ - Name: "absent", - ArgTypes: []promParser.ValueType{ - promParser.ValueTypeVector, - }, - Variadic: 0, - ReturnType: promParser.ValueTypeVector, - }, - Args: promParser.Expressions{ - mustParseVector(`bar`, 22), - }, - PosRange: posrange.PositionRange{ - Start: 15, - End: 26, - }, - }, + Call: mustParse[*promParser.Call](t, `absent(bar)`, 15), }, }, }, @@ -1922,7 +1969,7 @@ sum(foo:count) by(job) > 20`, Returns: promParser.ValueTypeVector, Operation: "absent_over_time", Selectors: []*promParser.VectorSelector{ - mustParseVector(`foo`, 17), + mustParse[*promParser.VectorSelector](t, `foo`, 17), }, FixedLabels: true, ExcludeReason: map[string]utils.ExcludedLabel{ @@ -1931,30 +1978,14 @@ sum(foo:count) by(job) > 20`, Fragment: `absent_over_time(foo[5m])`, }, }, - Call: &promParser.Call{ - Func: &promParser.Function{ - Name: "absent_over_time", - ArgTypes: []promParser.ValueType{ - promParser.ValueTypeMatrix, - }, - Variadic: 0, - ReturnType: promParser.ValueTypeVector, - }, - Args: promParser.Expressions{ - mustParseMatrix(`foo[5m]`, 17), - }, - PosRange: posrange.PositionRange{ - Start: 0, - End: 25, - }, - }, + Call: mustParse[*promParser.Call](t, `absent_over_time(foo[5m])`, 0), }, { Type: utils.FuncSource, Returns: promParser.ValueTypeVector, Operation: "absent", Selectors: []*promParser.VectorSelector{ - mustParseVector(`bar`, 36), + mustParse[*promParser.VectorSelector](t, `bar`, 36), }, FixedLabels: true, ExcludeReason: map[string]utils.ExcludedLabel{ @@ -1963,23 +1994,7 @@ sum(foo:count) by(job) > 20`, Fragment: `absent(bar)`, }, }, - Call: &promParser.Call{ - Func: &promParser.Function{ - Name: "absent", - ArgTypes: []promParser.ValueType{ - promParser.ValueTypeVector, - }, - Variadic: 0, - ReturnType: promParser.ValueTypeVector, - }, - Args: promParser.Expressions{ - mustParseVector(`bar`, 36), - }, - PosRange: posrange.PositionRange{ - Start: 29, - End: 40, - }, - }, + Call: mustParse[*promParser.Call](t, `absent(bar)`, 29), }, }, }, @@ -1991,7 +2006,7 @@ sum(foo:count) by(job) > 20`, Returns: promParser.ValueTypeVector, Operation: "absent", Selectors: []*promParser.VectorSelector{ - mustParseVector(`foo{job="xxx"}`, 44), + mustParse[*promParser.VectorSelector](t, `foo{job="xxx"}`, 44), }, IncludedLabels: []string{"job", "cluster", "env"}, GuaranteedLabels: []string{"job"}, @@ -2002,21 +2017,14 @@ sum(foo:count) by(job) > 20`, Fragment: `absent(foo{job="xxx"})`, }, }, - Call: &promParser.Call{ - Func: &promParser.Function{ - Name: "absent", - ArgTypes: []promParser.ValueType{ - promParser.ValueTypeVector, + Call: mustParse[*promParser.Call](t, `absent(foo{job="xxx"})`, 37), + Joins: []utils.Source{ + { + Type: utils.SelectorSource, + Returns: promParser.ValueTypeVector, + Selectors: []*promParser.VectorSelector{ + mustParse[*promParser.VectorSelector](t, "bar", 0), }, - Variadic: 0, - ReturnType: promParser.ValueTypeVector, - }, - Args: promParser.Expressions{ - mustParseVector(`foo{job="xxx"}`, 44), - }, - PosRange: posrange.PositionRange{ - Start: 37, - End: 59, }, }, }, @@ -2030,7 +2038,7 @@ sum(foo:count) by(job) > 20`, Returns: promParser.ValueTypeVector, Operation: "absent", Selectors: []*promParser.VectorSelector{ - mustParseVector(`foo{job="xxx"}`, 32), + mustParse[*promParser.VectorSelector](t, `foo{job="xxx"}`, 32), }, IncludedLabels: []string{"job"}, GuaranteedLabels: []string{"job"}, @@ -2041,21 +2049,14 @@ sum(foo:count) by(job) > 20`, Fragment: `absent(foo{job="xxx"})`, }, }, - Call: &promParser.Call{ - Func: &promParser.Function{ - Name: "absent", - ArgTypes: []promParser.ValueType{ - promParser.ValueTypeVector, + Call: mustParse[*promParser.Call](t, `absent(foo{job="xxx"})`, 25), + Joins: []utils.Source{ + { + Type: utils.SelectorSource, + Returns: promParser.ValueTypeVector, + Selectors: []*promParser.VectorSelector{ + mustParse[*promParser.VectorSelector](t, "bar", 0), }, - Variadic: 0, - ReturnType: promParser.ValueTypeVector, - }, - Args: promParser.Expressions{ - mustParseVector(`foo{job="xxx"}`, 32), - }, - PosRange: posrange.PositionRange{ - Start: 25, - End: 47, }, }, }, @@ -2077,29 +2078,7 @@ sum(foo:count) by(job) > 20`, Fragment: `vector(1)`, }, }, - Call: &promParser.Call{ - Func: &promParser.Function{ - Name: "vector", - ArgTypes: []promParser.ValueType{ - promParser.ValueTypeScalar, - }, - Variadic: 0, - ReturnType: promParser.ValueTypeVector, - }, - Args: promParser.Expressions{ - &promParser.NumberLiteral{ - Val: 1, - PosRange: posrange.PositionRange{ - Start: 7, - End: 8, - }, - }, - }, - PosRange: posrange.PositionRange{ - Start: 0, - End: 9, - }, - }, + Call: mustParse[*promParser.Call](t, `vector(1)`, 0), }, }, }, @@ -2118,39 +2097,7 @@ sum(foo:count) by(job) > 20`, Fragment: `vector(scalar(foo))`, }, }, - Call: &promParser.Call{ - Func: &promParser.Function{ - Name: "vector", - ArgTypes: []promParser.ValueType{ - promParser.ValueTypeScalar, - }, - Variadic: 0, - ReturnType: promParser.ValueTypeVector, - }, - Args: promParser.Expressions{ - &promParser.Call{ - Func: &promParser.Function{ - Name: "scalar", - ArgTypes: []promParser.ValueType{ - promParser.ValueTypeVector, - }, - Variadic: 0, - ReturnType: promParser.ValueTypeScalar, - }, - Args: promParser.Expressions{ - mustParseVector("foo", 14), - }, - PosRange: posrange.PositionRange{ - Start: 7, - End: 18, - }, - }, - }, - PosRange: posrange.PositionRange{ - Start: 0, - End: 19, - }, - }, + Call: mustParse[*promParser.Call](t, `vector(scalar(foo))`, 0), }, }, }, @@ -2169,40 +2116,8 @@ sum(foo:count) by(job) > 20`, Fragment: `vector(0.0 >= bool 0.5)`, }, }, - Call: &promParser.Call{ - Func: &promParser.Function{ - Name: "vector", - ArgTypes: []promParser.ValueType{ - promParser.ValueTypeScalar, - }, - Variadic: 0, - ReturnType: promParser.ValueTypeVector, - }, - Args: promParser.Expressions{ - &promParser.BinaryExpr{ - Op: promParser.GTE, - LHS: &promParser.NumberLiteral{ - Val: 0, - PosRange: posrange.PositionRange{ - Start: 7, - End: 10, - }, - }, - RHS: &promParser.NumberLiteral{ - Val: 0.5, - PosRange: posrange.PositionRange{ - Start: 20, - End: 23, - }, - }, - ReturnBool: true, - }, - }, - PosRange: posrange.PositionRange{ - Start: 0, - End: 24, - }, - }, + Call: mustParse[*promParser.Call](t, `vector(0.0 >= bool 0.5)`, 0), + IsConditional: true, }, }, }, @@ -2214,26 +2129,10 @@ sum(foo:count) by(job) > 20`, Returns: promParser.ValueTypeVector, Operation: "sum_over_time", Selectors: []*promParser.VectorSelector{ - mustParseVector(`foo{job="myjob"}`, 14), + mustParse[*promParser.VectorSelector](t, `foo{job="myjob"}`, 14), }, GuaranteedLabels: []string{"job"}, - Call: &promParser.Call{ - Func: &promParser.Function{ - Name: "sum_over_time", - ArgTypes: []promParser.ValueType{ - promParser.ValueTypeMatrix, - }, - Variadic: 0, - ReturnType: promParser.ValueTypeVector, - }, - Args: promParser.Expressions{ - mustParseMatrix(`foo{job="myjob"}[5m]`, 14), - }, - PosRange: posrange.PositionRange{ - Start: 0, - End: 35, - }, - }, + Call: mustParse[*promParser.Call](t, `sum_over_time(foo{job="myjob"}[5m])`, 0), }, }, }, @@ -2252,21 +2151,7 @@ sum(foo:count) by(job) > 20`, Fragment: `days_in_month()`, }, }, - Call: &promParser.Call{ - Func: &promParser.Function{ - Name: "days_in_month", - ArgTypes: []promParser.ValueType{ - promParser.ValueTypeVector, - }, - Variadic: 1, - ReturnType: promParser.ValueTypeVector, - }, - Args: promParser.Expressions{}, - PosRange: posrange.PositionRange{ - Start: 0, - End: 15, - }, - }, + Call: mustParse[*promParser.Call](t, `days_in_month()`, 0), }, }, }, @@ -2278,26 +2163,10 @@ sum(foo:count) by(job) > 20`, Returns: promParser.ValueTypeVector, Operation: "days_in_month", Selectors: []*promParser.VectorSelector{ - mustParseVector(`foo{job="foo"}`, 14), + mustParse[*promParser.VectorSelector](t, `foo{job="foo"}`, 14), }, GuaranteedLabels: []string{"job"}, - Call: &promParser.Call{ - Func: &promParser.Function{ - Name: "days_in_month", - ArgTypes: []promParser.ValueType{ - promParser.ValueTypeVector, - }, - Variadic: 1, - ReturnType: promParser.ValueTypeVector, - }, - Args: promParser.Expressions{ - mustParseVector(`foo{job="foo"}`, 14), - }, - PosRange: posrange.PositionRange{ - Start: 0, - End: 29, - }, - }, + Call: mustParse[*promParser.Call](t, `days_in_month(foo{job="foo"})`, 0), }, }, }, @@ -2309,56 +2178,32 @@ sum(foo:count) by(job) > 20`, Returns: promParser.ValueTypeVector, Operation: "label_replace", Selectors: []*promParser.VectorSelector{ - mustParseVector(`up{job="api-server",service="a:c"}`, 14), + mustParse[*promParser.VectorSelector](t, `up{job="api-server",service="a:c"}`, 14), }, GuaranteedLabels: []string{"job", "service", "foo"}, - Call: &promParser.Call{ - Func: &promParser.Function{ - Name: "label_replace", - ArgTypes: []promParser.ValueType{ - promParser.ValueTypeVector, - promParser.ValueTypeString, - promParser.ValueTypeString, - promParser.ValueTypeString, - promParser.ValueTypeString, - }, - Variadic: 0, - ReturnType: promParser.ValueTypeVector, - }, - Args: promParser.Expressions{ - mustParseVector(`up{job="api-server",service="a:c"}`, 14), - &promParser.StringLiteral{ - Val: "foo", - PosRange: posrange.PositionRange{ - Start: 50, - End: 55, - }, - }, - &promParser.StringLiteral{ - Val: "$1", - PosRange: posrange.PositionRange{ - Start: 57, - End: 61, - }, - }, - &promParser.StringLiteral{ - Val: "service", - PosRange: posrange.PositionRange{ - Start: 63, - End: 72, - }, - }, - &promParser.StringLiteral{ - Val: "(.*):.*", - PosRange: posrange.PositionRange{ - Start: 74, - End: 83, - }, - }, - }, - PosRange: posrange.PositionRange{ - Start: 0, - End: 84, + Call: mustParse[*promParser.Call](t, `label_replace(up{job="api-server",service="a:c"}, "foo", "$1", "service", "(.*):.*")`, 0), + }, + }, + }, + { + expr: `label_replace(sum by (pod) (pod_status) > 0, "cluster", "$1", "pod", "(.*)")`, + output: []utils.Source{ + { + Type: utils.FuncSource, + Returns: promParser.ValueTypeVector, + Operation: "label_replace", + Selectors: []*promParser.VectorSelector{ + mustParse[*promParser.VectorSelector](t, `pod_status`, 28), + }, + FixedLabels: true, + IsConditional: true, + IncludedLabels: []string{"pod"}, + GuaranteedLabels: []string{"cluster"}, + Call: mustParse[*promParser.Call](t, `label_replace(sum by (pod) (pod_status) > 0, "cluster", "$1", "pod", "(.*)")`, 0), + ExcludeReason: map[string]utils.ExcludedLabel{ + "": { + Reason: "Query is using aggregation with `by(pod)`, only labels included inside `by(...)` will be present on the results.", + Fragment: `sum by (pod) (pod_status)`, }, }, }, @@ -2371,8 +2216,9 @@ sum(foo:count) by(job) > 20`, Type: utils.SelectorSource, Returns: promParser.ValueTypeVector, Selectors: []*promParser.VectorSelector{ - mustParseVector("my_metric", 10), + mustParse[*promParser.VectorSelector](t, "my_metric", 10), }, + IsConditional: true, }, }, }, @@ -2384,7 +2230,7 @@ sum(foo:count) by(job) > 20`, Returns: promParser.ValueTypeVector, Operation: promParser.CardOneToOne.String(), Selectors: []*promParser.VectorSelector{ - mustParseVector(`up{instance="a", job="prometheus"}`, 0), + mustParse[*promParser.VectorSelector](t, `up{instance="a", job="prometheus"}`, 0), }, GuaranteedLabels: []string{"instance"}, ExcludedLabels: []string{"job"}, @@ -2394,6 +2240,16 @@ sum(foo:count) by(job) > 20`, Fragment: `up{instance="a", job="prometheus"} * ignoring(job) up{instance="a", job="pint"}`, }, }, + Joins: []utils.Source{ + { + Type: utils.SelectorSource, + Returns: promParser.ValueTypeVector, + Selectors: []*promParser.VectorSelector{ + mustParse[*promParser.VectorSelector](t, `up{instance="a", job="pint"}`, 51), + }, + GuaranteedLabels: []string{"instance", "job"}, + }, + }, }, }, }, @@ -2412,7 +2268,7 @@ or avg without(router, colo_id, instance) (router_anycast_prefix_enabled{cidr_us Returns: promParser.ValueTypeVector, Operation: "avg", Selectors: []*promParser.VectorSelector{ - mustParseVector(`router_anycast_prefix_enabled{cidr_use_case!~".*offpeak.*"}`, 41), + mustParse[*promParser.VectorSelector](t, `router_anycast_prefix_enabled{cidr_use_case!~".*offpeak.*"}`, 41), }, ExcludedLabels: []string{"router", "colo_id", "instance"}, ExcludeReason: map[string]utils.ExcludedLabel{ @@ -2429,13 +2285,14 @@ or avg without(router, colo_id, instance) (router_anycast_prefix_enabled{cidr_us Fragment: `avg without(router, colo_id, instance) (router_anycast_prefix_enabled{cidr_use_case!~".*offpeak.*"})`, }, }, + IsConditional: true, }, { Type: utils.AggregateSource, Returns: promParser.ValueTypeVector, Operation: "sum", Selectors: []*promParser.VectorSelector{ - mustParseVector(`router_anycast_prefix_enabled{cidr_use_case=~".*tier1.*"}`, 155), + mustParse[*promParser.VectorSelector](t, `router_anycast_prefix_enabled{cidr_use_case=~".*tier1.*"}`, 155), }, GuaranteedLabels: []string{"cidr_use_case"}, ExcludedLabels: []string{"router", "colo_id", "instance"}, @@ -2458,13 +2315,31 @@ or avg without(router, colo_id, instance) (router_anycast_prefix_enabled{cidr_us Fragment: "sum without(router, colo_id, instance) (router_anycast_prefix_enabled{cidr_use_case=~\".*tier1.*\"})\n< on() count(colo_router_tier:disabled_pops:max{tier=\"1\",router=~\"edge.*\"}) * 0.4", }, }, + IsConditional: true, + Joins: []utils.Source{ + { + Type: utils.AggregateSource, + Returns: promParser.ValueTypeVector, + Operation: "count", + Selectors: []*promParser.VectorSelector{ + mustParse[*promParser.VectorSelector](t, `colo_router_tier:disabled_pops:max{tier="1",router=~"edge.*"}`, 227), + }, + FixedLabels: true, + ExcludeReason: map[string]utils.ExcludedLabel{ + "": { + Reason: "Query is using aggregation that removes all labels.", + Fragment: `count(colo_router_tier:disabled_pops:max{tier="1",router=~"edge.*"})`, + }, + }, + }, + }, }, { Type: utils.AggregateSource, Returns: promParser.ValueTypeVector, Operation: "avg", Selectors: []*promParser.VectorSelector{ - mustParseVector(`router_anycast_prefix_enabled{cidr_use_case=~".*regional.*"}`, 343), + mustParse[*promParser.VectorSelector](t, `router_anycast_prefix_enabled{cidr_use_case=~".*regional.*"}`, 343), }, GuaranteedLabels: []string{"cidr_use_case"}, ExcludedLabels: []string{"router", "colo_id", "instance"}, @@ -2482,6 +2357,7 @@ or avg without(router, colo_id, instance) (router_anycast_prefix_enabled{cidr_us Fragment: `avg without(router, colo_id, instance) (router_anycast_prefix_enabled{cidr_use_case=~".*regional.*"})`, }, }, + IsConditional: true, }, }, }, @@ -2493,67 +2369,11 @@ or avg without(router, colo_id, instance) (router_anycast_prefix_enabled{cidr_us Returns: promParser.ValueTypeVector, Operation: "label_replace", Selectors: []*promParser.VectorSelector{ - mustParseVector(`foo`, 18), + mustParse[*promParser.VectorSelector](t, `foo`, 18), }, GuaranteedLabels: []string{"instance"}, - Call: &promParser.Call{ - Func: &promParser.Function{ - Name: "label_replace", - ArgTypes: []promParser.ValueType{ - promParser.ValueTypeVector, - promParser.ValueTypeString, - promParser.ValueTypeString, - promParser.ValueTypeString, - promParser.ValueTypeString, - }, - Variadic: 0, - ReturnType: promParser.ValueTypeVector, - }, - Args: promParser.Expressions{ - &promParser.AggregateExpr{ - Op: promParser.SUM, - Expr: mustParseVector("foo", 18), - Grouping: []string{"instance"}, - Without: true, - PosRange: posrange.PositionRange{ - Start: 14, - End: 40, - }, - }, - &promParser.StringLiteral{ - Val: "instance", - PosRange: posrange.PositionRange{ - Start: 42, - End: 52, - }, - }, - &promParser.StringLiteral{ - Val: "none", - PosRange: posrange.PositionRange{ - Start: 54, - End: 60, - }, - }, - &promParser.StringLiteral{ - Val: "", - PosRange: posrange.PositionRange{ - Start: 62, - End: 64, - }, - }, - &promParser.StringLiteral{ - Val: "", - PosRange: posrange.PositionRange{ - Start: 66, - End: 68, - }, - }, - }, - PosRange: posrange.PositionRange{ - Start: 0, - End: 69, - }, - }, + ExcludeReason: map[string]utils.ExcludedLabel{}, + Call: mustParse[*promParser.Call](t, `label_replace(sum(foo) without(instance), "instance", "none", "", "")`, 0), }, }, }, @@ -2570,7 +2390,7 @@ sum by (region, target, colo_name) ( Returns: promParser.ValueTypeVector, Operation: "sum", Selectors: []*promParser.VectorSelector{ - mustParseVector(`probe_success{job="abc"}`, 56), + mustParse[*promParser.VectorSelector](t, `probe_success{job="abc"}`, 56), }, IncludedLabels: []string{"region", "target", "colo_name"}, FixedLabels: true, @@ -2580,6 +2400,7 @@ sum by (region, target, colo_name) ( Fragment: "sum by (region, target, colo_name) (\n sum_over_time(probe_success{job=\"abc\"}[5m])\n\tor\n\tvector(1)\n)", }, }, + IsConditional: true, }, { Type: utils.AggregateSource, @@ -2595,6 +2416,7 @@ sum by (region, target, colo_name) ( Fragment: "vector(1)", }, }, + IsConditional: true, }, }, }, @@ -2614,36 +2436,14 @@ sum by (region, target, colo_name) ( Fragment: "vector(1)", }, }, - Call: &promParser.Call{ - Func: &promParser.Function{ - Name: "vector", - ArgTypes: []promParser.ValueType{ - promParser.ValueTypeScalar, - }, - Variadic: 0, - ReturnType: promParser.ValueTypeVector, - }, - Args: promParser.Expressions{ - &promParser.NumberLiteral{ - Val: 1, - PosRange: posrange.PositionRange{ - Start: 7, - End: 8, - }, - }, - }, - PosRange: posrange.PositionRange{ - Start: 0, - End: 9, - }, - }, + Call: mustParse[*promParser.Call](t, "vector(1)", 0), }, { Type: utils.SelectorSource, Operation: promParser.CardManyToMany.String(), Returns: promParser.ValueTypeVector, Selectors: []*promParser.VectorSelector{ - mustParseVector("foo", 13), + mustParse[*promParser.VectorSelector](t, "foo", 13), }, IsDead: true, }, @@ -2666,29 +2466,8 @@ sum by (region, target, colo_name) ( Fragment: "vector(0)", }, }, - Call: &promParser.Call{ - Func: &promParser.Function{ - Name: "vector", - ArgTypes: []promParser.ValueType{ - promParser.ValueTypeScalar, - }, - Variadic: 0, - ReturnType: promParser.ValueTypeVector, - }, - Args: promParser.Expressions{ - &promParser.NumberLiteral{ - Val: 0, - PosRange: posrange.PositionRange{ - Start: 7, - End: 8, - }, - }, - }, - PosRange: posrange.PositionRange{ - Start: 0, - End: 9, - }, - }, + Call: mustParse[*promParser.Call](t, "vector(0)", 0), + IsConditional: true, }, }, }, @@ -2700,7 +2479,7 @@ sum by (region, target, colo_name) ( Returns: promParser.ValueTypeVector, Operation: "sum", Selectors: []*promParser.VectorSelector{ - mustParseVector(`foo`, 4), + mustParse[*promParser.VectorSelector](t, `foo`, 4), }, FixedLabels: true, ExcludeReason: map[string]utils.ExcludedLabel{ @@ -2709,6 +2488,7 @@ sum by (region, target, colo_name) ( Fragment: `sum(foo or vector(0))`, }, }, + IsConditional: true, }, { Type: utils.AggregateSource, @@ -2724,6 +2504,7 @@ sum by (region, target, colo_name) ( Fragment: "sum(foo or vector(0))", }, }, + IsConditional: true, }, }, }, @@ -2735,7 +2516,7 @@ sum by (region, target, colo_name) ( Returns: promParser.ValueTypeVector, Operation: "sum", Selectors: []*promParser.VectorSelector{ - mustParseVector(`foo`, 5), + mustParse[*promParser.VectorSelector](t, `foo`, 5), }, FixedLabels: true, ExcludeReason: map[string]utils.ExcludedLabel{ @@ -2744,6 +2525,7 @@ sum by (region, target, colo_name) ( Fragment: `sum(foo or vector(1))`, }, }, + IsConditional: true, }, { Type: utils.AggregateSource, @@ -2759,6 +2541,7 @@ sum by (region, target, colo_name) ( Fragment: "sum(foo or vector(1))", }, }, + IsConditional: true, }, }, }, @@ -2770,7 +2553,7 @@ sum by (region, target, colo_name) ( Returns: promParser.ValueTypeVector, Operation: "sum", Selectors: []*promParser.VectorSelector{ - mustParseVector(`foo`, 5), + mustParse[*promParser.VectorSelector](t, `foo`, 5), }, FixedLabels: true, ExcludeReason: map[string]utils.ExcludedLabel{ @@ -2779,6 +2562,7 @@ sum by (region, target, colo_name) ( Fragment: `sum(foo or vector(1))`, }, }, + IsConditional: true, }, { Type: utils.AggregateSource, @@ -2793,6 +2577,7 @@ sum by (region, target, colo_name) ( Fragment: "sum(foo or vector(1))", }, }, + IsConditional: true, }, }, }, @@ -2804,7 +2589,7 @@ sum by (region, target, colo_name) ( Returns: promParser.ValueTypeVector, Operation: "sum", Selectors: []*promParser.VectorSelector{ - mustParseVector(`foo`, 5), + mustParse[*promParser.VectorSelector](t, `foo`, 5), }, FixedLabels: true, ExcludeReason: map[string]utils.ExcludedLabel{ @@ -2813,6 +2598,7 @@ sum by (region, target, colo_name) ( Fragment: `sum(foo or vector(2))`, }, }, + IsConditional: true, }, { Type: utils.AggregateSource, @@ -2828,6 +2614,210 @@ sum by (region, target, colo_name) ( Fragment: "sum(foo or vector(2))", }, }, + IsConditional: true, + }, + }, + }, + { + expr: ` +(sum(sometimes{foo!="bar"} or vector(0))) +or +((bob > 10) or sum(foo) or vector(1))`, + output: []utils.Source{ + { + Type: utils.AggregateSource, + Returns: promParser.ValueTypeVector, + Operation: "sum", + Selectors: []*promParser.VectorSelector{ + mustParse[*promParser.VectorSelector](t, `sometimes{foo!="bar"}`, 6), + }, + FixedLabels: true, + ExcludeReason: map[string]utils.ExcludedLabel{ + "": { + Reason: "Query is using aggregation that removes all labels.", + Fragment: `sum(sometimes{foo!="bar"} or vector(0)))`, // FIXME bogus ) + }, + }, + }, + { + Type: utils.AggregateSource, + Returns: promParser.ValueTypeVector, + Operation: "sum", + AlwaysReturns: true, + ReturnedNumbers: []float64{0}, + FixedLabels: true, + ExcludeReason: map[string]utils.ExcludedLabel{ + "": { + Reason: "Query is using aggregation that removes all labels.", + Fragment: `sum(sometimes{foo!="bar"} or vector(0)))`, // FIXME bogus ) + }, + }, + }, + { + Type: utils.SelectorSource, + Operation: promParser.CardManyToMany.String(), + Returns: promParser.ValueTypeVector, + Selectors: []*promParser.VectorSelector{ + mustParse[*promParser.VectorSelector](t, `bob`, 48), + }, + IsConditional: true, + }, + { + Type: utils.AggregateSource, + Returns: promParser.ValueTypeVector, + Operation: "sum", + Selectors: []*promParser.VectorSelector{ + mustParse[*promParser.VectorSelector](t, `foo`, 65), + }, + FixedLabels: true, + ExcludeReason: map[string]utils.ExcludedLabel{ + "": { + Reason: "Query is using aggregation that removes all labels.", + Fragment: `sum(foo)`, + }, + }, + }, + { + Type: utils.FuncSource, + Returns: promParser.ValueTypeVector, + Operation: "vector", + AlwaysReturns: true, + ReturnedNumbers: []float64{1}, + FixedLabels: true, + Call: mustParse[*promParser.Call](t, "vector(1)", 73), + ExcludeReason: map[string]utils.ExcludedLabel{ + "": { + Reason: "Calling `vector()` will return a vector value with no labels.", + Fragment: "vector(1)", + }, + }, + }, + }, + }, + { + expr: ` +( + sum(sometimes{foo!="bar"}) + or + vector(1) +) and ( + ((bob > 10) or sum(bar)) + or + notfound > 0 +)`, + output: []utils.Source{ + { + Type: utils.AggregateSource, + Returns: promParser.ValueTypeVector, + Operation: "sum", + Selectors: []*promParser.VectorSelector{ + mustParse[*promParser.VectorSelector](t, `sometimes{foo!="bar"}`, 8), + }, + FixedLabels: true, + ExcludeReason: map[string]utils.ExcludedLabel{ + "": { + Reason: "Query is using aggregation that removes all labels.", + Fragment: `sum(sometimes{foo!="bar"})`, + }, + }, + Joins: []utils.Source{ + { + Type: utils.SelectorSource, + Operation: promParser.CardManyToMany.String(), + Returns: promParser.ValueTypeVector, + Selectors: []*promParser.VectorSelector{ + mustParse[*promParser.VectorSelector](t, `bob`, 57), + }, + IsConditional: true, + }, + { + Type: utils.AggregateSource, + Returns: promParser.ValueTypeVector, + Operation: "sum", + Selectors: []*promParser.VectorSelector{ + mustParse[*promParser.VectorSelector](t, `bar`, 74), + }, + FixedLabels: true, + ExcludeReason: map[string]utils.ExcludedLabel{ + "": { + Reason: "Query is using aggregation that removes all labels.", + Fragment: `sum(bar))`, // FIXME bogus ) + }, + }, + }, + { + Type: utils.SelectorSource, + Operation: promParser.CardManyToMany.String(), + Returns: promParser.ValueTypeVector, + Selectors: []*promParser.VectorSelector{ + mustParse[*promParser.VectorSelector](t, `notfound`, 85), + }, + IsConditional: true, + }, + }, + }, + { + Type: utils.FuncSource, + Returns: promParser.ValueTypeVector, + Operation: "vector", + AlwaysReturns: true, + ReturnedNumbers: []float64{1}, + FixedLabels: true, + Call: mustParse[*promParser.Call](t, "vector(1)", 36), + ExcludeReason: map[string]utils.ExcludedLabel{ + "": { + Reason: "Calling `vector()` will return a vector value with no labels.", + Fragment: "vector(1)", + }, + }, + Joins: []utils.Source{ + { + Type: utils.SelectorSource, + Operation: promParser.CardManyToMany.String(), + Returns: promParser.ValueTypeVector, + Selectors: []*promParser.VectorSelector{ + mustParse[*promParser.VectorSelector](t, `bob`, 57), + }, + IsConditional: true, + }, + { + Type: utils.AggregateSource, + Returns: promParser.ValueTypeVector, + Operation: "sum", + Selectors: []*promParser.VectorSelector{ + mustParse[*promParser.VectorSelector](t, `bar`, 74), + }, + FixedLabels: true, + ExcludeReason: map[string]utils.ExcludedLabel{ + "": { + Reason: "Query is using aggregation that removes all labels.", + Fragment: `sum(bar))`, // FIXME bogus ) + }, + }, + }, + { + Type: utils.SelectorSource, + Operation: promParser.CardManyToMany.String(), + Returns: promParser.ValueTypeVector, + Selectors: []*promParser.VectorSelector{ + mustParse[*promParser.VectorSelector](t, `notfound`, 85), + }, + IsConditional: true, + }, + }, + }, + }, + }, + { + expr: "foo offset 5m > 5", + output: []utils.Source{ + { + Type: utils.SelectorSource, + Returns: promParser.ValueTypeVector, + Selectors: []*promParser.VectorSelector{ + mustParse[*promParser.VectorSelector](t, "foo offset 5m", 0), + }, + IsConditional: true, }, }, }, From bb985de163d54b9940385d27d9680c60217e1e80 Mon Sep 17 00:00:00 2001 From: Lukasz Mierzwa Date: Tue, 11 Feb 2025 14:02:29 +0000 Subject: [PATCH 2/3] Remove codecov retries --- .github/workflows/test.yml | 21 +-------------------- 1 file changed, 1 insertion(+), 20 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index c34084b6..0f3f2699 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -31,10 +31,7 @@ jobs: - name: Check for local changes run: git diff --exit-code - # Codecov reporting is unreliable. - # Re-run report 3 times to have a better - # chance of success. - - name: Report code coverage (1) + - name: Report code coverage uses: codecov/codecov-action@13ce06bfc6bbe3ecf90edbbf1bc32fe5978ca1d3 # v5.3.1 with: token: ${{ secrets.CODECOV_TOKEN }} @@ -43,19 +40,3 @@ jobs: handle_no_reports_found: true continue-on-error: true - - name: Report code coverage (2) - uses: codecov/codecov-action@13ce06bfc6bbe3ecf90edbbf1bc32fe5978ca1d3 # v5.3.1 - with: - token: ${{ secrets.CODECOV_TOKEN }} - files: ./.cover/coverage.out - fail_ci_if_error: true - handle_no_reports_found: true - continue-on-error: true - - - name: Report code coverage (3) - uses: codecov/codecov-action@13ce06bfc6bbe3ecf90edbbf1bc32fe5978ca1d3 # v5.3.1 - with: - token: ${{ secrets.CODECOV_TOKEN }} - files: ./.cover/coverage.out - fail_ci_if_error: true - handle_no_reports_found: true From bd876148cf67b8f459a03213eafa4608400f16f1 Mon Sep 17 00:00:00 2001 From: Lukasz Mierzwa Date: Tue, 11 Feb 2025 14:30:49 +0000 Subject: [PATCH 3/3] Refactor Source to have a single selector --- internal/checks/promql_rate.go | 6 +- internal/checks/promql_series.go | 12 +- internal/parser/utils/source.go | 63 +- internal/parser/utils/source_test.go | 1218 ++++++++++---------------- 4 files changed, 502 insertions(+), 797 deletions(-) diff --git a/internal/checks/promql_rate.go b/internal/checks/promql_rate.go index 2f146acf..b2f1ec5b 100644 --- a/internal/checks/promql_rate.go +++ b/internal/checks/promql_rate.go @@ -157,8 +157,8 @@ func (c RateCheck) checkNode(ctx context.Context, node *parser.PromQLNode, entri if src.Type != utils.AggregateSource { continue } - for _, vs := range src.Selectors { - metadata, err := c.prom.Metadata(ctx, vs.Name) + if src.Selector != nil { + metadata, err := c.prom.Metadata(ctx, src.Selector.Name) if err != nil { if errors.Is(err, promapi.ErrUnsupported) { continue @@ -186,7 +186,7 @@ func (c RateCheck) checkNode(ctx context.Context, node *parser.PromQLNode, entri } problems = append(problems, exprProblem{ text: fmt.Sprintf("`rate(%s(counter))` chain detected, `%s` is called here on results of `%s(%s)`.", - src.Operation, node.Expr, src.Operation, vs), + src.Operation, node.Expr, src.Operation, src.Selector), details: fmt.Sprintf( "You can only calculate `rate()` directly from a counter metric. "+ "Calling `rate()` on `%s()` results will return bogus results because `%s()` will hide information on when each counter resets. "+ diff --git a/internal/checks/promql_series.go b/internal/checks/promql_series.go index 6098a479..8cc2ff4e 100644 --- a/internal/checks/promql_series.go +++ b/internal/checks/promql_series.go @@ -783,21 +783,21 @@ func getNonFallbackSelectors(n parser.PromQLExpr) (selectors []*promParser.Vecto } for _, ls := range sources { if !hasVectorFallback { - for _, s := range ls.Selectors { - selectors = append(selectors, selectorWithoutOffset(s)) + if ls.Selector != nil { + selectors = append(selectors, selectorWithoutOffset(ls.Selector)) } } for _, js := range ls.Joins { - for _, s := range js.Selectors { - selectors = append(selectors, selectorWithoutOffset(s)) + if js.Selector != nil { + selectors = append(selectors, selectorWithoutOffset(js.Selector)) } } for _, us := range ls.Unless { if !us.IsConditional { continue } - for _, s := range us.Selectors { - selectors = append(selectors, selectorWithoutOffset(s)) + if us.Selector != nil { + selectors = append(selectors, selectorWithoutOffset(us.Selector)) } } } diff --git a/internal/parser/utils/source.go b/internal/parser/utils/source.go index f55f4d84..85c867dc 100644 --- a/internal/parser/utils/source.go +++ b/internal/parser/utils/source.go @@ -30,7 +30,7 @@ type ExcludedLabel struct { type Source struct { Joins []Source // Any other sources this source joins with. Unless []Source // Any other sources this source is suppressed by. - Selectors []*promParser.VectorSelector + Selector *promParser.VectorSelector Call *promParser.Call ExcludeReason map[string]ExcludedLabel // Reason why a label was excluded Operation string @@ -115,7 +115,7 @@ func walkNode(expr string, node promParser.Node) (src []Source) { case *promParser.VectorSelector: s.Type = SelectorSource s.Returns = promParser.ValueTypeVector - s.Selectors = append(s.Selectors, n) + s.Selector = n s = guaranteeLabel(s, labelsFromSelectors(guaranteedLabelsMatches, n)...) src = append(src, s) @@ -182,32 +182,25 @@ func setInMap(dst map[string]ExcludedLabel, key string, val ExcludedLabel) map[s var guaranteedLabelsMatches = []labels.MatchType{labels.MatchEqual, labels.MatchRegexp} -func labelsFromSelectors(matches []labels.MatchType, selectors ...*promParser.VectorSelector) (names []string) { +func labelsFromSelectors(matches []labels.MatchType, selector *promParser.VectorSelector) (names []string) { nameCount := map[string]int{} var ok bool - for _, selector := range selectors { - // Any label used in positive filters is gurnateed to be present. - for _, lm := range selector.LabelMatchers { - if lm.Name == labels.MetricName { - continue - } + // Any label used in positive filters is gurnateed to be present. + for _, lm := range selector.LabelMatchers { + if lm.Name == labels.MetricName { + continue + } - if !slices.Contains(matches, lm.Type) { - continue - } + if !slices.Contains(matches, lm.Type) { + continue + } - names = appendToSlice(names, lm.Name) + names = appendToSlice(names, lm.Name) - if _, ok = nameCount[lm.Name]; !ok { - nameCount[lm.Name] = 0 - } - nameCount[lm.Name]++ - } - } - for name, cnt := range nameCount { - if cnt != len(selectors) { - names = removeFromSlice(names, name) + if _, ok = nameCount[lm.Name]; !ok { + nameCount[lm.Name] = 0 } + nameCount[lm.Name]++ } return names } @@ -362,29 +355,29 @@ func parsePromQLFunc(s Source, expr string, n *promParser.Call) Source { case "abs", "sgn", "acos", "acosh", "asin", "asinh", "atan", "atanh", "cos", "cosh", "sin", "sinh", "tan", "tanh": // No change to labels. s.Returns = promParser.ValueTypeVector - s = guaranteeLabel(s, labelsFromSelectors(guaranteedLabelsMatches, s.Selectors...)...) + s = guaranteeLabel(s, labelsFromSelectors(guaranteedLabelsMatches, s.Selector)...) case "ceil", "floor", "round": // No change to labels. s.Returns = promParser.ValueTypeVector - s = guaranteeLabel(s, labelsFromSelectors(guaranteedLabelsMatches, s.Selectors...)...) + s = guaranteeLabel(s, labelsFromSelectors(guaranteedLabelsMatches, s.Selector)...) case "changes", "resets": // No change to labels. s.Returns = promParser.ValueTypeVector - s = guaranteeLabel(s, labelsFromSelectors(guaranteedLabelsMatches, s.Selectors...)...) + s = guaranteeLabel(s, labelsFromSelectors(guaranteedLabelsMatches, s.Selector)...) case "clamp", "clamp_max", "clamp_min": // No change to labels. s.Returns = promParser.ValueTypeVector - s = guaranteeLabel(s, labelsFromSelectors(guaranteedLabelsMatches, s.Selectors...)...) + s = guaranteeLabel(s, labelsFromSelectors(guaranteedLabelsMatches, s.Selector)...) case "absent", "absent_over_time": s.Returns = promParser.ValueTypeVector s.FixedLabels = true s.IncludedLabels = nil s.GuaranteedLabels = nil - for _, name := range labelsFromSelectors([]labels.MatchType{labels.MatchEqual}, s.Selectors...) { + for _, name := range labelsFromSelectors([]labels.MatchType{labels.MatchEqual}, s.Selector) { s = includeLabel(s, name) s = guaranteeLabel(s, name) } @@ -405,7 +398,7 @@ If you're hoping to get instance specific labels this way and alert when some ta case "avg_over_time", "count_over_time", "last_over_time", "max_over_time", "min_over_time", "present_over_time", "quantile_over_time", "stddev_over_time", "stdvar_over_time", "sum_over_time": // No change to labels. s.Returns = promParser.ValueTypeVector - s = guaranteeLabel(s, labelsFromSelectors(guaranteedLabelsMatches, s.Selectors...)...) + s = guaranteeLabel(s, labelsFromSelectors(guaranteedLabelsMatches, s.Selector)...) case "days_in_month", "day_of_month", "day_of_week", "day_of_year", "hour", "minute", "month", "year": s.Returns = promParser.ValueTypeVector @@ -426,33 +419,33 @@ If you're hoping to get instance specific labels this way and alert when some ta }, ) } else { - s = guaranteeLabel(s, labelsFromSelectors(guaranteedLabelsMatches, s.Selectors...)...) + s = guaranteeLabel(s, labelsFromSelectors(guaranteedLabelsMatches, s.Selector)...) } case "deg", "rad", "ln", "log10", "log2", "sqrt", "exp": // No change to labels. s.Returns = promParser.ValueTypeVector - s = guaranteeLabel(s, labelsFromSelectors(guaranteedLabelsMatches, s.Selectors...)...) + s = guaranteeLabel(s, labelsFromSelectors(guaranteedLabelsMatches, s.Selector)...) case "delta", "idelta", "increase", "deriv", "irate", "rate": // No change to labels. s.Returns = promParser.ValueTypeVector - s = guaranteeLabel(s, labelsFromSelectors(guaranteedLabelsMatches, s.Selectors...)...) + s = guaranteeLabel(s, labelsFromSelectors(guaranteedLabelsMatches, s.Selector)...) case "histogram_avg", "histogram_count", "histogram_sum", "histogram_stddev", "histogram_stdvar", "histogram_fraction", "histogram_quantile": // No change to labels. s.Returns = promParser.ValueTypeVector - s = guaranteeLabel(s, labelsFromSelectors(guaranteedLabelsMatches, s.Selectors...)...) + s = guaranteeLabel(s, labelsFromSelectors(guaranteedLabelsMatches, s.Selector)...) case "holt_winters", "predict_linear": // No change to labels. s.Returns = promParser.ValueTypeVector - s = guaranteeLabel(s, labelsFromSelectors(guaranteedLabelsMatches, s.Selectors...)...) + s = guaranteeLabel(s, labelsFromSelectors(guaranteedLabelsMatches, s.Selector)...) case "label_replace", "label_join": // One label added to the results. s.Returns = promParser.ValueTypeVector - s = guaranteeLabel(s, labelsFromSelectors(guaranteedLabelsMatches, s.Selectors...)...) + s = guaranteeLabel(s, labelsFromSelectors(guaranteedLabelsMatches, s.Selector)...) s = guaranteeLabel(s, s.Call.Args[1].(*promParser.StringLiteral).Val) case "pi": @@ -507,7 +500,7 @@ If you're hoping to get instance specific labels this way and alert when some ta case "timestamp": // No change to labels. s.Returns = promParser.ValueTypeVector - s = guaranteeLabel(s, labelsFromSelectors(guaranteedLabelsMatches, s.Selectors...)...) + s = guaranteeLabel(s, labelsFromSelectors(guaranteedLabelsMatches, s.Selector)...) case "vector": s.Returns = promParser.ValueTypeVector diff --git a/internal/parser/utils/source_test.go b/internal/parser/utils/source_test.go index 796341fb..744a2d95 100644 --- a/internal/parser/utils/source_test.go +++ b/internal/parser/utils/source_test.go @@ -207,17 +207,13 @@ func TestLabelsSource(t *testing.T) { Type: utils.SelectorSource, Returns: promParser.ValueTypeVector, Operation: promParser.CardManyToMany.String(), - Selectors: []*promParser.VectorSelector{ - mustParse[*promParser.VectorSelector](t, "foo", 1), - }, + Selector: mustParse[*promParser.VectorSelector](t, "foo", 1), }, { Type: utils.SelectorSource, Returns: promParser.ValueTypeVector, Operation: promParser.CardManyToMany.String(), - Selectors: []*promParser.VectorSelector{ - mustParse[*promParser.VectorSelector](t, "bar", 8), - }, + Selector: mustParse[*promParser.VectorSelector](t, "bar", 8), }, }, }, @@ -228,9 +224,7 @@ func TestLabelsSource(t *testing.T) { Type: utils.SelectorSource, Returns: promParser.ValueTypeVector, Operation: promParser.CardManyToMany.String(), - Selectors: []*promParser.VectorSelector{ - mustParse[*promParser.VectorSelector](t, "foo", 1), - }, + Selector: mustParse[*promParser.VectorSelector](t, "foo", 1), }, { Type: utils.FuncSource, @@ -256,9 +250,7 @@ func TestLabelsSource(t *testing.T) { Type: utils.SelectorSource, Returns: promParser.ValueTypeVector, Operation: promParser.CardManyToMany.String(), - Selectors: []*promParser.VectorSelector{ - mustParse[*promParser.VectorSelector](t, "foo", 1), - }, + Selector: mustParse[*promParser.VectorSelector](t, "foo", 1), Joins: []utils.Source{ { Type: utils.FuncSource, @@ -279,10 +271,8 @@ func TestLabelsSource(t *testing.T) { Type: utils.SelectorSource, Returns: promParser.ValueTypeVector, Operation: promParser.CardManyToMany.String(), - Selectors: []*promParser.VectorSelector{ - mustParse[*promParser.VectorSelector](t, "bar", 35), - }, - IsDead: true, + Selector: mustParse[*promParser.VectorSelector](t, "bar", 35), + IsDead: true, }, }, }, @@ -320,10 +310,8 @@ func TestLabelsSource(t *testing.T) { Type: utils.SelectorSource, Returns: promParser.ValueTypeVector, Operation: promParser.CardManyToMany.String(), - Selectors: []*promParser.VectorSelector{ - mustParse[*promParser.VectorSelector](t, "bar", 35), - }, - IsDead: true, + Selector: mustParse[*promParser.VectorSelector](t, "bar", 35), + IsDead: true, }, }, }, @@ -388,11 +376,9 @@ func TestLabelsSource(t *testing.T) { expr: "foo", output: []utils.Source{ { - Type: utils.SelectorSource, - Returns: promParser.ValueTypeVector, - Selectors: []*promParser.VectorSelector{ - mustParse[*promParser.VectorSelector](t, "foo", 0), - }, + Type: utils.SelectorSource, + Returns: promParser.ValueTypeVector, + Selector: mustParse[*promParser.VectorSelector](t, "foo", 0), }, }, }, @@ -400,11 +386,9 @@ func TestLabelsSource(t *testing.T) { expr: "foo offset 5m", output: []utils.Source{ { - Type: utils.SelectorSource, - Returns: promParser.ValueTypeVector, - Selectors: []*promParser.VectorSelector{ - mustParse[*promParser.VectorSelector](t, "foo offset 5m", 0), - }, + Type: utils.SelectorSource, + Returns: promParser.ValueTypeVector, + Selector: mustParse[*promParser.VectorSelector](t, "foo offset 5m", 0), }, }, }, @@ -412,11 +396,9 @@ func TestLabelsSource(t *testing.T) { expr: `foo{job="bar"}`, output: []utils.Source{ { - Type: utils.SelectorSource, - Returns: promParser.ValueTypeVector, - Selectors: []*promParser.VectorSelector{ - mustParse[*promParser.VectorSelector](t, `foo{job="bar"}`, 0), - }, + Type: utils.SelectorSource, + Returns: promParser.ValueTypeVector, + Selector: mustParse[*promParser.VectorSelector](t, `foo{job="bar"}`, 0), GuaranteedLabels: []string{"job"}, }, }, @@ -425,20 +407,16 @@ func TestLabelsSource(t *testing.T) { expr: `foo{job="bar"} or bar{job="foo"}`, output: []utils.Source{ { - Type: utils.SelectorSource, - Returns: promParser.ValueTypeVector, - Selectors: []*promParser.VectorSelector{ - mustParse[*promParser.VectorSelector](t, `foo{job="bar"}`, 0), - }, + Type: utils.SelectorSource, + Returns: promParser.ValueTypeVector, + Selector: mustParse[*promParser.VectorSelector](t, `foo{job="bar"}`, 0), Operation: promParser.CardManyToMany.String(), GuaranteedLabels: []string{"job"}, }, { - Type: utils.SelectorSource, - Returns: promParser.ValueTypeVector, - Selectors: []*promParser.VectorSelector{ - mustParse[*promParser.VectorSelector](t, `bar{job="foo"}`, 18), - }, + Type: utils.SelectorSource, + Returns: promParser.ValueTypeVector, + Selector: mustParse[*promParser.VectorSelector](t, `bar{job="foo"}`, 18), Operation: promParser.CardManyToMany.String(), GuaranteedLabels: []string{"job"}, }, @@ -448,20 +426,16 @@ func TestLabelsSource(t *testing.T) { expr: `foo{a="bar"} or bar{b="foo"}`, output: []utils.Source{ { - Type: utils.SelectorSource, - Returns: promParser.ValueTypeVector, - Selectors: []*promParser.VectorSelector{ - mustParse[*promParser.VectorSelector](t, `foo{a="bar"}`, 0), - }, + Type: utils.SelectorSource, + Returns: promParser.ValueTypeVector, + Selector: mustParse[*promParser.VectorSelector](t, `foo{a="bar"}`, 0), Operation: promParser.CardManyToMany.String(), GuaranteedLabels: []string{"a"}, }, { - Type: utils.SelectorSource, - Returns: promParser.ValueTypeVector, - Selectors: []*promParser.VectorSelector{ - mustParse[*promParser.VectorSelector](t, `bar{b="foo"}`, 16), - }, + Type: utils.SelectorSource, + Returns: promParser.ValueTypeVector, + Selector: mustParse[*promParser.VectorSelector](t, `bar{b="foo"}`, 16), Operation: promParser.CardManyToMany.String(), GuaranteedLabels: []string{"b"}, }, @@ -471,11 +445,9 @@ func TestLabelsSource(t *testing.T) { expr: "foo[5m]", output: []utils.Source{ { - Type: utils.SelectorSource, - Returns: promParser.ValueTypeVector, - Selectors: []*promParser.VectorSelector{ - mustParse[*promParser.VectorSelector](t, "foo", 0), - }, + Type: utils.SelectorSource, + Returns: promParser.ValueTypeVector, + Selector: mustParse[*promParser.VectorSelector](t, "foo", 0), }, }, }, @@ -483,11 +455,9 @@ func TestLabelsSource(t *testing.T) { expr: "prometheus_build_info[2m:1m]", output: []utils.Source{ { - Type: utils.SelectorSource, - Returns: promParser.ValueTypeVector, - Selectors: []*promParser.VectorSelector{ - mustParse[*promParser.VectorSelector](t, "prometheus_build_info", 0), - }, + Type: utils.SelectorSource, + Returns: promParser.ValueTypeVector, + Selector: mustParse[*promParser.VectorSelector](t, "prometheus_build_info", 0), }, }, }, @@ -498,10 +468,8 @@ func TestLabelsSource(t *testing.T) { Type: utils.FuncSource, Returns: promParser.ValueTypeVector, Operation: "deriv", - Selectors: []*promParser.VectorSelector{ - mustParse[*promParser.VectorSelector](t, "distance_covered_meters_total", 11), - }, - Call: mustParse[*promParser.Call](t, "deriv(rate(distance_covered_meters_total[1m])[5m:1m])", 0), + Selector: mustParse[*promParser.VectorSelector](t, "distance_covered_meters_total", 11), + Call: mustParse[*promParser.Call](t, "deriv(rate(distance_covered_meters_total[1m])[5m:1m])", 0), }, }, }, @@ -509,11 +477,9 @@ func TestLabelsSource(t *testing.T) { expr: "foo - 1", output: []utils.Source{ { - Type: utils.SelectorSource, - Returns: promParser.ValueTypeVector, - Selectors: []*promParser.VectorSelector{ - mustParse[*promParser.VectorSelector](t, "foo", 0), - }, + Type: utils.SelectorSource, + Returns: promParser.ValueTypeVector, + Selector: mustParse[*promParser.VectorSelector](t, "foo", 0), }, }, }, @@ -521,11 +487,9 @@ func TestLabelsSource(t *testing.T) { expr: "foo / 5", output: []utils.Source{ { - Type: utils.SelectorSource, - Returns: promParser.ValueTypeVector, - Selectors: []*promParser.VectorSelector{ - mustParse[*promParser.VectorSelector](t, "foo", 0), - }, + Type: utils.SelectorSource, + Returns: promParser.ValueTypeVector, + Selector: mustParse[*promParser.VectorSelector](t, "foo", 0), }, }, }, @@ -533,11 +497,9 @@ func TestLabelsSource(t *testing.T) { expr: "-foo", output: []utils.Source{ { - Type: utils.SelectorSource, - Returns: promParser.ValueTypeVector, - Selectors: []*promParser.VectorSelector{ - mustParse[*promParser.VectorSelector](t, "foo", 1), - }, + Type: utils.SelectorSource, + Returns: promParser.ValueTypeVector, + Selector: mustParse[*promParser.VectorSelector](t, "foo", 1), }, }, }, @@ -545,12 +507,10 @@ func TestLabelsSource(t *testing.T) { expr: `sum(foo{job="myjob"})`, output: []utils.Source{ { - Type: utils.AggregateSource, - Returns: promParser.ValueTypeVector, - Operation: "sum", - Selectors: []*promParser.VectorSelector{ - mustParse[*promParser.VectorSelector](t, `foo{job="myjob"}`, 4), - }, + Type: utils.AggregateSource, + Returns: promParser.ValueTypeVector, + Operation: "sum", + Selector: mustParse[*promParser.VectorSelector](t, `foo{job="myjob"}`, 4), FixedLabels: true, ExcludeReason: map[string]utils.ExcludedLabel{ "": { @@ -565,12 +525,10 @@ func TestLabelsSource(t *testing.T) { expr: `sum(foo{job="myjob"}) > 20`, output: []utils.Source{ { - Type: utils.AggregateSource, - Returns: promParser.ValueTypeVector, - Operation: "sum", - Selectors: []*promParser.VectorSelector{ - mustParse[*promParser.VectorSelector](t, `foo{job="myjob"}`, 4), - }, + Type: utils.AggregateSource, + Returns: promParser.ValueTypeVector, + Operation: "sum", + Selector: mustParse[*promParser.VectorSelector](t, `foo{job="myjob"}`, 4), FixedLabels: true, ExcludeReason: map[string]utils.ExcludedLabel{ "": { @@ -586,12 +544,10 @@ func TestLabelsSource(t *testing.T) { expr: `sum(foo{job="myjob"}) without(job)`, output: []utils.Source{ { - Type: utils.AggregateSource, - Returns: promParser.ValueTypeVector, - Operation: "sum", - Selectors: []*promParser.VectorSelector{ - mustParse[*promParser.VectorSelector](t, `foo{job="myjob"}`, 4), - }, + Type: utils.AggregateSource, + Returns: promParser.ValueTypeVector, + Operation: "sum", + Selector: mustParse[*promParser.VectorSelector](t, `foo{job="myjob"}`, 4), ExcludedLabels: []string{"job"}, ExcludeReason: map[string]utils.ExcludedLabel{ "job": { @@ -606,12 +562,10 @@ func TestLabelsSource(t *testing.T) { expr: `sum(foo) by(job)`, output: []utils.Source{ { - Type: utils.AggregateSource, - Returns: promParser.ValueTypeVector, - Operation: "sum", - Selectors: []*promParser.VectorSelector{ - mustParse[*promParser.VectorSelector](t, `foo`, 4), - }, + Type: utils.AggregateSource, + Returns: promParser.ValueTypeVector, + Operation: "sum", + Selector: mustParse[*promParser.VectorSelector](t, `foo`, 4), IncludedLabels: []string{"job"}, FixedLabels: true, ExcludeReason: map[string]utils.ExcludedLabel{ @@ -627,12 +581,10 @@ func TestLabelsSource(t *testing.T) { expr: `sum(foo{job="myjob"}) by(job)`, output: []utils.Source{ { - Type: utils.AggregateSource, - Returns: promParser.ValueTypeVector, - Operation: "sum", - Selectors: []*promParser.VectorSelector{ - mustParse[*promParser.VectorSelector](t, `foo{job="myjob"}`, 4), - }, + Type: utils.AggregateSource, + Returns: promParser.ValueTypeVector, + Operation: "sum", + Selector: mustParse[*promParser.VectorSelector](t, `foo{job="myjob"}`, 4), IncludedLabels: []string{"job"}, GuaranteedLabels: []string{"job"}, FixedLabels: true, @@ -649,12 +601,10 @@ func TestLabelsSource(t *testing.T) { expr: `abs(foo{job="myjob"} offset 5m)`, output: []utils.Source{ { - Type: utils.FuncSource, - Returns: promParser.ValueTypeVector, - Operation: "abs", - Selectors: []*promParser.VectorSelector{ - mustParse[*promParser.VectorSelector](t, `foo{job="myjob"} offset 5m`, 4), - }, + Type: utils.FuncSource, + Returns: promParser.ValueTypeVector, + Operation: "abs", + Selector: mustParse[*promParser.VectorSelector](t, `foo{job="myjob"} offset 5m`, 4), Call: mustParse[*promParser.Call](t, `abs(foo{job="myjob"} offset 5m)`, 0), GuaranteedLabels: []string{"job"}, }, @@ -664,22 +614,18 @@ func TestLabelsSource(t *testing.T) { expr: `abs(foo{job="myjob"} or bar{cluster="dev"})`, output: []utils.Source{ { - Type: utils.FuncSource, - Returns: promParser.ValueTypeVector, - Operation: "abs", - Selectors: []*promParser.VectorSelector{ - mustParse[*promParser.VectorSelector](t, `foo{job="myjob"}`, 4), - }, + Type: utils.FuncSource, + Returns: promParser.ValueTypeVector, + Operation: "abs", + Selector: mustParse[*promParser.VectorSelector](t, `foo{job="myjob"}`, 4), GuaranteedLabels: []string{"job"}, Call: mustParse[*promParser.Call](t, `abs(foo{job="myjob"} or bar{cluster="dev"})`, 0), }, { - Type: utils.FuncSource, - Returns: promParser.ValueTypeVector, - Operation: "abs", - Selectors: []*promParser.VectorSelector{ - mustParse[*promParser.VectorSelector](t, `bar{cluster="dev"}`, 24), - }, + Type: utils.FuncSource, + Returns: promParser.ValueTypeVector, + Operation: "abs", + Selector: mustParse[*promParser.VectorSelector](t, `bar{cluster="dev"}`, 24), Call: mustParse[*promParser.Call](t, `abs(foo{job="myjob"} or bar{cluster="dev"})`, 0), GuaranteedLabels: []string{"cluster"}, }, @@ -689,12 +635,10 @@ func TestLabelsSource(t *testing.T) { expr: `sum(foo{job="myjob"} or bar{cluster="dev"}) without(instance)`, output: []utils.Source{ { - Type: utils.AggregateSource, - Returns: promParser.ValueTypeVector, - Operation: "sum", - Selectors: []*promParser.VectorSelector{ - mustParse[*promParser.VectorSelector](t, `foo{job="myjob"}`, 4), - }, + Type: utils.AggregateSource, + Returns: promParser.ValueTypeVector, + Operation: "sum", + Selector: mustParse[*promParser.VectorSelector](t, `foo{job="myjob"}`, 4), GuaranteedLabels: []string{"job"}, ExcludedLabels: []string{"instance"}, ExcludeReason: map[string]utils.ExcludedLabel{ @@ -705,12 +649,10 @@ func TestLabelsSource(t *testing.T) { }, }, { - Type: utils.AggregateSource, - Returns: promParser.ValueTypeVector, - Operation: "sum", - Selectors: []*promParser.VectorSelector{ - mustParse[*promParser.VectorSelector](t, `bar{cluster="dev"}`, 24), - }, + Type: utils.AggregateSource, + Returns: promParser.ValueTypeVector, + Operation: "sum", + Selector: mustParse[*promParser.VectorSelector](t, `bar{cluster="dev"}`, 24), GuaranteedLabels: []string{"cluster"}, ExcludedLabels: []string{"instance"}, ExcludeReason: map[string]utils.ExcludedLabel{ @@ -726,12 +668,10 @@ func TestLabelsSource(t *testing.T) { expr: `sum(foo{job="myjob"}) without(instance)`, output: []utils.Source{ { - Type: utils.AggregateSource, - Returns: promParser.ValueTypeVector, - Operation: "sum", - Selectors: []*promParser.VectorSelector{ - mustParse[*promParser.VectorSelector](t, `foo{job="myjob"}`, 4), - }, + Type: utils.AggregateSource, + Returns: promParser.ValueTypeVector, + Operation: "sum", + Selector: mustParse[*promParser.VectorSelector](t, `foo{job="myjob"}`, 4), GuaranteedLabels: []string{"job"}, ExcludedLabels: []string{"instance"}, ExcludeReason: map[string]utils.ExcludedLabel{ @@ -747,12 +687,10 @@ func TestLabelsSource(t *testing.T) { expr: `min(foo{job="myjob"}) / max(foo{job="myjob"})`, output: []utils.Source{ { - Type: utils.AggregateSource, - Returns: promParser.ValueTypeVector, - Operation: "min", - Selectors: []*promParser.VectorSelector{ - mustParse[*promParser.VectorSelector](t, `foo{job="myjob"}`, 4), - }, + Type: utils.AggregateSource, + Returns: promParser.ValueTypeVector, + Operation: "min", + Selector: mustParse[*promParser.VectorSelector](t, `foo{job="myjob"}`, 4), FixedLabels: true, ExcludeReason: map[string]utils.ExcludedLabel{ "": { @@ -762,12 +700,10 @@ func TestLabelsSource(t *testing.T) { }, Joins: []utils.Source{ { - Type: utils.AggregateSource, - Operation: "max", - Returns: promParser.ValueTypeVector, - Selectors: []*promParser.VectorSelector{ - mustParse[*promParser.VectorSelector](t, `foo{job="myjob"}`, 28), - }, + Type: utils.AggregateSource, + Operation: "max", + Returns: promParser.ValueTypeVector, + Selector: mustParse[*promParser.VectorSelector](t, `foo{job="myjob"}`, 28), FixedLabels: true, ExcludeReason: map[string]utils.ExcludedLabel{ "": { @@ -784,12 +720,10 @@ func TestLabelsSource(t *testing.T) { expr: `max(foo{job="myjob"}) / min(foo{job="myjob"})`, output: []utils.Source{ { - Type: utils.AggregateSource, - Returns: promParser.ValueTypeVector, - Operation: "max", - Selectors: []*promParser.VectorSelector{ - mustParse[*promParser.VectorSelector](t, `foo{job="myjob"}`, 4), - }, + Type: utils.AggregateSource, + Returns: promParser.ValueTypeVector, + Operation: "max", + Selector: mustParse[*promParser.VectorSelector](t, `foo{job="myjob"}`, 4), FixedLabels: true, ExcludeReason: map[string]utils.ExcludedLabel{ "": { @@ -799,12 +733,10 @@ func TestLabelsSource(t *testing.T) { }, Joins: []utils.Source{ { - Type: utils.AggregateSource, - Operation: "min", - Returns: promParser.ValueTypeVector, - Selectors: []*promParser.VectorSelector{ - mustParse[*promParser.VectorSelector](t, `foo{job="myjob"}`, 28), - }, + Type: utils.AggregateSource, + Operation: "min", + Returns: promParser.ValueTypeVector, + Selector: mustParse[*promParser.VectorSelector](t, `foo{job="myjob"}`, 28), FixedLabels: true, ExcludeReason: map[string]utils.ExcludedLabel{ "": { @@ -821,12 +753,10 @@ func TestLabelsSource(t *testing.T) { expr: `avg(foo{job="myjob"}) by(job)`, output: []utils.Source{ { - Type: utils.AggregateSource, - Returns: promParser.ValueTypeVector, - Operation: "avg", - Selectors: []*promParser.VectorSelector{ - mustParse[*promParser.VectorSelector](t, `foo{job="myjob"}`, 4), - }, + Type: utils.AggregateSource, + Returns: promParser.ValueTypeVector, + Operation: "avg", + Selector: mustParse[*promParser.VectorSelector](t, `foo{job="myjob"}`, 4), GuaranteedLabels: []string{"job"}, IncludedLabels: []string{"job"}, FixedLabels: true, @@ -843,12 +773,10 @@ func TestLabelsSource(t *testing.T) { expr: `group(foo) by(job)`, output: []utils.Source{ { - Type: utils.AggregateSource, - Returns: promParser.ValueTypeVector, - Operation: "group", - Selectors: []*promParser.VectorSelector{ - mustParse[*promParser.VectorSelector](t, `foo`, 6), - }, + Type: utils.AggregateSource, + Returns: promParser.ValueTypeVector, + Operation: "group", + Selector: mustParse[*promParser.VectorSelector](t, `foo`, 6), IncludedLabels: []string{"job"}, FixedLabels: true, ExcludeReason: map[string]utils.ExcludedLabel{ @@ -864,12 +792,10 @@ func TestLabelsSource(t *testing.T) { expr: `stddev(rate(foo[5m]))`, output: []utils.Source{ { - Type: utils.AggregateSource, - Returns: promParser.ValueTypeVector, - Operation: "stddev", - Selectors: []*promParser.VectorSelector{ - mustParse[*promParser.VectorSelector](t, `foo`, 12), - }, + Type: utils.AggregateSource, + Returns: promParser.ValueTypeVector, + Operation: "stddev", + Selector: mustParse[*promParser.VectorSelector](t, `foo`, 12), FixedLabels: true, ExcludeReason: map[string]utils.ExcludedLabel{ "": { @@ -884,12 +810,10 @@ func TestLabelsSource(t *testing.T) { expr: `stdvar(rate(foo[5m]))`, output: []utils.Source{ { - Type: utils.AggregateSource, - Returns: promParser.ValueTypeVector, - Operation: "stdvar", - Selectors: []*promParser.VectorSelector{ - mustParse[*promParser.VectorSelector](t, `foo`, 12), - }, + Type: utils.AggregateSource, + Returns: promParser.ValueTypeVector, + Operation: "stdvar", + Selector: mustParse[*promParser.VectorSelector](t, `foo`, 12), FixedLabels: true, ExcludeReason: map[string]utils.ExcludedLabel{ "": { @@ -907,10 +831,8 @@ func TestLabelsSource(t *testing.T) { Type: utils.FuncSource, Returns: promParser.ValueTypeVector, Operation: "stddev_over_time", - Selectors: []*promParser.VectorSelector{ - mustParse[*promParser.VectorSelector](t, `foo`, 17), - }, - Call: mustParse[*promParser.Call](t, `stddev_over_time(foo[5m])`, 0), + Selector: mustParse[*promParser.VectorSelector](t, `foo`, 17), + Call: mustParse[*promParser.Call](t, `stddev_over_time(foo[5m])`, 0), }, }, }, @@ -921,10 +843,8 @@ func TestLabelsSource(t *testing.T) { Type: utils.FuncSource, Returns: promParser.ValueTypeVector, Operation: "stdvar_over_time", - Selectors: []*promParser.VectorSelector{ - mustParse[*promParser.VectorSelector](t, `foo`, 17), - }, - Call: mustParse[*promParser.Call](t, `stdvar_over_time(foo[5m])`, 0), + Selector: mustParse[*promParser.VectorSelector](t, `foo`, 17), + Call: mustParse[*promParser.Call](t, `stdvar_over_time(foo[5m])`, 0), }, }, }, @@ -932,12 +852,10 @@ func TestLabelsSource(t *testing.T) { expr: `quantile(0.9, rate(foo[5m]))`, output: []utils.Source{ { - Type: utils.AggregateSource, - Returns: promParser.ValueTypeVector, - Operation: "quantile", - Selectors: []*promParser.VectorSelector{ - mustParse[*promParser.VectorSelector](t, `foo`, 19), - }, + Type: utils.AggregateSource, + Returns: promParser.ValueTypeVector, + Operation: "quantile", + Selector: mustParse[*promParser.VectorSelector](t, `foo`, 19), FixedLabels: true, ExcludeReason: map[string]utils.ExcludedLabel{ "": { @@ -952,12 +870,10 @@ func TestLabelsSource(t *testing.T) { expr: `count_values("version", build_version)`, output: []utils.Source{ { - Type: utils.AggregateSource, - Returns: promParser.ValueTypeVector, - Operation: "count_values", - Selectors: []*promParser.VectorSelector{ - mustParse[*promParser.VectorSelector](t, `build_version`, 24), - }, + Type: utils.AggregateSource, + Returns: promParser.ValueTypeVector, + Operation: "count_values", + Selector: mustParse[*promParser.VectorSelector](t, `build_version`, 24), GuaranteedLabels: []string{"version"}, IncludedLabels: []string{"version"}, FixedLabels: true, @@ -974,12 +890,10 @@ func TestLabelsSource(t *testing.T) { expr: `count_values("version", build_version) without(job)`, output: []utils.Source{ { - Type: utils.AggregateSource, - Returns: promParser.ValueTypeVector, - Operation: "count_values", - Selectors: []*promParser.VectorSelector{ - mustParse[*promParser.VectorSelector](t, `build_version`, 24), - }, + Type: utils.AggregateSource, + Returns: promParser.ValueTypeVector, + Operation: "count_values", + Selector: mustParse[*promParser.VectorSelector](t, `build_version`, 24), IncludedLabels: []string{"version"}, GuaranteedLabels: []string{"version"}, ExcludedLabels: []string{"job"}, @@ -996,12 +910,10 @@ func TestLabelsSource(t *testing.T) { expr: `count_values("version", build_version{job="foo"}) without(job)`, output: []utils.Source{ { - Type: utils.AggregateSource, - Returns: promParser.ValueTypeVector, - Operation: "count_values", - Selectors: []*promParser.VectorSelector{ - mustParse[*promParser.VectorSelector](t, `build_version{job="foo"}`, 24), - }, + Type: utils.AggregateSource, + Returns: promParser.ValueTypeVector, + Operation: "count_values", + Selector: mustParse[*promParser.VectorSelector](t, `build_version{job="foo"}`, 24), IncludedLabels: []string{"version"}, GuaranteedLabels: []string{"version"}, ExcludedLabels: []string{"job"}, @@ -1018,12 +930,10 @@ func TestLabelsSource(t *testing.T) { expr: `count_values("version", build_version) by(job)`, output: []utils.Source{ { - Type: utils.AggregateSource, - Returns: promParser.ValueTypeVector, - Operation: "count_values", - Selectors: []*promParser.VectorSelector{ - mustParse[*promParser.VectorSelector](t, `build_version`, 24), - }, + Type: utils.AggregateSource, + Returns: promParser.ValueTypeVector, + Operation: "count_values", + Selector: mustParse[*promParser.VectorSelector](t, `build_version`, 24), GuaranteedLabels: []string{"version"}, IncludedLabels: []string{"job", "version"}, FixedLabels: true, @@ -1040,12 +950,10 @@ func TestLabelsSource(t *testing.T) { expr: `topk(10, foo{job="myjob"}) > 10`, output: []utils.Source{ { - Type: utils.AggregateSource, - Returns: promParser.ValueTypeVector, - Operation: "topk", - Selectors: []*promParser.VectorSelector{ - mustParse[*promParser.VectorSelector](t, `foo{job="myjob"}`, 9), - }, + Type: utils.AggregateSource, + Returns: promParser.ValueTypeVector, + Operation: "topk", + Selector: mustParse[*promParser.VectorSelector](t, `foo{job="myjob"}`, 9), GuaranteedLabels: []string{"job"}, IsConditional: true, }, @@ -1058,17 +966,13 @@ func TestLabelsSource(t *testing.T) { Type: utils.AggregateSource, Returns: promParser.ValueTypeVector, Operation: "topk", - Selectors: []*promParser.VectorSelector{ - mustParse[*promParser.VectorSelector](t, `foo`, 9), - }, + Selector: mustParse[*promParser.VectorSelector](t, `foo`, 9), }, { Type: utils.AggregateSource, Operation: "topk", Returns: promParser.ValueTypeVector, - Selectors: []*promParser.VectorSelector{ - mustParse[*promParser.VectorSelector](t, `bar`, 16), - }, + Selector: mustParse[*promParser.VectorSelector](t, `bar`, 16), }, }, }, @@ -1079,10 +983,8 @@ func TestLabelsSource(t *testing.T) { Type: utils.FuncSource, Returns: promParser.ValueTypeVector, Operation: "rate", - Selectors: []*promParser.VectorSelector{ - mustParse[*promParser.VectorSelector](t, `foo`, 5), - }, - Call: mustParse[*promParser.Call](t, `rate(foo[10m])`, 0), + Selector: mustParse[*promParser.VectorSelector](t, `foo`, 5), + Call: mustParse[*promParser.Call](t, `rate(foo[10m])`, 0), }, }, }, @@ -1090,12 +992,10 @@ func TestLabelsSource(t *testing.T) { expr: `sum(rate(foo[10m])) without(instance)`, output: []utils.Source{ { - Type: utils.AggregateSource, - Returns: promParser.ValueTypeVector, - Operation: "sum", - Selectors: []*promParser.VectorSelector{ - mustParse[*promParser.VectorSelector](t, `foo`, 9), - }, + Type: utils.AggregateSource, + Returns: promParser.ValueTypeVector, + Operation: "sum", + Selector: mustParse[*promParser.VectorSelector](t, `foo`, 9), ExcludedLabels: []string{"instance"}, ExcludeReason: map[string]utils.ExcludedLabel{ "instance": { @@ -1110,20 +1010,16 @@ func TestLabelsSource(t *testing.T) { expr: `foo{job="foo"} / bar`, output: []utils.Source{ { - Type: utils.SelectorSource, - Returns: promParser.ValueTypeVector, - Operation: promParser.CardOneToOne.String(), - Selectors: []*promParser.VectorSelector{ - mustParse[*promParser.VectorSelector](t, `foo{job="foo"}`, 0), - }, + Type: utils.SelectorSource, + Returns: promParser.ValueTypeVector, + Operation: promParser.CardOneToOne.String(), + Selector: mustParse[*promParser.VectorSelector](t, `foo{job="foo"}`, 0), GuaranteedLabels: []string{"job"}, Joins: []utils.Source{ { - Type: utils.SelectorSource, - Returns: promParser.ValueTypeVector, - Selectors: []*promParser.VectorSelector{ - mustParse[*promParser.VectorSelector](t, `bar`, 17), - }, + Type: utils.SelectorSource, + Returns: promParser.ValueTypeVector, + Selector: mustParse[*promParser.VectorSelector](t, `bar`, 17), }, }, }, @@ -1133,12 +1029,10 @@ func TestLabelsSource(t *testing.T) { expr: `foo{job="foo"} * on(instance) bar`, output: []utils.Source{ { - Type: utils.SelectorSource, - Returns: promParser.ValueTypeVector, - Operation: promParser.CardOneToOne.String(), - Selectors: []*promParser.VectorSelector{ - mustParse[*promParser.VectorSelector](t, `foo{job="foo"}`, 0), - }, + Type: utils.SelectorSource, + Returns: promParser.ValueTypeVector, + Operation: promParser.CardOneToOne.String(), + Selector: mustParse[*promParser.VectorSelector](t, `foo{job="foo"}`, 0), GuaranteedLabels: []string{"job"}, IncludedLabels: []string{"instance"}, FixedLabels: true, @@ -1150,11 +1044,9 @@ func TestLabelsSource(t *testing.T) { }, Joins: []utils.Source{ { - Type: utils.SelectorSource, - Returns: promParser.ValueTypeVector, - Selectors: []*promParser.VectorSelector{ - mustParse[*promParser.VectorSelector](t, `bar`, 30), - }, + Type: utils.SelectorSource, + Returns: promParser.ValueTypeVector, + Selector: mustParse[*promParser.VectorSelector](t, `bar`, 30), }, }, }, @@ -1164,21 +1056,17 @@ func TestLabelsSource(t *testing.T) { expr: `foo{job="foo"} * on(instance) group_left(bar) bar`, output: []utils.Source{ { - Type: utils.SelectorSource, - Returns: promParser.ValueTypeVector, - Operation: promParser.CardManyToOne.String(), - Selectors: []*promParser.VectorSelector{ - mustParse[*promParser.VectorSelector](t, `foo{job="foo"}`, 0), - }, + Type: utils.SelectorSource, + Returns: promParser.ValueTypeVector, + Operation: promParser.CardManyToOne.String(), + Selector: mustParse[*promParser.VectorSelector](t, `foo{job="foo"}`, 0), IncludedLabels: []string{"bar", "instance"}, GuaranteedLabels: []string{"job"}, Joins: []utils.Source{ { - Type: utils.SelectorSource, - Returns: promParser.ValueTypeVector, - Selectors: []*promParser.VectorSelector{ - mustParse[*promParser.VectorSelector](t, `bar`, 46), - }, + Type: utils.SelectorSource, + Returns: promParser.ValueTypeVector, + Selector: mustParse[*promParser.VectorSelector](t, `bar`, 46), }, }, }, @@ -1188,21 +1076,17 @@ func TestLabelsSource(t *testing.T) { expr: `foo{job="foo"} * on(instance) group_left(cluster) bar{cluster="bar", ignored="true"}`, output: []utils.Source{ { - Type: utils.SelectorSource, - Returns: promParser.ValueTypeVector, - Operation: promParser.CardManyToOne.String(), - Selectors: []*promParser.VectorSelector{ - mustParse[*promParser.VectorSelector](t, `foo{job="foo"}`, 0), - }, + Type: utils.SelectorSource, + Returns: promParser.ValueTypeVector, + Operation: promParser.CardManyToOne.String(), + Selector: mustParse[*promParser.VectorSelector](t, `foo{job="foo"}`, 0), IncludedLabels: []string{"cluster", "instance"}, GuaranteedLabels: []string{"job"}, Joins: []utils.Source{ { - Type: utils.SelectorSource, - Returns: promParser.ValueTypeVector, - Selectors: []*promParser.VectorSelector{ - mustParse[*promParser.VectorSelector](t, `bar{cluster="bar", ignored="true"}`, 50), - }, + Type: utils.SelectorSource, + Returns: promParser.ValueTypeVector, + Selector: mustParse[*promParser.VectorSelector](t, `bar{cluster="bar", ignored="true"}`, 50), GuaranteedLabels: []string{"cluster", "ignored"}, }, }, @@ -1213,21 +1097,17 @@ func TestLabelsSource(t *testing.T) { expr: `foo{job="foo", ignored="true"} * on(instance) group_right(job) bar{cluster="bar"}`, output: []utils.Source{ { - Type: utils.SelectorSource, - Returns: promParser.ValueTypeVector, - Operation: promParser.CardOneToMany.String(), - Selectors: []*promParser.VectorSelector{ - mustParse[*promParser.VectorSelector](t, `bar{cluster="bar"}`, 63), - }, + Type: utils.SelectorSource, + Returns: promParser.ValueTypeVector, + Operation: promParser.CardOneToMany.String(), + Selector: mustParse[*promParser.VectorSelector](t, `bar{cluster="bar"}`, 63), IncludedLabels: []string{"job", "instance"}, GuaranteedLabels: []string{"cluster"}, Joins: []utils.Source{ { - Type: utils.SelectorSource, - Returns: promParser.ValueTypeVector, - Selectors: []*promParser.VectorSelector{ - mustParse[*promParser.VectorSelector](t, `foo{job="foo", ignored="true"}`, 0), - }, + Type: utils.SelectorSource, + Returns: promParser.ValueTypeVector, + Selector: mustParse[*promParser.VectorSelector](t, `foo{job="foo", ignored="true"}`, 0), GuaranteedLabels: []string{"job", "ignored"}, }, }, @@ -1238,12 +1118,10 @@ func TestLabelsSource(t *testing.T) { expr: `count(foo / bar)`, output: []utils.Source{ { - Type: utils.AggregateSource, - Returns: promParser.ValueTypeVector, - Operation: "count", - Selectors: []*promParser.VectorSelector{ - mustParse[*promParser.VectorSelector](t, `foo`, 6), - }, + Type: utils.AggregateSource, + Returns: promParser.ValueTypeVector, + Operation: "count", + Selector: mustParse[*promParser.VectorSelector](t, `foo`, 6), FixedLabels: true, ExcludeReason: map[string]utils.ExcludedLabel{ "": { @@ -1253,11 +1131,9 @@ func TestLabelsSource(t *testing.T) { }, Joins: []utils.Source{ { - Type: utils.SelectorSource, - Returns: promParser.ValueTypeVector, - Selectors: []*promParser.VectorSelector{ - mustParse[*promParser.VectorSelector](t, `bar`, 12), - }, + Type: utils.SelectorSource, + Returns: promParser.ValueTypeVector, + Selector: mustParse[*promParser.VectorSelector](t, `bar`, 12), }, }, }, @@ -1267,12 +1143,10 @@ func TestLabelsSource(t *testing.T) { expr: `count(up{job="a"} / on () up{job="b"})`, output: []utils.Source{ { - Type: utils.AggregateSource, - Returns: promParser.ValueTypeVector, - Operation: "count", - Selectors: []*promParser.VectorSelector{ - mustParse[*promParser.VectorSelector](t, `up{job="a"}`, 6), - }, + Type: utils.AggregateSource, + Returns: promParser.ValueTypeVector, + Operation: "count", + Selector: mustParse[*promParser.VectorSelector](t, `up{job="a"}`, 6), FixedLabels: true, ExcludeReason: map[string]utils.ExcludedLabel{ "": { @@ -1282,11 +1156,9 @@ func TestLabelsSource(t *testing.T) { }, Joins: []utils.Source{ { - Type: utils.SelectorSource, - Returns: promParser.ValueTypeVector, - Selectors: []*promParser.VectorSelector{ - mustParse[*promParser.VectorSelector](t, `up{job="b"}`, 26), - }, + Type: utils.SelectorSource, + Returns: promParser.ValueTypeVector, + Selector: mustParse[*promParser.VectorSelector](t, `up{job="b"}`, 26), GuaranteedLabels: []string{"job"}, }, }, @@ -1297,12 +1169,10 @@ func TestLabelsSource(t *testing.T) { expr: `count(up{job="a"} / on (env) up{job="b"})`, output: []utils.Source{ { - Type: utils.AggregateSource, - Returns: promParser.ValueTypeVector, - Operation: "count", - Selectors: []*promParser.VectorSelector{ - mustParse[*promParser.VectorSelector](t, `up{job="a"}`, 6), - }, + Type: utils.AggregateSource, + Returns: promParser.ValueTypeVector, + Operation: "count", + Selector: mustParse[*promParser.VectorSelector](t, `up{job="a"}`, 6), FixedLabels: true, ExcludeReason: map[string]utils.ExcludedLabel{ "": { @@ -1312,11 +1182,9 @@ func TestLabelsSource(t *testing.T) { }, Joins: []utils.Source{ { - Type: utils.SelectorSource, - Returns: promParser.ValueTypeVector, - Selectors: []*promParser.VectorSelector{ - mustParse[*promParser.VectorSelector](t, `up{job="b"}`, 29), - }, + Type: utils.SelectorSource, + Returns: promParser.ValueTypeVector, + Selector: mustParse[*promParser.VectorSelector](t, `up{job="b"}`, 29), GuaranteedLabels: []string{"job"}, }, }, @@ -1327,20 +1195,16 @@ func TestLabelsSource(t *testing.T) { expr: `foo{job="foo", instance="1"} and bar`, output: []utils.Source{ { - Type: utils.SelectorSource, - Returns: promParser.ValueTypeVector, - Operation: promParser.CardManyToMany.String(), - Selectors: []*promParser.VectorSelector{ - mustParse[*promParser.VectorSelector](t, `foo{job="foo", instance="1"}`, 0), - }, + Type: utils.SelectorSource, + Returns: promParser.ValueTypeVector, + Operation: promParser.CardManyToMany.String(), + Selector: mustParse[*promParser.VectorSelector](t, `foo{job="foo", instance="1"}`, 0), GuaranteedLabels: []string{"job", "instance"}, Joins: []utils.Source{ { - Type: utils.SelectorSource, - Returns: promParser.ValueTypeVector, - Selectors: []*promParser.VectorSelector{ - mustParse[*promParser.VectorSelector](t, `bar`, 33), - }, + Type: utils.SelectorSource, + Returns: promParser.ValueTypeVector, + Selector: mustParse[*promParser.VectorSelector](t, `bar`, 33), }, }, }, @@ -1350,21 +1214,17 @@ func TestLabelsSource(t *testing.T) { expr: `foo{job="foo", instance="1"} and on(cluster) bar`, output: []utils.Source{ { - Type: utils.SelectorSource, - Returns: promParser.ValueTypeVector, - Operation: promParser.CardManyToMany.String(), - Selectors: []*promParser.VectorSelector{ - mustParse[*promParser.VectorSelector](t, `foo{job="foo", instance="1"}`, 0), - }, + Type: utils.SelectorSource, + Returns: promParser.ValueTypeVector, + Operation: promParser.CardManyToMany.String(), + Selector: mustParse[*promParser.VectorSelector](t, `foo{job="foo", instance="1"}`, 0), IncludedLabels: []string{"cluster"}, GuaranteedLabels: []string{"job", "instance"}, Joins: []utils.Source{ { - Type: utils.SelectorSource, - Returns: promParser.ValueTypeVector, - Selectors: []*promParser.VectorSelector{ - mustParse[*promParser.VectorSelector](t, `bar`, 45), - }, + Type: utils.SelectorSource, + Returns: promParser.ValueTypeVector, + Selector: mustParse[*promParser.VectorSelector](t, `bar`, 45), }, }, }, @@ -1377,9 +1237,7 @@ func TestLabelsSource(t *testing.T) { Type: utils.AggregateSource, Returns: promParser.ValueTypeVector, Operation: "topk", - Selectors: []*promParser.VectorSelector{ - mustParse[*promParser.VectorSelector](t, `foo`, 9), - }, + Selector: mustParse[*promParser.VectorSelector](t, `foo`, 9), }, }, }, @@ -1390,9 +1248,7 @@ func TestLabelsSource(t *testing.T) { Type: utils.AggregateSource, Returns: promParser.ValueTypeVector, Operation: "topk", - Selectors: []*promParser.VectorSelector{ - mustParse[*promParser.VectorSelector](t, `foo`, 9), - }, + Selector: mustParse[*promParser.VectorSelector](t, `foo`, 9), }, }, }, @@ -1403,9 +1259,7 @@ func TestLabelsSource(t *testing.T) { Type: utils.AggregateSource, Returns: promParser.ValueTypeVector, Operation: "topk", - Selectors: []*promParser.VectorSelector{ - mustParse[*promParser.VectorSelector](t, `foo`, 9), - }, + Selector: mustParse[*promParser.VectorSelector](t, `foo`, 9), }, }, }, @@ -1413,12 +1267,10 @@ func TestLabelsSource(t *testing.T) { expr: `bottomk(10, sum(rate(foo[5m])) without(job))`, output: []utils.Source{ { - Type: utils.AggregateSource, - Returns: promParser.ValueTypeVector, - Operation: "bottomk", - Selectors: []*promParser.VectorSelector{ - mustParse[*promParser.VectorSelector](t, `foo`, 21), - }, + Type: utils.AggregateSource, + Returns: promParser.ValueTypeVector, + Operation: "bottomk", + Selector: mustParse[*promParser.VectorSelector](t, `foo`, 21), ExcludedLabels: []string{"job"}, ExcludeReason: map[string]utils.ExcludedLabel{ "job": { @@ -1436,17 +1288,13 @@ func TestLabelsSource(t *testing.T) { Type: utils.SelectorSource, Returns: promParser.ValueTypeVector, Operation: promParser.CardManyToMany.String(), - Selectors: []*promParser.VectorSelector{ - mustParse[*promParser.VectorSelector](t, `foo`, 0), - }, + Selector: mustParse[*promParser.VectorSelector](t, `foo`, 0), }, { Type: utils.SelectorSource, Returns: promParser.ValueTypeVector, Operation: promParser.CardManyToMany.String(), - Selectors: []*promParser.VectorSelector{ - mustParse[*promParser.VectorSelector](t, `bar`, 7), - }, + Selector: mustParse[*promParser.VectorSelector](t, `bar`, 7), }, }, }, @@ -1457,25 +1305,19 @@ func TestLabelsSource(t *testing.T) { Type: utils.SelectorSource, Returns: promParser.ValueTypeVector, Operation: promParser.CardManyToMany.String(), - Selectors: []*promParser.VectorSelector{ - mustParse[*promParser.VectorSelector](t, `foo`, 0), - }, + Selector: mustParse[*promParser.VectorSelector](t, `foo`, 0), }, { Type: utils.SelectorSource, Returns: promParser.ValueTypeVector, Operation: promParser.CardManyToMany.String(), - Selectors: []*promParser.VectorSelector{ - mustParse[*promParser.VectorSelector](t, `bar`, 7), - }, + Selector: mustParse[*promParser.VectorSelector](t, `bar`, 7), }, { Type: utils.SelectorSource, Returns: promParser.ValueTypeVector, Operation: promParser.CardManyToMany.String(), - Selectors: []*promParser.VectorSelector{ - mustParse[*promParser.VectorSelector](t, `baz`, 14), - }, + Selector: mustParse[*promParser.VectorSelector](t, `baz`, 14), }, }, }, @@ -1486,25 +1328,19 @@ func TestLabelsSource(t *testing.T) { Type: utils.SelectorSource, Returns: promParser.ValueTypeVector, Operation: promParser.CardManyToMany.String(), - Selectors: []*promParser.VectorSelector{ - mustParse[*promParser.VectorSelector](t, `foo`, 1), - }, + Selector: mustParse[*promParser.VectorSelector](t, `foo`, 1), }, { Type: utils.SelectorSource, Returns: promParser.ValueTypeVector, Operation: promParser.CardManyToMany.String(), - Selectors: []*promParser.VectorSelector{ - mustParse[*promParser.VectorSelector](t, `bar`, 8), - }, + Selector: mustParse[*promParser.VectorSelector](t, `bar`, 8), }, { Type: utils.SelectorSource, Returns: promParser.ValueTypeVector, Operation: promParser.CardManyToMany.String(), - Selectors: []*promParser.VectorSelector{ - mustParse[*promParser.VectorSelector](t, `baz`, 16), - }, + Selector: mustParse[*promParser.VectorSelector](t, `baz`, 16), }, }, }, @@ -1515,16 +1351,12 @@ func TestLabelsSource(t *testing.T) { Type: utils.SelectorSource, Returns: promParser.ValueTypeVector, Operation: promParser.CardManyToMany.String(), - Selectors: []*promParser.VectorSelector{ - mustParse[*promParser.VectorSelector](t, `foo`, 0), - }, + Selector: mustParse[*promParser.VectorSelector](t, `foo`, 0), Unless: []utils.Source{ { - Type: utils.SelectorSource, - Returns: promParser.ValueTypeVector, - Selectors: []*promParser.VectorSelector{ - mustParse[*promParser.VectorSelector](t, `bar`, 11), - }, + Type: utils.SelectorSource, + Returns: promParser.ValueTypeVector, + Selector: mustParse[*promParser.VectorSelector](t, `bar`, 11), }, }, }, @@ -1537,16 +1369,12 @@ func TestLabelsSource(t *testing.T) { Type: utils.SelectorSource, Returns: promParser.ValueTypeVector, Operation: promParser.CardManyToMany.String(), - Selectors: []*promParser.VectorSelector{ - mustParse[*promParser.VectorSelector](t, `foo`, 0), - }, + Selector: mustParse[*promParser.VectorSelector](t, `foo`, 0), Unless: []utils.Source{ { - Type: utils.SelectorSource, - Returns: promParser.ValueTypeVector, - Selectors: []*promParser.VectorSelector{ - mustParse[*promParser.VectorSelector](t, `bar`, 11), - }, + Type: utils.SelectorSource, + Returns: promParser.ValueTypeVector, + Selector: mustParse[*promParser.VectorSelector](t, `bar`, 11), IsConditional: true, }, }, @@ -1560,23 +1388,17 @@ func TestLabelsSource(t *testing.T) { Type: utils.SelectorSource, Returns: promParser.ValueTypeVector, Operation: promParser.CardManyToMany.String(), - Selectors: []*promParser.VectorSelector{ - mustParse[*promParser.VectorSelector](t, `foo`, 0), - }, + Selector: mustParse[*promParser.VectorSelector](t, `foo`, 0), Unless: []utils.Source{ { - Type: utils.SelectorSource, - Returns: promParser.ValueTypeVector, - Selectors: []*promParser.VectorSelector{ - mustParse[*promParser.VectorSelector](t, `bar`, 11), - }, + Type: utils.SelectorSource, + Returns: promParser.ValueTypeVector, + Selector: mustParse[*promParser.VectorSelector](t, `bar`, 11), }, { - Type: utils.SelectorSource, - Returns: promParser.ValueTypeVector, - Selectors: []*promParser.VectorSelector{ - mustParse[*promParser.VectorSelector](t, `baz`, 22), - }, + Type: utils.SelectorSource, + Returns: promParser.ValueTypeVector, + Selector: mustParse[*promParser.VectorSelector](t, `baz`, 22), }, }, }, @@ -1586,12 +1408,10 @@ func TestLabelsSource(t *testing.T) { expr: `count(sum(up{job="foo", cluster="dev"}) by(job, cluster) == 0) without(job, cluster)`, output: []utils.Source{ { - Type: utils.AggregateSource, - Returns: promParser.ValueTypeVector, - Operation: "count", - Selectors: []*promParser.VectorSelector{ - mustParse[*promParser.VectorSelector](t, `up{job="foo", cluster="dev"}`, 10), - }, + Type: utils.AggregateSource, + Returns: promParser.ValueTypeVector, + Operation: "count", + Selector: mustParse[*promParser.VectorSelector](t, `up{job="foo", cluster="dev"}`, 10), ExcludedLabels: []string{"job", "cluster"}, // FIXME empty FixedLabels: true, ExcludeReason: map[string]utils.ExcludedLabel{ @@ -1638,10 +1458,8 @@ func TestLabelsSource(t *testing.T) { Type: utils.FuncSource, Returns: promParser.ValueTypeVector, Operation: "year", - Selectors: []*promParser.VectorSelector{ - mustParse[*promParser.VectorSelector](t, "foo", 5), - }, - Call: mustParse[*promParser.Call](t, `year(foo)`, 0), + Selector: mustParse[*promParser.VectorSelector](t, "foo", 5), + Call: mustParse[*promParser.Call](t, `year(foo)`, 0), }, }, }, @@ -1649,12 +1467,10 @@ func TestLabelsSource(t *testing.T) { expr: `label_join(up{job="api-server",src1="a",src2="b",src3="c"}, "foo", ",", "src1", "src2", "src3")`, output: []utils.Source{ { - Type: utils.FuncSource, - Returns: promParser.ValueTypeVector, - Operation: "label_join", - Selectors: []*promParser.VectorSelector{ - mustParse[*promParser.VectorSelector](t, `up{job="api-server",src1="a",src2="b",src3="c"}`, 11), - }, + Type: utils.FuncSource, + Returns: promParser.ValueTypeVector, + Operation: "label_join", + Selector: mustParse[*promParser.VectorSelector](t, `up{job="api-server",src1="a",src2="b",src3="c"}`, 11), GuaranteedLabels: []string{"job", "src1", "src2", "src3", "foo"}, Call: mustParse[*promParser.Call](t, `label_join(up{job="api-server",src1="a",src2="b",src3="c"}, "foo", ",", "src1", "src2", "src3")`, 0), }, @@ -1671,30 +1487,24 @@ and on(job) sum(foo:count) by(job) > 20`, output: []utils.Source{ { - Type: utils.AggregateSource, - Returns: promParser.ValueTypeVector, - Operation: "sum", - Selectors: []*promParser.VectorSelector{ - mustParse[*promParser.VectorSelector](t, `foo:sum`, 8), - }, + Type: utils.AggregateSource, + Returns: promParser.ValueTypeVector, + Operation: "sum", + Selector: mustParse[*promParser.VectorSelector](t, `foo:sum`, 8), IncludedLabels: []string{"notify", "job"}, ExcludeReason: map[string]utils.ExcludedLabel{}, IsConditional: false, // FIXME should be true Joins: []utils.Source{ { - Type: utils.SelectorSource, - Returns: promParser.ValueTypeVector, - Selectors: []*promParser.VectorSelector{ - mustParse[*promParser.VectorSelector](t, `job:notify`, 68), - }, + Type: utils.SelectorSource, + Returns: promParser.ValueTypeVector, + Selector: mustParse[*promParser.VectorSelector](t, `job:notify`, 68), }, { - Type: utils.AggregateSource, - Returns: promParser.ValueTypeVector, - Operation: "sum", - Selectors: []*promParser.VectorSelector{ - mustParse[*promParser.VectorSelector](t, `foo:count`, 97), - }, + Type: utils.AggregateSource, + Returns: promParser.ValueTypeVector, + Operation: "sum", + Selector: mustParse[*promParser.VectorSelector](t, `foo:count`, 97), IncludedLabels: []string{"job"}, FixedLabels: true, ExcludeReason: map[string]utils.ExcludedLabel{ @@ -1713,12 +1523,10 @@ sum(foo:count) by(job) > 20`, expr: `container_file_descriptors / on (instance, app_name) container_ulimits_soft{ulimit="max_open_files"}`, output: []utils.Source{ { - Type: utils.SelectorSource, - Returns: promParser.ValueTypeVector, - Operation: promParser.CardOneToOne.String(), - Selectors: []*promParser.VectorSelector{ - mustParse[*promParser.VectorSelector](t, `container_file_descriptors`, 0), - }, + Type: utils.SelectorSource, + Returns: promParser.ValueTypeVector, + Operation: promParser.CardOneToOne.String(), + Selector: mustParse[*promParser.VectorSelector](t, `container_file_descriptors`, 0), IncludedLabels: []string{"instance", "app_name"}, FixedLabels: true, ExcludeReason: map[string]utils.ExcludedLabel{ @@ -1729,11 +1537,9 @@ sum(foo:count) by(job) > 20`, }, Joins: []utils.Source{ { - Type: utils.SelectorSource, - Returns: promParser.ValueTypeVector, - Selectors: []*promParser.VectorSelector{ - mustParse[*promParser.VectorSelector](t, `container_ulimits_soft{ulimit="max_open_files"}`, 53), - }, + Type: utils.SelectorSource, + Returns: promParser.ValueTypeVector, + Selector: mustParse[*promParser.VectorSelector](t, `container_ulimits_soft{ulimit="max_open_files"}`, 53), GuaranteedLabels: []string{"ulimit"}, }, }, @@ -1744,20 +1550,16 @@ sum(foo:count) by(job) > 20`, expr: `container_file_descriptors / on (instance, app_name) group_left() container_ulimits_soft{ulimit="max_open_files"}`, output: []utils.Source{ { - Type: utils.SelectorSource, - Returns: promParser.ValueTypeVector, - Operation: promParser.CardManyToOne.String(), - Selectors: []*promParser.VectorSelector{ - mustParse[*promParser.VectorSelector](t, `container_file_descriptors`, 0), - }, + Type: utils.SelectorSource, + Returns: promParser.ValueTypeVector, + Operation: promParser.CardManyToOne.String(), + Selector: mustParse[*promParser.VectorSelector](t, `container_file_descriptors`, 0), IncludedLabels: []string{"instance", "app_name"}, Joins: []utils.Source{ { - Type: utils.SelectorSource, - Returns: promParser.ValueTypeVector, - Selectors: []*promParser.VectorSelector{ - mustParse[*promParser.VectorSelector](t, `container_ulimits_soft{ulimit="max_open_files"}`, 66), - }, + Type: utils.SelectorSource, + Returns: promParser.ValueTypeVector, + Selector: mustParse[*promParser.VectorSelector](t, `container_ulimits_soft{ulimit="max_open_files"}`, 66), GuaranteedLabels: []string{"ulimit"}, }, }, @@ -1768,12 +1570,10 @@ sum(foo:count) by(job) > 20`, expr: `absent(foo{job="bar"})`, output: []utils.Source{ { - Type: utils.FuncSource, - Returns: promParser.ValueTypeVector, - Operation: "absent", - Selectors: []*promParser.VectorSelector{ - mustParse[*promParser.VectorSelector](t, `foo{job="bar"}`, 7), - }, + Type: utils.FuncSource, + Returns: promParser.ValueTypeVector, + Operation: "absent", + Selector: mustParse[*promParser.VectorSelector](t, `foo{job="bar"}`, 7), IncludedLabels: []string{"job"}, GuaranteedLabels: []string{"job"}, FixedLabels: true, @@ -1791,12 +1591,10 @@ sum(foo:count) by(job) > 20`, expr: `absent(foo{job="bar", cluster!="dev", instance=~".+", env="prod"})`, output: []utils.Source{ { - Type: utils.FuncSource, - Returns: promParser.ValueTypeVector, - Operation: "absent", - Selectors: []*promParser.VectorSelector{ - mustParse[*promParser.VectorSelector](t, `foo{job="bar", cluster!="dev", instance=~".+", env="prod"}`, 7), - }, + Type: utils.FuncSource, + Returns: promParser.ValueTypeVector, + Operation: "absent", + Selector: mustParse[*promParser.VectorSelector](t, `foo{job="bar", cluster!="dev", instance=~".+", env="prod"}`, 7), IncludedLabels: []string{"job", "env"}, GuaranteedLabels: []string{"job", "env"}, FixedLabels: true, @@ -1814,12 +1612,10 @@ sum(foo:count) by(job) > 20`, expr: `absent(sum(foo) by(job, instance))`, output: []utils.Source{ { - Type: utils.FuncSource, - Returns: promParser.ValueTypeVector, - Operation: "absent", - Selectors: []*promParser.VectorSelector{ - mustParse[*promParser.VectorSelector](t, `foo`, 11), - }, + Type: utils.FuncSource, + Returns: promParser.ValueTypeVector, + Operation: "absent", + Selector: mustParse[*promParser.VectorSelector](t, `foo`, 11), FixedLabels: true, ExcludeReason: map[string]utils.ExcludedLabel{ "": { @@ -1835,12 +1631,10 @@ sum(foo:count) by(job) > 20`, expr: `absent(foo{job="prometheus", xxx="1"}) AND on(job) prometheus_build_info`, output: []utils.Source{ { - Type: utils.FuncSource, - Returns: promParser.ValueTypeVector, - Operation: "absent", - Selectors: []*promParser.VectorSelector{ - mustParse[*promParser.VectorSelector](t, `foo{job="prometheus", xxx="1"}`, 7), - }, + Type: utils.FuncSource, + Returns: promParser.ValueTypeVector, + Operation: "absent", + Selector: mustParse[*promParser.VectorSelector](t, `foo{job="prometheus", xxx="1"}`, 7), IncludedLabels: []string{"job", "xxx"}, GuaranteedLabels: []string{"job", "xxx"}, FixedLabels: true, @@ -1853,11 +1647,9 @@ sum(foo:count) by(job) > 20`, Call: mustParse[*promParser.Call](t, `absent(foo{job="prometheus", xxx="1"})`, 0), Joins: []utils.Source{ { - Type: utils.SelectorSource, - Returns: promParser.ValueTypeVector, - Selectors: []*promParser.VectorSelector{ - mustParse[*promParser.VectorSelector](t, "prometheus_build_info", 51), - }, + Type: utils.SelectorSource, + Returns: promParser.ValueTypeVector, + Selector: mustParse[*promParser.VectorSelector](t, "prometheus_build_info", 51), }, }, }, @@ -1867,12 +1659,10 @@ sum(foo:count) by(job) > 20`, expr: `1 + sum(foo) by(notjob)`, output: []utils.Source{ { - Type: utils.AggregateSource, - Returns: promParser.ValueTypeVector, - Operation: "sum", - Selectors: []*promParser.VectorSelector{ - mustParse[*promParser.VectorSelector](t, `foo`, 8), - }, + Type: utils.AggregateSource, + Returns: promParser.ValueTypeVector, + Operation: "sum", + Selector: mustParse[*promParser.VectorSelector](t, `foo`, 8), IncludedLabels: []string{"notjob"}, FixedLabels: true, ExcludeReason: map[string]utils.ExcludedLabel{ @@ -1888,12 +1678,10 @@ sum(foo:count) by(job) > 20`, expr: `count(node_exporter_build_info) by (instance, version) != ignoring(package,version) group_left(foo) count(deb_package_version) by (instance, version, package)`, output: []utils.Source{ { - Type: utils.AggregateSource, - Returns: promParser.ValueTypeVector, - Operation: "count", - Selectors: []*promParser.VectorSelector{ - mustParse[*promParser.VectorSelector](t, `node_exporter_build_info`, 6), - }, + Type: utils.AggregateSource, + Returns: promParser.ValueTypeVector, + Operation: "count", + Selector: mustParse[*promParser.VectorSelector](t, `node_exporter_build_info`, 6), IncludedLabels: []string{"instance", "version", "foo"}, // FIXME foo shouldn't be there because count() doesn't produce it FixedLabels: true, ExcludeReason: map[string]utils.ExcludedLabel{ @@ -1905,12 +1693,10 @@ sum(foo:count) by(job) > 20`, IsConditional: true, Joins: []utils.Source{ { - Type: utils.AggregateSource, - Returns: promParser.ValueTypeVector, - Operation: "count", - Selectors: []*promParser.VectorSelector{ - mustParse[*promParser.VectorSelector](t, "deb_package_version", 106), - }, + Type: utils.AggregateSource, + Returns: promParser.ValueTypeVector, + Operation: "count", + Selector: mustParse[*promParser.VectorSelector](t, "deb_package_version", 106), IncludedLabels: []string{"instance", "version", "package"}, FixedLabels: true, ExcludeReason: map[string]utils.ExcludedLabel{ @@ -1928,12 +1714,10 @@ sum(foo:count) by(job) > 20`, expr: `absent(foo) or absent(bar)`, output: []utils.Source{ { - Type: utils.FuncSource, - Returns: promParser.ValueTypeVector, - Operation: "absent", - Selectors: []*promParser.VectorSelector{ - mustParse[*promParser.VectorSelector](t, `foo`, 7), - }, + Type: utils.FuncSource, + Returns: promParser.ValueTypeVector, + Operation: "absent", + Selector: mustParse[*promParser.VectorSelector](t, `foo`, 7), FixedLabels: true, ExcludeReason: map[string]utils.ExcludedLabel{ "": { @@ -1944,12 +1728,10 @@ sum(foo:count) by(job) > 20`, Call: mustParse[*promParser.Call](t, `absent(foo)`, 0), }, { - Type: utils.FuncSource, - Returns: promParser.ValueTypeVector, - Operation: "absent", - Selectors: []*promParser.VectorSelector{ - mustParse[*promParser.VectorSelector](t, `bar`, 22), - }, + Type: utils.FuncSource, + Returns: promParser.ValueTypeVector, + Operation: "absent", + Selector: mustParse[*promParser.VectorSelector](t, `bar`, 22), FixedLabels: true, ExcludeReason: map[string]utils.ExcludedLabel{ "": { @@ -1965,12 +1747,10 @@ sum(foo:count) by(job) > 20`, expr: `absent_over_time(foo[5m]) or absent(bar)`, output: []utils.Source{ { - Type: utils.FuncSource, - Returns: promParser.ValueTypeVector, - Operation: "absent_over_time", - Selectors: []*promParser.VectorSelector{ - mustParse[*promParser.VectorSelector](t, `foo`, 17), - }, + Type: utils.FuncSource, + Returns: promParser.ValueTypeVector, + Operation: "absent_over_time", + Selector: mustParse[*promParser.VectorSelector](t, `foo`, 17), FixedLabels: true, ExcludeReason: map[string]utils.ExcludedLabel{ "": { @@ -1981,12 +1761,10 @@ sum(foo:count) by(job) > 20`, Call: mustParse[*promParser.Call](t, `absent_over_time(foo[5m])`, 0), }, { - Type: utils.FuncSource, - Returns: promParser.ValueTypeVector, - Operation: "absent", - Selectors: []*promParser.VectorSelector{ - mustParse[*promParser.VectorSelector](t, `bar`, 36), - }, + Type: utils.FuncSource, + Returns: promParser.ValueTypeVector, + Operation: "absent", + Selector: mustParse[*promParser.VectorSelector](t, `bar`, 36), FixedLabels: true, ExcludeReason: map[string]utils.ExcludedLabel{ "": { @@ -2002,12 +1780,10 @@ sum(foo:count) by(job) > 20`, expr: `bar * on() group_right(cluster, env) absent(foo{job="xxx"})`, output: []utils.Source{ { - Type: utils.FuncSource, - Returns: promParser.ValueTypeVector, - Operation: "absent", - Selectors: []*promParser.VectorSelector{ - mustParse[*promParser.VectorSelector](t, `foo{job="xxx"}`, 44), - }, + Type: utils.FuncSource, + Returns: promParser.ValueTypeVector, + Operation: "absent", + Selector: mustParse[*promParser.VectorSelector](t, `foo{job="xxx"}`, 44), IncludedLabels: []string{"job", "cluster", "env"}, GuaranteedLabels: []string{"job"}, FixedLabels: true, @@ -2020,11 +1796,9 @@ sum(foo:count) by(job) > 20`, Call: mustParse[*promParser.Call](t, `absent(foo{job="xxx"})`, 37), Joins: []utils.Source{ { - Type: utils.SelectorSource, - Returns: promParser.ValueTypeVector, - Selectors: []*promParser.VectorSelector{ - mustParse[*promParser.VectorSelector](t, "bar", 0), - }, + Type: utils.SelectorSource, + Returns: promParser.ValueTypeVector, + Selector: mustParse[*promParser.VectorSelector](t, "bar", 0), }, }, }, @@ -2034,12 +1808,10 @@ sum(foo:count) by(job) > 20`, expr: `bar * on() group_right() absent(foo{job="xxx"})`, output: []utils.Source{ { - Type: utils.FuncSource, - Returns: promParser.ValueTypeVector, - Operation: "absent", - Selectors: []*promParser.VectorSelector{ - mustParse[*promParser.VectorSelector](t, `foo{job="xxx"}`, 32), - }, + Type: utils.FuncSource, + Returns: promParser.ValueTypeVector, + Operation: "absent", + Selector: mustParse[*promParser.VectorSelector](t, `foo{job="xxx"}`, 32), IncludedLabels: []string{"job"}, GuaranteedLabels: []string{"job"}, FixedLabels: true, @@ -2052,11 +1824,9 @@ sum(foo:count) by(job) > 20`, Call: mustParse[*promParser.Call](t, `absent(foo{job="xxx"})`, 25), Joins: []utils.Source{ { - Type: utils.SelectorSource, - Returns: promParser.ValueTypeVector, - Selectors: []*promParser.VectorSelector{ - mustParse[*promParser.VectorSelector](t, "bar", 0), - }, + Type: utils.SelectorSource, + Returns: promParser.ValueTypeVector, + Selector: mustParse[*promParser.VectorSelector](t, "bar", 0), }, }, }, @@ -2125,12 +1895,10 @@ sum(foo:count) by(job) > 20`, expr: `sum_over_time(foo{job="myjob"}[5m])`, output: []utils.Source{ { - Type: utils.FuncSource, - Returns: promParser.ValueTypeVector, - Operation: "sum_over_time", - Selectors: []*promParser.VectorSelector{ - mustParse[*promParser.VectorSelector](t, `foo{job="myjob"}`, 14), - }, + Type: utils.FuncSource, + Returns: promParser.ValueTypeVector, + Operation: "sum_over_time", + Selector: mustParse[*promParser.VectorSelector](t, `foo{job="myjob"}`, 14), GuaranteedLabels: []string{"job"}, Call: mustParse[*promParser.Call](t, `sum_over_time(foo{job="myjob"}[5m])`, 0), }, @@ -2159,12 +1927,10 @@ sum(foo:count) by(job) > 20`, expr: `days_in_month(foo{job="foo"})`, output: []utils.Source{ { - Type: utils.FuncSource, - Returns: promParser.ValueTypeVector, - Operation: "days_in_month", - Selectors: []*promParser.VectorSelector{ - mustParse[*promParser.VectorSelector](t, `foo{job="foo"}`, 14), - }, + Type: utils.FuncSource, + Returns: promParser.ValueTypeVector, + Operation: "days_in_month", + Selector: mustParse[*promParser.VectorSelector](t, `foo{job="foo"}`, 14), GuaranteedLabels: []string{"job"}, Call: mustParse[*promParser.Call](t, `days_in_month(foo{job="foo"})`, 0), }, @@ -2174,12 +1940,10 @@ sum(foo:count) by(job) > 20`, expr: `label_replace(up{job="api-server",service="a:c"}, "foo", "$1", "service", "(.*):.*")`, output: []utils.Source{ { - Type: utils.FuncSource, - Returns: promParser.ValueTypeVector, - Operation: "label_replace", - Selectors: []*promParser.VectorSelector{ - mustParse[*promParser.VectorSelector](t, `up{job="api-server",service="a:c"}`, 14), - }, + Type: utils.FuncSource, + Returns: promParser.ValueTypeVector, + Operation: "label_replace", + Selector: mustParse[*promParser.VectorSelector](t, `up{job="api-server",service="a:c"}`, 14), GuaranteedLabels: []string{"job", "service", "foo"}, Call: mustParse[*promParser.Call](t, `label_replace(up{job="api-server",service="a:c"}, "foo", "$1", "service", "(.*):.*")`, 0), }, @@ -2189,12 +1953,10 @@ sum(foo:count) by(job) > 20`, expr: `label_replace(sum by (pod) (pod_status) > 0, "cluster", "$1", "pod", "(.*)")`, output: []utils.Source{ { - Type: utils.FuncSource, - Returns: promParser.ValueTypeVector, - Operation: "label_replace", - Selectors: []*promParser.VectorSelector{ - mustParse[*promParser.VectorSelector](t, `pod_status`, 28), - }, + Type: utils.FuncSource, + Returns: promParser.ValueTypeVector, + Operation: "label_replace", + Selector: mustParse[*promParser.VectorSelector](t, `pod_status`, 28), FixedLabels: true, IsConditional: true, IncludedLabels: []string{"pod"}, @@ -2213,11 +1975,9 @@ sum(foo:count) by(job) > 20`, expr: `(time() - my_metric) > 5*3600`, output: []utils.Source{ { - Type: utils.SelectorSource, - Returns: promParser.ValueTypeVector, - Selectors: []*promParser.VectorSelector{ - mustParse[*promParser.VectorSelector](t, "my_metric", 10), - }, + Type: utils.SelectorSource, + Returns: promParser.ValueTypeVector, + Selector: mustParse[*promParser.VectorSelector](t, "my_metric", 10), IsConditional: true, }, }, @@ -2226,12 +1986,10 @@ sum(foo:count) by(job) > 20`, expr: `up{instance="a", job="prometheus"} * ignoring(job) up{instance="a", job="pint"}`, output: []utils.Source{ { - Type: utils.SelectorSource, - Returns: promParser.ValueTypeVector, - Operation: promParser.CardOneToOne.String(), - Selectors: []*promParser.VectorSelector{ - mustParse[*promParser.VectorSelector](t, `up{instance="a", job="prometheus"}`, 0), - }, + Type: utils.SelectorSource, + Returns: promParser.ValueTypeVector, + Operation: promParser.CardOneToOne.String(), + Selector: mustParse[*promParser.VectorSelector](t, `up{instance="a", job="prometheus"}`, 0), GuaranteedLabels: []string{"instance"}, ExcludedLabels: []string{"job"}, ExcludeReason: map[string]utils.ExcludedLabel{ @@ -2242,11 +2000,9 @@ sum(foo:count) by(job) > 20`, }, Joins: []utils.Source{ { - Type: utils.SelectorSource, - Returns: promParser.ValueTypeVector, - Selectors: []*promParser.VectorSelector{ - mustParse[*promParser.VectorSelector](t, `up{instance="a", job="pint"}`, 51), - }, + Type: utils.SelectorSource, + Returns: promParser.ValueTypeVector, + Selector: mustParse[*promParser.VectorSelector](t, `up{instance="a", job="pint"}`, 51), GuaranteedLabels: []string{"instance", "job"}, }, }, @@ -2264,12 +2020,10 @@ or avg without(router, colo_id, instance) (router_anycast_prefix_enabled{cidr_us `, output: []utils.Source{ { - Type: utils.AggregateSource, - Returns: promParser.ValueTypeVector, - Operation: "avg", - Selectors: []*promParser.VectorSelector{ - mustParse[*promParser.VectorSelector](t, `router_anycast_prefix_enabled{cidr_use_case!~".*offpeak.*"}`, 41), - }, + Type: utils.AggregateSource, + Returns: promParser.ValueTypeVector, + Operation: "avg", + Selector: mustParse[*promParser.VectorSelector](t, `router_anycast_prefix_enabled{cidr_use_case!~".*offpeak.*"}`, 41), ExcludedLabels: []string{"router", "colo_id", "instance"}, ExcludeReason: map[string]utils.ExcludedLabel{ "router": { @@ -2288,12 +2042,10 @@ or avg without(router, colo_id, instance) (router_anycast_prefix_enabled{cidr_us IsConditional: true, }, { - Type: utils.AggregateSource, - Returns: promParser.ValueTypeVector, - Operation: "sum", - Selectors: []*promParser.VectorSelector{ - mustParse[*promParser.VectorSelector](t, `router_anycast_prefix_enabled{cidr_use_case=~".*tier1.*"}`, 155), - }, + Type: utils.AggregateSource, + Returns: promParser.ValueTypeVector, + Operation: "sum", + Selector: mustParse[*promParser.VectorSelector](t, `router_anycast_prefix_enabled{cidr_use_case=~".*tier1.*"}`, 155), GuaranteedLabels: []string{"cidr_use_case"}, ExcludedLabels: []string{"router", "colo_id", "instance"}, FixedLabels: true, @@ -2318,12 +2070,10 @@ or avg without(router, colo_id, instance) (router_anycast_prefix_enabled{cidr_us IsConditional: true, Joins: []utils.Source{ { - Type: utils.AggregateSource, - Returns: promParser.ValueTypeVector, - Operation: "count", - Selectors: []*promParser.VectorSelector{ - mustParse[*promParser.VectorSelector](t, `colo_router_tier:disabled_pops:max{tier="1",router=~"edge.*"}`, 227), - }, + Type: utils.AggregateSource, + Returns: promParser.ValueTypeVector, + Operation: "count", + Selector: mustParse[*promParser.VectorSelector](t, `colo_router_tier:disabled_pops:max{tier="1",router=~"edge.*"}`, 227), FixedLabels: true, ExcludeReason: map[string]utils.ExcludedLabel{ "": { @@ -2335,12 +2085,10 @@ or avg without(router, colo_id, instance) (router_anycast_prefix_enabled{cidr_us }, }, { - Type: utils.AggregateSource, - Returns: promParser.ValueTypeVector, - Operation: "avg", - Selectors: []*promParser.VectorSelector{ - mustParse[*promParser.VectorSelector](t, `router_anycast_prefix_enabled{cidr_use_case=~".*regional.*"}`, 343), - }, + Type: utils.AggregateSource, + Returns: promParser.ValueTypeVector, + Operation: "avg", + Selector: mustParse[*promParser.VectorSelector](t, `router_anycast_prefix_enabled{cidr_use_case=~".*regional.*"}`, 343), GuaranteedLabels: []string{"cidr_use_case"}, ExcludedLabels: []string{"router", "colo_id", "instance"}, ExcludeReason: map[string]utils.ExcludedLabel{ @@ -2365,12 +2113,10 @@ or avg without(router, colo_id, instance) (router_anycast_prefix_enabled{cidr_us expr: `label_replace(sum(foo) without(instance), "instance", "none", "", "")`, output: []utils.Source{ { - Type: utils.FuncSource, - Returns: promParser.ValueTypeVector, - Operation: "label_replace", - Selectors: []*promParser.VectorSelector{ - mustParse[*promParser.VectorSelector](t, `foo`, 18), - }, + Type: utils.FuncSource, + Returns: promParser.ValueTypeVector, + Operation: "label_replace", + Selector: mustParse[*promParser.VectorSelector](t, `foo`, 18), GuaranteedLabels: []string{"instance"}, ExcludeReason: map[string]utils.ExcludedLabel{}, Call: mustParse[*promParser.Call](t, `label_replace(sum(foo) without(instance), "instance", "none", "", "")`, 0), @@ -2386,12 +2132,10 @@ sum by (region, target, colo_name) ( ) == 0`, output: []utils.Source{ { - Type: utils.AggregateSource, - Returns: promParser.ValueTypeVector, - Operation: "sum", - Selectors: []*promParser.VectorSelector{ - mustParse[*promParser.VectorSelector](t, `probe_success{job="abc"}`, 56), - }, + Type: utils.AggregateSource, + Returns: promParser.ValueTypeVector, + Operation: "sum", + Selector: mustParse[*promParser.VectorSelector](t, `probe_success{job="abc"}`, 56), IncludedLabels: []string{"region", "target", "colo_name"}, FixedLabels: true, ExcludeReason: map[string]utils.ExcludedLabel{ @@ -2442,10 +2186,8 @@ sum by (region, target, colo_name) ( Type: utils.SelectorSource, Operation: promParser.CardManyToMany.String(), Returns: promParser.ValueTypeVector, - Selectors: []*promParser.VectorSelector{ - mustParse[*promParser.VectorSelector](t, "foo", 13), - }, - IsDead: true, + Selector: mustParse[*promParser.VectorSelector](t, "foo", 13), + IsDead: true, }, }, }, @@ -2475,12 +2217,10 @@ sum by (region, target, colo_name) ( expr: `sum(foo or vector(0)) > 0`, output: []utils.Source{ { - Type: utils.AggregateSource, - Returns: promParser.ValueTypeVector, - Operation: "sum", - Selectors: []*promParser.VectorSelector{ - mustParse[*promParser.VectorSelector](t, `foo`, 4), - }, + Type: utils.AggregateSource, + Returns: promParser.ValueTypeVector, + Operation: "sum", + Selector: mustParse[*promParser.VectorSelector](t, `foo`, 4), FixedLabels: true, ExcludeReason: map[string]utils.ExcludedLabel{ "": { @@ -2512,12 +2252,10 @@ sum by (region, target, colo_name) ( expr: `(sum(foo or vector(1)) > 0) == 2`, output: []utils.Source{ { - Type: utils.AggregateSource, - Returns: promParser.ValueTypeVector, - Operation: "sum", - Selectors: []*promParser.VectorSelector{ - mustParse[*promParser.VectorSelector](t, `foo`, 5), - }, + Type: utils.AggregateSource, + Returns: promParser.ValueTypeVector, + Operation: "sum", + Selector: mustParse[*promParser.VectorSelector](t, `foo`, 5), FixedLabels: true, ExcludeReason: map[string]utils.ExcludedLabel{ "": { @@ -2549,12 +2287,10 @@ sum by (region, target, colo_name) ( expr: `(sum(foo or vector(1)) > 0) != 2`, output: []utils.Source{ { - Type: utils.AggregateSource, - Returns: promParser.ValueTypeVector, - Operation: "sum", - Selectors: []*promParser.VectorSelector{ - mustParse[*promParser.VectorSelector](t, `foo`, 5), - }, + Type: utils.AggregateSource, + Returns: promParser.ValueTypeVector, + Operation: "sum", + Selector: mustParse[*promParser.VectorSelector](t, `foo`, 5), FixedLabels: true, ExcludeReason: map[string]utils.ExcludedLabel{ "": { @@ -2585,12 +2321,10 @@ sum by (region, target, colo_name) ( expr: `(sum(foo or vector(2)) > 0) != 2`, output: []utils.Source{ { - Type: utils.AggregateSource, - Returns: promParser.ValueTypeVector, - Operation: "sum", - Selectors: []*promParser.VectorSelector{ - mustParse[*promParser.VectorSelector](t, `foo`, 5), - }, + Type: utils.AggregateSource, + Returns: promParser.ValueTypeVector, + Operation: "sum", + Selector: mustParse[*promParser.VectorSelector](t, `foo`, 5), FixedLabels: true, ExcludeReason: map[string]utils.ExcludedLabel{ "": { @@ -2625,12 +2359,10 @@ or ((bob > 10) or sum(foo) or vector(1))`, output: []utils.Source{ { - Type: utils.AggregateSource, - Returns: promParser.ValueTypeVector, - Operation: "sum", - Selectors: []*promParser.VectorSelector{ - mustParse[*promParser.VectorSelector](t, `sometimes{foo!="bar"}`, 6), - }, + Type: utils.AggregateSource, + Returns: promParser.ValueTypeVector, + Operation: "sum", + Selector: mustParse[*promParser.VectorSelector](t, `sometimes{foo!="bar"}`, 6), FixedLabels: true, ExcludeReason: map[string]utils.ExcludedLabel{ "": { @@ -2654,21 +2386,17 @@ or }, }, { - Type: utils.SelectorSource, - Operation: promParser.CardManyToMany.String(), - Returns: promParser.ValueTypeVector, - Selectors: []*promParser.VectorSelector{ - mustParse[*promParser.VectorSelector](t, `bob`, 48), - }, + Type: utils.SelectorSource, + Operation: promParser.CardManyToMany.String(), + Returns: promParser.ValueTypeVector, + Selector: mustParse[*promParser.VectorSelector](t, `bob`, 48), IsConditional: true, }, { - Type: utils.AggregateSource, - Returns: promParser.ValueTypeVector, - Operation: "sum", - Selectors: []*promParser.VectorSelector{ - mustParse[*promParser.VectorSelector](t, `foo`, 65), - }, + Type: utils.AggregateSource, + Returns: promParser.ValueTypeVector, + Operation: "sum", + Selector: mustParse[*promParser.VectorSelector](t, `foo`, 65), FixedLabels: true, ExcludeReason: map[string]utils.ExcludedLabel{ "": { @@ -2707,12 +2435,10 @@ or )`, output: []utils.Source{ { - Type: utils.AggregateSource, - Returns: promParser.ValueTypeVector, - Operation: "sum", - Selectors: []*promParser.VectorSelector{ - mustParse[*promParser.VectorSelector](t, `sometimes{foo!="bar"}`, 8), - }, + Type: utils.AggregateSource, + Returns: promParser.ValueTypeVector, + Operation: "sum", + Selector: mustParse[*promParser.VectorSelector](t, `sometimes{foo!="bar"}`, 8), FixedLabels: true, ExcludeReason: map[string]utils.ExcludedLabel{ "": { @@ -2722,21 +2448,17 @@ or }, Joins: []utils.Source{ { - Type: utils.SelectorSource, - Operation: promParser.CardManyToMany.String(), - Returns: promParser.ValueTypeVector, - Selectors: []*promParser.VectorSelector{ - mustParse[*promParser.VectorSelector](t, `bob`, 57), - }, + Type: utils.SelectorSource, + Operation: promParser.CardManyToMany.String(), + Returns: promParser.ValueTypeVector, + Selector: mustParse[*promParser.VectorSelector](t, `bob`, 57), IsConditional: true, }, { - Type: utils.AggregateSource, - Returns: promParser.ValueTypeVector, - Operation: "sum", - Selectors: []*promParser.VectorSelector{ - mustParse[*promParser.VectorSelector](t, `bar`, 74), - }, + Type: utils.AggregateSource, + Returns: promParser.ValueTypeVector, + Operation: "sum", + Selector: mustParse[*promParser.VectorSelector](t, `bar`, 74), FixedLabels: true, ExcludeReason: map[string]utils.ExcludedLabel{ "": { @@ -2746,12 +2468,10 @@ or }, }, { - Type: utils.SelectorSource, - Operation: promParser.CardManyToMany.String(), - Returns: promParser.ValueTypeVector, - Selectors: []*promParser.VectorSelector{ - mustParse[*promParser.VectorSelector](t, `notfound`, 85), - }, + Type: utils.SelectorSource, + Operation: promParser.CardManyToMany.String(), + Returns: promParser.ValueTypeVector, + Selector: mustParse[*promParser.VectorSelector](t, `notfound`, 85), IsConditional: true, }, }, @@ -2772,21 +2492,17 @@ or }, Joins: []utils.Source{ { - Type: utils.SelectorSource, - Operation: promParser.CardManyToMany.String(), - Returns: promParser.ValueTypeVector, - Selectors: []*promParser.VectorSelector{ - mustParse[*promParser.VectorSelector](t, `bob`, 57), - }, + Type: utils.SelectorSource, + Operation: promParser.CardManyToMany.String(), + Returns: promParser.ValueTypeVector, + Selector: mustParse[*promParser.VectorSelector](t, `bob`, 57), IsConditional: true, }, { - Type: utils.AggregateSource, - Returns: promParser.ValueTypeVector, - Operation: "sum", - Selectors: []*promParser.VectorSelector{ - mustParse[*promParser.VectorSelector](t, `bar`, 74), - }, + Type: utils.AggregateSource, + Returns: promParser.ValueTypeVector, + Operation: "sum", + Selector: mustParse[*promParser.VectorSelector](t, `bar`, 74), FixedLabels: true, ExcludeReason: map[string]utils.ExcludedLabel{ "": { @@ -2796,12 +2512,10 @@ or }, }, { - Type: utils.SelectorSource, - Operation: promParser.CardManyToMany.String(), - Returns: promParser.ValueTypeVector, - Selectors: []*promParser.VectorSelector{ - mustParse[*promParser.VectorSelector](t, `notfound`, 85), - }, + Type: utils.SelectorSource, + Operation: promParser.CardManyToMany.String(), + Returns: promParser.ValueTypeVector, + Selector: mustParse[*promParser.VectorSelector](t, `notfound`, 85), IsConditional: true, }, }, @@ -2812,11 +2526,9 @@ or expr: "foo offset 5m > 5", output: []utils.Source{ { - Type: utils.SelectorSource, - Returns: promParser.ValueTypeVector, - Selectors: []*promParser.VectorSelector{ - mustParse[*promParser.VectorSelector](t, "foo offset 5m", 0), - }, + Type: utils.SelectorSource, + Returns: promParser.ValueTypeVector, + Selector: mustParse[*promParser.VectorSelector](t, "foo offset 5m", 0), IsConditional: true, }, },