package v4 import ( "fmt" "time" metricsV3 "go.signoz.io/signoz/pkg/query-service/app/metrics/v3" "go.signoz.io/signoz/pkg/query-service/app/metrics/v4/cumulative" "go.signoz.io/signoz/pkg/query-service/app/metrics/v4/delta" "go.signoz.io/signoz/pkg/query-service/app/metrics/v4/helpers" "go.signoz.io/signoz/pkg/query-service/common" "go.signoz.io/signoz/pkg/query-service/model" v3 "go.signoz.io/signoz/pkg/query-service/model/v3" ) // PrepareMetricQuery prepares the query to be used for fetching metrics // from the database // start and end are in milliseconds // step is in seconds func PrepareMetricQuery(start, end int64, queryType v3.QueryType, panelType v3.PanelType, mq *v3.BuilderQuery, options metricsV3.Options) (string, error) { start, end = common.AdjustedMetricTimeRange(start, end, mq.StepInterval, *mq) var quantile float64 percentileOperator := mq.SpaceAggregation if v3.IsPercentileOperator(mq.SpaceAggregation) && mq.AggregateAttribute.Type != v3.AttributeKeyType(v3.MetricTypeExponentialHistogram) { quantile = v3.GetPercentileFromOperator(mq.SpaceAggregation) // If quantile is set, we need to group by le // and set the space aggregation to sum // and time aggregation to rate mq.TimeAggregation = v3.TimeAggregationRate mq.SpaceAggregation = v3.SpaceAggregationSum // If le is not present in group by for quantile, add it leFound := false for _, groupBy := range mq.GroupBy { if groupBy.Key == "le" { leFound = true break } } if !leFound { mq.GroupBy = append(mq.GroupBy, v3.AttributeKey{ Key: "le", Type: v3.AttributeKeyTypeTag, DataType: v3.AttributeKeyDataTypeString, }) } } var query string var err error if mq.Temporality == v3.Delta { if panelType == v3.PanelTypeTable { query, err = delta.PrepareMetricQueryDeltaTable(start, end, mq.StepInterval, mq) } else { query, err = delta.PrepareMetricQueryDeltaTimeSeries(start, end, mq.StepInterval, mq) } } else { if panelType == v3.PanelTypeTable { query, err = cumulative.PrepareMetricQueryCumulativeTable(start, end, mq.StepInterval, mq) } else { query, err = cumulative.PrepareMetricQueryCumulativeTimeSeries(start, end, mq.StepInterval, mq) } } if err != nil { return "", err } groupByWithoutLe := []v3.AttributeKey{} for _, groupBy := range mq.GroupBy { if groupBy.Key != "le" { groupByWithoutLe = append(groupByWithoutLe, groupBy) } } groupBy := helpers.GroupByAttributeKeyTags(groupByWithoutLe...) orderBy := helpers.OrderByAttributeKeyTags(mq.OrderBy, groupByWithoutLe) // fixed-bucket histogram quantiles are calculated with UDF if quantile != 0 && mq.AggregateAttribute.Type != v3.AttributeKeyType(v3.MetricTypeExponentialHistogram) { query = fmt.Sprintf(`SELECT %s, histogramQuantile(arrayMap(x -> toFloat64(x), groupArray(le)), groupArray(value), %.3f) as value FROM (%s) GROUP BY %s ORDER BY %s`, groupBy, quantile, query, groupBy, orderBy) mq.SpaceAggregation = percentileOperator } return query, nil } func BuildPromQuery(promQuery *v3.PromQuery, step, start, end int64) *model.QueryRangeParams { return &model.QueryRangeParams{ Query: promQuery.Query, Start: time.UnixMilli(start), End: time.UnixMilli(end), Step: time.Duration(step * int64(time.Second)), } }