From ec2581435442dca0a07b9b34fe717559c5f3ea9c Mon Sep 17 00:00:00 2001 From: Wan Kai Date: Tue, 28 Mar 2023 11:04:52 +0800 Subject: [PATCH] Support parse PromQL expression has empty labels in the braces for metadata query. (#10599) --- docs/en/changes/changes.md | 1 + .../promql/rt/grammar/PromQLParser.g4 | 2 +- .../rt/parser/PromQLMatchVisitorTest.java | 47 +++++++++++++++---- 3 files changed, 41 insertions(+), 9 deletions(-) diff --git a/docs/en/changes/changes.md b/docs/en/changes/changes.md index 55498f22b1..38073edeb5 100644 --- a/docs/en/changes/changes.md +++ b/docs/en/changes/changes.md @@ -20,6 +20,7 @@ * [Breaking Change] Support cross-thread trace profiling. The data structure and query APIs are changed. * Fix PromQL HTTP API `/api/v1/labels` response missing `service` label. * Fix possible NPE when initialize `IntList`. +* Support parse PromQL expression has empty labels in the braces for metadata query. #### UI * Revert: cpm5d function. This feature is cancelled from backend. diff --git a/oap-server/server-query-plugin/promql-plugin/src/main/antlr4/org/apache/skywalking/promql/rt/grammar/PromQLParser.g4 b/oap-server/server-query-plugin/promql-plugin/src/main/antlr4/org/apache/skywalking/promql/rt/grammar/PromQLParser.g4 index ae29a801e0..3d0abf8485 100644 --- a/oap-server/server-query-plugin/promql-plugin/src/main/antlr4/org/apache/skywalking/promql/rt/grammar/PromQLParser.g4 +++ b/oap-server/server-query-plugin/promql-plugin/src/main/antlr4/org/apache/skywalking/promql/rt/grammar/PromQLParser.g4 @@ -36,7 +36,7 @@ mulDivMod: MUL | DIV | MOD; compare: (DEQ | NEQ | LTE | LT | GTE | GT) BOOL?; metricName: NAME_STRING; -metricInstant: metricName | metricName L_BRACE labelList R_BRACE; +metricInstant: metricName | metricName L_BRACE labelList? R_BRACE; metricRange: metricInstant L_BRACKET DURATION R_BRACKET; labelName: NAME_STRING; diff --git a/oap-server/server-query-plugin/promql-plugin/src/test/java/org/apache/skywalking/promql/rt/parser/PromQLMatchVisitorTest.java b/oap-server/server-query-plugin/promql-plugin/src/test/java/org/apache/skywalking/promql/rt/parser/PromQLMatchVisitorTest.java index e4becc6643..232c4c4801 100644 --- a/oap-server/server-query-plugin/promql-plugin/src/test/java/org/apache/skywalking/promql/rt/parser/PromQLMatchVisitorTest.java +++ b/oap-server/server-query-plugin/promql-plugin/src/test/java/org/apache/skywalking/promql/rt/parser/PromQLMatchVisitorTest.java @@ -18,6 +18,8 @@ package org.apache.skywalking.promql.rt.parser; +import java.util.Arrays; +import java.util.Collection; import org.antlr.v4.runtime.CharStreams; import org.antlr.v4.runtime.CommonTokenStream; import org.antlr.v4.runtime.tree.ParseTree; @@ -27,20 +29,49 @@ import org.apache.skywalking.oap.query.promql.rt.result.ParseResultType; import org.apache.skywalking.promql.rt.grammar.PromQLLexer; import org.apache.skywalking.promql.rt.grammar.PromQLParser; import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.MethodSource; public class PromQLMatchVisitorTest { - @Test - public void testMatchVisitor() { - PromQLLexer lexer = new PromQLLexer( - CharStreams.fromString("service_cpm{service='serviceA', layer='GENERAL'}")); + + public static Collection data() { + return Arrays.asList(new Object[][] { + { + "service_cpm", + ParseResultType.MATCH, + "service_cpm", + 0 + }, + { + "service_cpm{}", + ParseResultType.MATCH, + "service_cpm", + 0 + }, + { + "service_cpm{service='serviceA', layer='GENERAL'}", + ParseResultType.MATCH, + "service_cpm", + 2 + } + }); + } + + @ParameterizedTest + @MethodSource("data") + public void testMatchVisitor( + String expression, + ParseResultType wantType, + String metricName, + int labelsSize) { + PromQLLexer lexer = new PromQLLexer(CharStreams.fromString(expression)); CommonTokenStream tokens = new CommonTokenStream(lexer); PromQLParser parser = new PromQLParser(tokens); ParseTree tree = parser.expression(); PromQLMatchVisitor visitor = new PromQLMatchVisitor(); MatcherSetResult parseResult = visitor.visit(tree); - Assertions.assertEquals(ParseResultType.MATCH, parseResult.getResultType()); - Assertions.assertEquals("service_cpm", parseResult.getMetricName()); - Assertions.assertEquals(2, parseResult.getLabelMap().size()); + Assertions.assertEquals(wantType, parseResult.getResultType()); + Assertions.assertEquals(metricName, parseResult.getMetricName()); + Assertions.assertEquals(labelsSize, parseResult.getLabelMap().size()); } }