diff --git a/runtime/queries/filterutil.go b/runtime/queries/filterutil.go index 496d0990b7bc..b25ce2ebebee 100644 --- a/runtime/queries/filterutil.go +++ b/runtime/queries/filterutil.go @@ -43,7 +43,7 @@ func FilterNotInClause(col *runtimev1.Expression, values []*runtimev1.Expression } } -func FilterLikeClause(col *runtimev1.Expression, val *runtimev1.Expression) *runtimev1.Expression { +func FilterLikeClause(col, val *runtimev1.Expression) *runtimev1.Expression { return &runtimev1.Expression{ Expression: &runtimev1.Expression_Cond{ Cond: &runtimev1.Condition{ @@ -54,7 +54,7 @@ func FilterLikeClause(col *runtimev1.Expression, val *runtimev1.Expression) *run } } -func FilterNotLikeClause(col *runtimev1.Expression, val *runtimev1.Expression) *runtimev1.Expression { +func FilterNotLikeClause(col, val *runtimev1.Expression) *runtimev1.Expression { return &runtimev1.Expression{ Expression: &runtimev1.Expression_Cond{ Cond: &runtimev1.Condition{ diff --git a/runtime/queries/metricsview_toplist.go b/runtime/queries/metricsview_toplist.go index 020beacbf625..e9ad1e4905c0 100644 --- a/runtime/queries/metricsview_toplist.go +++ b/runtime/queries/metricsview_toplist.go @@ -240,7 +240,7 @@ func (q *MetricsViewToplist) buildMetricsTopListSQL(mv *runtimev1.MetricsViewSpe havingClause := "" if q.Having != nil { var havingClauseArgs []any - havingClause, havingClauseArgs, err = buildFromExpression(q.Having, nil, dialect) + havingClause, havingClauseArgs, err = buildFromExpression(q.Having, measureAliases, dialect) if err != nil { return "", nil, err } diff --git a/runtime/queries/metricsview_toplist_test.go b/runtime/queries/metricsview_toplist_test.go index 2775fe5c3c02..9bcb7e5b8681 100644 --- a/runtime/queries/metricsview_toplist_test.go +++ b/runtime/queries/metricsview_toplist_test.go @@ -9,6 +9,7 @@ import ( "github.com/rilldata/rill/runtime/queries" "github.com/rilldata/rill/runtime/testruntime" "github.com/stretchr/testify/require" + "google.golang.org/protobuf/types/known/structpb" "google.golang.org/protobuf/types/known/timestamppb" ) @@ -38,6 +39,25 @@ func TestMetricsViewsToplist_measure_filters(t *testing.T) { MetricsView: mv.Spec, TimeStart: ctr.Result.Min, TimeEnd: timestamppb.New(maxTime), + Having: &runtimev1.Expression{ + Expression: &runtimev1.Expression_Cond{ + Cond: &runtimev1.Condition{ + Op: runtimev1.Operation_OPERATION_GT, + Exprs: []*runtimev1.Expression{ + { + Expression: &runtimev1.Expression_Ident{ + Ident: "measure_1", + }, + }, + { + Expression: &runtimev1.Expression_Val{ + Val: structpb.NewNumberValue(3.25), + }, + }, + }, + }, + }, + }, Sort: []*runtimev1.MetricsViewSort{ { Name: "domain", diff --git a/runtime/server/observability_utils.go b/runtime/server/observability_utils.go index 96477c3ef0ea..af225b9e5eb1 100644 --- a/runtime/server/observability_utils.go +++ b/runtime/server/observability_utils.go @@ -12,11 +12,20 @@ func safeTimeStr(t *timestamppb.Timestamp) string { return t.AsTime().String() } -func filterCount(m *runtimev1.MetricsViewFilter) int { +func filterCount(m *runtimev1.Expression) int { if m == nil { return 0 } - return len(m.Include) + len(m.Exclude) + c := 0 + switch e := m.Expression.(type) { + case *runtimev1.Expression_Ident: + c++ + case *runtimev1.Expression_Cond: + for _, expr := range e.Cond.Exprs { + c += filterCount(expr) + } + } + return c } func marshalInlineMeasure(ms []*runtimev1.InlineMeasure) []string { diff --git a/runtime/server/queries_metrics.go b/runtime/server/queries_metrics.go index f43fba7e568c..c9a920b413f9 100644 --- a/runtime/server/queries_metrics.go +++ b/runtime/server/queries_metrics.go @@ -26,8 +26,7 @@ func (s *Server) MetricsViewAggregation(ctx context.Context, req *runtimev1.Metr attribute.StringSlice("args.sort.names", marshalMetricsViewAggregationSort(req.Sort)), attribute.String("args.time_start", safeTimeStr(req.TimeStart)), attribute.String("args.time_end", safeTimeStr(req.TimeEnd)), - // TODO filter and having - //attribute.Int("args.filter_count", filterCount(req.Filter)), + attribute.Int("args.filter_count", filterCount(req.Where)), attribute.Int64("args.limit", req.Limit), attribute.Int64("args.offset", req.Offset), attribute.Int("args.priority", int(req.Priority)), @@ -104,10 +103,9 @@ func (s *Server) MetricsViewToplist(ctx context.Context, req *runtimev1.MetricsV attribute.Int("args.priority", int(req.Priority)), attribute.String("args.time_start", safeTimeStr(req.TimeStart)), attribute.String("args.time_end", safeTimeStr(req.TimeEnd)), + attribute.Int("args.filter_count", filterCount(req.Where)), attribute.StringSlice("args.sort.names", marshalMetricsViewSort(req.Sort)), attribute.StringSlice("args.inline_measures", marshalInlineMeasure(req.InlineMeasures)), - // TODO filter and having - //attribute.Int("args.filter_count", filterCount(req.Filter)), ) s.addInstanceRequestAttributes(ctx, req.InstanceId) @@ -177,8 +175,7 @@ func (s *Server) MetricsViewComparison(ctx context.Context, req *runtimev1.Metri attribute.String("args.dimension", req.Dimension.Name), attribute.StringSlice("args.measures", measureNames), attribute.StringSlice("args.sort.names", marshalMetricsViewComparisonSort(req.Sort)), - // TODO filter and having - //attribute.Int("args.filter_count", filterCount(req.Filter)), + attribute.Int("args.filter_count", filterCount(req.Where)), attribute.Int64("args.limit", req.Limit), attribute.Int64("args.offset", req.Offset), attribute.Int("args.priority", int(req.Priority)), @@ -253,8 +250,7 @@ func (s *Server) MetricsViewTimeSeries(ctx context.Context, req *runtimev1.Metri attribute.String("args.time_start", safeTimeStr(req.TimeStart)), attribute.String("args.time_end", safeTimeStr(req.TimeEnd)), attribute.String("args.time_granularity", req.TimeGranularity.String()), - // TODO filter and having - //attribute.Int("args.filter_count", filterCount(req.Filter)), + attribute.Int("args.filter_count", filterCount(req.Where)), attribute.Int("args.priority", int(req.Priority)), ) @@ -311,8 +307,7 @@ func (s *Server) MetricsViewTotals(ctx context.Context, req *runtimev1.MetricsVi attribute.StringSlice("args.inline_measures.names", marshalInlineMeasure(req.InlineMeasures)), attribute.String("args.time_start", safeTimeStr(req.TimeStart)), attribute.String("args.time_end", safeTimeStr(req.TimeEnd)), - // TODO filter and having - //attribute.Int("args.filter_count", filterCount(req.Filter)), + attribute.Int("args.filter_count", filterCount(req.Where)), attribute.Int("args.priority", int(req.Priority)), ) @@ -365,8 +360,7 @@ func (s *Server) MetricsViewRows(ctx context.Context, req *runtimev1.MetricsView attribute.String("args.time_start", safeTimeStr(req.TimeStart)), attribute.String("args.time_end", safeTimeStr(req.TimeEnd)), attribute.String("args.time_granularity", req.TimeGranularity.String()), - // TODO filter and having - //attribute.Int("args.filter_count", filterCount(req.Filter)), + attribute.Int("args.filter_count", filterCount(req.Where)), attribute.StringSlice("args.sort.names", marshalMetricsViewSort(req.Sort)), attribute.Int("args.limit", int(req.Limit)), attribute.Int64("args.offset", req.Offset),