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")
|
||||
}
|
||||
if len(lhs) == 0 { // Short-circuit.
|
||||
return rhs
|
||||
enh.Out = append(enh.Out, rhs...)
|
||||
return enh.Out
|
||||
} else if len(rhs) == 0 {
|
||||
return lhs
|
||||
enh.Out = append(enh.Out, lhs...)
|
||||
return enh.Out
|
||||
}
|
||||
|
||||
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;
|
||||
// empty lhs means we will return empty - don't need to build a map.
|
||||
if len(lhs) == 0 || len(rhs) == 0 {
|
||||
return lhs
|
||||
enh.Out = append(enh.Out, lhs...)
|
||||
return enh.Out
|
||||
}
|
||||
|
||||
rightSigs := map[string]struct{}{}
|
||||
|
|
|
@ -2410,6 +2410,32 @@ func TestRangeQuery(t *testing.T) {
|
|||
End: time.Unix(120, 0),
|
||||
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 {
|
||||
t.Run(c.Name, func(t *testing.T) {
|
||||
|
|
Loading…
Reference in New Issue