Skip to content

Commit

Permalink
Write tests for metric_time filters in YAML definitions
Browse files Browse the repository at this point in the history
  • Loading branch information
courtneyholcomb committed Jul 17, 2024
1 parent ec2a052 commit dbe9a2f
Show file tree
Hide file tree
Showing 6 changed files with 330 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -120,3 +120,37 @@ metric:
metrics:
- name: simple_metric_with_time_granularity
- name: monthly_metric_0
---
metric:
name: simple_metric_with_time_granularity_and_metric_time_filter
description: Simple metric with time granularity and metric_time filter
type: simple
type_params:
measure: monthly_measure_1
time_granularity: quarter
filter: |
{{ TimeDimension('metric_time') }} > '2020-01-01'
---
metric:
name: derived_metric_with_time_granularity_and_outer_metric_time_filter
description: Derived metric with time granularity
type: derived
time_granularity: year
type_params:
expr: simple_metric_with_time_granularity * 2
metrics:
- name: simple_metric_with_time_granularity
filter: |
{{ TimeDimension('metric_time') }} > '2020-01-01'
---
metric:
name: derived_metric_with_time_granularity_and_inner_metric_time_filter
description: Derived metric with time granularity
type: derived
time_granularity: year
type_params:
expr: simple_metric_with_time_granularity_and_metric_time_filter * 2
metrics:
- name: simple_metric_with_time_granularity_and_metric_time_filter
filter: |
{{ TimeDimension('metric_time') }} = '2020-01-01'
Original file line number Diff line number Diff line change
Expand Up @@ -114,3 +114,61 @@ def test_non_metric_time_ignores_default_granularity( # noqa: D103
obj_id="result_0",
obj=query_spec,
)


def test_simple_metric_with_defined_metric_time_filter(
request: FixtureRequest,
mf_test_configuration: MetricFlowTestConfiguration,
ambiguous_resolution_query_parser: MetricFlowQueryParser,
) -> None:
"""Tests that a simple metric's metric_time filter defined in its YAML uses metric's default granularity."""
query_spec = ambiguous_resolution_query_parser.parse_and_validate_query(
metric_names=["simple_metric_with_time_granularity_and_metric_time_filter"]
).query_spec

assert_object_snapshot_equal(
request=request,
mf_test_configuration=mf_test_configuration,
obj_id="result_0",
obj=query_spec,
)


def test_derived_metric_with_defined_metric_time_filter(
request: FixtureRequest,
mf_test_configuration: MetricFlowTestConfiguration,
ambiguous_resolution_query_parser: MetricFlowQueryParser,
) -> None:
"""Tests that a derived metric's metric_time filter defined in its YAML uses outer metric's default granularity."""
query_spec = ambiguous_resolution_query_parser.parse_and_validate_query(
metric_names=["derived_metric_with_time_granularity_and_outer_metric_time_filter"]
).query_spec

assert_object_snapshot_equal(
request=request,
mf_test_configuration=mf_test_configuration,
obj_id="result_0",
obj=query_spec,
)


