Skip to content

Commit 2037111

Browse files
[FIX] PromQL: Ignore histograms in scalar, sort and sort_desc functions (prometheus#15964)
PromQL: Ignore histograms in scalar, sort and sort_desc functions --------- Signed-off-by: Neeraj Gartia <neerajgartia211002@gmail.com>
1 parent cb096a8 commit 2037111

File tree

2 files changed

+52
-23
lines changed

2 files changed

+52
-23
lines changed

promql/functions.go

Lines changed: 32 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -486,11 +486,22 @@ func funcDoubleExponentialSmoothing(vals []parser.Value, args parser.Expressions
486486
return append(enh.Out, Sample{F: s1}), nil
487487
}
488488

489+
// filterFloats filters out histogram samples from the vector in-place.
490+
func filterFloats(v Vector) Vector {
491+
floats := v[:0]
492+
for _, s := range v {
493+
if s.H == nil {
494+
floats = append(floats, s)
495+
}
496+
}
497+
return floats
498+
}
499+
489500
// === sort(node parser.ValueTypeVector) (Vector, Annotations) ===
490501
func funcSort(vals []parser.Value, args parser.Expressions, enh *EvalNodeHelper) (Vector, annotations.Annotations) {
491502
// NaN should sort to the bottom, so take descending sort with NaN first and
492503
// reverse it.
493-
byValueSorter := vectorByReverseValueHeap(vals[0].(Vector))
504+
byValueSorter := vectorByReverseValueHeap(filterFloats(vals[0].(Vector)))
494505
sort.Sort(sort.Reverse(byValueSorter))
495506
return Vector(byValueSorter), nil
496507
}
@@ -499,7 +510,7 @@ func funcSort(vals []parser.Value, args parser.Expressions, enh *EvalNodeHelper)
499510
func funcSortDesc(vals []parser.Value, args parser.Expressions, enh *EvalNodeHelper) (Vector, annotations.Annotations) {
500511
// NaN should sort to the bottom, so take ascending sort with NaN first and
501512
// reverse it.
502-
byValueSorter := vectorByValueHeap(vals[0].(Vector))
513+
byValueSorter := vectorByValueHeap(filterFloats(vals[0].(Vector)))
503514
sort.Sort(sort.Reverse(byValueSorter))
504515
return Vector(byValueSorter), nil
505516
}
@@ -631,11 +642,27 @@ func funcRound(vals []parser.Value, args parser.Expressions, enh *EvalNodeHelper
631642

632643
// === Scalar(node parser.ValueTypeVector) Scalar ===
633644
func funcScalar(vals []parser.Value, args parser.Expressions, enh *EvalNodeHelper) (Vector, annotations.Annotations) {
634-
v := vals[0].(Vector)
635-
if len(v) != 1 {
645+
var (
646+
v = vals[0].(Vector)
647+
value float64
648+
found bool
649+
)
650+
651+
for _, s := range v {
652+
if s.H == nil {
653+
if found {
654+
// More than one float found, return NaN.
655+
return append(enh.Out, Sample{F: math.NaN()}), nil
656+
}
657+
found = true
658+
value = s.F
659+
}
660+
}
661+
// Return the single float if found, otherwise return NaN.
662+
if !found {
636663
return append(enh.Out, Sample{F: math.NaN()}), nil
637664
}
638-
return append(enh.Out, Sample{F: v[0].F}), nil
665+
return append(enh.Out, Sample{F: value}), nil
639666
}
640667

641668
func aggrOverTime(vals []parser.Value, enh *EvalNodeHelper, aggrFn func(Series) float64) Vector {
@@ -1896,16 +1923,7 @@ func (s vectorByValueHeap) Len() int {
18961923
}
18971924

18981925
func (s vectorByValueHeap) Less(i, j int) bool {
1899-
// We compare histograms based on their sum of observations.
1900-
// TODO(beorn7): Is that what we want?
19011926
vi, vj := s[i].F, s[j].F
1902-
if s[i].H != nil {
1903-
vi = s[i].H.Sum
1904-
}
1905-
if s[j].H != nil {
1906-
vj = s[j].H.Sum
1907-
}
1908-
19091927
if math.IsNaN(vi) {
19101928
return true
19111929
}
@@ -1935,16 +1953,7 @@ func (s vectorByReverseValueHeap) Len() int {
19351953
}
19361954

19371955
func (s vectorByReverseValueHeap) Less(i, j int) bool {
1938-
// We compare histograms based on their sum of observations.
1939-
// TODO(beorn7): Is that what we want?
19401956
vi, vj := s[i].F, s[j].F
1941-
if s[i].H != nil {
1942-
vi = s[i].H.Sum
1943-
}
1944-
if s[j].H != nil {
1945-
vj = s[j].H.Sum
1946-
}
1947-
19481957
if math.IsNaN(vi) {
19491958
return true
19501959
}

promql/promqltest/testdata/functions.test

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -642,6 +642,7 @@ load 5m
642642
http_requests{job="app-server", instance="1", group="production"} 0+60x10
643643
http_requests{job="app-server", instance="0", group="canary"} 0+70x10
644644
http_requests{job="app-server", instance="1", group="canary"} 0+80x10
645+
http_requests{job="app-server", instance="2", group="canary"} {{schema:0 sum:1 count:1}}x15
645646

646647
eval_ordered instant at 50m sort(http_requests)
647648
http_requests{group="production", instance="0", job="api-server"} 100
@@ -1652,3 +1653,22 @@ load 1m
16521653

16531654
eval range from 0 to 5m step 1m round(mixed_metric)
16541655
{} _ 1 2 3
1656+
1657+
# Test scalar() with histograms.
1658+
load 1m
1659+
metric{type="float", l="x"} 1
1660+
metric{type="float", l="y"} 2
1661+
metric{type="histogram", l="x"} {{schema:0 sum:1 count:1}}
1662+
metric{type="histogram", l="x"} {{schema:0 sum:1 count:1}}
1663+
1664+
# Two floats in the vector.
1665+
eval instant at 0m scalar(metric)
1666+
NaN
1667+
1668+
# No floats in the vector.
1669+
eval instant at 0m scalar({type="histogram"})
1670+
NaN
1671+
1672+
# One float in the vector.
1673+
eval instant at 0m scalar({l="x"})
1674+
1

0 commit comments

Comments
 (0)