Fix Grouping String function and usage so it prints "without ()" (#9515)

**What this PR does / why we need it**:

The changes rangemapper made to LogQL expressions created invalid LogQL.
It added a `without` clause instead of `without ()`. This PR changes the
String function of the Grouping struct. This is then used in the
rangemapper.

This caused the following panic:

```
panic: error cloning query: count without (rate({namespace="apps"}[15s])): parse error at line 1, col 16: syntax error: unexpected RATE, expecting IDENTIFIER or )
```

**Checklist**
- [x] Reviewed the
[`CONTRIBUTING.md`](https://github.com/grafana/loki/blob/main/CONTRIBUTING.md)
guide (**required**)
- [ ] Documentation added
- [x] Tests updated
- [x] `CHANGELOG.md` updated
- [ ] Changes that require user attention or interaction to upgrade are
documented in `docs/sources/upgrading/_index.md`
- [ ] For Helm chart changes bump the Helm chart version in
`production/helm/loki/Chart.yaml` and update
`production/helm/loki/CHANGELOG.md` and
`production/helm/loki/README.md`. [Example
PR](d10549e3ec)

---------

Signed-off-by: Michel Hollands <michel.hollands@grafana.com>
pull/9516/head
Michel Hollands 2 years ago committed by GitHub
parent 89b786fe51
commit 478510a1bb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 1
      CHANGELOG.md
  2. 2
      pkg/logql/rangemapper.go
  3. 206
      pkg/logql/rangemapper_test.go
  4. 10
      pkg/logql/syntax/ast.go
  5. 38
      pkg/logql/syntax/ast_test.go
  6. 4
      pkg/logql/syntax/parser_test.go

@ -6,6 +6,7 @@
##### Enhancements
* [9515](https://github.com/grafana/loki/pull/9515) **MichelHollands**: Fix String() on vector aggregation LogQL expressions that contain `without ()`.
* [8067](https://github.com/grafana/loki/pull/8067) **DylanGuedes**: Distributor: Add auto-forget unhealthy members support.
* [9175](https://github.com/grafana/loki/pull/9175) **MichelHollands**: Ingester: update the `prepare_shutdown` endpoint so it supports GET and DELETE and stores the state on disk.
* [8953](https://github.com/grafana/loki/pull/8953) **dannykopping**: Querier: block queries by hash.

@ -230,6 +230,7 @@ func (m RangeMapper) sumOverFullRange(expr *syntax.RangeAggregationExpr, overrid
Left: m.mapConcatSampleExpr(downstreamExpr, rangeInterval, recorder),
Grouping: &syntax.Grouping{
Without: true,
Groups: []string{},
},
Operation: syntax.OpTypeSum,
},
@ -252,6 +253,7 @@ func (m RangeMapper) vectorAggrWithRangeDownstreams(expr *syntax.RangeAggregatio
if expr.Grouping == nil {
grouping = &syntax.Grouping{
Without: true,
Groups: []string{},
}
}
var downstream syntax.SampleExpr = expr

@ -19,14 +19,14 @@ func Test_SplitRangeInterval(t *testing.T) {
}{
{
`bytes_over_time({app="foo"}[3s])`,
`sum without(
`sum without () (
downstream<bytes_over_time({app="foo"}[1s] offset 2s), shard=<nil>>
++ downstream<bytes_over_time({app="foo"}[2s]), shard=<nil>>
)`,
},
{
`count_over_time({app="foo"}[5s])`,
`sum without(
`sum without () (
downstream<count_over_time({app="foo"}[1s] offset 4s), shard=<nil>>
++ downstream<count_over_time({app="foo"}[2s] offset 2s), shard=<nil>>
++ downstream<count_over_time({app="foo"}[2s]), shard=<nil>>
@ -34,7 +34,7 @@ func Test_SplitRangeInterval(t *testing.T) {
},
{
`rate({app="foo"}[4s] offset 1m)`,
`(sum without(
`(sum without () (
downstream<count_over_time({app="foo"}[2s] offset 1m2s), shard=<nil>>
++ downstream<count_over_time({app="foo"}[2s] offset 1m0s), shard=<nil>>
) / 4)`,
@ -62,7 +62,7 @@ func Test_SplitRangeVectorMapping(t *testing.T) {
// Range vector aggregators
{
`bytes_over_time({app="foo"}[3m])`,
`sum without(
`sum without () (
downstream<bytes_over_time({app="foo"}[1m] offset 2m0s), shard=<nil>>
++ downstream<bytes_over_time({app="foo"}[1m] offset 1m0s), shard=<nil>>
++ downstream<bytes_over_time({app="foo"}[1m]), shard=<nil>>
@ -70,7 +70,7 @@ func Test_SplitRangeVectorMapping(t *testing.T) {
},
{
`count_over_time({app="foo"}[3m])`,
`sum without(
`sum without () (
downstream<count_over_time({app="foo"}[1m] offset 2m0s), shard=<nil>>
++ downstream<count_over_time({app="foo"}[1m] offset 1m0s), shard=<nil>>
++ downstream<count_over_time({app="foo"}[1m]), shard=<nil>>
@ -78,7 +78,7 @@ func Test_SplitRangeVectorMapping(t *testing.T) {
},
{
`sum_over_time({app="foo"} | unwrap bar [3m])`,
`sum without(
`sum without () (
downstream<sum_over_time({app="foo"} | unwrap bar [1m] offset 2m0s), shard=<nil>>
++ downstream<sum_over_time({app="foo"} | unwrap bar [1m] offset 1m0s), shard=<nil>>
++ downstream<sum_over_time({app="foo"} | unwrap bar [1m]), shard=<nil>>
@ -86,7 +86,7 @@ func Test_SplitRangeVectorMapping(t *testing.T) {
},
{
`max_over_time({app="foo"} | unwrap bar [3m])`,
`max without(
`max without () (
downstream<max_over_time({app="foo"} | unwrap bar [1m] offset 2m0s), shard=<nil>>
++ downstream<max_over_time({app="foo"} | unwrap bar [1m] offset 1m0s), shard=<nil>>
++ downstream<max_over_time({app="foo"} | unwrap bar [1m]), shard=<nil>>
@ -110,7 +110,7 @@ func Test_SplitRangeVectorMapping(t *testing.T) {
},
{
`min_over_time({app="foo"} | unwrap bar [3m])`,
`min without(
`min without () (
downstream<min_over_time({app="foo"} | unwrap bar [1m] offset 2m0s), shard=<nil>>
++ downstream<min_over_time({app="foo"} | unwrap bar [1m] offset 1m0s), shard=<nil>>
++ downstream<min_over_time({app="foo"} | unwrap bar [1m]), shard=<nil>>
@ -126,7 +126,7 @@ func Test_SplitRangeVectorMapping(t *testing.T) {
},
{
`rate({app="foo"}[3m])`,
`(sum without(
`(sum without () (
downstream<count_over_time({app="foo"}[1m] offset 2m0s), shard=<nil>>
++ downstream<count_over_time({app="foo"}[1m] offset 1m0s), shard=<nil>>
++ downstream<count_over_time({app="foo"}[1m]), shard=<nil>>
@ -134,7 +134,7 @@ func Test_SplitRangeVectorMapping(t *testing.T) {
},
{
`rate({app="foo"} | unwrap bar[3m])`,
`(sum without(
`(sum without () (
downstream<sum_over_time({app="foo"} | unwrap bar [1m] offset 2m0s), shard=<nil>>
++ downstream<sum_over_time({app="foo"} | unwrap bar [1m] offset 1m0s), shard=<nil>>
++ downstream<sum_over_time({app="foo"} | unwrap bar [1m]), shard=<nil>>
@ -142,7 +142,7 @@ func Test_SplitRangeVectorMapping(t *testing.T) {
},
{
`bytes_rate({app="foo"}[3m])`,
`(sum without(
`(sum without () (
downstream<bytes_over_time({app="foo"}[1m] offset 2m0s), shard=<nil>>
++ downstream<bytes_over_time({app="foo"}[1m] offset 1m0s), shard=<nil>>
++ downstream<bytes_over_time({app="foo"}[1m]), shard=<nil>>
@ -153,7 +153,7 @@ func Test_SplitRangeVectorMapping(t *testing.T) {
{
`sum(bytes_over_time({app="foo"}[3m]))`,
`sum(
sum without (
sum without () (
downstream<sum(bytes_over_time({app="foo"}[1m] offset 2m0s)), shard=<nil>>
++ downstream<sum(bytes_over_time({app="foo"}[1m] offset 1m0s)), shard=<nil>>
++ downstream<sum(bytes_over_time({app="foo"}[1m])), shard=<nil>>
@ -163,7 +163,7 @@ func Test_SplitRangeVectorMapping(t *testing.T) {
{
`sum(count_over_time({app="foo"}[3m]))`,
`sum(
sum without (
sum without () (
downstream<sum(count_over_time({app="foo"}[1m] offset 2m0s)), shard=<nil>>
++ downstream<sum(count_over_time({app="foo"}[1m] offset 1m0s)), shard=<nil>>
++ downstream<sum(count_over_time({app="foo"}[1m])), shard=<nil>>
@ -173,7 +173,7 @@ func Test_SplitRangeVectorMapping(t *testing.T) {
{
`sum(sum_over_time({app="foo"} | unwrap bar [3m]))`,
`sum(
sum without (
sum without () (
downstream<sum(sum_over_time({app="foo"} | unwrap bar [1m] offset 2m0s)), shard=<nil>>
++ downstream<sum(sum_over_time({app="foo"} | unwrap bar [1m] offset 1m0s)), shard=<nil>>
++ downstream<sum(sum_over_time({app="foo"} | unwrap bar [1m])), shard=<nil>>
@ -183,7 +183,7 @@ func Test_SplitRangeVectorMapping(t *testing.T) {
{
`sum(max_over_time({app="foo"} | unwrap bar [3m]))`,
`sum(
max without (
max without () (
downstream<sum(max_over_time({app="foo"} | unwrap bar [1m] offset 2m0s)), shard=<nil>>
++ downstream<sum(max_over_time({app="foo"} | unwrap bar [1m] offset 1m0s)), shard=<nil>>
++ downstream<sum(max_over_time({app="foo"} | unwrap bar [1m])), shard=<nil>>
@ -203,7 +203,7 @@ func Test_SplitRangeVectorMapping(t *testing.T) {
{
`sum(min_over_time({app="foo"} | unwrap bar [3m]))`,
`sum(
min without (
min without () (
downstream<sum(min_over_time({app="foo"} | unwrap bar [1m] offset 2m0s)), shard=<nil>>
++ downstream<sum(min_over_time({app="foo"} | unwrap bar [1m] offset 1m0s)), shard=<nil>>
++ downstream<sum(min_over_time({app="foo"} | unwrap bar [1m])), shard=<nil>>
@ -223,7 +223,7 @@ func Test_SplitRangeVectorMapping(t *testing.T) {
{
`sum(rate({app="foo"}[3m]))`,
`sum(
(sum without (
(sum without () (
downstream<sum(count_over_time({app="foo"}[1m] offset 2m0s)), shard=<nil>>
++ downstream<sum(count_over_time({app="foo"}[1m] offset 1m0s)), shard=<nil>>
++ downstream<sum(count_over_time({app="foo"}[1m])), shard=<nil>>
@ -233,7 +233,7 @@ func Test_SplitRangeVectorMapping(t *testing.T) {
{
`sum(bytes_rate({app="foo"}[3m]))`,
`sum(
(sum without (
(sum without () (
downstream<sum(bytes_over_time({app="foo"}[1m] offset 2m0s)), shard=<nil>>
++ downstream<sum(bytes_over_time({app="foo"}[1m] offset 1m0s)), shard=<nil>>
++ downstream<sum(bytes_over_time({app="foo"}[1m])), shard=<nil>>
@ -245,7 +245,7 @@ func Test_SplitRangeVectorMapping(t *testing.T) {
{
`sum by (baz) (bytes_over_time({app="foo"}[3m]))`,
`sum by (baz) (
sum without (
sum without () (
downstream<sum by (baz) (bytes_over_time({app="foo"} [1m] offset 2m0s)), shard=<nil>>
++ downstream<sum by (baz) (bytes_over_time({app="foo"} [1m] offset 1m0s)), shard=<nil>>
++ downstream<sum by (baz) (bytes_over_time({app="foo"} [1m])), shard=<nil>>
@ -255,7 +255,7 @@ func Test_SplitRangeVectorMapping(t *testing.T) {
{
`sum by (baz) (count_over_time({app="foo"}[3m]))`,
`sum by (baz) (
sum without (
sum without () (
downstream<sum by (baz) (count_over_time({app="foo"} [1m] offset 2m0s)), shard=<nil>>
++ downstream<sum by (baz) (count_over_time({app="foo"} [1m] offset 1m0s)), shard=<nil>>
++ downstream<sum by (baz) (count_over_time({app="foo"} [1m])), shard=<nil>>
@ -265,7 +265,7 @@ func Test_SplitRangeVectorMapping(t *testing.T) {
{
`sum by (baz) (sum_over_time({app="foo"} | unwrap bar [3m]))`,
`sum by (baz) (
sum without (
sum without () (
downstream<sum by (baz) (sum_over_time({app="foo"} | unwrap bar [1m] offset 2m0s)), shard=<nil>>
++ downstream<sum by (baz) (sum_over_time({app="foo"} | unwrap bar [1m] offset 1m0s)), shard=<nil>>
++ downstream<sum by (baz) (sum_over_time({app="foo"} | unwrap bar [1m])), shard=<nil>>
@ -275,7 +275,7 @@ func Test_SplitRangeVectorMapping(t *testing.T) {
{
`sum by (baz) (max_over_time({app="foo"} | unwrap bar [3m]))`,
`sum by (baz) (
max without (
max without () (
downstream<sum by (baz) (max_over_time({app="foo"} | unwrap bar [1m] offset 2m0s)), shard=<nil>>
++ downstream<sum by (baz) (max_over_time({app="foo"} | unwrap bar [1m] offset 1m0s)), shard=<nil>>
++ downstream<sum by (baz) (max_over_time({app="foo"} | unwrap bar [1m])), shard=<nil>>
@ -295,7 +295,7 @@ func Test_SplitRangeVectorMapping(t *testing.T) {
{
`sum by (baz) (min_over_time({app="foo"} | unwrap bar [3m]))`,
`sum by (baz) (
min without (
min without () (
downstream<sum by (baz) (min_over_time({app="foo"} | unwrap bar [1m] offset 2m0s)), shard=<nil>>
++ downstream<sum by (baz) (min_over_time({app="foo"} | unwrap bar [1m] offset 1m0s)), shard=<nil>>
++ downstream<sum by (baz) (min_over_time({app="foo"} | unwrap bar [1m])), shard=<nil>>
@ -315,7 +315,7 @@ func Test_SplitRangeVectorMapping(t *testing.T) {
{
`sum by (baz) (rate({app="foo"}[3m]))`,
`sum by (baz) (
(sum without (
(sum without () (
downstream<sum by (baz) (count_over_time({app="foo"}[1m] offset 2m0s)), shard=<nil>>
++ downstream<sum by (baz) (count_over_time({app="foo"}[1m] offset 1m0s)), shard=<nil>>
++ downstream<sum by (baz) (count_over_time({app="foo"}[1m])), shard=<nil>>
@ -325,7 +325,7 @@ func Test_SplitRangeVectorMapping(t *testing.T) {
{
`sum by (baz) (bytes_rate({app="foo"}[3m]))`,
`sum by (baz) (
(sum without (
(sum without () (
downstream<sum by (baz) (bytes_over_time({app="foo"}[1m] offset 2m0s)), shard=<nil>>
++ downstream<sum by (baz) (bytes_over_time({app="foo"}[1m] offset 1m0s)), shard=<nil>>
++ downstream<sum by (baz) (bytes_over_time({app="foo"}[1m])), shard=<nil>>
@ -337,7 +337,7 @@ func Test_SplitRangeVectorMapping(t *testing.T) {
{
`count(bytes_over_time({app="foo"}[3m]))`,
`count(
sum without (
sum without () (
downstream<bytes_over_time({app="foo"}[1m] offset 2m0s), shard=<nil>>
++ downstream<bytes_over_time({app="foo"}[1m] offset 1m0s), shard=<nil>>
++ downstream<bytes_over_time({app="foo"}[1m]), shard=<nil>>
@ -347,7 +347,7 @@ func Test_SplitRangeVectorMapping(t *testing.T) {
{
`count(count_over_time({app="foo"}[3m]))`,
`count(
sum without (
sum without () (
downstream<count_over_time({app="foo"}[1m] offset 2m0s), shard=<nil>>
++ downstream<count_over_time({app="foo"}[1m] offset 1m0s), shard=<nil>>
++ downstream<count_over_time({app="foo"}[1m]), shard=<nil>>
@ -357,7 +357,7 @@ func Test_SplitRangeVectorMapping(t *testing.T) {
{
`count(sum_over_time({app="foo"} | unwrap bar [3m]))`,
`count(
sum without (
sum without () (
downstream<sum_over_time({app="foo"} | unwrap bar [1m] offset 2m0s), shard=<nil>>
++ downstream<sum_over_time({app="foo"} | unwrap bar [1m] offset 1m0s), shard=<nil>>
++ downstream<sum_over_time({app="foo"} | unwrap bar [1m]), shard=<nil>>
@ -367,7 +367,7 @@ func Test_SplitRangeVectorMapping(t *testing.T) {
{
`count(max_over_time({app="foo"} | unwrap bar [3m]))`,
`count(
max without (
max without () (
downstream<max_over_time({app="foo"} | unwrap bar [1m] offset 2m0s), shard=<nil>>
++ downstream<max_over_time({app="foo"} | unwrap bar [1m] offset 1m0s), shard=<nil>>
++ downstream<max_over_time({app="foo"} | unwrap bar [1m]), shard=<nil>>
@ -387,7 +387,7 @@ func Test_SplitRangeVectorMapping(t *testing.T) {
{
`count(min_over_time({app="foo"} | unwrap bar [3m]))`,
`count(
min without (
min without () (
downstream<min_over_time({app="foo"} | unwrap bar [1m] offset 2m0s), shard=<nil>>
++ downstream<min_over_time({app="foo"} | unwrap bar [1m] offset 1m0s), shard=<nil>>
++ downstream<min_over_time({app="foo"} | unwrap bar [1m]), shard=<nil>>
@ -407,7 +407,7 @@ func Test_SplitRangeVectorMapping(t *testing.T) {
{
`count(rate({app="foo"}[3m]))`,
`count(
(sum without (
(sum without () (
downstream<count_over_time({app="foo"}[1m] offset 2m0s), shard=<nil>>
++ downstream<count_over_time({app="foo"}[1m] offset 1m0s), shard=<nil>>
++ downstream<count_over_time({app="foo"}[1m]), shard=<nil>>
@ -417,7 +417,7 @@ func Test_SplitRangeVectorMapping(t *testing.T) {
{
`count(bytes_rate({app="foo"}[3m]))`,
`count(
(sum without (
(sum without () (
downstream<bytes_over_time({app="foo"}[1m] offset 2m0s), shard=<nil>>
++ downstream<bytes_over_time({app="foo"}[1m] offset 1m0s), shard=<nil>>
++ downstream<bytes_over_time({app="foo"}[1m]), shard=<nil>>
@ -429,7 +429,7 @@ func Test_SplitRangeVectorMapping(t *testing.T) {
{
`count by (baz) (bytes_over_time({app="foo"}[3m]))`,
`count by (baz) (
sum without (
sum without () (
downstream<bytes_over_time({app="foo"}[1m] offset 2m0s), shard=<nil>>
++ downstream<bytes_over_time({app="foo"}[1m] offset 1m0s), shard=<nil>>
++ downstream<bytes_over_time({app="foo"}[1m]), shard=<nil>>
@ -439,7 +439,7 @@ func Test_SplitRangeVectorMapping(t *testing.T) {
{
`count by (baz) (count_over_time({app="foo"}[3m]))`,
`count by (baz) (
sum without (
sum without () (
downstream<count_over_time({app="foo"}[1m] offset 2m0s), shard=<nil>>
++ downstream<count_over_time({app="foo"}[1m] offset 1m0s), shard=<nil>>
++ downstream<count_over_time({app="foo"}[1m]), shard=<nil>>
@ -449,7 +449,7 @@ func Test_SplitRangeVectorMapping(t *testing.T) {
{
`count by (baz) (sum_over_time({app="foo"} | unwrap bar [3m]))`,
`count by (baz) (
sum without (
sum without () (
downstream<sum_over_time({app="foo"} | unwrap bar [1m] offset 2m0s), shard=<nil>>
++ downstream<sum_over_time({app="foo"} | unwrap bar [1m] offset 1m0s), shard=<nil>>
++ downstream<sum_over_time({app="foo"} | unwrap bar [1m]), shard=<nil>>
@ -459,7 +459,7 @@ func Test_SplitRangeVectorMapping(t *testing.T) {
{
`count by (baz) (max_over_time({app="foo"} | unwrap bar [3m]))`,
`count by (baz) (
max without (
max without () (
downstream<max_over_time({app="foo"} | unwrap bar [1m] offset 2m0s), shard=<nil>>
++ downstream<max_over_time({app="foo"} | unwrap bar [1m] offset 1m0s), shard=<nil>>
++ downstream<max_over_time({app="foo"} | unwrap bar [1m]), shard=<nil>>
@ -479,7 +479,7 @@ func Test_SplitRangeVectorMapping(t *testing.T) {
{
`count by (baz) (min_over_time({app="foo"} | unwrap bar [3m]))`,
`count by (baz) (
min without (
min without () (
downstream<min_over_time({app="foo"} | unwrap bar [1m] offset 2m0s), shard=<nil>>
++ downstream<min_over_time({app="foo"} | unwrap bar [1m] offset 1m0s), shard=<nil>>
++ downstream<min_over_time({app="foo"} | unwrap bar [1m]), shard=<nil>>
@ -499,7 +499,7 @@ func Test_SplitRangeVectorMapping(t *testing.T) {
{
`count by (baz) (rate({app="foo"}[3m]))`,
`count by (baz) (
(sum without (
(sum without () (
downstream<count_over_time({app="foo"}[1m] offset 2m0s), shard=<nil>>
++ downstream<count_over_time({app="foo"}[1m] offset 1m0s), shard=<nil>>
++ downstream<count_over_time({app="foo"}[1m]), shard=<nil>>
@ -509,7 +509,7 @@ func Test_SplitRangeVectorMapping(t *testing.T) {
{
`count by (baz) (bytes_rate({app="foo"}[3m]))`,
`count by (baz) (
(sum without (
(sum without () (
downstream<bytes_over_time({app="foo"}[1m] offset 2m0s), shard=<nil>>
++ downstream<bytes_over_time({app="foo"}[1m] offset 1m0s), shard=<nil>>
++ downstream<bytes_over_time({app="foo"}[1m]), shard=<nil>>
@ -521,7 +521,7 @@ func Test_SplitRangeVectorMapping(t *testing.T) {
{
`max(bytes_over_time({app="foo"}[3m]))`,
`max(
sum without (
sum without () (
downstream<max(bytes_over_time({app="foo"}[1m] offset 2m0s)), shard=<nil>>
++ downstream<max(bytes_over_time({app="foo"}[1m] offset 1m0s)), shard=<nil>>
++ downstream<max(bytes_over_time({app="foo"}[1m])), shard=<nil>>
@ -531,7 +531,7 @@ func Test_SplitRangeVectorMapping(t *testing.T) {
{
`max(count_over_time({app="foo"}[3m]))`,
`max(
sum without (
sum without () (
downstream<max(count_over_time({app="foo"}[1m] offset 2m0s)), shard=<nil>>
++ downstream<max(count_over_time({app="foo"}[1m] offset 1m0s)), shard=<nil>>
++ downstream<max(count_over_time({app="foo"}[1m])), shard=<nil>>
@ -541,7 +541,7 @@ func Test_SplitRangeVectorMapping(t *testing.T) {
{
`max(sum_over_time({app="foo"} | unwrap bar [3m]))`,
`max(
sum without (
sum without () (
downstream<max(sum_over_time({app="foo"} | unwrap bar [1m] offset 2m0s)), shard=<nil>>
++ downstream<max(sum_over_time({app="foo"} | unwrap bar [1m] offset 1m0s)), shard=<nil>>
++ downstream<max(sum_over_time({app="foo"} | unwrap bar [1m])), shard=<nil>>
@ -551,7 +551,7 @@ func Test_SplitRangeVectorMapping(t *testing.T) {
{
`max(max_over_time({app="foo"} | unwrap bar [3m]))`,
`max(
max without (
max without () (
downstream<max(max_over_time({app="foo"} | unwrap bar [1m] offset 2m0s)), shard=<nil>>
++ downstream<max(max_over_time({app="foo"} | unwrap bar [1m] offset 1m0s)), shard=<nil>>
++ downstream<max(max_over_time({app="foo"} | unwrap bar [1m])), shard=<nil>>
@ -571,7 +571,7 @@ func Test_SplitRangeVectorMapping(t *testing.T) {
{
`max(min_over_time({app="foo"} | unwrap bar [3m]))`,
`max(
min without (
min without () (
downstream<max(min_over_time({app="foo"} | unwrap bar [1m] offset 2m0s)), shard=<nil>>
++ downstream<max(min_over_time({app="foo"} | unwrap bar [1m] offset 1m0s)), shard=<nil>>
++ downstream<max(min_over_time({app="foo"} | unwrap bar [1m])), shard=<nil>>
@ -591,7 +591,7 @@ func Test_SplitRangeVectorMapping(t *testing.T) {
{
`max(rate({app="foo"}[3m]))`,
`max(
(sum without (
(sum without () (
downstream<max(count_over_time({app="foo"}[1m] offset 2m0s)), shard=<nil>>
++ downstream<max(count_over_time({app="foo"}[1m] offset 1m0s)), shard=<nil>>
++ downstream<max(count_over_time({app="foo"}[1m])), shard=<nil>>
@ -601,7 +601,7 @@ func Test_SplitRangeVectorMapping(t *testing.T) {
{
`max(bytes_rate({app="foo"}[3m]))`,
`max(
(sum without (
(sum without () (
downstream<max(bytes_over_time({app="foo"}[1m] offset 2m0s)), shard=<nil>>
++ downstream<max(bytes_over_time({app="foo"}[1m] offset 1m0s)), shard=<nil>>
++ downstream<max(bytes_over_time({app="foo"}[1m])), shard=<nil>>
@ -613,7 +613,7 @@ func Test_SplitRangeVectorMapping(t *testing.T) {
{
`max by (baz) (bytes_over_time({app="foo"}[3m]))`,
`max by (baz) (
sum without (
sum without () (
downstream<max by (baz) (bytes_over_time({app="foo"}[1m] offset 2m0s)), shard=<nil>>
++ downstream<max by (baz) (bytes_over_time({app="foo"}[1m] offset 1m0s)), shard=<nil>>
++ downstream<max by (baz) (bytes_over_time({app="foo"}[1m])), shard=<nil>>
@ -623,7 +623,7 @@ func Test_SplitRangeVectorMapping(t *testing.T) {
{
`max by (baz) (count_over_time({app="foo"}[3m]))`,
`max by (baz) (
sum without (
sum without () (
downstream<max by (baz) (count_over_time({app="foo"}[1m] offset 2m0s)), shard=<nil>>
++ downstream<max by (baz) (count_over_time({app="foo"}[1m] offset 1m0s)), shard=<nil>>
++ downstream<max by (baz) (count_over_time({app="foo"}[1m])), shard=<nil>>
@ -633,7 +633,7 @@ func Test_SplitRangeVectorMapping(t *testing.T) {
{
`max by (baz) (sum_over_time({app="foo"} | unwrap bar [3m]))`,
`max by (baz) (
sum without (
sum without () (
downstream<max by (baz) (sum_over_time({app="foo"} | unwrap bar [1m] offset 2m0s)), shard=<nil>>
++ downstream<max by (baz) (sum_over_time({app="foo"} | unwrap bar [1m] offset 1m0s)), shard=<nil>>
++ downstream<max by (baz) (sum_over_time({app="foo"} | unwrap bar [1m])), shard=<nil>>
@ -643,7 +643,7 @@ func Test_SplitRangeVectorMapping(t *testing.T) {
{
`max by (baz) (max_over_time({app="foo"} | unwrap bar [3m]))`,
`max by (baz) (
max without (
max without () (
downstream<max by (baz) (max_over_time({app="foo"} | unwrap bar [1m] offset 2m0s)), shard=<nil>>
++ downstream<max by (baz) (max_over_time({app="foo"} | unwrap bar [1m] offset 1m0s)), shard=<nil>>
++ downstream<max by (baz) (max_over_time({app="foo"} | unwrap bar [1m])), shard=<nil>>
@ -663,7 +663,7 @@ func Test_SplitRangeVectorMapping(t *testing.T) {
{
`max by (baz) (min_over_time({app="foo"} | unwrap bar [3m]))`,
`max by (baz) (
min without (
min without () (
downstream<max by (baz) (min_over_time({app="foo"} | unwrap bar [1m] offset 2m0s)), shard=<nil>>
++ downstream<max by (baz) (min_over_time({app="foo"} | unwrap bar [1m] offset 1m0s)), shard=<nil>>
++ downstream<max by (baz) (min_over_time({app="foo"} | unwrap bar [1m])), shard=<nil>>
@ -683,7 +683,7 @@ func Test_SplitRangeVectorMapping(t *testing.T) {
{
`max by (baz) (rate({app="foo"}[3m]))`,
`max by (baz) (
(sum without (
(sum without () (
downstream<max by (baz) (count_over_time({app="foo"}[1m] offset 2m0s)), shard=<nil>>
++ downstream<max by (baz) (count_over_time({app="foo"}[1m] offset 1m0s)), shard=<nil>>
++ downstream<max by (baz) (count_over_time({app="foo"}[1m])), shard=<nil>>
@ -693,7 +693,7 @@ func Test_SplitRangeVectorMapping(t *testing.T) {
{
`max by (baz) (bytes_rate({app="foo"}[3m]))`,
`max by (baz) (
(sum without (
(sum without () (
downstream<max by (baz) (bytes_over_time({app="foo"}[1m] offset 2m0s)), shard=<nil>>
++ downstream<max by (baz) (bytes_over_time({app="foo"}[1m] offset 1m0s)), shard=<nil>>
++ downstream<max by (baz) (bytes_over_time({app="foo"}[1m])), shard=<nil>>
@ -705,7 +705,7 @@ func Test_SplitRangeVectorMapping(t *testing.T) {
{
`min(bytes_over_time({app="foo"}[3m]))`,
`min(
sum without (
sum without () (
downstream<min(bytes_over_time({app="foo"}[1m] offset 2m0s)), shard=<nil>>
++ downstream<min(bytes_over_time({app="foo"}[1m] offset 1m0s)), shard=<nil>>
++ downstream<min(bytes_over_time({app="foo"}[1m])), shard=<nil>>
@ -715,7 +715,7 @@ func Test_SplitRangeVectorMapping(t *testing.T) {
{
`min(count_over_time({app="foo"}[3m]))`,
`min(
sum without (
sum without () (
downstream<min(count_over_time({app="foo"}[1m] offset 2m0s)), shard=<nil>>
++ downstream<min(count_over_time({app="foo"}[1m] offset 1m0s)), shard=<nil>>
++ downstream<min(count_over_time({app="foo"}[1m])), shard=<nil>>
@ -725,7 +725,7 @@ func Test_SplitRangeVectorMapping(t *testing.T) {
{
`min(sum_over_time({app="foo"} | unwrap bar [3m]))`,
`min(
sum without (
sum without () (
downstream<min(sum_over_time({app="foo"} | unwrap bar [1m] offset 2m0s)), shard=<nil>>
++ downstream<min(sum_over_time({app="foo"} | unwrap bar [1m] offset 1m0s)), shard=<nil>>
++ downstream<min(sum_over_time({app="foo"} | unwrap bar [1m])), shard=<nil>>
@ -735,7 +735,7 @@ func Test_SplitRangeVectorMapping(t *testing.T) {
{
`min(max_over_time({app="foo"} | unwrap bar [3m]))`,
`min(
max without (
max without () (
downstream<min(max_over_time({app="foo"} | unwrap bar [1m] offset 2m0s)), shard=<nil>>
++ downstream<min(max_over_time({app="foo"} | unwrap bar [1m] offset 1m0s)), shard=<nil>>
++ downstream<min(max_over_time({app="foo"} | unwrap bar [1m])), shard=<nil>>
@ -755,7 +755,7 @@ func Test_SplitRangeVectorMapping(t *testing.T) {
{
`min(min_over_time({app="foo"} | unwrap bar [3m]))`,
`min(
min without (
min without () (
downstream<min(min_over_time({app="foo"} | unwrap bar [1m] offset 2m0s)), shard=<nil>>
++ downstream<min(min_over_time({app="foo"} | unwrap bar [1m] offset 1m0s)), shard=<nil>>
++ downstream<min(min_over_time({app="foo"} | unwrap bar [1m])), shard=<nil>>
@ -775,7 +775,7 @@ func Test_SplitRangeVectorMapping(t *testing.T) {
{
`min(rate({app="foo"}[3m]))`,
`min(
(sum without (
(sum without () (
downstream<min(count_over_time({app="foo"}[1m] offset 2m0s)), shard=<nil>>
++ downstream<min(count_over_time({app="foo"}[1m] offset 1m0s)), shard=<nil>>
++ downstream<min(count_over_time({app="foo"}[1m])), shard=<nil>>
@ -785,7 +785,7 @@ func Test_SplitRangeVectorMapping(t *testing.T) {
{
`min(bytes_rate({app="foo"}[3m]))`,
`min(
(sum without (
(sum without () (
downstream<min(bytes_over_time({app="foo"}[1m] offset 2m0s)), shard=<nil>>
++ downstream<min(bytes_over_time({app="foo"}[1m] offset 1m0s)), shard=<nil>>
++ downstream<min(bytes_over_time({app="foo"}[1m])), shard=<nil>>
@ -797,7 +797,7 @@ func Test_SplitRangeVectorMapping(t *testing.T) {
{
`min by (baz) (bytes_over_time({app="foo"}[3m]))`,
`min by (baz) (
sum without (
sum without () (
downstream<min by (baz) (bytes_over_time({app="foo"}[1m] offset 2m0s)), shard=<nil>>
++ downstream<min by (baz) (bytes_over_time({app="foo"}[1m] offset 1m0s)), shard=<nil>>
++ downstream<min by (baz) (bytes_over_time({app="foo"}[1m])), shard=<nil>>
@ -807,7 +807,7 @@ func Test_SplitRangeVectorMapping(t *testing.T) {
{
`min by (baz) (count_over_time({app="foo"}[3m]))`,
`min by (baz) (
sum without (
sum without () (
downstream<min by (baz) (count_over_time({app="foo"}[1m] offset 2m0s)), shard=<nil>>
++ downstream<min by (baz) (count_over_time({app="foo"}[1m] offset 1m0s)), shard=<nil>>
++ downstream<min by (baz) (count_over_time({app="foo"}[1m])), shard=<nil>>
@ -817,7 +817,7 @@ func Test_SplitRangeVectorMapping(t *testing.T) {
{
`min by (baz) (sum_over_time({app="foo"} | unwrap bar [3m]))`,
`min by (baz) (
sum without (
sum without () (
downstream<min by (baz) (sum_over_time({app="foo"} | unwrap bar [1m] offset 2m0s)), shard=<nil>>
++ downstream<min by (baz) (sum_over_time({app="foo"} | unwrap bar [1m] offset 1m0s)), shard=<nil>>
++ downstream<min by (baz) (sum_over_time({app="foo"} | unwrap bar [1m])), shard=<nil>>
@ -827,7 +827,7 @@ func Test_SplitRangeVectorMapping(t *testing.T) {
{
`min by (baz) (max_over_time({app="foo"} | unwrap bar [3m]))`,
`min by (baz) (
max without (
max without () (
downstream<min by (baz) (max_over_time({app="foo"} | unwrap bar [1m] offset 2m0s)), shard=<nil>>
++ downstream<min by (baz) (max_over_time({app="foo"} | unwrap bar [1m] offset 1m0s)), shard=<nil>>
++ downstream<min by (baz) (max_over_time({app="foo"} | unwrap bar [1m])), shard=<nil>>
@ -847,7 +847,7 @@ func Test_SplitRangeVectorMapping(t *testing.T) {
{
`min by (baz) (min_over_time({app="foo"} | unwrap bar [3m]))`,
`min by (baz) (
min without (
min without () (
downstream<min by (baz) (min_over_time({app="foo"} | unwrap bar [1m] offset 2m0s)), shard=<nil>>
++ downstream<min by (baz) (min_over_time({app="foo"} | unwrap bar [1m] offset 1m0s)), shard=<nil>>
++ downstream<min by (baz) (min_over_time({app="foo"} | unwrap bar [1m])), shard=<nil>>
@ -867,7 +867,7 @@ func Test_SplitRangeVectorMapping(t *testing.T) {
{
`min by (baz) (rate({app="foo"}[3m]))`,
`min by (baz) (
(sum without (
(sum without () (
downstream<min by (baz) (count_over_time({app="foo"}[1m] offset 2m0s)), shard=<nil>>
++ downstream<min by (baz) (count_over_time({app="foo"}[1m] offset 1m0s)), shard=<nil>>
++ downstream<min by (baz) (count_over_time({app="foo"}[1m])), shard=<nil>>
@ -877,7 +877,7 @@ func Test_SplitRangeVectorMapping(t *testing.T) {
{
`min by (baz) (bytes_rate({app="foo"}[3m]))`,
`min by (baz) (
(sum without (
(sum without () (
downstream<min by (baz) (bytes_over_time({app="foo"}[1m] offset 2m0s)), shard=<nil>>
++ downstream<min by (baz) (bytes_over_time({app="foo"}[1m] offset 1m0s)), shard=<nil>>
++ downstream<min by (baz) (bytes_over_time({app="foo"}[1m])), shard=<nil>>
@ -921,7 +921,7 @@ func Test_SplitRangeVectorMapping(t *testing.T) {
{
`sum(sum_over_time({app="foo"} | logfmt | unwrap bar [3m]))`,
`sum(
sum without (
sum without () (
downstream<sum(sum_over_time({app="foo"} | logfmt | unwrap bar [1m] offset 2m0s)), shard=<nil>>
++ downstream<sum(sum_over_time({app="foo"} | logfmt | unwrap bar [1m] offset 1m0s)), shard=<nil>>
++ downstream<sum(sum_over_time({app="foo"} | logfmt | unwrap bar [1m])), shard=<nil>>
@ -931,7 +931,7 @@ func Test_SplitRangeVectorMapping(t *testing.T) {
{
`sum(max_over_time({app="foo"} | json | unwrap bar [3m]))`,
`sum(
max without (
max without () (
downstream<sum(max_over_time({app="foo"} | json | unwrap bar [1m] offset 2m0s)), shard=<nil>>
++ downstream<sum(max_over_time({app="foo"} | json | unwrap bar [1m] offset 1m0s)), shard=<nil>>
++ downstream<sum(max_over_time({app="foo"} | json | unwrap bar [1m])), shard=<nil>>
@ -951,7 +951,7 @@ func Test_SplitRangeVectorMapping(t *testing.T) {
{
`sum(min_over_time({app="foo"} | json | unwrap bar [3m]))`,
`sum(
min without (
min without () (
downstream<sum(min_over_time({app="foo"} | json | unwrap bar [1m] offset 2m0s)), shard=<nil>>
++ downstream<sum(min_over_time({app="foo"} | json | unwrap bar [1m] offset 1m0s)), shard=<nil>>
++ downstream<sum(min_over_time({app="foo"} | json | unwrap bar [1m])), shard=<nil>>
@ -971,7 +971,7 @@ func Test_SplitRangeVectorMapping(t *testing.T) {
{
`sum(rate({app="foo"} | json [3m]))`,
`sum(
(sum without (
(sum without () (
downstream<sum(count_over_time({app="foo"} | json [1m] offset 2m0s)), shard=<nil>>
++ downstream<sum(count_over_time({app="foo"} | json [1m] offset 1m0s)), shard=<nil>>
++ downstream<sum(count_over_time({app="foo"} | json [1m])), shard=<nil>>
@ -981,7 +981,7 @@ func Test_SplitRangeVectorMapping(t *testing.T) {
{
`sum(bytes_rate({app="foo"} | logfmt [3m]))`,
`sum(
(sum without (
(sum without () (
downstream<sum(bytes_over_time({app="foo"} | logfmt [1m] offset 2m0s)), shard=<nil>>
++ downstream<sum(bytes_over_time({app="foo"} | logfmt [1m] offset 1m0s)), shard=<nil>>
++ downstream<sum(bytes_over_time({app="foo"} | logfmt [1m])), shard=<nil>>
@ -1007,7 +1007,7 @@ func Test_SplitRangeVectorMapping(t *testing.T) {
{
`sum by (baz) (sum_over_time({app="foo"} | json | unwrap bar [3m]))`,
`sum by (baz) (
sum without (
sum without () (
downstream<sum by (baz) (sum_over_time({app="foo"} | json | unwrap bar [1m] offset 2m0s)), shard=<nil>>
++ downstream<sum by (baz) (sum_over_time({app="foo"} | json | unwrap bar [1m] offset 1m0s)), shard=<nil>>
++ downstream<sum by (baz) (sum_over_time({app="foo"} | json | unwrap bar [1m])), shard=<nil>>
@ -1017,7 +1017,7 @@ func Test_SplitRangeVectorMapping(t *testing.T) {
{
`sum by (baz) (max_over_time({app="foo"} | logfmt | unwrap bar [3m]))`,
`sum by (baz) (
max without (
max without () (
downstream<sum by (baz) (max_over_time({app="foo"} | logfmt | unwrap bar [1m] offset 2m0s)), shard=<nil>>
++ downstream<sum by (baz) (max_over_time({app="foo"} | logfmt | unwrap bar [1m] offset 1m0s)), shard=<nil>>
++ downstream<sum by (baz) (max_over_time({app="foo"} | logfmt | unwrap bar [1m])), shard=<nil>>
@ -1037,7 +1037,7 @@ func Test_SplitRangeVectorMapping(t *testing.T) {
{
`sum by (baz) (min_over_time({app="foo"} | logfmt | unwrap bar [3m]))`,
`sum by (baz) (
min without (
min without () (
downstream<sum by (baz) (min_over_time({app="foo"} | logfmt | unwrap bar [1m] offset 2m0s)), shard=<nil>>
++ downstream<sum by (baz) (min_over_time({app="foo"} | logfmt | unwrap bar [1m] offset 1m0s)), shard=<nil>>
++ downstream<sum by (baz) (min_over_time({app="foo"} | logfmt | unwrap bar [1m])), shard=<nil>>
@ -1057,7 +1057,7 @@ func Test_SplitRangeVectorMapping(t *testing.T) {
{
`sum by (baz) (rate({app="foo"} | logfmt [3m]))`,
`sum by (baz) (
(sum without (
(sum without () (
downstream<sum by (baz) (count_over_time({app="foo"} | logfmt [1m] offset 2m0s)), shard=<nil>>
++ downstream<sum by (baz) (count_over_time({app="foo"} | logfmt [1m] offset 1m0s)), shard=<nil>>
++ downstream<sum by (baz) (count_over_time({app="foo"} | logfmt [1m])), shard=<nil>>
@ -1067,7 +1067,7 @@ func Test_SplitRangeVectorMapping(t *testing.T) {
{
`sum by (baz) (bytes_rate({app="foo"} | json [3m]))`,
`sum by (baz) (
(sum without (
(sum without () (
downstream<sum by (baz) (bytes_over_time({app="foo"} | json [1m] offset 2m0s)), shard=<nil>>
++ downstream<sum by (baz) (bytes_over_time({app="foo"} | json [1m] offset 1m0s)), shard=<nil>>
++ downstream<sum by (baz) (bytes_over_time({app="foo"} | json [1m])), shard=<nil>>
@ -1133,7 +1133,7 @@ func Test_SplitRangeVectorMapping(t *testing.T) {
{
`max(sum_over_time({app="foo"} | logfmt | unwrap bar [3m]))`,
`max(
sum without (
sum without () (
downstream<max(sum_over_time({app="foo"} | logfmt | unwrap bar [1m] offset 2m0s)), shard=<nil>>
++ downstream<max(sum_over_time({app="foo"} | logfmt | unwrap bar [1m] offset 1m0s)), shard=<nil>>
++ downstream<max(sum_over_time({app="foo"} | logfmt | unwrap bar [1m])), shard=<nil>>
@ -1143,7 +1143,7 @@ func Test_SplitRangeVectorMapping(t *testing.T) {
{
`max(max_over_time({app="foo"} | json | unwrap bar [3m]))`,
`max(
max without (
max without () (
downstream<max(max_over_time({app="foo"} | json | unwrap bar [1m] offset 2m0s)), shard=<nil>>
++ downstream<max(max_over_time({app="foo"} | json | unwrap bar [1m] offset 1m0s)), shard=<nil>>
++ downstream<max(max_over_time({app="foo"} | json | unwrap bar [1m])), shard=<nil>>
@ -1163,7 +1163,7 @@ func Test_SplitRangeVectorMapping(t *testing.T) {
{
`max(min_over_time({app="foo"} | json | unwrap bar [3m]))`,
`max(
min without (
min without () (
downstream<max(min_over_time({app="foo"} | json | unwrap bar [1m] offset 2m0s)), shard=<nil>>
++ downstream<max(min_over_time({app="foo"} | json | unwrap bar [1m] offset 1m0s)), shard=<nil>>
++ downstream<max(min_over_time({app="foo"} | json | unwrap bar [1m])), shard=<nil>>
@ -1199,7 +1199,7 @@ func Test_SplitRangeVectorMapping(t *testing.T) {
{
`max by (baz) (sum_over_time({app="foo"} | json | unwrap bar [3m]))`,
`max by (baz) (
sum without (
sum without () (
downstream<max by (baz) (sum_over_time({app="foo"} | json | unwrap bar [1m] offset 2m0s)), shard=<nil>>
++ downstream<max by (baz) (sum_over_time({app="foo"} | json | unwrap bar [1m] offset 1m0s)), shard=<nil>>
++ downstream<max by (baz) (sum_over_time({app="foo"} | json | unwrap bar [1m])), shard=<nil>>
@ -1209,7 +1209,7 @@ func Test_SplitRangeVectorMapping(t *testing.T) {
{
`max by (baz) (max_over_time({app="foo"} | logfmt | unwrap bar [3m]))`,
`max by (baz) (
max without (
max without () (
downstream<max by (baz) (max_over_time({app="foo"} | logfmt | unwrap bar [1m] offset 2m0s)), shard=<nil>>
++ downstream<max by (baz) (max_over_time({app="foo"} | logfmt | unwrap bar [1m] offset 1m0s)), shard=<nil>>
++ downstream<max by (baz) (max_over_time({app="foo"} | logfmt | unwrap bar [1m])), shard=<nil>>
@ -1229,7 +1229,7 @@ func Test_SplitRangeVectorMapping(t *testing.T) {
{
`max by (baz) (min_over_time({app="foo"} | logfmt | unwrap bar [3m]))`,
`max by (baz) (
min without (
min without () (
downstream<max by (baz) (min_over_time({app="foo"} | logfmt | unwrap bar [1m] offset 2m0s)), shard=<nil>>
++ downstream<max by (baz) (min_over_time({app="foo"} | logfmt | unwrap bar [1m] offset 1m0s)), shard=<nil>>
++ downstream<max by (baz) (min_over_time({app="foo"} | logfmt | unwrap bar [1m])), shard=<nil>>
@ -1265,7 +1265,7 @@ func Test_SplitRangeVectorMapping(t *testing.T) {
{
`min(sum_over_time({app="foo"} | logfmt | unwrap bar [3m]))`,
`min(
sum without (
sum without () (
downstream<min(sum_over_time({app="foo"} | logfmt | unwrap bar [1m] offset 2m0s)), shard=<nil>>
++ downstream<min(sum_over_time({app="foo"} | logfmt | unwrap bar [1m] offset 1m0s)), shard=<nil>>
++ downstream<min(sum_over_time({app="foo"} | logfmt | unwrap bar [1m])), shard=<nil>>
@ -1275,7 +1275,7 @@ func Test_SplitRangeVectorMapping(t *testing.T) {
{
`min(max_over_time({app="foo"} | json | unwrap bar [3m]))`,
`min(
max without (
max without () (
downstream<min(max_over_time({app="foo"} | json | unwrap bar [1m] offset 2m0s)), shard=<nil>>
++ downstream<min(max_over_time({app="foo"} | json | unwrap bar [1m] offset 1m0s)), shard=<nil>>
++ downstream<min(max_over_time({app="foo"} | json | unwrap bar [1m])), shard=<nil>>
@ -1295,7 +1295,7 @@ func Test_SplitRangeVectorMapping(t *testing.T) {
{
`min(min_over_time({app="foo"} | json | unwrap bar [3m]))`,
`min(
min without (
min without () (
downstream<min(min_over_time({app="foo"} | json | unwrap bar [1m] offset 2m0s)), shard=<nil>>
++ downstream<min(min_over_time({app="foo"} | json | unwrap bar [1m] offset 1m0s)), shard=<nil>>
++ downstream<min(min_over_time({app="foo"} | json | unwrap bar [1m])), shard=<nil>>
@ -1331,7 +1331,7 @@ func Test_SplitRangeVectorMapping(t *testing.T) {
{
`min by (baz) (sum_over_time({app="foo"} | json | unwrap bar [3m]))`,
`min by (baz) (
sum without (
sum without () (
downstream<min by (baz) (sum_over_time({app="foo"} | json | unwrap bar [1m] offset 2m0s)), shard=<nil>>
++ downstream<min by (baz) (sum_over_time({app="foo"} | json | unwrap bar [1m] offset 1m0s)), shard=<nil>>
++ downstream<min by (baz) (sum_over_time({app="foo"} | json | unwrap bar [1m])), shard=<nil>>
@ -1341,7 +1341,7 @@ func Test_SplitRangeVectorMapping(t *testing.T) {
{
`min by (baz) (max_over_time({app="foo"} | logfmt | unwrap bar [3m]))`,
`min by (baz) (
max without (
max without () (
downstream<min by (baz) (max_over_time({app="foo"} | logfmt | unwrap bar [1m] offset 2m0s)), shard=<nil>>
++ downstream<min by (baz) (max_over_time({app="foo"} | logfmt | unwrap bar [1m] offset 1m0s)), shard=<nil>>
++ downstream<min by (baz) (max_over_time({app="foo"} | logfmt | unwrap bar [1m])), shard=<nil>>
@ -1361,7 +1361,7 @@ func Test_SplitRangeVectorMapping(t *testing.T) {
{
`min by (baz) (min_over_time({app="foo"} | logfmt | unwrap bar [3m]))`,
`min by (baz) (
min without (
min without () (
downstream<min by (baz) (min_over_time({app="foo"} | logfmt | unwrap bar [1m] offset 2m0s)), shard=<nil>>
++ downstream<min by (baz) (min_over_time({app="foo"} | logfmt | unwrap bar [1m] offset 1m0s)), shard=<nil>>
++ downstream<min by (baz) (min_over_time({app="foo"} | logfmt | unwrap bar [1m])), shard=<nil>>
@ -1384,7 +1384,7 @@ func Test_SplitRangeVectorMapping(t *testing.T) {
`2 * bytes_over_time({app="foo"}[3m])`,
`(
2 *
sum without (
sum without () (
downstream<bytes_over_time({app="foo"}[1m] offset 2m0s), shard=<nil>>
++ downstream<bytes_over_time({app="foo"}[1m] offset 1m0s), shard=<nil>>
++ downstream<bytes_over_time({app="foo"}[1m]), shard=<nil>>
@ -1394,7 +1394,7 @@ func Test_SplitRangeVectorMapping(t *testing.T) {
{
`count_over_time({app="foo"}[3m]) * 2`,
`(
sum without (
sum without () (
downstream<count_over_time({app="foo"}[1m] offset 2m0s), shard=<nil>>
++ downstream<count_over_time({app="foo"}[1m] offset 1m0s), shard=<nil>>
++ downstream<count_over_time({app="foo"}[1m]), shard=<nil>>
@ -1404,12 +1404,12 @@ func Test_SplitRangeVectorMapping(t *testing.T) {
},
{
`bytes_over_time({app="foo"}[3m]) + count_over_time({app="foo"}[4m])`,
`(sum without (
`(sum without () (
downstream<bytes_over_time({app="foo"}[1m] offset 2m0s), shard=<nil>>
++ downstream<bytes_over_time({app="foo"}[1m] offset 1m0s), shard=<nil>>
++ downstream<bytes_over_time({app="foo"}[1m]), shard=<nil>>
) +
sum without (
sum without () (
downstream<count_over_time({app="foo"}[1m] offset 3m0s), shard=<nil>>
++ downstream<count_over_time({app="foo"}[1m] offset 2m0s), shard=<nil>>
++ downstream<count_over_time({app="foo"}[1m] offset 1m0s), shard=<nil>>
@ -1420,13 +1420,13 @@ func Test_SplitRangeVectorMapping(t *testing.T) {
{
`sum(count_over_time({app="foo"}[3m]) * count(sum_over_time({app="foo"} | unwrap bar [4m])))`,
`sum(
(sum without(
(sum without () (
downstream<count_over_time({app="foo"}[1m] offset 2m0s), shard=<nil>>
++ downstream<count_over_time({app="foo"}[1m] offset 1m0s), shard=<nil>>
++ downstream<count_over_time({app="foo"}[1m]), shard=<nil>>
) *
count (
sum without(
sum without () (
downstream<sum_over_time({app="foo"} | unwrap bar [1m] offset 3m0s), shard=<nil>>
++ downstream<sum_over_time({app="foo"} | unwrap bar [1m] offset 2m0s), shard=<nil>>
++ downstream<sum_over_time({app="foo"} | unwrap bar [1m] offset 1m0s), shard=<nil>>
@ -1440,7 +1440,7 @@ func Test_SplitRangeVectorMapping(t *testing.T) {
`sum by (app) (bytes_rate({app="foo"}[3m])) / sum by (app) (rate({app="foo"}[3m]))`,
`(
sum by (app) (
(sum without (
(sum without () (
downstream<sum by (app) (bytes_over_time({app="foo"}[1m] offset 2m0s)), shard=<nil>>
++ downstream<sum by (app) (bytes_over_time({app="foo"}[1m] offset 1m0s)), shard=<nil>>
++ downstream<sum by (app) (bytes_over_time({app="foo"}[1m])), shard=<nil>>
@ -1448,7 +1448,7 @@ func Test_SplitRangeVectorMapping(t *testing.T) {
)
/
sum by (app) (
(sum without (
(sum without () (
downstream<sum by (app) (count_over_time({app="foo"}[1m] offset 2m0s)), shard=<nil>>
++ downstream<sum by (app) (count_over_time({app="foo"}[1m] offset 1m0s)), shard=<nil>>
++ downstream<sum by (app) (count_over_time({app="foo"}[1m])), shard=<nil>>
@ -1466,7 +1466,7 @@ func Test_SplitRangeVectorMapping(t *testing.T) {
)
/
sum (
sum without (
sum without () (
downstream<sum (count_over_time({app="foo"} [1m] offset 2m0s)), shard=<nil>>
++ downstream<sum (count_over_time({app="foo"} [1m] offset 1m0s)), shard=<nil>>
++ downstream<sum (count_over_time({app="foo"} [1m])), shard=<nil>>
@ -1480,7 +1480,7 @@ func Test_SplitRangeVectorMapping(t *testing.T) {
`sum(max(bytes_over_time({app="foo"}[3m])))`,
`sum(
max(
sum without(
sum without () (
downstream<max(bytes_over_time({app="foo"}[1m] offset 2m0s)), shard=<nil>>
++ downstream<max(bytes_over_time({app="foo"}[1m] offset 1m0s)), shard=<nil>>
++ downstream<max(bytes_over_time({app="foo"}[1m])), shard=<nil>>
@ -1494,7 +1494,7 @@ func Test_SplitRangeVectorMapping(t *testing.T) {
{
`topk(2, count_over_time({app="foo"}[3m]))`,
`topk(2,
sum without(
sum without () (
downstream<count_over_time({app="foo"}[1m] offset 2m0s), shard=<nil>>
++ downstream<count_over_time({app="foo"}[1m] offset 1m0s), shard=<nil>>
++ downstream<count_over_time({app="foo"}[1m]), shard=<nil>>
@ -1508,7 +1508,7 @@ func Test_SplitRangeVectorMapping(t *testing.T) {
`topk(10,
sum by (org_id) (
(
sum without(
sum without () (
downstream<sum by(org_id)(sum_over_time({container="query-frontend",namespace="loki"} |= "metrics.go" | logfmt | unwrap bytes(total_bytes) | __error__="" [1m] offset 2m0s)),shard=<nil>>
++ downstream<sum by(org_id)(sum_over_time({container="query-frontend",namespace="loki"} |= "metrics.go" | logfmt | unwrap bytes(total_bytes) | __error__="" [1m] offset 1m0s)),shard=<nil>>
++ downstream<sum by(org_id)(sum_over_time({container="query-frontend",namespace="loki"} |= "metrics.go" | logfmt | unwrap bytes(total_bytes) | __error__="" [1m])),shard=<nil>>
@ -1524,7 +1524,7 @@ func Test_SplitRangeVectorMapping(t *testing.T) {
`label_replace(sum by (baz) (count_over_time({app="foo"}[3m])), "x", "$1", "a", "(.*)")`,
`label_replace(
sum by (baz) (
sum without (
sum without () (
downstream<sum by (baz) (count_over_time({app="foo"} [1m] offset 2m0s)), shard=<nil>>
++ downstream<sum by (baz) (count_over_time({app="foo"} [1m] offset 1m0s)), shard=<nil>>
++ downstream<sum by (baz) (count_over_time({app="foo"} [1m])), shard=<nil>>
@ -1537,7 +1537,7 @@ func Test_SplitRangeVectorMapping(t *testing.T) {
`label_replace(rate({job="api-server", service="a:c"} |= "err" [3m]), "foo", "$1", "service", "(.*):.*")`,
`label_replace(
(
sum without (
sum without () (
downstream<count_over_time({job="api-server",service="a:c"} |= "err" [1m] offset 2m0s), shard=<nil>>
++ downstream<count_over_time({job="api-server",service="a:c"} |= "err" [1m] offset 1m0s), shard=<nil>>
++ downstream<count_over_time({job="api-server",service="a:c"} |= "err" [1m]), shard=<nil>>

@ -1101,9 +1101,14 @@ type Grouping struct {
// impls Stringer
func (g Grouping) String() string {
var sb strings.Builder
if g.Groups == nil {
return ""
}
if g.Without {
sb.WriteString(" without ")
} else if len(g.Groups) > 0 {
} else {
sb.WriteString(" by ")
}
@ -1112,6 +1117,9 @@ func (g Grouping) String() string {
sb.WriteString(strings.Join(g.Groups, ","))
sb.WriteString(")")
}
if len(g.Groups) == 0 {
sb.WriteString("()")
}
return sb.String()
}

@ -681,3 +681,41 @@ func TestParseLargeQuery(t *testing.T) {
_, err := ParseExpr(line)
require.NoError(t, err)
}
func TestGroupingString(t *testing.T) {
g := Grouping{
Groups: []string{"a", "b"},
Without: false,
}
require.Equal(t, " by (a,b)", g.String())
g = Grouping{
Groups: []string{},
Without: false,
}
require.Equal(t, " by ()", g.String())
g = Grouping{
Groups: nil,
Without: false,
}
require.Equal(t, "", g.String())
g = Grouping{
Groups: []string{"a", "b"},
Without: true,
}
require.Equal(t, " without (a,b)", g.String())
g = Grouping{
Groups: []string{},
Without: true,
}
require.Equal(t, " without ()", g.String())
g = Grouping{
Groups: nil,
Without: true,
}
require.Equal(t, "", g.String())
}

@ -3352,6 +3352,10 @@ func TestParseSampleExpr_equalityMatcher(t *testing.T) {
{
in: `1 + count_over_time({app=~".+"}[5m]) + count_over_time({app=~".+"}[5m]) + 1`,
},
{
in: `count without (rate({namespace="apps"}[15s]))`,
err: logqlmodel.NewParseError("syntax error: unexpected RATE, expecting IDENTIFIER or )", 1, 16),
},
} {
t.Run(tc.in, func(t *testing.T) {
_, err := ParseSampleExpr(tc.in)

Loading…
Cancel
Save