From cd559ccf8467c65c9c7d2d0b60c79f478a160d14 Mon Sep 17 00:00:00 2001 From: Courtney Holcomb Date: Tue, 10 Oct 2023 14:40:53 -0700 Subject: [PATCH] Case insensitivity for query params --- metricflow/query/query_parser.py | 5 +- metricflow/test/query/test_query_parser.py | 60 ++++++++++++++++++++++ 2 files changed, 63 insertions(+), 2 deletions(-) diff --git a/metricflow/query/query_parser.py b/metricflow/query/query_parser.py index aa3acd4f15..6bb4185da2 100644 --- a/metricflow/query/query_parser.py +++ b/metricflow/query/query_parser.py @@ -681,7 +681,7 @@ def _parse_group_by( structured_names = [StructuredLinkableSpecName.from_name(name) for name in group_by_names] elif group_by: for group_by_obj in group_by: - parsed_name = StructuredLinkableSpecName.from_name(group_by_obj.name) + parsed_name = StructuredLinkableSpecName.from_name(group_by_obj.name.lower()) structured_name = StructuredLinkableSpecName( entity_link_names=parsed_name.entity_link_names, element_name=parsed_name.element_name, @@ -832,6 +832,7 @@ def _parse_order_by( time_granularity: Optional[TimeGranularity] = None date_part: Optional[DatePart] = None if isinstance(order, str): + order = order.lower() # Note: date part cannot be requested via string parameter. descending = False if order.startswith("-"): @@ -841,7 +842,7 @@ def _parse_order_by( time_granularity = parsed_name.time_granularity else: descending = order.descending - parsed_name = StructuredLinkableSpecName.from_name(order.order_by.name) + parsed_name = StructuredLinkableSpecName.from_name(order.order_by.name.lower()) if isinstance(order.order_by, TimeDimensionQueryParameter): time_granularity = order.order_by.grain date_part = order.order_by.date_part diff --git a/metricflow/test/query/test_query_parser.py b/metricflow/test/query/test_query_parser.py index e362fd8ed2..19ece527b4 100644 --- a/metricflow/test/query/test_query_parser.py +++ b/metricflow/test/query/test_query_parser.py @@ -190,6 +190,66 @@ def test_query_parser(bookings_query_parser: MetricFlowQueryParser) -> None: # ) +def test_query_parser_case_insensitivity(bookings_query_parser: MetricFlowQueryParser) -> None: # noqa: D + # String params + query_spec = bookings_query_parser.parse_and_validate_query( + metric_names=["BOOKINGS"], + group_by_names=["BOOKING__IS_INSTANT", "LISTING", MTD.upper()], + order_by_names=[MTD.upper(), "-BOOKINGS"], + ) + + assert query_spec.metric_specs == (MetricSpec(element_name="bookings"),) + assert query_spec.dimension_specs == ( + DimensionSpec(element_name="is_instant", entity_links=(EntityReference("booking"),)), + ) + assert query_spec.time_dimension_specs == ( + TimeDimensionSpec(element_name=MTD, entity_links=(), time_granularity=TimeGranularity.DAY), + ) + assert query_spec.entity_specs == (EntitySpec(element_name="listing", entity_links=()),) + assert query_spec.order_by_specs == ( + OrderBySpec( + instance_spec=TimeDimensionSpec(element_name=MTD, entity_links=(), time_granularity=TimeGranularity.DAY), + descending=False, + ), + OrderBySpec( + instance_spec=MetricSpec(element_name="bookings"), + descending=True, + ), + ) + + # Object params + Metric = namedtuple("Metric", ["name", "descending"]) + metric = Metric("BOOKINGS", False) + group_by = ( + DimensionOrEntityParameter("BOOKING__IS_INSTANT"), + DimensionOrEntityParameter("LISTING"), + TimeDimensionParameter(MTD.upper()), + ) + order_by = ( + OrderByParameter(order_by=TimeDimensionParameter(MTD.upper())), + OrderByParameter(order_by=MetricParameter("BOOKINGS"), descending=True), + ) + query_spec = bookings_query_parser.parse_and_validate_query(metrics=[metric], group_by=group_by, order_by=order_by) + assert query_spec.metric_specs == (MetricSpec(element_name="bookings"),) + assert query_spec.dimension_specs == ( + DimensionSpec(element_name="is_instant", entity_links=(EntityReference("booking"),)), + ) + assert query_spec.time_dimension_specs == ( + TimeDimensionSpec(element_name=MTD, entity_links=(), time_granularity=TimeGranularity.DAY), + ) + assert query_spec.entity_specs == (EntitySpec(element_name="listing", entity_links=()),) + assert query_spec.order_by_specs == ( + OrderBySpec( + instance_spec=TimeDimensionSpec(element_name=MTD, entity_links=(), time_granularity=TimeGranularity.DAY), + descending=False, + ), + OrderBySpec( + instance_spec=MetricSpec(element_name="bookings"), + descending=True, + ), + ) + + def test_query_parser_with_object_params(bookings_query_parser: MetricFlowQueryParser) -> None: # noqa: D Metric = namedtuple("Metric", ["name", "descending"]) metric = Metric("bookings", False)