mirror of
https://github.com/VictoriaMetrics/VictoriaMetrics.git
synced 2024-12-15 08:23:34 +01:00
app/vmselect/promql: properly override label values from group_left
and group_right
lists like Prometheus does
Updates https://github.com/VictoriaMetrics/VictoriaMetrics/issues/577
This commit is contained in:
parent
50aa34bcbe
commit
70bf8218bb
@ -206,7 +206,7 @@ func groupJoin(singleTimeseriesSide string, be *metricsql.BinaryOpExpr, rvsLeft,
|
|||||||
resetMetricGroupIfRequired(be, tsLeft)
|
resetMetricGroupIfRequired(be, tsLeft)
|
||||||
if len(tssRight) == 1 {
|
if len(tssRight) == 1 {
|
||||||
// Easy case - right part contains only a single matching time series.
|
// Easy case - right part contains only a single matching time series.
|
||||||
tsLeft.MetricName.AddMissingTags(joinTags, &tssRight[0].MetricName)
|
tsLeft.MetricName.SetTags(joinTags, &tssRight[0].MetricName)
|
||||||
rvsLeft = append(rvsLeft, tsLeft)
|
rvsLeft = append(rvsLeft, tsLeft)
|
||||||
rvsRight = append(rvsRight, tssRight[0])
|
rvsRight = append(rvsRight, tssRight[0])
|
||||||
continue
|
continue
|
||||||
@ -225,7 +225,7 @@ func groupJoin(singleTimeseriesSide string, be *metricsql.BinaryOpExpr, rvsLeft,
|
|||||||
for _, tsRight := range tssRight {
|
for _, tsRight := range tssRight {
|
||||||
var tsCopy timeseries
|
var tsCopy timeseries
|
||||||
tsCopy.CopyFromShallowTimestamps(tsLeft)
|
tsCopy.CopyFromShallowTimestamps(tsLeft)
|
||||||
tsCopy.MetricName.AddMissingTags(joinTags, &tsRight.MetricName)
|
tsCopy.MetricName.SetTags(joinTags, &tsRight.MetricName)
|
||||||
bb.B = marshalMetricTagsSorted(bb.B[:0], &tsCopy.MetricName)
|
bb.B = marshalMetricTagsSorted(bb.B[:0], &tsCopy.MetricName)
|
||||||
if tsExisting := m[string(bb.B)]; tsExisting != nil {
|
if tsExisting := m[string(bb.B)]; tsExisting != nil {
|
||||||
// Try merging tsExisting with tsRight if they don't overlap.
|
// Try merging tsExisting with tsRight if they don't overlap.
|
||||||
|
@ -2009,25 +2009,37 @@ func TestExecSuccess(t *testing.T) {
|
|||||||
})
|
})
|
||||||
t.Run(`scalar * ignoring(foo) group_right vector`, func(t *testing.T) {
|
t.Run(`scalar * ignoring(foo) group_right vector`, func(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
q := `sort_desc(2 * ignoring(foo) group_right(a,foo) (label_set(time(), "foo", "bar") or label_set(10, "foo", "qwert")))`
|
q := `sort_desc(label_set(2, "a", "2") * ignoring(foo,a) group_right(a) (label_set(time(), "foo", "bar", "a", "1"), label_set(10, "foo", "qwert")))`
|
||||||
r1 := netstorage.Result{
|
r1 := netstorage.Result{
|
||||||
MetricName: metricNameExpected,
|
MetricName: metricNameExpected,
|
||||||
Values: []float64{2000, 2400, 2800, 3200, 3600, 4000},
|
Values: []float64{2000, 2400, 2800, 3200, 3600, 4000},
|
||||||
Timestamps: timestampsExpected,
|
Timestamps: timestampsExpected,
|
||||||
}
|
}
|
||||||
r1.MetricName.Tags = []storage.Tag{{
|
r1.MetricName.Tags = []storage.Tag{
|
||||||
Key: []byte("foo"),
|
{
|
||||||
Value: []byte("bar"),
|
Key: []byte("a"),
|
||||||
}}
|
Value: []byte("2"),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Key: []byte("foo"),
|
||||||
|
Value: []byte("bar"),
|
||||||
|
},
|
||||||
|
}
|
||||||
r2 := netstorage.Result{
|
r2 := netstorage.Result{
|
||||||
MetricName: metricNameExpected,
|
MetricName: metricNameExpected,
|
||||||
Values: []float64{20, 20, 20, 20, 20, 20},
|
Values: []float64{20, 20, 20, 20, 20, 20},
|
||||||
Timestamps: timestampsExpected,
|
Timestamps: timestampsExpected,
|
||||||
}
|
}
|
||||||
r2.MetricName.Tags = []storage.Tag{{
|
r2.MetricName.Tags = []storage.Tag{
|
||||||
Key: []byte("foo"),
|
{
|
||||||
Value: []byte("qwert"),
|
Key: []byte("a"),
|
||||||
}}
|
Value: []byte("2"),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Key: []byte("foo"),
|
||||||
|
Value: []byte("qwert"),
|
||||||
|
},
|
||||||
|
}
|
||||||
resultExpected := []netstorage.Result{r1, r2}
|
resultExpected := []netstorage.Result{r1, r2}
|
||||||
f(q, resultExpected)
|
f(q, resultExpected)
|
||||||
})
|
})
|
||||||
@ -2342,9 +2354,9 @@ func TestExecSuccess(t *testing.T) {
|
|||||||
t.Run(`vector + vector on group_left matching`, func(t *testing.T) {
|
t.Run(`vector + vector on group_left matching`, func(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
q := `sort_desc(
|
q := `sort_desc(
|
||||||
(label_set(time(), "t1", "v123", "t2", "v3") or label_set(10, "t2", "v3", "xxx", "yy"))
|
(label_set(time(), "t1", "v123", "t2", "v3"), label_set(10, "t2", "v3", "xxx", "yy"))
|
||||||
+ on (foo, t2) group_left (t1, noxxx)
|
+ on (foo, t2) group_left (t1, noxxx)
|
||||||
(label_set(100, "t1", "v1") or label_set(time(), "t2", "v3", "noxxx", "aa"))
|
(label_set(100, "t1", "v1"), label_set(time(), "t2", "v3", "noxxx", "aa"))
|
||||||
)`
|
)`
|
||||||
r1 := netstorage.Result{
|
r1 := netstorage.Result{
|
||||||
MetricName: metricNameExpected,
|
MetricName: metricNameExpected,
|
||||||
@ -2356,10 +2368,6 @@ func TestExecSuccess(t *testing.T) {
|
|||||||
Key: []byte("noxxx"),
|
Key: []byte("noxxx"),
|
||||||
Value: []byte("aa"),
|
Value: []byte("aa"),
|
||||||
},
|
},
|
||||||
{
|
|
||||||
Key: []byte("t1"),
|
|
||||||
Value: []byte("v123"),
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
Key: []byte("t2"),
|
Key: []byte("t2"),
|
||||||
Value: []byte("v3"),
|
Value: []byte("v3"),
|
||||||
|
@ -298,20 +298,30 @@ func (mn *MetricName) GetTagValue(tagKey string) []byte {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// AddMissingTags adds tags from src with keys matching addTags.
|
// SetTags sets tags from src with keys matching addTags.
|
||||||
func (mn *MetricName) AddMissingTags(addTags []string, src *MetricName) {
|
func (mn *MetricName) SetTags(addTags []string, src *MetricName) {
|
||||||
if hasTag(addTags, metricGroupTagKey) {
|
for _, tagName := range addTags {
|
||||||
mn.MetricGroup = append(mn.MetricGroup[:0], src.MetricGroup...)
|
if tagName == string(metricGroupTagKey) {
|
||||||
}
|
mn.MetricGroup = append(mn.MetricGroup[:0], src.MetricGroup...)
|
||||||
for i := range src.Tags {
|
continue
|
||||||
srcTag := &src.Tags[i]
|
}
|
||||||
if !hasTag(addTags, srcTag.Key) {
|
var srcTag *Tag
|
||||||
|
for i := range src.Tags {
|
||||||
|
t := &src.Tags[i]
|
||||||
|
if string(t.Key) == tagName {
|
||||||
|
srcTag = t
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if srcTag == nil {
|
||||||
|
mn.RemoveTag(tagName)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
found := false
|
found := false
|
||||||
for j := range mn.Tags {
|
for i := range mn.Tags {
|
||||||
tag := &mn.Tags[j]
|
t := &mn.Tags[i]
|
||||||
if string(tag.Key) == string(srcTag.Key) {
|
if string(t.Key) == tagName {
|
||||||
|
t.Value = append(t.Value[:0], srcTag.Value...)
|
||||||
found = true
|
found = true
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user