app/vmselect/promql: properly detect aggregate topk* and bottomk* aggregate functions in order to disable duplicate sorting

Updates https://github.com/VictoriaMetrics/VictoriaMetrics/issues/1189
This commit is contained in:
Aliaksandr Valialkin 2021-04-08 00:09:34 +03:00
parent 9ce3b7e1dd
commit f90bf265f4
2 changed files with 29 additions and 16 deletions

View File

@ -618,7 +618,9 @@ func newAggrFuncTopK(isReverse bool) aggrFunc {
}) })
fillNaNsAtIdx(n, ks[n], tss) fillNaNsAtIdx(n, ks[n], tss)
} }
return removeNaNs(tss) tss = removeNaNs(tss)
reverseSeries(tss)
return tss
} }
return aggrFuncExt(afe, args[1], &afa.ae.Modifier, afa.ae.Limit, true) return aggrFuncExt(afe, args[1], &afa.ae.Modifier, afa.ae.Limit, true)
} }
@ -683,7 +685,17 @@ func getRangeTopKTimeseries(tss []*timeseries, modifier *metricsql.ModifierExpr,
if remainingSumTS != nil { if remainingSumTS != nil {
tss = append(tss, remainingSumTS) tss = append(tss, remainingSumTS)
} }
return removeNaNs(tss) tss = removeNaNs(tss)
reverseSeries(tss)
return tss
}
func reverseSeries(tss []*timeseries) {
j := len(tss)
for i := 0; i < len(tss)/2; i++ {
j--
tss[i], tss[j] = tss[j], tss[i]
}
} }
func getRemainingSumTimeseries(tss []*timeseries, modifier *metricsql.ModifierExpr, ks []float64, remainingSumTagName string) *timeseries { func getRemainingSumTimeseries(tss []*timeseries, modifier *metricsql.ModifierExpr, ks []float64, remainingSumTagName string) *timeseries {

View File

@ -86,21 +86,22 @@ func Exec(ec *EvalConfig, q string, isFirstPointOnly bool) ([]netstorage.Result,
} }
func maySortResults(e metricsql.Expr, tss []*timeseries) bool { func maySortResults(e metricsql.Expr, tss []*timeseries) bool {
fe, ok := e.(*metricsql.FuncExpr) switch v := e.(type) {
if !ok { case *metricsql.FuncExpr:
return true switch strings.ToLower(v.Name) {
}
switch fe.Name {
case "sort", "sort_desc", case "sort", "sort_desc",
"sort_by_label", "sort_by_label_desc", "sort_by_label", "sort_by_label_desc":
"topk", "bottomk",
"topk_max", "topk_min", "topk_avg", "topk_median",
"bottomk_max", "bottomk_min", "bottomk_avg", "bottomk_median",
"outliersk":
return false return false
default:
return true
} }
case *metricsql.AggrFuncExpr:
switch strings.ToLower(v.Name) {
case "topk", "bottomk", "outliersk",
"topk_max", "topk_min", "topk_avg", "topk_median",
"bottomk_max", "bottomk_min", "bottomk_avg", "bottomk_median":
return false
}
}
return true
} }
func timeseriesToResult(tss []*timeseries, maySort bool) ([]netstorage.Result, error) { func timeseriesToResult(tss []*timeseries, maySort bool) ([]netstorage.Result, error) {