From b927aac70d7dfd9112201344077f0a65998a74b2 Mon Sep 17 00:00:00 2001 From: Shaik Sher Ali Date: Thu, 2 Nov 2023 22:01:00 -0700 Subject: [PATCH] misc(query): make match[] parameter optional for LabelNames queries (#1687) --- .../MultiPartitionPlannerSpec.scala | 23 +++++++++++++++++++ .../filodb/prometheus/parse/Parser.scala | 14 +++++++---- 2 files changed, 32 insertions(+), 5 deletions(-) diff --git a/coordinator/src/test/scala/filodb.coordinator/queryplanner/MultiPartitionPlannerSpec.scala b/coordinator/src/test/scala/filodb.coordinator/queryplanner/MultiPartitionPlannerSpec.scala index a2de722611..2f47ddf533 100644 --- a/coordinator/src/test/scala/filodb.coordinator/queryplanner/MultiPartitionPlannerSpec.scala +++ b/coordinator/src/test/scala/filodb.coordinator/queryplanner/MultiPartitionPlannerSpec.scala @@ -1337,6 +1337,29 @@ class MultiPartitionPlannerSpec extends AnyFunSpec with Matchers with PlanValida .children(0).asInstanceOf[LabelNamesExec].endMs shouldEqual (endSeconds * 1000) } + it("should materialize LabelNames with empty query correctly") { + val (startSeconds: Int, endSeconds: Int, engine: MultiPartitionPlanner) = getPlannerForMetadataQueryTests + + val promQl = """""" + val lv = Parser.labelNamesQueryToLogicalPlan(promQl, TimeStepParams(startSeconds, step, endSeconds)) + + val promQlQueryParams = PromQlQueryParams(promQl, startSeconds, step, endSeconds, Some("/api/v2/labels/name")) + val execPlan = engine.materialize(lv, QueryContext(origQueryParams = promQlQueryParams, plannerParams = + PlannerParams(processMultiPartition = true))) + + execPlan.isInstanceOf[LabelNamesDistConcatExec] shouldEqual true + execPlan.children.size shouldEqual 2 + + val expectedUrlParams = Map("match[]" -> "{}") + execPlan.children(1).asInstanceOf[MetadataRemoteExec].urlParams shouldEqual (expectedUrlParams) + execPlan.children(1).asInstanceOf[MetadataRemoteExec].queryContext.origQueryParams.asInstanceOf[PromQlQueryParams]. + endSecs shouldEqual (localPartitionStart - 1) + execPlan.children(0).asInstanceOf[LabelNamesDistConcatExec] + .children(0).asInstanceOf[LabelNamesExec].startMs shouldEqual (localPartitionStart * 1000) + execPlan.children(0).asInstanceOf[LabelNamesDistConcatExec] + .children(0).asInstanceOf[LabelNamesExec].endMs shouldEqual (endSeconds * 1000) + } + it ("should generate correct plan for multipartition BinaryJoin with instant function") { def partitions(timeRange: TimeRange): List[PartitionAssignment] = List(PartitionAssignment("remote", "remote-url", TimeRange(timeRange.startMs, timeRange.endMs))) diff --git a/prometheus/src/main/scala/filodb/prometheus/parse/Parser.scala b/prometheus/src/main/scala/filodb/prometheus/parse/Parser.scala index f6bde99cef..3fb870e0bd 100644 --- a/prometheus/src/main/scala/filodb/prometheus/parse/Parser.scala +++ b/prometheus/src/main/scala/filodb/prometheus/parse/Parser.scala @@ -5,7 +5,7 @@ import com.typesafe.scalalogging.StrictLogging import filodb.core.GlobalConfig import filodb.core.query.{ColumnFilter, Filter, QueryConfig, QueryUtils} import filodb.prometheus.ast._ -import filodb.query.{LabelValues, LogicalPlan} +import filodb.query.{LabelNames, LabelValues, LogicalPlan} /** * Parser routes requests to LegacyParser or AntlrParser. @@ -169,10 +169,14 @@ object Parser extends StrictLogging { def labelNamesQueryToLogicalPlan(query: String, timeParams: TimeRangeParams): LogicalPlan = { - val expression = parseQuery(query) - expression match { - case p: InstantExpression => p.toLabelNamesPlan(timeParams) - case _ => throw new UnsupportedOperationException() + if (query == null || query.isEmpty) { + LabelNames(Seq.empty, timeParams.start * 1000, timeParams.end * 1000) + } else { + val expression = parseQuery(query) + expression match { + case p: InstantExpression => p.toLabelNamesPlan(timeParams) + case _ => throw new UnsupportedOperationException() + } } }