From e46af9ac50fb8790c69164658420dcc61e271f7d Mon Sep 17 00:00:00 2001 From: Courtney Holcomb Date: Mon, 15 Jul 2024 18:29:30 -0700 Subject: [PATCH] Use `MetricTimeDefaultGranularityPattern` to resolve `metric_time` granularity (#1332) Resolve metric time using new spec pattern in group by and filter nodes. This is a change from defaulting to the minimum time granularity for `metric_time`. Now we will use the max default granularity for the requested metrics. Note the snapshot updates. These reflect another behavior change in which we don't error if `metric_time` is queried for metrics with two different default granularities. Instead, we choose the larger of the two, which is guaranteed to work for both metrics. --- .../unreleased/Features-20240628-074617.yaml | 6 + .../group_by_item/group_by_item_resolver.py | 22 ++- .../query/query_parser.py | 17 +- ...h_different_parent_time_grains__result.txt | 132 ++++------------ ...ics_with_different_time_grains__result.txt | 127 +++++---------- ...tion_for_invalid_metric_filter__result.txt | 143 +++++------------ ...or_invalid_metric_input_filter__result.txt | 148 +++++------------- ...h_different_parent_time_grains__result.txt | 143 +++++------------ ...ics_with_different_time_grains__result.txt | 138 +++++----------- 9 files changed, 263 insertions(+), 613 deletions(-) create mode 100644 .changes/unreleased/Features-20240628-074617.yaml diff --git a/.changes/unreleased/Features-20240628-074617.yaml b/.changes/unreleased/Features-20240628-074617.yaml new file mode 100644 index 0000000000..7661d43434 --- /dev/null +++ b/.changes/unreleased/Features-20240628-074617.yaml @@ -0,0 +1,6 @@ +kind: Features +body: Use Metric.time_granularity to resolve metric_time. +time: 2024-06-28T07:46:17.768805-07:00 +custom: + Author: courtneyholcomb + Issue: "1310" diff --git a/metricflow-semantics/metricflow_semantics/query/group_by_item/group_by_item_resolver.py b/metricflow-semantics/metricflow_semantics/query/group_by_item/group_by_item_resolver.py index 0381da30a6..401c4dae9b 100644 --- a/metricflow-semantics/metricflow_semantics/query/group_by_item/group_by_item_resolver.py +++ b/metricflow-semantics/metricflow_semantics/query/group_by_item/group_by_item_resolver.py @@ -28,6 +28,7 @@ ) from metricflow_semantics.query.suggestion_generator import QueryItemSuggestionGenerator from metricflow_semantics.specs.instance_spec import LinkableInstanceSpec +from metricflow_semantics.specs.patterns.metric_time_default_granularity import MetricTimeDefaultGranularityPattern from metricflow_semantics.specs.patterns.minimum_time_grain import MinimumTimeGrainPattern from metricflow_semantics.specs.patterns.no_group_by_metric import NoGroupByMetricPattern from metricflow_semantics.specs.patterns.spec_pattern import SpecPattern @@ -81,10 +82,10 @@ def resolve_matching_item_for_querying( spec_pattern: SpecPattern, suggestion_generator: Optional[QueryItemSuggestionGenerator], ) -> GroupByItemResolution: - """Returns the spec that corresponds the one described by spec_pattern and is valid for the query. + """Returns the spec that corresponds to the one described by spec_pattern and is valid for the query. For queries, if the pattern matches to a spec for the same element at different grains, the spec with the finest - common grain is returned. + common grain is returned, unless the spec is metric_time, in which case the default grain is returned. """ push_down_visitor = _PushDownGroupByItemCandidatesVisitor( manifest_lookup=self._manifest_lookup, @@ -101,9 +102,13 @@ def resolve_matching_item_for_querying( issue_set=push_down_result.issue_set, ) - push_down_result = push_down_result.filter_candidates_by_pattern( + for candidate_filter in ( + # Default pattern must come first to avoid removing default grain options prematurely. + MetricTimeDefaultGranularityPattern(push_down_result.max_metric_default_time_granularity), MinimumTimeGrainPattern(), - ) + ): + push_down_result = push_down_result.filter_candidates_by_pattern(candidate_filter) + logger.info( f"Spec pattern:\n" f"{indent(mf_pformat(spec_pattern))}\n" @@ -152,12 +157,19 @@ def resolve_matching_item_for_filters( push_down_visitor = _PushDownGroupByItemCandidatesVisitor( manifest_lookup=self._manifest_lookup, - source_spec_patterns=(spec_pattern, MinimumTimeGrainPattern()), + source_spec_patterns=(spec_pattern,), suggestion_generator=suggestion_generator, ) push_down_result: PushDownResult = resolution_node.accept(push_down_visitor) + for candidate_filter in ( + # Default pattern must come first to avoid removing default grain options prematurely. + MetricTimeDefaultGranularityPattern(push_down_result.max_metric_default_time_granularity), + MinimumTimeGrainPattern(), + ): + push_down_result = push_down_result.filter_candidates_by_pattern(candidate_filter) + if push_down_result.candidate_set.num_candidates == 0: return GroupByItemResolution( spec=None, diff --git a/metricflow-semantics/metricflow_semantics/query/query_parser.py b/metricflow-semantics/metricflow_semantics/query/query_parser.py index 4233ce89c2..e8db500bad 100644 --- a/metricflow-semantics/metricflow_semantics/query/query_parser.py +++ b/metricflow-semantics/metricflow_semantics/query/query_parser.py @@ -146,7 +146,9 @@ def _get_saved_query(self, saved_query_parameter: SavedQueryParameter) -> SavedQ return matching_saved_queries[0] @staticmethod - def _metric_time_granularity(time_dimension_specs: Sequence[TimeDimensionSpec]) -> Optional[TimeGranularity]: + def _get_smallest_requested_metric_time_granularity( + time_dimension_specs: Sequence[TimeDimensionSpec], + ) -> Optional[TimeGranularity]: matching_specs: Sequence[InstanceSpec] = time_dimension_specs for pattern_to_apply in ( @@ -172,18 +174,21 @@ def _adjust_time_constraint( time_dimension_specs_in_query: Sequence[TimeDimensionSpec], time_constraint: TimeRangeConstraint, ) -> TimeRangeConstraint: - metric_time_granularity = MetricFlowQueryParser._metric_time_granularity(time_dimension_specs_in_query) + """Change the time range so that the ends are at the ends of the requested time granularity windows. + + e.g. [2020-01-15, 2020-2-15] with MONTH granularity -> [2020-01-01, 2020-02-29] + """ + metric_time_granularity = MetricFlowQueryParser._get_smallest_requested_metric_time_granularity( + time_dimension_specs_in_query + ) if metric_time_granularity is None: + # This indicates there were no metric time specs in the query, so use smallest available granularity for metric_time. group_by_item_resolver = GroupByItemResolver( manifest_lookup=self._manifest_lookup, resolution_dag=resolution_dag, ) metric_time_granularity = group_by_item_resolver.resolve_min_metric_time_grain() - """Change the time range so that the ends are at the ends of the appropriate time granularity windows. - - e.g. [2020-01-15, 2020-2-15] with MONTH granularity -> [2020-01-01, 2020-02-29] - """ return self._time_period_adjuster.expand_time_constraint_to_fill_granularity( time_constraint=time_constraint, granularity=metric_time_granularity, diff --git a/metricflow-semantics/tests_metricflow_semantics/snapshots/test_matching_item_for_filters.py/GroupByItemResolution/test_ambiguous_metric_time_in_query_filter__derived_metric_with_different_parent_time_grains__result.txt b/metricflow-semantics/tests_metricflow_semantics/snapshots/test_matching_item_for_filters.py/GroupByItemResolution/test_ambiguous_metric_time_in_query_filter__derived_metric_with_different_parent_time_grains__result.txt index 0229fb11e7..2c2ce3e910 100644 --- a/metricflow-semantics/tests_metricflow_semantics/snapshots/test_matching_item_for_filters.py/GroupByItemResolution/test_ambiguous_metric_time_in_query_filter__derived_metric_with_different_parent_time_grains__result.txt +++ b/metricflow-semantics/tests_metricflow_semantics/snapshots/test_matching_item_for_filters.py/GroupByItemResolution/test_ambiguous_metric_time_in_query_filter__derived_metric_with_different_parent_time_grains__result.txt @@ -1,108 +1,44 @@ GroupByItemResolution( - linkable_element_set=LinkableElementSet(), - issue_set=MetricFlowQueryResolutionIssueSet( - issues=( - NoCommonItemsInParents( - issue_type=ERROR, - query_resolution_path=MetricFlowQueryResolutionPath( - resolution_path_nodes=( - QueryGroupByItemResolutionNode(node_id=qr_5), - MetricGroupByItemResolutionNode(node_id=mtr_10), + spec=TimeDimensionSpec(element_name='metric_time', time_granularity=YEAR), + 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', ), - ), - parent_candidate_sets=( - GroupByItemCandidateSet( - linkable_element_set=LinkableElementSet( - path_key_to_linkable_dimensions={ - ElementPathKey( - element_name='metric_time', - element_type=TIME_DIMENSION, - time_granularity=MONTH, - ): ( - 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( - 'METRIC_TIME', - ), - time_granularity=MONTH, - ), - ), - }, - ), - measure_paths=( - MetricFlowQueryResolutionPath( - resolution_path_nodes=( - QueryGroupByItemResolutionNode(node_id=qr_5), - MetricGroupByItemResolutionNode(node_id=mtr_10), - MetricGroupByItemResolutionNode(node_id=mtr_8), - MeasureGroupByItemSourceNode(node_id=msr_7), - ), - ), - ), - path_from_leaf_node=MetricFlowQueryResolutionPath( - resolution_path_nodes=( - QueryGroupByItemResolutionNode(node_id=qr_5), - MetricGroupByItemResolutionNode(node_id=mtr_10), - MetricGroupByItemResolutionNode(node_id=mtr_8), - ), + element_name='metric_time', + dimension_type=TIME, + join_path=SemanticModelJoinPath( + left_semantic_model_reference=SemanticModelReference( + semantic_model_name='monthly_measures_source', ), ), - GroupByItemCandidateSet( - 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='yearly_measure_source', - ), - element_name='metric_time', - dimension_type=TIME, - join_path=SemanticModelJoinPath( - left_semantic_model_reference=SemanticModelReference( - semantic_model_name='yearly_measure_source', - ), - ), - properties=frozenset( - 'METRIC_TIME', - ), - time_granularity=YEAR, - ), - ), - }, - ), - measure_paths=( - MetricFlowQueryResolutionPath( - resolution_path_nodes=( - QueryGroupByItemResolutionNode(node_id=qr_5), - MetricGroupByItemResolutionNode(node_id=mtr_10), - MetricGroupByItemResolutionNode(node_id=mtr_9), - MeasureGroupByItemSourceNode(node_id=msr_8), - ), - ), - ), - path_from_leaf_node=MetricFlowQueryResolutionPath( - resolution_path_nodes=( - QueryGroupByItemResolutionNode(node_id=qr_5), - MetricGroupByItemResolutionNode(node_id=mtr_10), - MetricGroupByItemResolutionNode(node_id=mtr_9), - ), + properties=frozenset( + 'DERIVED_TIME_GRANULARITY', + 'METRIC_TIME', + ), + time_granularity=YEAR, + ), + LinkableDimension( + defined_in_semantic_model=SemanticModelReference( + semantic_model_name='yearly_measure_source', + ), + element_name='metric_time', + dimension_type=TIME, + join_path=SemanticModelJoinPath( + left_semantic_model_reference=SemanticModelReference( + semantic_model_name='yearly_measure_source', ), ), + properties=frozenset('METRIC_TIME',), + time_granularity=YEAR, ), ), - ), + }, ), ) diff --git a/metricflow-semantics/tests_metricflow_semantics/snapshots/test_matching_item_for_filters.py/GroupByItemResolution/test_ambiguous_metric_time_in_query_filter__metrics_with_different_time_grains__result.txt b/metricflow-semantics/tests_metricflow_semantics/snapshots/test_matching_item_for_filters.py/GroupByItemResolution/test_ambiguous_metric_time_in_query_filter__metrics_with_different_time_grains__result.txt index 9adc6ac8da..2c2ce3e910 100644 --- a/metricflow-semantics/tests_metricflow_semantics/snapshots/test_matching_item_for_filters.py/GroupByItemResolution/test_ambiguous_metric_time_in_query_filter__metrics_with_different_time_grains__result.txt +++ b/metricflow-semantics/tests_metricflow_semantics/snapshots/test_matching_item_for_filters.py/GroupByItemResolution/test_ambiguous_metric_time_in_query_filter__metrics_with_different_time_grains__result.txt @@ -1,101 +1,44 @@ GroupByItemResolution( - linkable_element_set=LinkableElementSet(), - issue_set=MetricFlowQueryResolutionIssueSet( - issues=( - NoCommonItemsInParents( - issue_type=ERROR, - query_resolution_path=MetricFlowQueryResolutionPath( - resolution_path_nodes=(QueryGroupByItemResolutionNode(node_id=qr_3),), - ), - parent_candidate_sets=( - GroupByItemCandidateSet( - linkable_element_set=LinkableElementSet( - path_key_to_linkable_dimensions={ - ElementPathKey( - element_name='metric_time', - element_type=TIME_DIMENSION, - time_granularity=MONTH, - ): ( - 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( - 'METRIC_TIME', - ), - time_granularity=MONTH, - ), - ), - }, - ), - measure_paths=( - MetricFlowQueryResolutionPath( - resolution_path_nodes=( - QueryGroupByItemResolutionNode(node_id=qr_3), - MetricGroupByItemResolutionNode(node_id=mtr_3), - MeasureGroupByItemSourceNode(node_id=msr_3), - ), - ), - ), - path_from_leaf_node=MetricFlowQueryResolutionPath( - resolution_path_nodes=( - QueryGroupByItemResolutionNode(node_id=qr_3), - MetricGroupByItemResolutionNode(node_id=mtr_3), - ), - ), + spec=TimeDimensionSpec(element_name='metric_time', time_granularity=YEAR), + 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', ), - GroupByItemCandidateSet( - 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='yearly_measure_source', - ), - element_name='metric_time', - dimension_type=TIME, - join_path=SemanticModelJoinPath( - left_semantic_model_reference=SemanticModelReference( - semantic_model_name='yearly_measure_source', - ), - ), - properties=frozenset( - 'METRIC_TIME', - ), - time_granularity=YEAR, - ), - ), - }, - ), - measure_paths=( - MetricFlowQueryResolutionPath( - resolution_path_nodes=( - QueryGroupByItemResolutionNode(node_id=qr_3), - MetricGroupByItemResolutionNode(node_id=mtr_4), - MeasureGroupByItemSourceNode(node_id=msr_4), - ), - ), + element_name='metric_time', + dimension_type=TIME, + join_path=SemanticModelJoinPath( + left_semantic_model_reference=SemanticModelReference( + semantic_model_name='monthly_measures_source', ), - path_from_leaf_node=MetricFlowQueryResolutionPath( - resolution_path_nodes=( - QueryGroupByItemResolutionNode(node_id=qr_3), - MetricGroupByItemResolutionNode(node_id=mtr_4), - ), + ), + properties=frozenset( + 'DERIVED_TIME_GRANULARITY', + 'METRIC_TIME', + ), + time_granularity=YEAR, + ), + LinkableDimension( + defined_in_semantic_model=SemanticModelReference( + semantic_model_name='yearly_measure_source', + ), + element_name='metric_time', + dimension_type=TIME, + join_path=SemanticModelJoinPath( + left_semantic_model_reference=SemanticModelReference( + semantic_model_name='yearly_measure_source', ), ), + properties=frozenset('METRIC_TIME',), + time_granularity=YEAR, ), ), - ), + }, ), ) diff --git a/metricflow-semantics/tests_metricflow_semantics/snapshots/test_spec_lookup.py/str/test_filter_resolution_for_invalid_metric_filter__result.txt b/metricflow-semantics/tests_metricflow_semantics/snapshots/test_spec_lookup.py/str/test_filter_resolution_for_invalid_metric_filter__result.txt index 119b0392e5..80b32c7364 100644 --- a/metricflow-semantics/tests_metricflow_semantics/snapshots/test_spec_lookup.py/str/test_filter_resolution_for_invalid_metric_filter__result.txt +++ b/metricflow-semantics/tests_metricflow_semantics/snapshots/test_spec_lookup.py/str/test_filter_resolution_for_invalid_metric_filter__result.txt @@ -22,116 +22,53 @@ FilterSpecResolutionLookUp( ), ], ), - resolved_linkable_element_set=LinkableElementSet(), - spec_pattern=TimeDimensionPattern( - parameter_set=EntityLinkPatternParameterSet( - fields_to_compare=(DATE_PART, ELEMENT_NAME, ENTITY_LINKS), - element_name='metric_time', - ), - ), - issue_set=MetricFlowQueryResolutionIssueSet( - issues=( - NoCommonItemsInParents( - issue_type=ERROR, - query_resolution_path=MetricFlowQueryResolutionPath( - resolution_path_nodes=( - QueryGroupByItemResolutionNode(node_id=qr_0), - MetricGroupByItemResolutionNode(node_id=mtr_2), + 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', ), - ), - parent_candidate_sets=( - GroupByItemCandidateSet( - linkable_element_set=LinkableElementSet( - path_key_to_linkable_dimensions={ - ElementPathKey( - element_name='metric_time', - element_type=TIME_DIMENSION, - time_granularity=MONTH, - ): ( - 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( - 'METRIC_TIME', - ), - time_granularity=MONTH, - ), - ), - }, - ), - measure_paths=( - MetricFlowQueryResolutionPath( - resolution_path_nodes=( - QueryGroupByItemResolutionNode(node_id=qr_0), - MetricGroupByItemResolutionNode(node_id=mtr_2), - MetricGroupByItemResolutionNode(node_id=mtr_0), - MeasureGroupByItemSourceNode(node_id=msr_0), - ), - ), - ), - path_from_leaf_node=MetricFlowQueryResolutionPath( - resolution_path_nodes=( - QueryGroupByItemResolutionNode(node_id=qr_0), - MetricGroupByItemResolutionNode(node_id=mtr_2), - MetricGroupByItemResolutionNode(node_id=mtr_0), - ), + element_name='metric_time', + dimension_type=TIME, + join_path=SemanticModelJoinPath( + left_semantic_model_reference=SemanticModelReference( + semantic_model_name='monthly_measures_source', ), ), - GroupByItemCandidateSet( - 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='yearly_measure_source', - ), - element_name='metric_time', - dimension_type=TIME, - join_path=SemanticModelJoinPath( - left_semantic_model_reference=SemanticModelReference( - semantic_model_name='yearly_measure_source', - ), - ), - properties=frozenset( - 'METRIC_TIME', - ), - time_granularity=YEAR, - ), - ), - }, - ), - measure_paths=( - MetricFlowQueryResolutionPath( - resolution_path_nodes=( - QueryGroupByItemResolutionNode(node_id=qr_0), - MetricGroupByItemResolutionNode(node_id=mtr_2), - MetricGroupByItemResolutionNode(node_id=mtr_1), - MeasureGroupByItemSourceNode(node_id=msr_1), - ), - ), - ), - path_from_leaf_node=MetricFlowQueryResolutionPath( - resolution_path_nodes=( - QueryGroupByItemResolutionNode(node_id=qr_0), - MetricGroupByItemResolutionNode(node_id=mtr_2), - MetricGroupByItemResolutionNode(node_id=mtr_1), - ), + properties=frozenset( + 'DERIVED_TIME_GRANULARITY', + 'METRIC_TIME', + ), + time_granularity=YEAR, + ), + LinkableDimension( + defined_in_semantic_model=SemanticModelReference( + semantic_model_name='yearly_measure_source', + ), + element_name='metric_time', + dimension_type=TIME, + join_path=SemanticModelJoinPath( + left_semantic_model_reference=SemanticModelReference( + semantic_model_name='yearly_measure_source', ), ), + properties=frozenset( + '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( diff --git a/metricflow-semantics/tests_metricflow_semantics/snapshots/test_spec_lookup.py/str/test_filter_resolution_for_invalid_metric_input_filter__result.txt b/metricflow-semantics/tests_metricflow_semantics/snapshots/test_spec_lookup.py/str/test_filter_resolution_for_invalid_metric_input_filter__result.txt index 7d9f61426a..139eba5580 100644 --- a/metricflow-semantics/tests_metricflow_semantics/snapshots/test_spec_lookup.py/str/test_filter_resolution_for_invalid_metric_input_filter__result.txt +++ b/metricflow-semantics/tests_metricflow_semantics/snapshots/test_spec_lookup.py/str/test_filter_resolution_for_invalid_metric_input_filter__result.txt @@ -22,121 +22,53 @@ FilterSpecResolutionLookUp( ), ], ), - resolved_linkable_element_set=LinkableElementSet(), - spec_pattern=TimeDimensionPattern( - parameter_set=EntityLinkPatternParameterSet( - fields_to_compare=(DATE_PART, ELEMENT_NAME, ENTITY_LINKS), - element_name='metric_time', - ), - ), - issue_set=MetricFlowQueryResolutionIssueSet( - issues=( - NoCommonItemsInParents( - issue_type=ERROR, - query_resolution_path=MetricFlowQueryResolutionPath( - resolution_path_nodes=( - QueryGroupByItemResolutionNode(node_id=qr_0), - MetricGroupByItemResolutionNode(node_id=mtr_3), - MetricGroupByItemResolutionNode(node_id=mtr_2), + 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', ), - ), - parent_candidate_sets=( - GroupByItemCandidateSet( - linkable_element_set=LinkableElementSet( - path_key_to_linkable_dimensions={ - ElementPathKey( - element_name='metric_time', - element_type=TIME_DIMENSION, - time_granularity=MONTH, - ): ( - 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( - 'METRIC_TIME', - ), - time_granularity=MONTH, - ), - ), - }, - ), - measure_paths=( - MetricFlowQueryResolutionPath( - resolution_path_nodes=( - QueryGroupByItemResolutionNode(node_id=qr_0), - MetricGroupByItemResolutionNode(node_id=mtr_3), - MetricGroupByItemResolutionNode(node_id=mtr_2), - MetricGroupByItemResolutionNode(node_id=mtr_0), - MeasureGroupByItemSourceNode(node_id=msr_0), - ), - ), - ), - path_from_leaf_node=MetricFlowQueryResolutionPath( - resolution_path_nodes=( - QueryGroupByItemResolutionNode(node_id=qr_0), - MetricGroupByItemResolutionNode(node_id=mtr_3), - MetricGroupByItemResolutionNode(node_id=mtr_2), - MetricGroupByItemResolutionNode(node_id=mtr_0), - ), + element_name='metric_time', + dimension_type=TIME, + join_path=SemanticModelJoinPath( + left_semantic_model_reference=SemanticModelReference( + semantic_model_name='monthly_measures_source', ), ), - GroupByItemCandidateSet( - 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='yearly_measure_source', - ), - element_name='metric_time', - dimension_type=TIME, - join_path=SemanticModelJoinPath( - left_semantic_model_reference=SemanticModelReference( - semantic_model_name='yearly_measure_source', - ), - ), - properties=frozenset( - 'METRIC_TIME', - ), - time_granularity=YEAR, - ), - ), - }, - ), - measure_paths=( - MetricFlowQueryResolutionPath( - resolution_path_nodes=( - QueryGroupByItemResolutionNode(node_id=qr_0), - MetricGroupByItemResolutionNode(node_id=mtr_3), - MetricGroupByItemResolutionNode(node_id=mtr_2), - MetricGroupByItemResolutionNode(node_id=mtr_1), - MeasureGroupByItemSourceNode(node_id=msr_1), - ), - ), - ), - path_from_leaf_node=MetricFlowQueryResolutionPath( - resolution_path_nodes=( - QueryGroupByItemResolutionNode(node_id=qr_0), - MetricGroupByItemResolutionNode(node_id=mtr_3), - MetricGroupByItemResolutionNode(node_id=mtr_2), - MetricGroupByItemResolutionNode(node_id=mtr_1), - ), + properties=frozenset( + 'DERIVED_TIME_GRANULARITY', + 'METRIC_TIME', + ), + time_granularity=YEAR, + ), + LinkableDimension( + defined_in_semantic_model=SemanticModelReference( + semantic_model_name='yearly_measure_source', + ), + element_name='metric_time', + dimension_type=TIME, + join_path=SemanticModelJoinPath( + left_semantic_model_reference=SemanticModelReference( + semantic_model_name='yearly_measure_source', ), ), + properties=frozenset( + '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( diff --git a/metricflow-semantics/tests_metricflow_semantics/snapshots/test_spec_lookup.py/str/test_filter_spec_resolution__derived_metric_with_different_parent_time_grains__result.txt b/metricflow-semantics/tests_metricflow_semantics/snapshots/test_spec_lookup.py/str/test_filter_spec_resolution__derived_metric_with_different_parent_time_grains__result.txt index 2fb667f41c..affa1a709f 100644 --- a/metricflow-semantics/tests_metricflow_semantics/snapshots/test_spec_lookup.py/str/test_filter_spec_resolution__derived_metric_with_different_parent_time_grains__result.txt +++ b/metricflow-semantics/tests_metricflow_semantics/snapshots/test_spec_lookup.py/str/test_filter_spec_resolution__derived_metric_with_different_parent_time_grains__result.txt @@ -22,116 +22,53 @@ FilterSpecResolutionLookUp( ), ], ), - resolved_linkable_element_set=LinkableElementSet(), - spec_pattern=TimeDimensionPattern( - parameter_set=EntityLinkPatternParameterSet( - fields_to_compare=(DATE_PART, ELEMENT_NAME, ENTITY_LINKS), - element_name='metric_time', - ), - ), - issue_set=MetricFlowQueryResolutionIssueSet( - issues=( - NoCommonItemsInParents( - issue_type=ERROR, - query_resolution_path=MetricFlowQueryResolutionPath( - resolution_path_nodes=( - QueryGroupByItemResolutionNode(node_id=qr_5), - MetricGroupByItemResolutionNode(node_id=mtr_10), + 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', ), - ), - parent_candidate_sets=( - GroupByItemCandidateSet( - linkable_element_set=LinkableElementSet( - path_key_to_linkable_dimensions={ - ElementPathKey( - element_name='metric_time', - element_type=TIME_DIMENSION, - time_granularity=MONTH, - ): ( - 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( - 'METRIC_TIME', - ), - time_granularity=MONTH, - ), - ), - }, - ), - measure_paths=( - MetricFlowQueryResolutionPath( - resolution_path_nodes=( - QueryGroupByItemResolutionNode(node_id=qr_5), - MetricGroupByItemResolutionNode(node_id=mtr_10), - MetricGroupByItemResolutionNode(node_id=mtr_8), - MeasureGroupByItemSourceNode(node_id=msr_7), - ), - ), - ), - path_from_leaf_node=MetricFlowQueryResolutionPath( - resolution_path_nodes=( - QueryGroupByItemResolutionNode(node_id=qr_5), - MetricGroupByItemResolutionNode(node_id=mtr_10), - MetricGroupByItemResolutionNode(node_id=mtr_8), - ), + element_name='metric_time', + dimension_type=TIME, + join_path=SemanticModelJoinPath( + left_semantic_model_reference=SemanticModelReference( + semantic_model_name='monthly_measures_source', ), ), - GroupByItemCandidateSet( - 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='yearly_measure_source', - ), - element_name='metric_time', - dimension_type=TIME, - join_path=SemanticModelJoinPath( - left_semantic_model_reference=SemanticModelReference( - semantic_model_name='yearly_measure_source', - ), - ), - properties=frozenset( - 'METRIC_TIME', - ), - time_granularity=YEAR, - ), - ), - }, - ), - measure_paths=( - MetricFlowQueryResolutionPath( - resolution_path_nodes=( - QueryGroupByItemResolutionNode(node_id=qr_5), - MetricGroupByItemResolutionNode(node_id=mtr_10), - MetricGroupByItemResolutionNode(node_id=mtr_9), - MeasureGroupByItemSourceNode(node_id=msr_8), - ), - ), - ), - path_from_leaf_node=MetricFlowQueryResolutionPath( - resolution_path_nodes=( - QueryGroupByItemResolutionNode(node_id=qr_5), - MetricGroupByItemResolutionNode(node_id=mtr_10), - MetricGroupByItemResolutionNode(node_id=mtr_9), - ), + properties=frozenset( + 'DERIVED_TIME_GRANULARITY', + 'METRIC_TIME', + ), + time_granularity=YEAR, + ), + LinkableDimension( + defined_in_semantic_model=SemanticModelReference( + semantic_model_name='yearly_measure_source', + ), + element_name='metric_time', + dimension_type=TIME, + join_path=SemanticModelJoinPath( + left_semantic_model_reference=SemanticModelReference( + semantic_model_name='yearly_measure_source', ), ), + properties=frozenset( + '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( diff --git a/metricflow-semantics/tests_metricflow_semantics/snapshots/test_spec_lookup.py/str/test_filter_spec_resolution__metrics_with_different_time_grains__result.txt b/metricflow-semantics/tests_metricflow_semantics/snapshots/test_spec_lookup.py/str/test_filter_spec_resolution__metrics_with_different_time_grains__result.txt index 870dd193e7..2dd9caf21d 100644 --- a/metricflow-semantics/tests_metricflow_semantics/snapshots/test_spec_lookup.py/str/test_filter_spec_resolution__metrics_with_different_time_grains__result.txt +++ b/metricflow-semantics/tests_metricflow_semantics/snapshots/test_spec_lookup.py/str/test_filter_spec_resolution__metrics_with_different_time_grains__result.txt @@ -25,111 +25,53 @@ FilterSpecResolutionLookUp( ), ], ), - resolved_linkable_element_set=LinkableElementSet(), - spec_pattern=TimeDimensionPattern( - parameter_set=EntityLinkPatternParameterSet( - fields_to_compare=(DATE_PART, ELEMENT_NAME, ENTITY_LINKS), - element_name='metric_time', - ), - ), - issue_set=MetricFlowQueryResolutionIssueSet( - issues=( - NoCommonItemsInParents( - issue_type=ERROR, - query_resolution_path=MetricFlowQueryResolutionPath( - resolution_path_nodes=( - QueryGroupByItemResolutionNode(node_id=qr_3), + 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', ), - ), - parent_candidate_sets=( - GroupByItemCandidateSet( - linkable_element_set=LinkableElementSet( - path_key_to_linkable_dimensions={ - ElementPathKey( - element_name='metric_time', - element_type=TIME_DIMENSION, - time_granularity=MONTH, - ): ( - 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( - 'METRIC_TIME', - ), - time_granularity=MONTH, - ), - ), - }, - ), - measure_paths=( - MetricFlowQueryResolutionPath( - resolution_path_nodes=( - QueryGroupByItemResolutionNode(node_id=qr_3), - MetricGroupByItemResolutionNode(node_id=mtr_3), - MeasureGroupByItemSourceNode(node_id=msr_3), - ), - ), - ), - path_from_leaf_node=MetricFlowQueryResolutionPath( - resolution_path_nodes=( - QueryGroupByItemResolutionNode(node_id=qr_3), - MetricGroupByItemResolutionNode(node_id=mtr_3), - ), + element_name='metric_time', + dimension_type=TIME, + join_path=SemanticModelJoinPath( + left_semantic_model_reference=SemanticModelReference( + semantic_model_name='monthly_measures_source', ), ), - GroupByItemCandidateSet( - 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='yearly_measure_source', - ), - element_name='metric_time', - dimension_type=TIME, - join_path=SemanticModelJoinPath( - left_semantic_model_reference=SemanticModelReference( - semantic_model_name='yearly_measure_source', - ), - ), - properties=frozenset( - 'METRIC_TIME', - ), - time_granularity=YEAR, - ), - ), - }, - ), - measure_paths=( - MetricFlowQueryResolutionPath( - resolution_path_nodes=( - QueryGroupByItemResolutionNode(node_id=qr_3), - MetricGroupByItemResolutionNode(node_id=mtr_4), - MeasureGroupByItemSourceNode(node_id=msr_4), - ), - ), - ), - path_from_leaf_node=MetricFlowQueryResolutionPath( - resolution_path_nodes=( - QueryGroupByItemResolutionNode(node_id=qr_3), - MetricGroupByItemResolutionNode(node_id=mtr_4), - ), + properties=frozenset( + 'DERIVED_TIME_GRANULARITY', + 'METRIC_TIME', + ), + time_granularity=YEAR, + ), + LinkableDimension( + defined_in_semantic_model=SemanticModelReference( + semantic_model_name='yearly_measure_source', + ), + element_name='metric_time', + dimension_type=TIME, + join_path=SemanticModelJoinPath( + left_semantic_model_reference=SemanticModelReference( + semantic_model_name='yearly_measure_source', ), ), + properties=frozenset( + '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(