mirror of
https://github.com/prometheus/prometheus.git
synced 2024-11-09 23:24:05 -08:00
Fix parser.VectorSelector.String()
with empty name matcher (#14015)
The check fell into "this matcher equals vector selector's name" case when vector selector doesn't have a name and the matcher is an explicit matcher for an empty __name__ label. To provide some context about why this is important: some downstream projects use the promql.Parse(expr.String()) to clone an expression's AST, and with this bug that matcher disappears in the cloning. Signed-off-by: Oleg Zaytsev <mail@olegzaytsev.com>
This commit is contained in:
parent
93be83069e
commit
4b7a44c7a0
|
@ -204,8 +204,8 @@ func (node *VectorSelector) String() string {
|
|||
labelStrings = make([]string, 0, len(node.LabelMatchers)-1)
|
||||
}
|
||||
for _, matcher := range node.LabelMatchers {
|
||||
// Only include the __name__ label if its equality matching and matches the name.
|
||||
if matcher.Name == labels.MetricName && matcher.Type == labels.MatchEqual && matcher.Value == node.Name {
|
||||
// Only include the __name__ label if its equality matching and matches the name, but don't skip if it's an explicit empty name matcher.
|
||||
if matcher.Name == labels.MetricName && matcher.Type == labels.MatchEqual && matcher.Value == node.Name && matcher.Value != "" {
|
||||
continue
|
||||
}
|
||||
labelStrings = append(labelStrings, matcher.String())
|
||||
|
|
|
@ -135,6 +135,9 @@ func TestExprString(t *testing.T) {
|
|||
{
|
||||
in: `a[1m] @ end()`,
|
||||
},
|
||||
{
|
||||
in: `{__name__="",a="x"}`,
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range inputs {
|
||||
|
@ -216,6 +219,16 @@ func TestVectorSelector_String(t *testing.T) {
|
|||
},
|
||||
expected: `{__name__="foobar"}`,
|
||||
},
|
||||
{
|
||||
name: "empty name matcher",
|
||||
vs: VectorSelector{
|
||||
LabelMatchers: []*labels.Matcher{
|
||||
labels.MustNewMatcher(labels.MatchEqual, labels.MetricName, ""),
|
||||
labels.MustNewMatcher(labels.MatchEqual, "a", "x"),
|
||||
},
|
||||
},
|
||||
expected: `{__name__="",a="x"}`,
|
||||
},
|
||||
} {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
require.Equal(t, tc.expected, tc.vs.String())
|
||||
|
|
Loading…
Reference in a new issue