Skip to content

Commit

Permalink
Correctly override node in aggregateBinaryExpr
Browse files Browse the repository at this point in the history
In #676 we added support for query push down for BinaryExp where it is a
literal and either a VectorSelector or a subset of AggregateExprs.
However this initial implementation introduced a bug for AggregateExprs.
Specifically it was doing the query push down but not doing the node
replace properly -- such that the literal operation was done twice (e.g.
add twice, multiply twice, etc.).

This patch will have the aggregateBinaryExpr replace the Binary Expr
(i.e. `(max(foo) * 100)` ) with the "filled in" AggregateExpr -- such
that the re-execution of the aggregation still occurs without re-doing
the literal calculation.

Fixes #688
  • Loading branch information
jacksontj committed Nov 1, 2024
1 parent a622d53 commit 127fb5b
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 11 deletions.
11 changes: 4 additions & 7 deletions pkg/proxystorage/proxy.go
Original file line number Diff line number Diff line change
Expand Up @@ -795,7 +795,7 @@ func (p *ProxyStorage) NodeReplacer(ctx context.Context, s *parser.EvalStmt, nod
// aggregateBinaryExpr will send the node as a query to the downstream and
// replace the aggregate expr with the resulting data. This will cause the aggregation
// (min, max, topk, bottomk) to be re-run against the expression.
aggregateBinaryExpr := func(agg *parser.AggregateExpr) error {
aggregateBinaryExpr := func(agg *parser.AggregateExpr) (parser.Node, error) {
logrus.Debugf("BinaryExpr (AggregateExpr + Literal): %v", n)

removeOffsetFn()
Expand All @@ -816,7 +816,7 @@ func (p *ProxyStorage) NodeReplacer(ctx context.Context, s *parser.EvalStmt, nod
result, warnings, err = state.client.Query(ctx, n.String(), s.Start.Add(-offset))
}
if err != nil {
return err
return nil, err
}

iterators := promclient.IteratorsForValue(result)
Expand All @@ -833,7 +833,7 @@ func (p *ProxyStorage) NodeReplacer(ctx context.Context, s *parser.EvalStmt, nod
ret.UnexpandedSeriesSet = proxyquerier.NewSeriesSet(series, promhttputil.WarningsConvert(warnings), err)

agg.Expr = ret
return nil
return agg, nil
}

// Only valid if the other side is either `NumberLiteral` or `StringLiteral`
Expand All @@ -853,10 +853,7 @@ func (p *ProxyStorage) NodeReplacer(ctx context.Context, s *parser.EvalStmt, nod
case *parser.AggregateExpr:
switch otherTyped.Op {
case parser.MIN, parser.MAX, parser.TOPK, parser.BOTTOMK:
if err := aggregateBinaryExpr(otherTyped); err != nil {
return nil, err
}
return n, nil
return aggregateBinaryExpr(otherTyped)
}
}
}
Expand Down
38 changes: 34 additions & 4 deletions pkg/proxystorage/proxy_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -192,32 +192,62 @@ func TestNodeReplacer(t *testing.T) {
// we expect to re-do the AggregateExpr but have replaced the VectorSelector with the query
{
in: "min(foo{}) > 1",
out: "min() > 1",
out: "min()",
queries: []string{
"min(foo) > 1 @ 10000",
},
},
{
in: "max(foo{}) > 1",
out: "max() > 1",
out: "max()",
queries: []string{
"max(foo) > 1 @ 10000",
},
},
{
in: "topk(5, foo{}) > 1",
out: "topk(5, ) > 1",
out: "topk(5, )",
queries: []string{
"topk(5, foo) > 1 @ 10000",
},
},
{
in: "bottomk(5, foo{}) > 1",
out: "bottomk(5, ) > 1",
out: "bottomk(5, )",
queries: []string{
"bottomk(5, foo) > 1 @ 10000",
},
},

{
in: "min(foo{}) * 1000",
out: "min()",
queries: []string{
"min(foo) * 1000 @ 10000",
},
},
{
in: "max(foo{}) * 1000",
out: "max()",
queries: []string{
"max(foo) * 1000 @ 10000",
},
},
{
in: "topk(5, foo{}) * 1000",
out: "topk(5, )",
queries: []string{
"topk(5, foo) * 1000 @ 10000",
},
},
{
in: "bottomk(5, foo{}) * 1000",
out: "bottomk(5, )",
queries: []string{
"bottomk(5, foo) * 1000 @ 10000",
},
},

// Check that some others do nothing
{
in: "avg(foo) > 1",
Expand Down

0 comments on commit 127fb5b

Please sign in to comment.