mirror of
https://github.com/prometheus/prometheus.git
synced 2025-03-05 20:59:13 -08:00
promql: copy data when short-circuiting (#9552)
* promql: copy data when short-circuiting Because the range query loop re-uses the output buffer each time round, we must copy results into the buffer rather than using input as output. Signed-off-by: Bryan Boreham <bjboreham@gmail.com>
This commit is contained in:
parent
1043d2b594
commit
a278ea4b58
|
@ -1792,9 +1792,11 @@ func (ev *evaluator) VectorOr(lhs, rhs Vector, matching *parser.VectorMatching,
|
||||||
panic("set operations must only use many-to-many matching")
|
panic("set operations must only use many-to-many matching")
|
||||||
}
|
}
|
||||||
if len(lhs) == 0 { // Short-circuit.
|
if len(lhs) == 0 { // Short-circuit.
|
||||||
return rhs
|
enh.Out = append(enh.Out, rhs...)
|
||||||
|
return enh.Out
|
||||||
} else if len(rhs) == 0 {
|
} else if len(rhs) == 0 {
|
||||||
return lhs
|
enh.Out = append(enh.Out, lhs...)
|
||||||
|
return enh.Out
|
||||||
}
|
}
|
||||||
|
|
||||||
leftSigs := map[string]struct{}{}
|
leftSigs := map[string]struct{}{}
|
||||||
|
@ -1819,7 +1821,8 @@ func (ev *evaluator) VectorUnless(lhs, rhs Vector, matching *parser.VectorMatchi
|
||||||
// Short-circuit: empty rhs means we will return everything in lhs;
|
// Short-circuit: empty rhs means we will return everything in lhs;
|
||||||
// empty lhs means we will return empty - don't need to build a map.
|
// empty lhs means we will return empty - don't need to build a map.
|
||||||
if len(lhs) == 0 || len(rhs) == 0 {
|
if len(lhs) == 0 || len(rhs) == 0 {
|
||||||
return lhs
|
enh.Out = append(enh.Out, lhs...)
|
||||||
|
return enh.Out
|
||||||
}
|
}
|
||||||
|
|
||||||
rightSigs := map[string]struct{}{}
|
rightSigs := map[string]struct{}{}
|
||||||
|
|
|
@ -2410,6 +2410,32 @@ func TestRangeQuery(t *testing.T) {
|
||||||
End: time.Unix(120, 0),
|
End: time.Unix(120, 0),
|
||||||
Interval: 1 * time.Minute,
|
Interval: 1 * time.Minute,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
Name: "short-circuit",
|
||||||
|
Load: `load 30s
|
||||||
|
foo{job="1"} 1+1x4
|
||||||
|
bar{job="2"} 1+1x4`,
|
||||||
|
Query: `foo > 2 or bar`,
|
||||||
|
Result: Matrix{
|
||||||
|
Series{
|
||||||
|
Points: []Point{{V: 1, T: 0}, {V: 3, T: 60000}, {V: 5, T: 120000}},
|
||||||
|
Metric: labels.Labels{
|
||||||
|
labels.Label{Name: "__name__", Value: "bar"},
|
||||||
|
labels.Label{Name: "job", Value: "2"},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Series{
|
||||||
|
Points: []Point{{V: 3, T: 60000}, {V: 5, T: 120000}},
|
||||||
|
Metric: labels.Labels{
|
||||||
|
labels.Label{Name: "__name__", Value: "foo"},
|
||||||
|
labels.Label{Name: "job", Value: "1"},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Start: time.Unix(0, 0),
|
||||||
|
End: time.Unix(120, 0),
|
||||||
|
Interval: 1 * time.Minute,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
for _, c := range cases {
|
for _, c := range cases {
|
||||||
t.Run(c.Name, func(t *testing.T) {
|
t.Run(c.Name, func(t *testing.T) {
|
||||||
|
|
Loading…
Reference in a new issue