def test_derived_metric_with_defined_metric_time_filter_on_input_metric(
request: FixtureRequest,
mf_test_configuration: MetricFlowTestConfiguration,
ambiguous_resolution_query_parser: MetricFlowQueryParser,
) -> None:
"""Tests a derived metric with a metric_time filter on its input metric.
Should use the outer metric's default granularity.
Should always use the default granularity for the object where the filter is defined.
"""
query_spec = ambiguous_resolution_query_parser.parse_and_validate_query(
metric_names=["derived_metric_with_time_granularity_and_inner_metric_time_filter"]
).query_spec
assert 0, "this don't werk"
assert_object_snapshot_equal(
request=request,
mf_test_configuration=mf_test_configuration,
obj_id="result_0",
obj=query_spec,
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
MetricFlowQuerySpec(
metric_specs=(MetricSpec(element_name='derived_metric_with_time_granularity_and_outer_metric_time_filter'),),
filter_intersection=PydanticWhereFilterIntersection(),
filter_spec_resolution_lookup=FilterSpecResolutionLookUp(
spec_resolutions=(
FilterSpecResolution(
lookup_key=ResolvedSpecLookUpKey(
filter_location=WhereFilterLocation(
metric_references=(
MetricReference(
element_name='derived_metric_with_time_granularity_and_outer_metric_time_filter',
),
),
),
call_parameter_set=TimeDimensionCallParameterSet(
time_dimension_reference=TimeDimensionReference(
element_name='metric_time',
),
),
),
where_filter_intersection=PydanticWhereFilterIntersection(
where_filters=[
PydanticWhereFilter(
where_sql_template="{{ TimeDimension('metric_time') }} > '2020-01-01'\n",
),
],
),
resolved_linkable_element_set=LinkableElementSet(
path_key_to_linkable_dimensions={
ElementPathKey(
element_name='metric_time',
element_type=TIME_DIMENSION,
time_granularity=YEAR,
): (
LinkableDimension(
defined_in_semantic_model=SemanticModelReference(
semantic_model_name='monthly_measures_source',
),
element_name='metric_time',
dimension_type=TIME,
join_path=SemanticModelJoinPath(
left_semantic_model_reference=SemanticModelReference(
semantic_model_name='monthly_measures_source',
),
),
properties=frozenset(
'DERIVED_TIME_GRANULARITY',
'METRIC_TIME',
),
time_granularity=YEAR,
),
),
},
),
spec_pattern=TimeDimensionPattern(
parameter_set=EntityLinkPatternParameterSet(
fields_to_compare=(
DATE_PART,
ELEMENT_NAME,
ENTITY_LINKS,
),
element_name='metric_time',
),
),
filter_location_path=MetricFlowQueryResolutionPath(
resolution_path_nodes=(
QueryGroupByItemResolutionNode(node_id=qr_1),
MetricGroupByItemResolutionNode(node_id=mtr_1),
),
),
object_builder_str="TimeDimension('metric_time')",
),
),
),
min_max_only=False,
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
MetricFlowQuerySpec(
metric_specs=(MetricSpec(element_name='derived_metric_with_time_granularity_and_inner_metric_time_filter'),),
filter_intersection=PydanticWhereFilterIntersection(),
filter_spec_resolution_lookup=FilterSpecResolutionLookUp(
spec_resolutions=(
FilterSpecResolution(
lookup_key=ResolvedSpecLookUpKey(
filter_location=WhereFilterLocation(
metric_references=(
MetricReference(
element_name='simple_metric_with_time_granularity_and_metric_time_filter',
),
),
),
call_parameter_set=TimeDimensionCallParameterSet(
time_dimension_reference=TimeDimensionReference(
element_name='metric_time',
),
),
),
where_filter_intersection=PydanticWhereFilterIntersection(
where_filters=[
PydanticWhereFilter(
where_sql_template="{{ TimeDimension('metric_time') }} > '2020-01-01'\n",
),
PydanticWhereFilter(
where_sql_template="{{ TimeDimension('metric_time') }} = '2020-01-01'",
),
],
),
resolved_linkable_element_set=LinkableElementSet(
path_key_to_linkable_dimensions={
ElementPathKey(
element_name='metric_time',
element_type=TIME_DIMENSION,
time_granularity=QUARTER,
): (
LinkableDimension(
defined_in_semantic_model=SemanticModelReference(
semantic_model_name='monthly_measures_source',
),
element_name='metric_time',
dimension_type=TIME,
join_path=SemanticModelJoinPath(
left_semantic_model_reference=SemanticModelReference(
semantic_model_name='monthly_measures_source',
),
),
properties=frozenset(
'DERIVED_TIME_GRANULARITY',
'METRIC_TIME',
),
time_granularity=QUARTER,
),
),
},
),
spec_pattern=TimeDimensionPattern(
parameter_set=EntityLinkPatternParameterSet(
fields_to_compare=(
DATE_PART,
ELEMENT_NAME,
ENTITY_LINKS,
),
element_name='metric_time',
),
),
filter_location_path=MetricFlowQueryResolutionPath(
resolution_path_nodes=(
QueryGroupByItemResolutionNode(node_id=qr_1),
MetricGroupByItemResolutionNode(node_id=mtr_1),
MetricGroupByItemResolutionNode(node_id=mtr_0),
),
),
object_builder_str="TimeDimension('metric_time')",
),
),
),
min_max_only=False,
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
MetricFlowQuerySpec(
metric_specs=(MetricSpec(element_name='simple_metric_with_time_granularity_and_metric_time_filter'),),
filter_intersection=PydanticWhereFilterIntersection(),
filter_spec_resolution_lookup=FilterSpecResolutionLookUp(
spec_resolutions=(
FilterSpecResolution(
lookup_key=ResolvedSpecLookUpKey(
filter_location=WhereFilterLocation(
metric_references=(
MetricReference(
element_name='simple_metric_with_time_granularity_and_metric_time_filter',
),
),
),
call_parameter_set=TimeDimensionCallParameterSet(
time_dimension_reference=TimeDimensionReference(
element_name='metric_time',
),
),
),
where_filter_intersection=PydanticWhereFilterIntersection(
where_filters=[
PydanticWhereFilter(
where_sql_template="{{ TimeDimension('metric_time') }} > '2020-01-01'\n",
),
],
),
resolved_linkable_element_set=LinkableElementSet(
path_key_to_linkable_dimensions={
ElementPathKey(
element_name='metric_time',
element_type=TIME_DIMENSION,
time_granularity=QUARTER,
): (
LinkableDimension(
defined_in_semantic_model=SemanticModelReference(
semantic_model_name='monthly_measures_source',
),
element_name='metric_time',
dimension_type=TIME,
join_path=SemanticModelJoinPath(
left_semantic_model_reference=SemanticModelReference(
semantic_model_name='monthly_measures_source',
),
),
properties=frozenset(
'DERIVED_TIME_GRANULARITY',
'METRIC_TIME',
),
time_granularity=QUARTER,
),
),
},
),
spec_pattern=TimeDimensionPattern(
parameter_set=EntityLinkPatternParameterSet(
fields_to_compare=(
DATE_PART,
ELEMENT_NAME,
ENTITY_LINKS,
),
element_name='metric_time',
),
),
filter_location_path=MetricFlowQueryResolutionPath(
resolution_path_nodes=(
QueryGroupByItemResolutionNode(node_id=qr_1),
MetricGroupByItemResolutionNode(node_id=mtr_0),
),
),
object_builder_str="TimeDimension('metric_time')",
),
),
),
min_max_only=False,
)
12 changes: 6 additions & 6 deletions metricflow/dataflow/builder/dataflow_plan_builder.py
Original file line number Diff line number Diff line change
Expand Up @@ -1543,12 +1543,12 @@ def _build_aggregated_measure_from_measure_source_node(
if non_additive_dimension_spec is not None:
# Apply semi additive join on the node
agg_time_dimension = measure_properties.agg_time_dimension
queried_time_dimension_spec: Optional[
TimeDimensionSpec
] = self._find_non_additive_dimension_in_linkable_specs(
agg_time_dimension=agg_time_dimension,
linkable_specs=queried_linkable_specs.as_tuple,
non_additive_dimension_spec=non_additive_dimension_spec,
queried_time_dimension_spec: Optional[TimeDimensionSpec] = (
self._find_non_additive_dimension_in_linkable_specs(
agg_time_dimension=agg_time_dimension,
linkable_specs=queried_linkable_specs.as_tuple,
non_additive_dimension_spec=non_additive_dimension_spec,
)
)
time_dimension_spec = TimeDimensionSpec.from_name(non_additive_dimension_spec.name)
window_groupings = tuple(
Expand Down

0 comments on commit dbe9a2f

Please sign in to comment.