mirror of
https://github.com/prometheus/prometheus.git
synced 2026-02-03 20:39:32 -05:00
fix/promql/parser: Fix utf-8 label quoting in format_query endpoint
Signed-off-by: ADITYA TIWARI <adityatiwari342005@gmail.com>
This commit is contained in:
parent
6f18cc3074
commit
5b299ef99e
2 changed files with 62 additions and 3 deletions
|
|
@ -109,7 +109,7 @@ func writeLabels(b *bytes.Buffer, ss []string) {
|
|||
if i > 0 {
|
||||
b.WriteString(", ")
|
||||
}
|
||||
if !model.LegacyValidation.IsValidMetricName(s) {
|
||||
if !model.LegacyValidation.IsValidLabelName(s) {
|
||||
b.Write(strconv.AppendQuote(b.AvailableBuffer(), s))
|
||||
} else {
|
||||
b.WriteString(s)
|
||||
|
|
@ -145,6 +145,19 @@ func (node *BinaryExpr) ShortString() string {
|
|||
return node.Op.String() + node.returnBool() + node.getMatchingStr()
|
||||
}
|
||||
|
||||
// joinLabels joins label names, quoting them if they are not valid legacy label names.
|
||||
func joinLabels(labels []string) string {
|
||||
quoted := make([]string, 0, len(labels))
|
||||
for _, label := range labels {
|
||||
if model.LegacyValidation.IsValidLabelName(label) {
|
||||
quoted = append(quoted, label)
|
||||
} else {
|
||||
quoted = append(quoted, strconv.Quote(label))
|
||||
}
|
||||
}
|
||||
return strings.Join(quoted, ", ")
|
||||
}
|
||||
|
||||
func (node *BinaryExpr) getMatchingStr() string {
|
||||
matching := ""
|
||||
vm := node.VectorMatching
|
||||
|
|
@ -154,7 +167,7 @@ func (node *BinaryExpr) getMatchingStr() string {
|
|||
if vm.On {
|
||||
vmTag = "on"
|
||||
}
|
||||
matching = fmt.Sprintf(" %s (%s)", vmTag, strings.Join(vm.MatchingLabels, ", "))
|
||||
matching = fmt.Sprintf(" %s (%s)", vmTag, joinLabels(vm.MatchingLabels))
|
||||
}
|
||||
|
||||
if vm.Card == CardManyToOne || vm.Card == CardOneToMany {
|
||||
|
|
@ -162,7 +175,7 @@ func (node *BinaryExpr) getMatchingStr() string {
|
|||
if vm.Card == CardManyToOne {
|
||||
vmCard = "left"
|
||||
}
|
||||
matching += fmt.Sprintf(" group_%s (%s)", vmCard, strings.Join(vm.Include, ", "))
|
||||
matching += fmt.Sprintf(" group_%s (%s)", vmCard, joinLabels(vm.Include))
|
||||
}
|
||||
}
|
||||
return matching
|
||||
|
|
|
|||
|
|
@ -269,6 +269,10 @@ func TestExprString(t *testing.T) {
|
|||
{
|
||||
in: `predict_linear(foo[1h], 3000)`,
|
||||
},
|
||||
{
|
||||
in: `sum by("üüü") (foo)`,
|
||||
out: `sum by ("üüü") (foo)`,
|
||||
},
|
||||
}
|
||||
|
||||
EnableExtendedRangeSelectors = true
|
||||
|
|
@ -394,3 +398,45 @@ func TestVectorSelector_String(t *testing.T) {
|
|||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestBinaryExprUTF8Labels(t *testing.T) {
|
||||
testCases := []struct {
|
||||
name string
|
||||
input string
|
||||
expected string
|
||||
}{
|
||||
{
|
||||
name: "UTF-8 labels in on clause",
|
||||
input: `foo / on("äää") bar`,
|
||||
expected: `foo / on ("äää") bar`,
|
||||
},
|
||||
{
|
||||
name: "UTF-8 labels in group_left clause",
|
||||
input: `foo / on("äää") group_left("ööö") bar`,
|
||||
expected: `foo / on ("äää") group_left ("ööö") bar`,
|
||||
},
|
||||
{
|
||||
name: "Mixed legacy and UTF-8 labels",
|
||||
input: `foo / on(legacy, "üüü") bar`,
|
||||
expected: `foo / on (legacy, "üüü") bar`,
|
||||
},
|
||||
{
|
||||
name: "Legacy labels only (should not quote)",
|
||||
input: `foo / on(job, instance) bar`,
|
||||
expected: `foo / on (job, instance) bar`,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
expr, err := ParseExpr(tc.input)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to parse: %v", err)
|
||||
}
|
||||
result := expr.String()
|
||||
if result != tc.expected {
|
||||
t.Errorf("Expected: %s\nGot: %s", tc.expected, result)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue