in pkg/query/logical/measure/measure_analyzer.go [57:114]
func Analyze(_ context.Context, criteria *measurev1.QueryRequest, metadata *commonv1.Metadata, s logical.Schema) (logical.Plan, error) {
groupByEntity := false
var groupByTags [][]*logical.Tag
if criteria.GetGroupBy() != nil {
groupByProjectionTags := criteria.GetGroupBy().GetTagProjection()
groupByTags = make([][]*logical.Tag, len(groupByProjectionTags.GetTagFamilies()))
tags := make([]string, 0)
for i, tagFamily := range groupByProjectionTags.GetTagFamilies() {
groupByTags[i] = logical.NewTags(tagFamily.GetName(), tagFamily.GetTags()...)
tags = append(tags, tagFamily.GetTags()...)
}
if logical.StringSlicesEqual(s.EntityList(), tags) {
groupByEntity = true
}
}
// parse fields
plan := parseFields(criteria, metadata, groupByEntity)
// parse limit and offset
limitParameter := criteria.GetLimit()
if limitParameter == 0 {
limitParameter = defaultLimit
}
pushedLimit := int(limitParameter + criteria.GetOffset())
if criteria.GetGroupBy() != nil {
plan = newUnresolvedGroupBy(plan, groupByTags, groupByEntity)
pushedLimit = math.MaxInt
}
if criteria.GetAgg() != nil {
plan = newUnresolvedAggregation(plan,
logical.NewField(criteria.GetAgg().GetFieldName()),
criteria.GetAgg().GetFunction(),
criteria.GetGroupBy() != nil,
)
pushedLimit = math.MaxInt
}
if criteria.GetTop() != nil {
plan = top(plan, criteria.GetTop())
}
plan = limit(plan, criteria.GetOffset(), limitParameter)
p, err := plan.Analyze(s)
if err != nil {
return nil, err
}
rules := []logical.OptimizeRule{
logical.NewPushDownOrder(criteria.OrderBy),
logical.NewPushDownMaxSize(pushedLimit),
}
if err := logical.ApplyRules(p, rules...); err != nil {
return nil, err
}
return p, nil
}