From 0a1d91b105006a5b97642afa44ce21d3cbd8a984 Mon Sep 17 00:00:00 2001 From: Courtney Holcomb Date: Mon, 15 Apr 2024 14:09:06 -0700 Subject: [PATCH 01/37] Add helper method SemanticModelJoinPath.from_single_element() --- .../model/semantics/linkable_spec_resolver.py | 24 +++++++++++++------ .../semantics/test_linkable_spec_resolver.py | 21 +++++----------- 2 files changed, 23 insertions(+), 22 deletions(-) diff --git a/metricflow/model/semantics/linkable_spec_resolver.py b/metricflow/model/semantics/linkable_spec_resolver.py index 387a8e7ace..c50fd0adfb 100644 --- a/metricflow/model/semantics/linkable_spec_resolver.py +++ b/metricflow/model/semantics/linkable_spec_resolver.py @@ -455,6 +455,20 @@ def last_entity_link(self) -> EntityReference: # noqa: D102 def entity_links(self) -> Tuple[EntityReference, ...]: # noqa: D102 return tuple(path_element.join_on_entity for path_element in self.path_elements) + @staticmethod + def from_single_element( + semantic_model_reference: SemanticModelReference, join_on_entity: EntityReference + ) -> SemanticModelJoinPath: + """Build SemanticModelJoinPath with just one join path element.""" + return SemanticModelJoinPath( + path_elements=( + SemanticModelJoinPathElement( + semantic_model_reference=semantic_model_reference, + join_on_entity=join_on_entity, + ), + ) + ) + class ValidLinkableSpecResolver: """Figures out what linkable specs are valid for a given metric. @@ -813,13 +827,9 @@ def _get_joined_elements(self, measure_semantic_model: SemanticModel) -> Linkabl if semantic_model.name == measure_semantic_model.name: continue join_paths.append( - SemanticModelJoinPath( - path_elements=( - SemanticModelJoinPathElement( - semantic_model_reference=semantic_model.reference, - join_on_entity=entity.reference, - ), - ) + SemanticModelJoinPath.from_single_element( + semantic_model_reference=semantic_model.reference, + join_on_entity=entity.reference, ) ) single_hop_elements = LinkableElementSet.merge_by_path_key( diff --git a/tests/model/semantics/test_linkable_spec_resolver.py b/tests/model/semantics/test_linkable_spec_resolver.py index 26ac6022ac..2085cccef5 100644 --- a/tests/model/semantics/test_linkable_spec_resolver.py +++ b/tests/model/semantics/test_linkable_spec_resolver.py @@ -15,7 +15,6 @@ from metricflow.model.semantics.linkable_element_properties import LinkableElementProperty from metricflow.model.semantics.linkable_spec_resolver import ( SemanticModelJoinPath, - SemanticModelJoinPathElement, ValidLinkableSpecResolver, ) from metricflow.model.semantics.semantic_model_join_evaluator import MAX_JOIN_HOPS @@ -142,13 +141,9 @@ def test_create_linkable_element_set_from_join_path( # noqa: D103 mf_test_configuration=mf_test_configuration, set_id="result0", linkable_element_set=simple_model_spec_resolver.create_linkable_element_set_from_join_path( - join_path=SemanticModelJoinPath( - path_elements=( - SemanticModelJoinPathElement( - semantic_model_reference=SemanticModelReference("listings_latest"), - join_on_entity=EntityReference("listing"), - ), - ) + join_path=SemanticModelJoinPath.from_single_element( + semantic_model_reference=SemanticModelReference("listings_latest"), + join_on_entity=EntityReference("listing"), ), with_properties=frozenset({LinkableElementProperty.JOINED}), ), @@ -165,13 +160,9 @@ def test_create_linkable_element_set_from_join_path_multi_hop( # noqa: D103 mf_test_configuration=mf_test_configuration, set_id="result0", linkable_element_set=simple_model_spec_resolver.create_linkable_element_set_from_join_path( - join_path=SemanticModelJoinPath( - path_elements=( - SemanticModelJoinPathElement( - semantic_model_reference=SemanticModelReference("listings_latest"), - join_on_entity=EntityReference("listing"), - ), - ) + join_path=SemanticModelJoinPath.from_single_element( + semantic_model_reference=SemanticModelReference("listings_latest"), + join_on_entity=EntityReference("listing"), ), with_properties=frozenset({LinkableElementProperty.JOINED, LinkableElementProperty.MULTI_HOP}), ), From 050ee327b439797df273ca326c3e9f2915d03946 Mon Sep 17 00:00:00 2001 From: Courtney Holcomb Date: Mon, 15 Apr 2024 14:15:24 -0700 Subject: [PATCH 02/37] Add MetricSubqueryJoinPath class --- .../model/semantics/linkable_spec_resolver.py | 30 +++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/metricflow/model/semantics/linkable_spec_resolver.py b/metricflow/model/semantics/linkable_spec_resolver.py index c50fd0adfb..f730234e33 100644 --- a/metricflow/model/semantics/linkable_spec_resolver.py +++ b/metricflow/model/semantics/linkable_spec_resolver.py @@ -374,6 +374,36 @@ class SemanticModelJoinPathElement: join_on_entity: EntityReference +@dataclass(frozen=True) +class MetricSubqueryJoinPathElement: + """Describes joining a metric subquery by the given entity.""" + + metric_reference: MetricReference + join_on_entity: EntityReference + + +@dataclass(frozen=True) +class MetricSubqueryJoinPath: + """Describes how to join to a metric subquery. + + Starts with semantic model join path, if exists. Always ends with metric subquery join path. + """ + + metric_subquery_join_path_element: MetricSubqueryJoinPathElement + semantic_model_join_path: Optional[SemanticModelJoinPath] = None + + @property + def entity_links(self) -> Tuple[EntityReference, ...]: # noqa: D102 + return (self.semantic_model_join_path.entity_links if self.semantic_model_join_path else ()) + ( + self.metric_subquery_join_path_element.join_on_entity, + ) + + @property + def last_semantic_model_reference(self) -> Optional[SemanticModelReference]: + """The last semantic model that would be joined in this path (if exists) before joining to metric.""" + return self.semantic_model_join_path.last_semantic_model_reference if self.semantic_model_join_path else None + + def _generate_linkable_time_dimensions( semantic_model_origin: SemanticModelReference, dimension: Dimension, From 11186c8de8623f9f6a3d0f4500941804a6b8d14e Mon Sep 17 00:00:00 2001 From: Courtney Holcomb Date: Mon, 15 Apr 2024 14:18:52 -0700 Subject: [PATCH 03/37] Rename method to specify 'valid' join (as opposed to fan-out join) --- .../model/semantics/linkable_spec_resolver.py | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/metricflow/model/semantics/linkable_spec_resolver.py b/metricflow/model/semantics/linkable_spec_resolver.py index f730234e33..1402c371f4 100644 --- a/metricflow/model/semantics/linkable_spec_resolver.py +++ b/metricflow/model/semantics/linkable_spec_resolver.py @@ -727,19 +727,19 @@ def _get_elements_in_semantic_model(self, semantic_model: SemanticModel) -> Link }, ) - def _get_semantic_models_with_joinable_entity( + def _get_semantic_models_with_valid_join( self, left_semantic_model_reference: SemanticModelReference, - entity_reference: EntityReference, + join_by_entity_reference: EntityReference, ) -> Sequence[SemanticModel]: # May switch to non-cached implementation. - semantic_models = self._entity_to_semantic_model[entity_reference.element_name] + semantic_models = self._entity_to_semantic_model[join_by_entity_reference.element_name] valid_semantic_models = [] for semantic_model in semantic_models: if self._join_evaluator.is_valid_semantic_model_join( left_semantic_model_reference=left_semantic_model_reference, right_semantic_model_reference=semantic_model.reference, - on_entity_reference=entity_reference, + on_entity_reference=join_by_entity_reference, ): valid_semantic_models.append(semantic_model) return valid_semantic_models @@ -849,9 +849,9 @@ def _get_joined_elements(self, measure_semantic_model: SemanticModel) -> Linkabl # Create single-hop elements join_paths = [] for entity in measure_semantic_model.entities: - semantic_models = self._get_semantic_models_with_joinable_entity( + semantic_models = self._get_semantic_models_with_valid_join( left_semantic_model_reference=measure_semantic_model.reference, - entity_reference=entity.reference, + join_by_entity_reference=entity.reference, ) for semantic_model in semantic_models: if semantic_model.name == measure_semantic_model.name: @@ -995,9 +995,9 @@ def _find_next_possible_paths( if entity_reference in set(x.join_on_entity for x in current_join_path.path_elements): continue - semantic_models_that_can_be_joined = self._get_semantic_models_with_joinable_entity( + semantic_models_that_can_be_joined = self._get_semantic_models_with_valid_join( left_semantic_model_reference=last_semantic_model_in_path.reference, - entity_reference=entity.reference, + join_by_entity_reference=entity.reference, ) for semantic_model in semantic_models_that_can_be_joined: # Don't create cycles in the join path by repeating a semantic model in the path. From 98c0fec482b1fd04f104a43e5bedf93374a42d1b Mon Sep 17 00:00:00 2001 From: Courtney Holcomb Date: Mon, 15 Apr 2024 14:27:56 -0700 Subject: [PATCH 04/37] Update LinkableMetric to use MetricSubqueryJoinPath and remove redundancies --- .../model/semantics/linkable_spec_resolver.py | 25 +++++++++++++------ 1 file changed, 18 insertions(+), 7 deletions(-) diff --git a/metricflow/model/semantics/linkable_spec_resolver.py b/metricflow/model/semantics/linkable_spec_resolver.py index 1402c371f4..bfb68b24b6 100644 --- a/metricflow/model/semantics/linkable_spec_resolver.py +++ b/metricflow/model/semantics/linkable_spec_resolver.py @@ -104,20 +104,31 @@ def reference(self) -> EntityReference: # noqa: D102 class LinkableMetric: """Describes how a metric can be realized by joining based on entity links.""" - element_name: str - join_by_semantic_model: SemanticModelReference - # TODO: Enable joining by dimension - entity_links: Tuple[EntityReference, ...] properties: FrozenSet[LinkableElementProperty] - join_path: Tuple[SemanticModelJoinPathElement, ...] + join_path: MetricSubqueryJoinPath + + def __post_init__(self) -> None: + """Ensure expected LinkableElementProperties have been set. + + LinkableMetrics always require a join to a metric subquery. + """ + assert {LinkableElementProperty.METRIC, LinkableElementProperty.JOINED}.issubset(self.properties) + + @property + def element_name(self) -> str: # noqa: D102 + return self.reference.element_name @property def path_key(self) -> ElementPathKey: # noqa: D102 - return ElementPathKey(element_name=self.element_name, entity_links=self.entity_links) + return ElementPathKey(element_name=self.element_name, entity_links=self.join_path.entity_links) @property def reference(self) -> MetricReference: # noqa: D102 - return MetricReference(element_name=self.element_name) + return self.join_path.metric_subquery_join_path_element.metric_reference + + @property + def join_by_semantic_model(self) -> Optional[SemanticModelReference]: # noqa: D102 + return self.join_path.last_semantic_model_reference @dataclass(frozen=True) From 735a451d837429fddcfd9c29944e29e2054ed2c2 Mon Sep 17 00:00:00 2001 From: Courtney Holcomb Date: Mon, 15 Apr 2024 14:38:53 -0700 Subject: [PATCH 05/37] Map joinable metrics to entities instead of semantic models for more specific group by resolution --- .../model/semantics/linkable_spec_resolver.py | 76 ++++++++----------- 1 file changed, 32 insertions(+), 44 deletions(-) diff --git a/metricflow/model/semantics/linkable_spec_resolver.py b/metricflow/model/semantics/linkable_spec_resolver.py index bfb68b24b6..c9d0349b7a 100644 --- a/metricflow/model/semantics/linkable_spec_resolver.py +++ b/metricflow/model/semantics/linkable_spec_resolver.py @@ -548,7 +548,6 @@ def __init__( self._entity_to_semantic_model[entity.reference.element_name].append(semantic_model) self._metric_to_linkable_element_sets: Dict[str, List[LinkableElementSet]] = {} - self._joinable_metrics_for_semantic_models: Dict[SemanticModelReference, Set[MetricReference]] = {} start_time = time.time() for metric in self._semantic_manifest.metrics: @@ -590,43 +589,22 @@ def __init__( self._metric_to_linkable_element_sets[metric.name] = linkable_sets_for_measure # This loop must happen after the one above so that _metric_to_linkable_element_sets is populated. + self._joinable_metrics_for_entities: Dict[EntityReference, Set[MetricReference]] = defaultdict(set) for metric in self._semantic_manifest.metrics: metric_reference = MetricReference(metric.name) linkable_element_set_for_metric = self.get_linkable_elements_for_metrics([metric_reference]) for linkable_entities in linkable_element_set_for_metric.path_key_to_linkable_entities.values(): for linkable_entity in linkable_entities: - semantic_model_reference = linkable_entity.semantic_model_origin - metrics = self._joinable_metrics_for_semantic_models.get(semantic_model_reference, set()) - metrics.add(metric_reference) - self._joinable_metrics_for_semantic_models[semantic_model_reference] = metrics + self._joinable_metrics_for_entities[linkable_entity.reference].add(metric_reference) # If no metrics are specified, the query interface supports querying distinct values for dimensions, entities, # and group by metrics. linkable_element_sets_for_no_metrics_queries: List[LinkableElementSet] = [] for semantic_model in semantic_manifest.semantic_models: linkable_element_sets_for_no_metrics_queries.append(self._get_elements_in_semantic_model(semantic_model)) - joinable_metrics = self._joinable_metrics_for_semantic_models.get(semantic_model.reference, set()) - for entity in semantic_model.entities: - linkable_metrics_set = LinkableElementSet( - path_key_to_linkable_metrics={ - ElementPathKey(element_name=metric.element_name, entity_links=(entity.reference,)): ( - LinkableMetric( - element_name=metric.element_name, - entity_links=(entity.reference,), - join_path=( - SemanticModelJoinPathElement( - semantic_model_reference=semantic_model.reference, - join_on_entity=entity.reference, - ), - ), - join_by_semantic_model=semantic_model.reference, - properties=frozenset({LinkableElementProperty.METRIC}), - ), - ) - for metric in joinable_metrics - }, - ) - linkable_element_sets_for_no_metrics_queries.append(linkable_metrics_set) + linkable_element_sets_for_no_metrics_queries.append( + self.get_joinable_metrics_for_semantic_model(semantic_model) + ) metric_time_elements_for_no_metrics = self._get_metric_time_elements(measure_reference=None) self._no_metric_linkable_element_set = LinkableElementSet.merge_by_path_key( @@ -650,24 +628,34 @@ def _get_semantic_model_for_measure(self, measure_reference: MeasureReference) - ) return semantic_models_where_measure_was_found[0] - def _get_joinable_metrics_for_semantic_model(self, semantic_model: SemanticModel) -> LinkableElementSet: - linkable_metrics = [] - for metric_ref in self._joinable_metrics_for_semantic_models.get(semantic_model.reference, set()): - for entity_link in [entity.reference for entity in semantic_model.entities]: - linkable_metrics.append( - LinkableMetric( - element_name=metric_ref.element_name, - join_by_semantic_model=semantic_model.reference, - entity_links=(entity_link,), - properties=frozenset({LinkableElementProperty.METRIC}), - join_path=(), - ) + def get_joinable_metrics_for_semantic_model( + self, semantic_model: SemanticModel, using_join_path: Optional[SemanticModelJoinPath] = None + ) -> LinkableElementSet: + """Get the set of linkable metrics that can be joined to this semantic model.""" + properties = frozenset({LinkableElementProperty.METRIC, LinkableElementProperty.JOINED}) + if using_join_path: + assert ( + semantic_model.reference == using_join_path.last_semantic_model_reference + ), "Last join path element should match semantic model when building LinkableMetrics." + properties = properties.union(frozenset({LinkableElementProperty.MULTI_HOP})) + + path_key_to_linkable_metrics: Dict[ElementPathKey, Tuple[LinkableMetric, ...]] = {} + for entity_reference in [entity.reference for entity in semantic_model.entities]: + if using_join_path and entity_reference in using_join_path.entity_links: + continue + for metric_reference in self._joinable_metrics_for_entities[entity_reference]: + linkable_metric = LinkableMetric( + properties=properties, + join_path=MetricSubqueryJoinPath( + metric_subquery_join_path_element=MetricSubqueryJoinPathElement( + metric_reference=metric_reference, join_on_entity=entity_reference + ), + semantic_model_join_path=using_join_path, + ), ) - return LinkableElementSet( - path_key_to_linkable_metrics={ - linkable_metric.path_key: (linkable_metric,) for linkable_metric in linkable_metrics - }, - ) + path_key_to_linkable_metrics[linkable_metric.path_key] = (linkable_metric,) + + return LinkableElementSet(path_key_to_linkable_metrics=path_key_to_linkable_metrics) def _get_elements_in_semantic_model(self, semantic_model: SemanticModel) -> LinkableElementSet: """Gets the elements in the semantic model, without requiring any joins. From 7d7d1638b5a2e59f3c390f6c50c9fe21435bb94f Mon Sep 17 00:00:00 2001 From: Courtney Holcomb Date: Mon, 15 Apr 2024 16:31:34 -0700 Subject: [PATCH 06/37] Use helper properties --- metricflow/model/semantics/linkable_spec_resolver.py | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/metricflow/model/semantics/linkable_spec_resolver.py b/metricflow/model/semantics/linkable_spec_resolver.py index c9d0349b7a..3722a15801 100644 --- a/metricflow/model/semantics/linkable_spec_resolver.py +++ b/metricflow/model/semantics/linkable_spec_resolver.py @@ -1026,8 +1026,6 @@ def create_linkable_element_set_from_join_path( with_properties: FrozenSet[LinkableElementProperty], ) -> LinkableElementSet: """Given the current path, generate the respective linkable elements from the last semantic model in the path.""" - entity_links = tuple(x.join_on_entity for x in join_path.path_elements) - semantic_model = self._semantic_model_lookup.get_by_reference(join_path.last_semantic_model_reference) assert semantic_model @@ -1042,7 +1040,7 @@ def create_linkable_element_set_from_join_path( LinkableDimension( semantic_model_origin=semantic_model.reference, element_name=dimension.reference.element_name, - entity_links=entity_links, + entity_links=join_path.entity_links, join_path=join_path.path_elements, properties=with_properties, time_granularity=None, @@ -1054,7 +1052,7 @@ def create_linkable_element_set_from_join_path( _generate_linkable_time_dimensions( semantic_model_origin=semantic_model.reference, dimension=dimension, - entity_links=entity_links, + entity_links=join_path.entity_links, join_path=join_path.path_elements, with_properties=with_properties, ) @@ -1064,12 +1062,12 @@ def create_linkable_element_set_from_join_path( for entity in semantic_model.entities: # Avoid creating "booking_id__booking_id" - if entity.reference != entity_links[-1]: + if entity.reference != join_path.last_entity_link: linkable_entities.append( LinkableEntity( semantic_model_origin=semantic_model.reference, element_name=entity.reference.element_name, - entity_links=entity_links, + entity_links=join_path.entity_links, join_path=join_path.path_elements, properties=with_properties.union({LinkableElementProperty.ENTITY}), ) @@ -1078,7 +1076,7 @@ def create_linkable_element_set_from_join_path( linkable_metrics = [ LinkableMetric( element_name=metric.element_name, - entity_links=entity_links, + entity_links=join_path.entity_links, join_path=join_path.path_elements, join_by_semantic_model=semantic_model.reference, properties=with_properties.union({LinkableElementProperty.METRIC}), From 0608c91a19b05763a6b5520cff4be00c119d8a48 Mon Sep 17 00:00:00 2001 From: Courtney Holcomb Date: Mon, 15 Apr 2024 16:33:32 -0700 Subject: [PATCH 07/37] Get more specific about avoiding cycle creation --- metricflow/model/semantics/linkable_spec_resolver.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/metricflow/model/semantics/linkable_spec_resolver.py b/metricflow/model/semantics/linkable_spec_resolver.py index 3722a15801..ac9aebc2c8 100644 --- a/metricflow/model/semantics/linkable_spec_resolver.py +++ b/metricflow/model/semantics/linkable_spec_resolver.py @@ -1061,8 +1061,8 @@ def create_linkable_element_set_from_join_path( raise RuntimeError(f"Unhandled type: {dimension_type}") for entity in semantic_model.entities: - # Avoid creating "booking_id__booking_id" - if entity.reference != join_path.last_entity_link: + # Avoid creating a cycle + if entity.reference not in join_path.entity_links: linkable_entities.append( LinkableEntity( semantic_model_origin=semantic_model.reference, From b5bf0387715262e80e4c693cb40416326a0b4c7f Mon Sep 17 00:00:00 2001 From: Courtney Holcomb Date: Tue, 16 Apr 2024 18:12:43 -0700 Subject: [PATCH 08/37] Types cleanup --- metricflow/model/semantics/linkable_spec_resolver.py | 6 +----- tests/snapshot_utils.py | 6 +++++- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/metricflow/model/semantics/linkable_spec_resolver.py b/metricflow/model/semantics/linkable_spec_resolver.py index ac9aebc2c8..192f491222 100644 --- a/metricflow/model/semantics/linkable_spec_resolver.py +++ b/metricflow/model/semantics/linkable_spec_resolver.py @@ -245,11 +245,7 @@ def intersection_by_path_key(linkable_element_sets: Sequence[LinkableElementSet] for path_key, entities in join_path_to_linkable_entities.items() }, path_key_to_linkable_metrics={ - path_key: tuple( - sorted( - metrics, key=lambda linkable_metric: linkable_metric.join_by_semantic_model.semantic_model_name - ) - ) + path_key: tuple(sorted(metrics, key=lambda linkable_metric: linkable_metric.element_name)) for path_key, metrics in join_path_to_linkable_metrics.items() }, ) diff --git a/tests/snapshot_utils.py b/tests/snapshot_utils.py index d6b7771c8a..0c6920f00b 100644 --- a/tests/snapshot_utils.py +++ b/tests/snapshot_utils.py @@ -249,7 +249,11 @@ def assert_linkable_element_set_snapshot_equal( # noqa: D103 rows.append( ( # Checking a limited set of fields as the result is large due to the paths in the object. - linkable_metric.join_by_semantic_model.semantic_model_name, + ( + linkable_metric.join_by_semantic_model.semantic_model_name + if linkable_metric.join_by_semantic_model + else "" + ), tuple(entity_link.element_name for entity_link in linkable_entity.entity_links), linkable_metric.element_name, "", From 268cf4098a81dce241d0619a2a5d3c8c7da78005 Mon Sep 17 00:00:00 2001 From: Courtney Holcomb Date: Tue, 16 Apr 2024 20:15:26 -0700 Subject: [PATCH 09/37] Fix bug in snapshot generation --- tests/snapshot_utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/snapshot_utils.py b/tests/snapshot_utils.py index 0c6920f00b..a90f48e601 100644 --- a/tests/snapshot_utils.py +++ b/tests/snapshot_utils.py @@ -254,7 +254,7 @@ def assert_linkable_element_set_snapshot_equal( # noqa: D103 if linkable_metric.join_by_semantic_model else "" ), - tuple(entity_link.element_name for entity_link in linkable_entity.entity_links), + tuple(entity_link.element_name for entity_link in linkable_metric.join_path.entity_links), linkable_metric.element_name, "", "", From 324f64a264324763213a99506f295124e837db16 Mon Sep 17 00:00:00 2001 From: Courtney Holcomb Date: Tue, 16 Apr 2024 20:27:02 -0700 Subject: [PATCH 10/37] Changelog --- .changes/unreleased/Fixes-20240416-202600.yaml | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 .changes/unreleased/Fixes-20240416-202600.yaml diff --git a/.changes/unreleased/Fixes-20240416-202600.yaml b/.changes/unreleased/Fixes-20240416-202600.yaml new file mode 100644 index 0000000000..006c4b440c --- /dev/null +++ b/.changes/unreleased/Fixes-20240416-202600.yaml @@ -0,0 +1,6 @@ +kind: Fixes +body: Refactor group by resolution for group by metrics. +time: 2024-04-16T20:26:00.637184-07:00 +custom: + Author: courtneyholcomb + Issue: "1139" From f05970ee0f80cad2b2bcc36e151fd164e0c14310 Mon Sep 17 00:00:00 2001 From: Courtney Holcomb Date: Thu, 18 Apr 2024 14:40:55 -0700 Subject: [PATCH 11/37] Move setup dict to avoid circular logic error --- metricflow/model/semantics/linkable_spec_resolver.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/metricflow/model/semantics/linkable_spec_resolver.py b/metricflow/model/semantics/linkable_spec_resolver.py index 192f491222..bea9a3bd3e 100644 --- a/metricflow/model/semantics/linkable_spec_resolver.py +++ b/metricflow/model/semantics/linkable_spec_resolver.py @@ -544,6 +544,7 @@ def __init__( self._entity_to_semantic_model[entity.reference.element_name].append(semantic_model) self._metric_to_linkable_element_sets: Dict[str, List[LinkableElementSet]] = {} + self._joinable_metrics_for_entities: Dict[EntityReference, Set[MetricReference]] = defaultdict(set) start_time = time.time() for metric in self._semantic_manifest.metrics: @@ -585,7 +586,6 @@ def __init__( self._metric_to_linkable_element_sets[metric.name] = linkable_sets_for_measure # This loop must happen after the one above so that _metric_to_linkable_element_sets is populated. - self._joinable_metrics_for_entities: Dict[EntityReference, Set[MetricReference]] = defaultdict(set) for metric in self._semantic_manifest.metrics: metric_reference = MetricReference(metric.name) linkable_element_set_for_metric = self.get_linkable_elements_for_metrics([metric_reference]) From 23f976ca8f55f293f05e250042c6ce5e2b729782 Mon Sep 17 00:00:00 2001 From: Courtney Holcomb Date: Thu, 18 Apr 2024 14:41:50 -0700 Subject: [PATCH 12/37] Privatize method --- metricflow/model/semantics/linkable_spec_resolver.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/metricflow/model/semantics/linkable_spec_resolver.py b/metricflow/model/semantics/linkable_spec_resolver.py index bea9a3bd3e..e9ecbe8c00 100644 --- a/metricflow/model/semantics/linkable_spec_resolver.py +++ b/metricflow/model/semantics/linkable_spec_resolver.py @@ -599,7 +599,7 @@ def __init__( for semantic_model in semantic_manifest.semantic_models: linkable_element_sets_for_no_metrics_queries.append(self._get_elements_in_semantic_model(semantic_model)) linkable_element_sets_for_no_metrics_queries.append( - self.get_joinable_metrics_for_semantic_model(semantic_model) + self._get_joinable_metrics_for_semantic_model(semantic_model) ) metric_time_elements_for_no_metrics = self._get_metric_time_elements(measure_reference=None) @@ -624,7 +624,7 @@ def _get_semantic_model_for_measure(self, measure_reference: MeasureReference) - ) return semantic_models_where_measure_was_found[0] - def get_joinable_metrics_for_semantic_model( + def _get_joinable_metrics_for_semantic_model( self, semantic_model: SemanticModel, using_join_path: Optional[SemanticModelJoinPath] = None ) -> LinkableElementSet: """Get the set of linkable metrics that can be joined to this semantic model.""" From ecbb5e968960253a3736e51fa9d7caffbc8fbde2 Mon Sep 17 00:00:00 2001 From: Courtney Holcomb Date: Thu, 18 Apr 2024 15:13:47 -0700 Subject: [PATCH 13/37] Set JOINED and MULTI_HOP properties from join_path length (cleanup) --- .../model/semantics/linkable_spec_resolver.py | 27 +++++++------------ .../semantics/test_linkable_spec_resolver.py | 17 ++++++++---- 2 files changed, 22 insertions(+), 22 deletions(-) diff --git a/metricflow/model/semantics/linkable_spec_resolver.py b/metricflow/model/semantics/linkable_spec_resolver.py index e9ecbe8c00..f12ab6075b 100644 --- a/metricflow/model/semantics/linkable_spec_resolver.py +++ b/metricflow/model/semantics/linkable_spec_resolver.py @@ -858,13 +858,7 @@ def _get_joined_elements(self, measure_semantic_model: SemanticModel) -> Linkabl ) ) single_hop_elements = LinkableElementSet.merge_by_path_key( - [ - self.create_linkable_element_set_from_join_path( - join_path=join_path, - with_properties=frozenset({LinkableElementProperty.JOINED}), - ) - for join_path in join_paths - ] + [self.create_linkable_element_set_from_join_path(join_path) for join_path in join_paths] ) # Create multi-hop elements. At each iteration, we generate the list of valid elements based on the current join @@ -886,11 +880,7 @@ def _get_joined_elements(self, measure_semantic_model: SemanticModel) -> Linkabl multi_hop_elements = LinkableElementSet.merge_by_path_key( (multi_hop_elements,) + tuple( - self.create_linkable_element_set_from_join_path( - join_path=new_join_path, - with_properties=frozenset({LinkableElementProperty.JOINED, LinkableElementProperty.MULTI_HOP}), - ) - for new_join_path in new_join_paths + self.create_linkable_element_set_from_join_path(new_join_path) for new_join_path in new_join_paths ) ) join_paths = new_join_paths @@ -1019,9 +1009,12 @@ def _find_next_possible_paths( def create_linkable_element_set_from_join_path( self, join_path: SemanticModelJoinPath, - with_properties: FrozenSet[LinkableElementProperty], ) -> LinkableElementSet: """Given the current path, generate the respective linkable elements from the last semantic model in the path.""" + properties = frozenset({LinkableElementProperty.JOINED}) + if len(join_path.path_elements) > 1: + properties = properties.union({LinkableElementProperty.MULTI_HOP}) + semantic_model = self._semantic_model_lookup.get_by_reference(join_path.last_semantic_model_reference) assert semantic_model @@ -1038,7 +1031,7 @@ def create_linkable_element_set_from_join_path( element_name=dimension.reference.element_name, entity_links=join_path.entity_links, join_path=join_path.path_elements, - properties=with_properties, + properties=properties, time_granularity=None, date_part=None, ) @@ -1050,7 +1043,7 @@ def create_linkable_element_set_from_join_path( dimension=dimension, entity_links=join_path.entity_links, join_path=join_path.path_elements, - with_properties=with_properties, + with_properties=properties, ) ) else: @@ -1065,7 +1058,7 @@ def create_linkable_element_set_from_join_path( element_name=entity.reference.element_name, entity_links=join_path.entity_links, join_path=join_path.path_elements, - properties=with_properties.union({LinkableElementProperty.ENTITY}), + properties=properties.union({LinkableElementProperty.ENTITY}), ) ) @@ -1075,7 +1068,7 @@ def create_linkable_element_set_from_join_path( entity_links=join_path.entity_links, join_path=join_path.path_elements, join_by_semantic_model=semantic_model.reference, - properties=with_properties.union({LinkableElementProperty.METRIC}), + properties=properties.union({LinkableElementProperty.METRIC}), ) for metric in self._joinable_metrics_for_semantic_models.get(join_path.last_semantic_model_reference, set()) ] diff --git a/tests/model/semantics/test_linkable_spec_resolver.py b/tests/model/semantics/test_linkable_spec_resolver.py index 2085cccef5..af6431b5c1 100644 --- a/tests/model/semantics/test_linkable_spec_resolver.py +++ b/tests/model/semantics/test_linkable_spec_resolver.py @@ -15,6 +15,7 @@ from metricflow.model.semantics.linkable_element_properties import LinkableElementProperty from metricflow.model.semantics.linkable_spec_resolver import ( SemanticModelJoinPath, + SemanticModelJoinPathElement, ValidLinkableSpecResolver, ) from metricflow.model.semantics.semantic_model_join_evaluator import MAX_JOIN_HOPS @@ -145,7 +146,6 @@ def test_create_linkable_element_set_from_join_path( # noqa: D103 semantic_model_reference=SemanticModelReference("listings_latest"), join_on_entity=EntityReference("listing"), ), - with_properties=frozenset({LinkableElementProperty.JOINED}), ), ) @@ -160,11 +160,18 @@ def test_create_linkable_element_set_from_join_path_multi_hop( # noqa: D103 mf_test_configuration=mf_test_configuration, set_id="result0", linkable_element_set=simple_model_spec_resolver.create_linkable_element_set_from_join_path( - join_path=SemanticModelJoinPath.from_single_element( - semantic_model_reference=SemanticModelReference("listings_latest"), - join_on_entity=EntityReference("listing"), + SemanticModelJoinPath( + ( + SemanticModelJoinPathElement( + semantic_model_reference=SemanticModelReference("bookings"), + join_on_entity=EntityReference("guest"), + ), + SemanticModelJoinPathElement( + semantic_model_reference=SemanticModelReference("listings_latest"), + join_on_entity=EntityReference("listing"), + ), + ) ), - with_properties=frozenset({LinkableElementProperty.JOINED, LinkableElementProperty.MULTI_HOP}), ), ) From 5b9210d461ea53dff5a7d7723ed3d66e0815d2e8 Mon Sep 17 00:00:00 2001 From: Courtney Holcomb Date: Thu, 18 Apr 2024 15:38:58 -0700 Subject: [PATCH 14/37] Move logic for directly linkable metrics to _get_joined_elements (semantics) --- .../model/semantics/linkable_spec_resolver.py | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/metricflow/model/semantics/linkable_spec_resolver.py b/metricflow/model/semantics/linkable_spec_resolver.py index f12ab6075b..c10fb5444e 100644 --- a/metricflow/model/semantics/linkable_spec_resolver.py +++ b/metricflow/model/semantics/linkable_spec_resolver.py @@ -841,6 +841,8 @@ def _get_metric_time_elements(self, measure_reference: Optional[MeasureReference def _get_joined_elements(self, measure_semantic_model: SemanticModel) -> LinkableElementSet: """Get the elements that can be generated by joining other models to the given model.""" + directly_linkable_metrics = self._get_joinable_metrics_for_semantic_model(semantic_model=measure_semantic_model) + # Create single-hop elements join_paths = [] for entity in measure_semantic_model.entities: @@ -885,7 +887,9 @@ def _get_joined_elements(self, measure_semantic_model: SemanticModel) -> Linkabl ) join_paths = new_join_paths - return LinkableElementSet.merge_by_path_key((single_hop_elements, multi_hop_elements)) + return LinkableElementSet.merge_by_path_key( + (directly_linkable_metrics, single_hop_elements, multi_hop_elements) + ) def _get_linkable_element_set_for_measure( self, @@ -897,17 +901,11 @@ def _get_linkable_element_set_for_measure( measure_semantic_model = self._get_semantic_model_for_measure(measure_reference) elements_in_semantic_model = self._get_elements_in_semantic_model(measure_semantic_model) - metrics_linked_to_semantic_model = self._get_joinable_metrics_for_semantic_model(measure_semantic_model) metric_time_elements = self._get_metric_time_elements(measure_reference) joined_elements = self._get_joined_elements(measure_semantic_model) return LinkableElementSet.merge_by_path_key( - ( - elements_in_semantic_model, - metrics_linked_to_semantic_model, - metric_time_elements, - joined_elements, - ) + (elements_in_semantic_model, metric_time_elements, joined_elements) ).filter( with_any_of=with_any_of, without_any_of=without_any_of, From b3d54a8d91d1dbb2bf715b58c61edf3d491b216b Mon Sep 17 00:00:00 2001 From: Courtney Holcomb Date: Thu, 18 Apr 2024 15:40:33 -0700 Subject: [PATCH 15/37] Use new logic for finding linkable metrics (from previous commit) in create_linkable_element_set_from_join_path --- .../model/semantics/linkable_spec_resolver.py | 18 +++--------------- 1 file changed, 3 insertions(+), 15 deletions(-) diff --git a/metricflow/model/semantics/linkable_spec_resolver.py b/metricflow/model/semantics/linkable_spec_resolver.py index c10fb5444e..7cb75d28a2 100644 --- a/metricflow/model/semantics/linkable_spec_resolver.py +++ b/metricflow/model/semantics/linkable_spec_resolver.py @@ -1018,7 +1018,6 @@ def create_linkable_element_set_from_join_path( linkable_dimensions: List[LinkableDimension] = [] linkable_entities: List[LinkableEntity] = [] - linkable_metrics: List[LinkableMetric] = [] for dimension in semantic_model.dimensions: dimension_type = dimension.type @@ -1060,17 +1059,6 @@ def create_linkable_element_set_from_join_path( ) ) - linkable_metrics = [ - LinkableMetric( - element_name=metric.element_name, - entity_links=join_path.entity_links, - join_path=join_path.path_elements, - join_by_semantic_model=semantic_model.reference, - properties=properties.union({LinkableElementProperty.METRIC}), - ) - for metric in self._joinable_metrics_for_semantic_models.get(join_path.last_semantic_model_reference, set()) - ] - return LinkableElementSet( path_key_to_linkable_dimensions={ linkable_dimension.path_key: (linkable_dimension,) for linkable_dimension in linkable_dimensions @@ -1078,7 +1066,7 @@ def create_linkable_element_set_from_join_path( path_key_to_linkable_entities={ linkable_entity.path_key: (linkable_entity,) for linkable_entity in linkable_entities }, - path_key_to_linkable_metrics={ - linkable_metric.path_key: (linkable_metric,) for linkable_metric in linkable_metrics - }, + path_key_to_linkable_metrics=self._get_joinable_metrics_for_semantic_model( + semantic_model=semantic_model, using_join_path=join_path + ).path_key_to_linkable_metrics, ) From ed59e3d05e2e3b9ad60e63bb039a1a51d43b7160 Mon Sep 17 00:00:00 2001 From: Courtney Holcomb Date: Thu, 18 Apr 2024 15:42:05 -0700 Subject: [PATCH 16/37] Update snapshots --- ...linkable_element_set_as_spec_set__set0.txt | 138 +++ ...le_element_set_from_join_path__result0.txt | 232 ++--- ..._set_from_join_path_multi_hop__result0.txt | 232 ++--- ...linkable_elements_for_measure__result0.txt | 848 +++++++++--------- ...elements_for_no_metrics_query__result0.txt | 10 - 5 files changed, 815 insertions(+), 645 deletions(-) diff --git a/tests/snapshots/test_linkable_spec_resolver.py/list/test_linkable_element_set_as_spec_set__set0.txt b/tests/snapshots/test_linkable_spec_resolver.py/list/test_linkable_element_set_as_spec_set__set0.txt index b6f57baa7f..17b183e31e 100644 --- a/tests/snapshots/test_linkable_spec_resolver.py/list/test_linkable_element_set_as_spec_set__set0.txt +++ b/tests/snapshots/test_linkable_spec_resolver.py/list/test_linkable_element_set_as_spec_set__set0.txt @@ -96,6 +96,69 @@ 'listing__lux_booking_fraction_of_max_value', 'listing__lux_booking_value_rate_expr', 'listing__lux_listing', + 'listing__lux_listing__active_listings', + 'listing__lux_listing__approximate_continuous_booking_value_p99', + 'listing__lux_listing__approximate_discrete_booking_value_p99', + 'listing__lux_listing__average_booking_value', + 'listing__lux_listing__average_instant_booking_value', + 'listing__lux_listing__bookers', + 'listing__lux_listing__booking_fees', + 'listing__lux_listing__booking_fees_last_week_per_booker_this_week', + 'listing__lux_listing__booking_fees_per_booker', + 'listing__lux_listing__booking_fees_since_start_of_month', + 'listing__lux_listing__booking_payments', + 'listing__lux_listing__booking_value', + 'listing__lux_listing__booking_value_for_non_null_listing_id', + 'listing__lux_listing__booking_value_p99', + 'listing__lux_listing__booking_value_per_view', + 'listing__lux_listing__booking_value_sub_instant', + 'listing__lux_listing__booking_value_sub_instant_add_10', + 'listing__lux_listing__bookings', + 'listing__lux_listing__bookings_5_day_lag', + 'listing__lux_listing__bookings_at_start_of_month', + 'listing__lux_listing__bookings_fill_nulls_with_0', + 'listing__lux_listing__bookings_fill_nulls_with_0_without_time_spine', + 'listing__lux_listing__bookings_growth_2_weeks', + 'listing__lux_listing__bookings_growth_2_weeks_fill_nulls_with_0', + 'listing__lux_listing__bookings_growth_2_weeks_fill_nulls_with_0_for_non_offset', + 'listing__lux_listing__bookings_growth_since_start_of_month', + 'listing__lux_listing__bookings_join_to_time_spine', + 'listing__lux_listing__bookings_month_start_compared_to_1_month_prior', + 'listing__lux_listing__bookings_offset_once', + 'listing__lux_listing__bookings_offset_twice', + 'listing__lux_listing__bookings_per_booker', + 'listing__lux_listing__bookings_per_dollar', + 'listing__lux_listing__bookings_per_listing', + 'listing__lux_listing__bookings_per_lux_listing_derived', + 'listing__lux_listing__bookings_per_view', + 'listing__lux_listing__derived_bookings_0', + 'listing__lux_listing__derived_bookings_1', + 'listing__lux_listing__discrete_booking_value_p99', + 'listing__lux_listing__double_counted_delayed_bookings', + 'listing__lux_listing__every_2_days_bookers_2_days_ago', + 'listing__lux_listing__every_two_days_bookers', + 'listing__lux_listing__every_two_days_bookers_fill_nulls_with_0', + 'listing__lux_listing__instant_booking_fraction_of_max_value', + 'listing__lux_listing__instant_booking_value', + 'listing__lux_listing__instant_booking_value_ratio', + 'listing__lux_listing__instant_bookings', + 'listing__lux_listing__instant_lux_booking_value_rate', + 'listing__lux_listing__instant_plus_non_referred_bookings_pct', + 'listing__lux_listing__largest_listing', + 'listing__lux_listing__listings', + 'listing__lux_listing__lux_booking_fraction_of_max_value', + 'listing__lux_listing__lux_booking_value_rate_expr', + 'listing__lux_listing__lux_listings', + 'listing__lux_listing__max_booking_value', + 'listing__lux_listing__median_booking_value', + 'listing__lux_listing__min_booking_value', + 'listing__lux_listing__nested_fill_nulls_without_time_spine', + 'listing__lux_listing__non_referred_bookings_pct', + 'listing__lux_listing__referred_bookings', + 'listing__lux_listing__smallest_listing', + 'listing__lux_listing__twice_bookings_fill_nulls_with_0_without_time_spine', + 'listing__lux_listing__views', + 'listing__lux_listing__views_times_booking_value', 'listing__lux_listings', 'listing__max_booking_value', 'listing__median_booking_value', @@ -165,6 +228,81 @@ 'user__bookings_per_lux_listing_derived', 'user__bookings_per_view', 'user__company', + 'user__company__active_listings', + 'user__company__approximate_continuous_booking_value_p99', + 'user__company__approximate_discrete_booking_value_p99', + 'user__company__average_booking_value', + 'user__company__average_instant_booking_value', + 'user__company__bookers', + 'user__company__booking_fees', + 'user__company__booking_fees_last_week_per_booker_this_week', + 'user__company__booking_fees_per_booker', + 'user__company__booking_fees_since_start_of_month', + 'user__company__booking_payments', + 'user__company__booking_value', + 'user__company__booking_value_for_non_null_listing_id', + 'user__company__booking_value_p99', + 'user__company__booking_value_per_view', + 'user__company__booking_value_sub_instant', + 'user__company__booking_value_sub_instant_add_10', + 'user__company__bookings', + 'user__company__bookings_5_day_lag', + 'user__company__bookings_at_start_of_month', + 'user__company__bookings_fill_nulls_with_0', + 'user__company__bookings_fill_nulls_with_0_without_time_spine', + 'user__company__bookings_growth_2_weeks', + 'user__company__bookings_growth_2_weeks_fill_nulls_with_0', + 'user__company__bookings_growth_2_weeks_fill_nulls_with_0_for_non_offset', + 'user__company__bookings_growth_since_start_of_month', + 'user__company__bookings_join_to_time_spine', + 'user__company__bookings_month_start_compared_to_1_month_prior', + 'user__company__bookings_offset_once', + 'user__company__bookings_offset_twice', + 'user__company__bookings_per_booker', + 'user__company__bookings_per_dollar', + 'user__company__bookings_per_view', + 'user__company__current_account_balance_by_user', + 'user__company__derived_bookings_0', + 'user__company__derived_bookings_1', + 'user__company__discrete_booking_value_p99', + 'user__company__double_counted_delayed_bookings', + 'user__company__every_2_days_bookers_2_days_ago', + 'user__company__every_two_days_bookers', + 'user__company__every_two_days_bookers_fill_nulls_with_0', + 'user__company__identity_verifications', + 'user__company__instant_booking_fraction_of_max_value', + 'user__company__instant_booking_value', + 'user__company__instant_booking_value_ratio', + 'user__company__instant_bookings', + 'user__company__instant_lux_booking_value_rate', + 'user__company__instant_plus_non_referred_bookings_pct', + 'user__company__largest_listing', + 'user__company__listings', + 'user__company__lux_booking_fraction_of_max_value', + 'user__company__lux_booking_value_rate_expr', + 'user__company__lux_listings', + 'user__company__max_booking_value', + 'user__company__median_booking_value', + 'user__company__min_booking_value', + 'user__company__nested_fill_nulls_without_time_spine', + 'user__company__non_referred_bookings_pct', + 'user__company__referred_bookings', + 'user__company__regional_starting_balance_ratios', + 'user__company__revenue', + 'user__company__revenue_all_time', + 'user__company__revenue_mtd', + 'user__company__smallest_listing', + 'user__company__total_account_balance_first_day', + 'user__company__trailing_2_months_revenue', + 'user__company__trailing_2_months_revenue_sub_10', + 'user__company__twice_bookings_fill_nulls_with_0_without_time_spine', + 'user__company__views', + 'user__company__views_times_booking_value', + 'user__company__visit_buy_conversion_rate', + 'user__company__visit_buy_conversion_rate_7days', + 'user__company__visit_buy_conversion_rate_7days_fill_nulls_with_0', + 'user__company__visit_buy_conversion_rate_by_session', + 'user__company__visit_buy_conversions', 'user__company_name', 'user__created_at__day', 'user__created_at__extract_day', diff --git a/tests/snapshots/test_linkable_spec_resolver.py/str/test_create_linkable_element_set_from_join_path__result0.txt b/tests/snapshots/test_linkable_spec_resolver.py/str/test_create_linkable_element_set_from_join_path__result0.txt index 8c045a620b..56e7aaf2e6 100644 --- a/tests/snapshots/test_linkable_spec_resolver.py/str/test_create_linkable_element_set_from_join_path__result0.txt +++ b/tests/snapshots/test_linkable_spec_resolver.py/str/test_create_linkable_element_set_from_join_path__result0.txt @@ -1,109 +1,123 @@ -Semantic Model Entity Links Name Time Granularity Date Part Properties ----------------- -------------- -------------------------------------------------------- ------------------ ----------- -------------------------------------- -listings_latest ('listing',) active_listings ['JOINED', 'METRIC'] -listings_latest ('listing',) approximate_continuous_booking_value_p99 ['JOINED', 'METRIC'] -listings_latest ('listing',) approximate_discrete_booking_value_p99 ['JOINED', 'METRIC'] -listings_latest ('listing',) average_booking_value ['JOINED', 'METRIC'] -listings_latest ('listing',) average_instant_booking_value ['JOINED', 'METRIC'] -listings_latest ('listing',) bookers ['JOINED', 'METRIC'] -listings_latest ('listing',) booking_fees ['JOINED', 'METRIC'] -listings_latest ('listing',) booking_fees_last_week_per_booker_this_week ['JOINED', 'METRIC'] -listings_latest ('listing',) booking_fees_per_booker ['JOINED', 'METRIC'] -listings_latest ('listing',) booking_fees_since_start_of_month ['JOINED', 'METRIC'] -listings_latest ('listing',) booking_payments ['JOINED', 'METRIC'] -listings_latest ('listing',) booking_value ['JOINED', 'METRIC'] -listings_latest ('listing',) booking_value_for_non_null_listing_id ['JOINED', 'METRIC'] -listings_latest ('listing',) booking_value_p99 ['JOINED', 'METRIC'] -listings_latest ('listing',) booking_value_per_view ['JOINED', 'METRIC'] -listings_latest ('listing',) booking_value_sub_instant ['JOINED', 'METRIC'] -listings_latest ('listing',) booking_value_sub_instant_add_10 ['JOINED', 'METRIC'] -listings_latest ('listing',) bookings ['JOINED', 'METRIC'] -listings_latest ('listing',) bookings_5_day_lag ['JOINED', 'METRIC'] -listings_latest ('listing',) bookings_at_start_of_month ['JOINED', 'METRIC'] -listings_latest ('listing',) bookings_fill_nulls_with_0 ['JOINED', 'METRIC'] -listings_latest ('listing',) bookings_fill_nulls_with_0_without_time_spine ['JOINED', 'METRIC'] -listings_latest ('listing',) bookings_growth_2_weeks ['JOINED', 'METRIC'] -listings_latest ('listing',) bookings_growth_2_weeks_fill_nulls_with_0 ['JOINED', 'METRIC'] -listings_latest ('listing',) bookings_growth_2_weeks_fill_nulls_with_0_for_non_offset ['JOINED', 'METRIC'] -listings_latest ('listing',) bookings_growth_since_start_of_month ['JOINED', 'METRIC'] -listings_latest ('listing',) bookings_join_to_time_spine ['JOINED', 'METRIC'] -listings_latest ('listing',) bookings_month_start_compared_to_1_month_prior ['JOINED', 'METRIC'] -listings_latest ('listing',) bookings_offset_once ['JOINED', 'METRIC'] -listings_latest ('listing',) bookings_offset_twice ['JOINED', 'METRIC'] -listings_latest ('listing',) bookings_per_booker ['JOINED', 'METRIC'] -listings_latest ('listing',) bookings_per_dollar ['JOINED', 'METRIC'] -listings_latest ('listing',) bookings_per_listing ['JOINED', 'METRIC'] -listings_latest ('listing',) bookings_per_lux_listing_derived ['JOINED', 'METRIC'] -listings_latest ('listing',) bookings_per_view ['JOINED', 'METRIC'] -listings_latest ('listing',) capacity_latest ['JOINED'] -listings_latest ('listing',) country_latest ['JOINED'] -listings_latest ('listing',) created_at DAY ['JOINED'] -listings_latest ('listing',) created_at DAY DAY ['JOINED'] -listings_latest ('listing',) created_at DAY DOW ['JOINED'] -listings_latest ('listing',) created_at DAY DOY ['JOINED'] -listings_latest ('listing',) created_at DAY MONTH ['JOINED'] -listings_latest ('listing',) created_at DAY QUARTER ['JOINED'] -listings_latest ('listing',) created_at DAY YEAR ['JOINED'] -listings_latest ('listing',) created_at MONTH ['DERIVED_TIME_GRANULARITY', 'JOINED'] -listings_latest ('listing',) created_at MONTH MONTH ['DERIVED_TIME_GRANULARITY', 'JOINED'] -listings_latest ('listing',) created_at MONTH QUARTER ['DERIVED_TIME_GRANULARITY', 'JOINED'] -listings_latest ('listing',) created_at MONTH YEAR ['DERIVED_TIME_GRANULARITY', 'JOINED'] -listings_latest ('listing',) created_at QUARTER ['DERIVED_TIME_GRANULARITY', 'JOINED'] -listings_latest ('listing',) created_at QUARTER QUARTER ['DERIVED_TIME_GRANULARITY', 'JOINED'] -listings_latest ('listing',) created_at QUARTER YEAR ['DERIVED_TIME_GRANULARITY', 'JOINED'] -listings_latest ('listing',) created_at WEEK ['DERIVED_TIME_GRANULARITY', 'JOINED'] -listings_latest ('listing',) created_at WEEK MONTH ['DERIVED_TIME_GRANULARITY', 'JOINED'] -listings_latest ('listing',) created_at WEEK QUARTER ['DERIVED_TIME_GRANULARITY', 'JOINED'] -listings_latest ('listing',) created_at WEEK YEAR ['DERIVED_TIME_GRANULARITY', 'JOINED'] -listings_latest ('listing',) created_at YEAR ['DERIVED_TIME_GRANULARITY', 'JOINED'] -listings_latest ('listing',) created_at YEAR YEAR ['DERIVED_TIME_GRANULARITY', 'JOINED'] -listings_latest ('listing',) derived_bookings_0 ['JOINED', 'METRIC'] -listings_latest ('listing',) derived_bookings_1 ['JOINED', 'METRIC'] -listings_latest ('listing',) discrete_booking_value_p99 ['JOINED', 'METRIC'] -listings_latest ('listing',) double_counted_delayed_bookings ['JOINED', 'METRIC'] -listings_latest ('listing',) ds DAY ['JOINED'] -listings_latest ('listing',) ds DAY DAY ['JOINED'] -listings_latest ('listing',) ds DAY DOW ['JOINED'] -listings_latest ('listing',) ds DAY DOY ['JOINED'] -listings_latest ('listing',) ds DAY MONTH ['JOINED'] -listings_latest ('listing',) ds DAY QUARTER ['JOINED'] -listings_latest ('listing',) ds DAY YEAR ['JOINED'] -listings_latest ('listing',) ds MONTH ['DERIVED_TIME_GRANULARITY', 'JOINED'] -listings_latest ('listing',) ds MONTH MONTH ['DERIVED_TIME_GRANULARITY', 'JOINED'] -listings_latest ('listing',) ds MONTH QUARTER ['DERIVED_TIME_GRANULARITY', 'JOINED'] -listings_latest ('listing',) ds MONTH YEAR ['DERIVED_TIME_GRANULARITY', 'JOINED'] -listings_latest ('listing',) ds QUARTER ['DERIVED_TIME_GRANULARITY', 'JOINED'] -listings_latest ('listing',) ds QUARTER QUARTER ['DERIVED_TIME_GRANULARITY', 'JOINED'] -listings_latest ('listing',) ds QUARTER YEAR ['DERIVED_TIME_GRANULARITY', 'JOINED'] -listings_latest ('listing',) ds WEEK ['DERIVED_TIME_GRANULARITY', 'JOINED'] -listings_latest ('listing',) ds WEEK MONTH ['DERIVED_TIME_GRANULARITY', 'JOINED'] -listings_latest ('listing',) ds WEEK QUARTER ['DERIVED_TIME_GRANULARITY', 'JOINED'] -listings_latest ('listing',) ds WEEK YEAR ['DERIVED_TIME_GRANULARITY', 'JOINED'] -listings_latest ('listing',) ds YEAR ['DERIVED_TIME_GRANULARITY', 'JOINED'] -listings_latest ('listing',) ds YEAR YEAR ['DERIVED_TIME_GRANULARITY', 'JOINED'] -listings_latest ('listing',) every_2_days_bookers_2_days_ago ['JOINED', 'METRIC'] -listings_latest ('listing',) every_two_days_bookers ['JOINED', 'METRIC'] -listings_latest ('listing',) every_two_days_bookers_fill_nulls_with_0 ['JOINED', 'METRIC'] -listings_latest ('listing',) instant_booking_fraction_of_max_value ['JOINED', 'METRIC'] -listings_latest ('listing',) instant_booking_value ['JOINED', 'METRIC'] -listings_latest ('listing',) instant_booking_value_ratio ['JOINED', 'METRIC'] -listings_latest ('listing',) instant_bookings ['JOINED', 'METRIC'] -listings_latest ('listing',) instant_lux_booking_value_rate ['JOINED', 'METRIC'] -listings_latest ('listing',) instant_plus_non_referred_bookings_pct ['JOINED', 'METRIC'] -listings_latest ('listing',) is_lux_latest ['JOINED'] -listings_latest ('listing',) largest_listing ['JOINED', 'METRIC'] -listings_latest ('listing',) listings ['JOINED', 'METRIC'] -listings_latest ('listing',) lux_booking_fraction_of_max_value ['JOINED', 'METRIC'] -listings_latest ('listing',) lux_booking_value_rate_expr ['JOINED', 'METRIC'] -listings_latest ('listing',) lux_listings ['JOINED', 'METRIC'] -listings_latest ('listing',) max_booking_value ['JOINED', 'METRIC'] -listings_latest ('listing',) median_booking_value ['JOINED', 'METRIC'] -listings_latest ('listing',) min_booking_value ['JOINED', 'METRIC'] -listings_latest ('listing',) nested_fill_nulls_without_time_spine ['JOINED', 'METRIC'] -listings_latest ('listing',) non_referred_bookings_pct ['JOINED', 'METRIC'] -listings_latest ('listing',) referred_bookings ['JOINED', 'METRIC'] -listings_latest ('listing',) smallest_listing ['JOINED', 'METRIC'] -listings_latest ('listing',) twice_bookings_fill_nulls_with_0_without_time_spine ['JOINED', 'METRIC'] -listings_latest ('listing',) user ['ENTITY', 'JOINED'] -listings_latest ('listing',) views ['JOINED', 'METRIC'] -listings_latest ('listing',) views_times_booking_value ['JOINED', 'METRIC'] +Semantic Model Entity Links Name Time Granularity Date Part Properties +---------------- ------------------- -------------------------------------------------------- ------------------ ----------- -------------------------------------- +listings_latest ('listing',) capacity_latest ['JOINED'] +listings_latest ('listing',) country_latest ['JOINED'] +listings_latest ('listing',) created_at DAY ['JOINED'] +listings_latest ('listing',) created_at DAY DAY ['JOINED'] +listings_latest ('listing',) created_at DAY DOW ['JOINED'] +listings_latest ('listing',) created_at DAY DOY ['JOINED'] +listings_latest ('listing',) created_at DAY MONTH ['JOINED'] +listings_latest ('listing',) created_at DAY QUARTER ['JOINED'] +listings_latest ('listing',) created_at DAY YEAR ['JOINED'] +listings_latest ('listing',) created_at MONTH ['DERIVED_TIME_GRANULARITY', 'JOINED'] +listings_latest ('listing',) created_at MONTH MONTH ['DERIVED_TIME_GRANULARITY', 'JOINED'] +listings_latest ('listing',) created_at MONTH QUARTER ['DERIVED_TIME_GRANULARITY', 'JOINED'] +listings_latest ('listing',) created_at MONTH YEAR ['DERIVED_TIME_GRANULARITY', 'JOINED'] +listings_latest ('listing',) created_at QUARTER ['DERIVED_TIME_GRANULARITY', 'JOINED'] +listings_latest ('listing',) created_at QUARTER QUARTER ['DERIVED_TIME_GRANULARITY', 'JOINED'] +listings_latest ('listing',) created_at QUARTER YEAR ['DERIVED_TIME_GRANULARITY', 'JOINED'] +listings_latest ('listing',) created_at WEEK ['DERIVED_TIME_GRANULARITY', 'JOINED'] +listings_latest ('listing',) created_at WEEK MONTH ['DERIVED_TIME_GRANULARITY', 'JOINED'] +listings_latest ('listing',) created_at WEEK QUARTER ['DERIVED_TIME_GRANULARITY', 'JOINED'] +listings_latest ('listing',) created_at WEEK YEAR ['DERIVED_TIME_GRANULARITY', 'JOINED'] +listings_latest ('listing',) created_at YEAR ['DERIVED_TIME_GRANULARITY', 'JOINED'] +listings_latest ('listing',) created_at YEAR YEAR ['DERIVED_TIME_GRANULARITY', 'JOINED'] +listings_latest ('listing',) ds DAY ['JOINED'] +listings_latest ('listing',) ds DAY DAY ['JOINED'] +listings_latest ('listing',) ds DAY DOW ['JOINED'] +listings_latest ('listing',) ds DAY DOY ['JOINED'] +listings_latest ('listing',) ds DAY MONTH ['JOINED'] +listings_latest ('listing',) ds DAY QUARTER ['JOINED'] +listings_latest ('listing',) ds DAY YEAR ['JOINED'] +listings_latest ('listing',) ds MONTH ['DERIVED_TIME_GRANULARITY', 'JOINED'] +listings_latest ('listing',) ds MONTH MONTH ['DERIVED_TIME_GRANULARITY', 'JOINED'] +listings_latest ('listing',) ds MONTH QUARTER ['DERIVED_TIME_GRANULARITY', 'JOINED'] +listings_latest ('listing',) ds MONTH YEAR ['DERIVED_TIME_GRANULARITY', 'JOINED'] +listings_latest ('listing',) ds QUARTER ['DERIVED_TIME_GRANULARITY', 'JOINED'] +listings_latest ('listing',) ds QUARTER QUARTER ['DERIVED_TIME_GRANULARITY', 'JOINED'] +listings_latest ('listing',) ds QUARTER YEAR ['DERIVED_TIME_GRANULARITY', 'JOINED'] +listings_latest ('listing',) ds WEEK ['DERIVED_TIME_GRANULARITY', 'JOINED'] +listings_latest ('listing',) ds WEEK MONTH ['DERIVED_TIME_GRANULARITY', 'JOINED'] +listings_latest ('listing',) ds WEEK QUARTER ['DERIVED_TIME_GRANULARITY', 'JOINED'] +listings_latest ('listing',) ds WEEK YEAR ['DERIVED_TIME_GRANULARITY', 'JOINED'] +listings_latest ('listing',) ds YEAR ['DERIVED_TIME_GRANULARITY', 'JOINED'] +listings_latest ('listing',) ds YEAR YEAR ['DERIVED_TIME_GRANULARITY', 'JOINED'] +listings_latest ('listing',) is_lux_latest ['JOINED'] +listings_latest ('listing',) user ['ENTITY', 'JOINED'] +listings_latest ('listing', 'user') active_listings ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('listing', 'user') approximate_continuous_booking_value_p99 ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('listing', 'user') approximate_discrete_booking_value_p99 ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('listing', 'user') average_booking_value ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('listing', 'user') average_instant_booking_value ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('listing', 'user') bookers ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('listing', 'user') booking_fees ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('listing', 'user') booking_fees_last_week_per_booker_this_week ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('listing', 'user') booking_fees_per_booker ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('listing', 'user') booking_fees_since_start_of_month ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('listing', 'user') booking_payments ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('listing', 'user') booking_value ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('listing', 'user') booking_value_for_non_null_listing_id ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('listing', 'user') booking_value_p99 ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('listing', 'user') booking_value_per_view ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('listing', 'user') booking_value_sub_instant ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('listing', 'user') booking_value_sub_instant_add_10 ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('listing', 'user') bookings ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('listing', 'user') bookings_5_day_lag ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('listing', 'user') bookings_at_start_of_month ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('listing', 'user') bookings_fill_nulls_with_0 ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('listing', 'user') bookings_fill_nulls_with_0_without_time_spine ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('listing', 'user') bookings_growth_2_weeks ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('listing', 'user') bookings_growth_2_weeks_fill_nulls_with_0 ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('listing', 'user') bookings_growth_2_weeks_fill_nulls_with_0_for_non_offset ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('listing', 'user') bookings_growth_since_start_of_month ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('listing', 'user') bookings_join_to_time_spine ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('listing', 'user') bookings_month_start_compared_to_1_month_prior ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('listing', 'user') bookings_offset_once ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('listing', 'user') bookings_offset_twice ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('listing', 'user') bookings_per_booker ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('listing', 'user') bookings_per_dollar ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('listing', 'user') bookings_per_listing ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('listing', 'user') bookings_per_lux_listing_derived ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('listing', 'user') bookings_per_view ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('listing', 'user') current_account_balance_by_user ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('listing', 'user') derived_bookings_0 ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('listing', 'user') derived_bookings_1 ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('listing', 'user') discrete_booking_value_p99 ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('listing', 'user') double_counted_delayed_bookings ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('listing', 'user') every_2_days_bookers_2_days_ago ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('listing', 'user') every_two_days_bookers ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('listing', 'user') every_two_days_bookers_fill_nulls_with_0 ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('listing', 'user') identity_verifications ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('listing', 'user') instant_booking_fraction_of_max_value ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('listing', 'user') instant_booking_value ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('listing', 'user') instant_booking_value_ratio ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('listing', 'user') instant_bookings ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('listing', 'user') instant_lux_booking_value_rate ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('listing', 'user') instant_plus_non_referred_bookings_pct ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('listing', 'user') largest_listing ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('listing', 'user') listings ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('listing', 'user') lux_booking_fraction_of_max_value ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('listing', 'user') lux_booking_value_rate_expr ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('listing', 'user') lux_listings ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('listing', 'user') max_booking_value ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('listing', 'user') median_booking_value ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('listing', 'user') min_booking_value ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('listing', 'user') nested_fill_nulls_without_time_spine ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('listing', 'user') non_referred_bookings_pct ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('listing', 'user') referred_bookings ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('listing', 'user') regional_starting_balance_ratios ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('listing', 'user') revenue ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('listing', 'user') revenue_all_time ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('listing', 'user') revenue_mtd ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('listing', 'user') smallest_listing ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('listing', 'user') total_account_balance_first_day ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('listing', 'user') trailing_2_months_revenue ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('listing', 'user') trailing_2_months_revenue_sub_10 ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('listing', 'user') twice_bookings_fill_nulls_with_0_without_time_spine ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('listing', 'user') views ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('listing', 'user') views_times_booking_value ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('listing', 'user') visit_buy_conversion_rate ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('listing', 'user') visit_buy_conversion_rate_7days ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('listing', 'user') visit_buy_conversion_rate_7days_fill_nulls_with_0 ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('listing', 'user') visit_buy_conversion_rate_by_session ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('listing', 'user') visit_buy_conversions ['JOINED', 'METRIC', 'MULTI_HOP'] diff --git a/tests/snapshots/test_linkable_spec_resolver.py/str/test_create_linkable_element_set_from_join_path_multi_hop__result0.txt b/tests/snapshots/test_linkable_spec_resolver.py/str/test_create_linkable_element_set_from_join_path_multi_hop__result0.txt index 13552fbf4b..d45d38ec9c 100644 --- a/tests/snapshots/test_linkable_spec_resolver.py/str/test_create_linkable_element_set_from_join_path_multi_hop__result0.txt +++ b/tests/snapshots/test_linkable_spec_resolver.py/str/test_create_linkable_element_set_from_join_path_multi_hop__result0.txt @@ -1,109 +1,123 @@ -Semantic Model Entity Links Name Time Granularity Date Part Properties ----------------- -------------- -------------------------------------------------------- ------------------ ----------- --------------------------------------------------- -listings_latest ('listing',) active_listings ['JOINED', 'METRIC', 'MULTI_HOP'] -listings_latest ('listing',) approximate_continuous_booking_value_p99 ['JOINED', 'METRIC', 'MULTI_HOP'] -listings_latest ('listing',) approximate_discrete_booking_value_p99 ['JOINED', 'METRIC', 'MULTI_HOP'] -listings_latest ('listing',) average_booking_value ['JOINED', 'METRIC', 'MULTI_HOP'] -listings_latest ('listing',) average_instant_booking_value ['JOINED', 'METRIC', 'MULTI_HOP'] -listings_latest ('listing',) bookers ['JOINED', 'METRIC', 'MULTI_HOP'] -listings_latest ('listing',) booking_fees ['JOINED', 'METRIC', 'MULTI_HOP'] -listings_latest ('listing',) booking_fees_last_week_per_booker_this_week ['JOINED', 'METRIC', 'MULTI_HOP'] -listings_latest ('listing',) booking_fees_per_booker ['JOINED', 'METRIC', 'MULTI_HOP'] -listings_latest ('listing',) booking_fees_since_start_of_month ['JOINED', 'METRIC', 'MULTI_HOP'] -listings_latest ('listing',) booking_payments ['JOINED', 'METRIC', 'MULTI_HOP'] -listings_latest ('listing',) booking_value ['JOINED', 'METRIC', 'MULTI_HOP'] -listings_latest ('listing',) booking_value_for_non_null_listing_id ['JOINED', 'METRIC', 'MULTI_HOP'] -listings_latest ('listing',) booking_value_p99 ['JOINED', 'METRIC', 'MULTI_HOP'] -listings_latest ('listing',) booking_value_per_view ['JOINED', 'METRIC', 'MULTI_HOP'] -listings_latest ('listing',) booking_value_sub_instant ['JOINED', 'METRIC', 'MULTI_HOP'] -listings_latest ('listing',) booking_value_sub_instant_add_10 ['JOINED', 'METRIC', 'MULTI_HOP'] -listings_latest ('listing',) bookings ['JOINED', 'METRIC', 'MULTI_HOP'] -listings_latest ('listing',) bookings_5_day_lag ['JOINED', 'METRIC', 'MULTI_HOP'] -listings_latest ('listing',) bookings_at_start_of_month ['JOINED', 'METRIC', 'MULTI_HOP'] -listings_latest ('listing',) bookings_fill_nulls_with_0 ['JOINED', 'METRIC', 'MULTI_HOP'] -listings_latest ('listing',) bookings_fill_nulls_with_0_without_time_spine ['JOINED', 'METRIC', 'MULTI_HOP'] -listings_latest ('listing',) bookings_growth_2_weeks ['JOINED', 'METRIC', 'MULTI_HOP'] -listings_latest ('listing',) bookings_growth_2_weeks_fill_nulls_with_0 ['JOINED', 'METRIC', 'MULTI_HOP'] -listings_latest ('listing',) bookings_growth_2_weeks_fill_nulls_with_0_for_non_offset ['JOINED', 'METRIC', 'MULTI_HOP'] -listings_latest ('listing',) bookings_growth_since_start_of_month ['JOINED', 'METRIC', 'MULTI_HOP'] -listings_latest ('listing',) bookings_join_to_time_spine ['JOINED', 'METRIC', 'MULTI_HOP'] -listings_latest ('listing',) bookings_month_start_compared_to_1_month_prior ['JOINED', 'METRIC', 'MULTI_HOP'] -listings_latest ('listing',) bookings_offset_once ['JOINED', 'METRIC', 'MULTI_HOP'] -listings_latest ('listing',) bookings_offset_twice ['JOINED', 'METRIC', 'MULTI_HOP'] -listings_latest ('listing',) bookings_per_booker ['JOINED', 'METRIC', 'MULTI_HOP'] -listings_latest ('listing',) bookings_per_dollar ['JOINED', 'METRIC', 'MULTI_HOP'] -listings_latest ('listing',) bookings_per_listing ['JOINED', 'METRIC', 'MULTI_HOP'] -listings_latest ('listing',) bookings_per_lux_listing_derived ['JOINED', 'METRIC', 'MULTI_HOP'] -listings_latest ('listing',) bookings_per_view ['JOINED', 'METRIC', 'MULTI_HOP'] -listings_latest ('listing',) capacity_latest ['JOINED', 'MULTI_HOP'] -listings_latest ('listing',) country_latest ['JOINED', 'MULTI_HOP'] -listings_latest ('listing',) created_at DAY ['JOINED', 'MULTI_HOP'] -listings_latest ('listing',) created_at DAY DAY ['JOINED', 'MULTI_HOP'] -listings_latest ('listing',) created_at DAY DOW ['JOINED', 'MULTI_HOP'] -listings_latest ('listing',) created_at DAY DOY ['JOINED', 'MULTI_HOP'] -listings_latest ('listing',) created_at DAY MONTH ['JOINED', 'MULTI_HOP'] -listings_latest ('listing',) created_at DAY QUARTER ['JOINED', 'MULTI_HOP'] -listings_latest ('listing',) created_at DAY YEAR ['JOINED', 'MULTI_HOP'] -listings_latest ('listing',) created_at MONTH ['DERIVED_TIME_GRANULARITY', 'JOINED', 'MULTI_HOP'] -listings_latest ('listing',) created_at MONTH MONTH ['DERIVED_TIME_GRANULARITY', 'JOINED', 'MULTI_HOP'] -listings_latest ('listing',) created_at MONTH QUARTER ['DERIVED_TIME_GRANULARITY', 'JOINED', 'MULTI_HOP'] -listings_latest ('listing',) created_at MONTH YEAR ['DERIVED_TIME_GRANULARITY', 'JOINED', 'MULTI_HOP'] -listings_latest ('listing',) created_at QUARTER ['DERIVED_TIME_GRANULARITY', 'JOINED', 'MULTI_HOP'] -listings_latest ('listing',) created_at QUARTER QUARTER ['DERIVED_TIME_GRANULARITY', 'JOINED', 'MULTI_HOP'] -listings_latest ('listing',) created_at QUARTER YEAR ['DERIVED_TIME_GRANULARITY', 'JOINED', 'MULTI_HOP'] -listings_latest ('listing',) created_at WEEK ['DERIVED_TIME_GRANULARITY', 'JOINED', 'MULTI_HOP'] -listings_latest ('listing',) created_at WEEK MONTH ['DERIVED_TIME_GRANULARITY', 'JOINED', 'MULTI_HOP'] -listings_latest ('listing',) created_at WEEK QUARTER ['DERIVED_TIME_GRANULARITY', 'JOINED', 'MULTI_HOP'] -listings_latest ('listing',) created_at WEEK YEAR ['DERIVED_TIME_GRANULARITY', 'JOINED', 'MULTI_HOP'] -listings_latest ('listing',) created_at YEAR ['DERIVED_TIME_GRANULARITY', 'JOINED', 'MULTI_HOP'] -listings_latest ('listing',) created_at YEAR YEAR ['DERIVED_TIME_GRANULARITY', 'JOINED', 'MULTI_HOP'] -listings_latest ('listing',) derived_bookings_0 ['JOINED', 'METRIC', 'MULTI_HOP'] -listings_latest ('listing',) derived_bookings_1 ['JOINED', 'METRIC', 'MULTI_HOP'] -listings_latest ('listing',) discrete_booking_value_p99 ['JOINED', 'METRIC', 'MULTI_HOP'] -listings_latest ('listing',) double_counted_delayed_bookings ['JOINED', 'METRIC', 'MULTI_HOP'] -listings_latest ('listing',) ds DAY ['JOINED', 'MULTI_HOP'] -listings_latest ('listing',) ds DAY DAY ['JOINED', 'MULTI_HOP'] -listings_latest ('listing',) ds DAY DOW ['JOINED', 'MULTI_HOP'] -listings_latest ('listing',) ds DAY DOY ['JOINED', 'MULTI_HOP'] -listings_latest ('listing',) ds DAY MONTH ['JOINED', 'MULTI_HOP'] -listings_latest ('listing',) ds DAY QUARTER ['JOINED', 'MULTI_HOP'] -listings_latest ('listing',) ds DAY YEAR ['JOINED', 'MULTI_HOP'] -listings_latest ('listing',) ds MONTH ['DERIVED_TIME_GRANULARITY', 'JOINED', 'MULTI_HOP'] -listings_latest ('listing',) ds MONTH MONTH ['DERIVED_TIME_GRANULARITY', 'JOINED', 'MULTI_HOP'] -listings_latest ('listing',) ds MONTH QUARTER ['DERIVED_TIME_GRANULARITY', 'JOINED', 'MULTI_HOP'] -listings_latest ('listing',) ds MONTH YEAR ['DERIVED_TIME_GRANULARITY', 'JOINED', 'MULTI_HOP'] -listings_latest ('listing',) ds QUARTER ['DERIVED_TIME_GRANULARITY', 'JOINED', 'MULTI_HOP'] -listings_latest ('listing',) ds QUARTER QUARTER ['DERIVED_TIME_GRANULARITY', 'JOINED', 'MULTI_HOP'] -listings_latest ('listing',) ds QUARTER YEAR ['DERIVED_TIME_GRANULARITY', 'JOINED', 'MULTI_HOP'] -listings_latest ('listing',) ds WEEK ['DERIVED_TIME_GRANULARITY', 'JOINED', 'MULTI_HOP'] -listings_latest ('listing',) ds WEEK MONTH ['DERIVED_TIME_GRANULARITY', 'JOINED', 'MULTI_HOP'] -listings_latest ('listing',) ds WEEK QUARTER ['DERIVED_TIME_GRANULARITY', 'JOINED', 'MULTI_HOP'] -listings_latest ('listing',) ds WEEK YEAR ['DERIVED_TIME_GRANULARITY', 'JOINED', 'MULTI_HOP'] -listings_latest ('listing',) ds YEAR ['DERIVED_TIME_GRANULARITY', 'JOINED', 'MULTI_HOP'] -listings_latest ('listing',) ds YEAR YEAR ['DERIVED_TIME_GRANULARITY', 'JOINED', 'MULTI_HOP'] -listings_latest ('listing',) every_2_days_bookers_2_days_ago ['JOINED', 'METRIC', 'MULTI_HOP'] -listings_latest ('listing',) every_two_days_bookers ['JOINED', 'METRIC', 'MULTI_HOP'] -listings_latest ('listing',) every_two_days_bookers_fill_nulls_with_0 ['JOINED', 'METRIC', 'MULTI_HOP'] -listings_latest ('listing',) instant_booking_fraction_of_max_value ['JOINED', 'METRIC', 'MULTI_HOP'] -listings_latest ('listing',) instant_booking_value ['JOINED', 'METRIC', 'MULTI_HOP'] -listings_latest ('listing',) instant_booking_value_ratio ['JOINED', 'METRIC', 'MULTI_HOP'] -listings_latest ('listing',) instant_bookings ['JOINED', 'METRIC', 'MULTI_HOP'] -listings_latest ('listing',) instant_lux_booking_value_rate ['JOINED', 'METRIC', 'MULTI_HOP'] -listings_latest ('listing',) instant_plus_non_referred_bookings_pct ['JOINED', 'METRIC', 'MULTI_HOP'] -listings_latest ('listing',) is_lux_latest ['JOINED', 'MULTI_HOP'] -listings_latest ('listing',) largest_listing ['JOINED', 'METRIC', 'MULTI_HOP'] -listings_latest ('listing',) listings ['JOINED', 'METRIC', 'MULTI_HOP'] -listings_latest ('listing',) lux_booking_fraction_of_max_value ['JOINED', 'METRIC', 'MULTI_HOP'] -listings_latest ('listing',) lux_booking_value_rate_expr ['JOINED', 'METRIC', 'MULTI_HOP'] -listings_latest ('listing',) lux_listings ['JOINED', 'METRIC', 'MULTI_HOP'] -listings_latest ('listing',) max_booking_value ['JOINED', 'METRIC', 'MULTI_HOP'] -listings_latest ('listing',) median_booking_value ['JOINED', 'METRIC', 'MULTI_HOP'] -listings_latest ('listing',) min_booking_value ['JOINED', 'METRIC', 'MULTI_HOP'] -listings_latest ('listing',) nested_fill_nulls_without_time_spine ['JOINED', 'METRIC', 'MULTI_HOP'] -listings_latest ('listing',) non_referred_bookings_pct ['JOINED', 'METRIC', 'MULTI_HOP'] -listings_latest ('listing',) referred_bookings ['JOINED', 'METRIC', 'MULTI_HOP'] -listings_latest ('listing',) smallest_listing ['JOINED', 'METRIC', 'MULTI_HOP'] -listings_latest ('listing',) twice_bookings_fill_nulls_with_0_without_time_spine ['JOINED', 'METRIC', 'MULTI_HOP'] -listings_latest ('listing',) user ['ENTITY', 'JOINED', 'MULTI_HOP'] -listings_latest ('listing',) views ['JOINED', 'METRIC', 'MULTI_HOP'] -listings_latest ('listing',) views_times_booking_value ['JOINED', 'METRIC', 'MULTI_HOP'] +Semantic Model Entity Links Name Time Granularity Date Part Properties +---------------- ---------------------------- -------------------------------------------------------- ------------------ ----------- --------------------------------------------------- +listings_latest ('guest', 'listing') capacity_latest ['JOINED', 'MULTI_HOP'] +listings_latest ('guest', 'listing') country_latest ['JOINED', 'MULTI_HOP'] +listings_latest ('guest', 'listing') created_at DAY ['JOINED', 'MULTI_HOP'] +listings_latest ('guest', 'listing') created_at DAY DAY ['JOINED', 'MULTI_HOP'] +listings_latest ('guest', 'listing') created_at DAY DOW ['JOINED', 'MULTI_HOP'] +listings_latest ('guest', 'listing') created_at DAY DOY ['JOINED', 'MULTI_HOP'] +listings_latest ('guest', 'listing') created_at DAY MONTH ['JOINED', 'MULTI_HOP'] +listings_latest ('guest', 'listing') created_at DAY QUARTER ['JOINED', 'MULTI_HOP'] +listings_latest ('guest', 'listing') created_at DAY YEAR ['JOINED', 'MULTI_HOP'] +listings_latest ('guest', 'listing') created_at MONTH ['DERIVED_TIME_GRANULARITY', 'JOINED', 'MULTI_HOP'] +listings_latest ('guest', 'listing') created_at MONTH MONTH ['DERIVED_TIME_GRANULARITY', 'JOINED', 'MULTI_HOP'] +listings_latest ('guest', 'listing') created_at MONTH QUARTER ['DERIVED_TIME_GRANULARITY', 'JOINED', 'MULTI_HOP'] +listings_latest ('guest', 'listing') created_at MONTH YEAR ['DERIVED_TIME_GRANULARITY', 'JOINED', 'MULTI_HOP'] +listings_latest ('guest', 'listing') created_at QUARTER ['DERIVED_TIME_GRANULARITY', 'JOINED', 'MULTI_HOP'] +listings_latest ('guest', 'listing') created_at QUARTER QUARTER ['DERIVED_TIME_GRANULARITY', 'JOINED', 'MULTI_HOP'] +listings_latest ('guest', 'listing') created_at QUARTER YEAR ['DERIVED_TIME_GRANULARITY', 'JOINED', 'MULTI_HOP'] +listings_latest ('guest', 'listing') created_at WEEK ['DERIVED_TIME_GRANULARITY', 'JOINED', 'MULTI_HOP'] +listings_latest ('guest', 'listing') created_at WEEK MONTH ['DERIVED_TIME_GRANULARITY', 'JOINED', 'MULTI_HOP'] +listings_latest ('guest', 'listing') created_at WEEK QUARTER ['DERIVED_TIME_GRANULARITY', 'JOINED', 'MULTI_HOP'] +listings_latest ('guest', 'listing') created_at WEEK YEAR ['DERIVED_TIME_GRANULARITY', 'JOINED', 'MULTI_HOP'] +listings_latest ('guest', 'listing') created_at YEAR ['DERIVED_TIME_GRANULARITY', 'JOINED', 'MULTI_HOP'] +listings_latest ('guest', 'listing') created_at YEAR YEAR ['DERIVED_TIME_GRANULARITY', 'JOINED', 'MULTI_HOP'] +listings_latest ('guest', 'listing') ds DAY ['JOINED', 'MULTI_HOP'] +listings_latest ('guest', 'listing') ds DAY DAY ['JOINED', 'MULTI_HOP'] +listings_latest ('guest', 'listing') ds DAY DOW ['JOINED', 'MULTI_HOP'] +listings_latest ('guest', 'listing') ds DAY DOY ['JOINED', 'MULTI_HOP'] +listings_latest ('guest', 'listing') ds DAY MONTH ['JOINED', 'MULTI_HOP'] +listings_latest ('guest', 'listing') ds DAY QUARTER ['JOINED', 'MULTI_HOP'] +listings_latest ('guest', 'listing') ds DAY YEAR ['JOINED', 'MULTI_HOP'] +listings_latest ('guest', 'listing') ds MONTH ['DERIVED_TIME_GRANULARITY', 'JOINED', 'MULTI_HOP'] +listings_latest ('guest', 'listing') ds MONTH MONTH ['DERIVED_TIME_GRANULARITY', 'JOINED', 'MULTI_HOP'] +listings_latest ('guest', 'listing') ds MONTH QUARTER ['DERIVED_TIME_GRANULARITY', 'JOINED', 'MULTI_HOP'] +listings_latest ('guest', 'listing') ds MONTH YEAR ['DERIVED_TIME_GRANULARITY', 'JOINED', 'MULTI_HOP'] +listings_latest ('guest', 'listing') ds QUARTER ['DERIVED_TIME_GRANULARITY', 'JOINED', 'MULTI_HOP'] +listings_latest ('guest', 'listing') ds QUARTER QUARTER ['DERIVED_TIME_GRANULARITY', 'JOINED', 'MULTI_HOP'] +listings_latest ('guest', 'listing') ds QUARTER YEAR ['DERIVED_TIME_GRANULARITY', 'JOINED', 'MULTI_HOP'] +listings_latest ('guest', 'listing') ds WEEK ['DERIVED_TIME_GRANULARITY', 'JOINED', 'MULTI_HOP'] +listings_latest ('guest', 'listing') ds WEEK MONTH ['DERIVED_TIME_GRANULARITY', 'JOINED', 'MULTI_HOP'] +listings_latest ('guest', 'listing') ds WEEK QUARTER ['DERIVED_TIME_GRANULARITY', 'JOINED', 'MULTI_HOP'] +listings_latest ('guest', 'listing') ds WEEK YEAR ['DERIVED_TIME_GRANULARITY', 'JOINED', 'MULTI_HOP'] +listings_latest ('guest', 'listing') ds YEAR ['DERIVED_TIME_GRANULARITY', 'JOINED', 'MULTI_HOP'] +listings_latest ('guest', 'listing') ds YEAR YEAR ['DERIVED_TIME_GRANULARITY', 'JOINED', 'MULTI_HOP'] +listings_latest ('guest', 'listing') is_lux_latest ['JOINED', 'MULTI_HOP'] +listings_latest ('guest', 'listing') user ['ENTITY', 'JOINED', 'MULTI_HOP'] +listings_latest ('guest', 'listing', 'user') active_listings ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('guest', 'listing', 'user') approximate_continuous_booking_value_p99 ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('guest', 'listing', 'user') approximate_discrete_booking_value_p99 ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('guest', 'listing', 'user') average_booking_value ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('guest', 'listing', 'user') average_instant_booking_value ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('guest', 'listing', 'user') bookers ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('guest', 'listing', 'user') booking_fees ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('guest', 'listing', 'user') booking_fees_last_week_per_booker_this_week ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('guest', 'listing', 'user') booking_fees_per_booker ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('guest', 'listing', 'user') booking_fees_since_start_of_month ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('guest', 'listing', 'user') booking_payments ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('guest', 'listing', 'user') booking_value ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('guest', 'listing', 'user') booking_value_for_non_null_listing_id ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('guest', 'listing', 'user') booking_value_p99 ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('guest', 'listing', 'user') booking_value_per_view ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('guest', 'listing', 'user') booking_value_sub_instant ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('guest', 'listing', 'user') booking_value_sub_instant_add_10 ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('guest', 'listing', 'user') bookings ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('guest', 'listing', 'user') bookings_5_day_lag ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('guest', 'listing', 'user') bookings_at_start_of_month ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('guest', 'listing', 'user') bookings_fill_nulls_with_0 ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('guest', 'listing', 'user') bookings_fill_nulls_with_0_without_time_spine ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('guest', 'listing', 'user') bookings_growth_2_weeks ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('guest', 'listing', 'user') bookings_growth_2_weeks_fill_nulls_with_0 ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('guest', 'listing', 'user') bookings_growth_2_weeks_fill_nulls_with_0_for_non_offset ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('guest', 'listing', 'user') bookings_growth_since_start_of_month ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('guest', 'listing', 'user') bookings_join_to_time_spine ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('guest', 'listing', 'user') bookings_month_start_compared_to_1_month_prior ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('guest', 'listing', 'user') bookings_offset_once ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('guest', 'listing', 'user') bookings_offset_twice ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('guest', 'listing', 'user') bookings_per_booker ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('guest', 'listing', 'user') bookings_per_dollar ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('guest', 'listing', 'user') bookings_per_listing ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('guest', 'listing', 'user') bookings_per_lux_listing_derived ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('guest', 'listing', 'user') bookings_per_view ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('guest', 'listing', 'user') current_account_balance_by_user ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('guest', 'listing', 'user') derived_bookings_0 ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('guest', 'listing', 'user') derived_bookings_1 ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('guest', 'listing', 'user') discrete_booking_value_p99 ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('guest', 'listing', 'user') double_counted_delayed_bookings ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('guest', 'listing', 'user') every_2_days_bookers_2_days_ago ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('guest', 'listing', 'user') every_two_days_bookers ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('guest', 'listing', 'user') every_two_days_bookers_fill_nulls_with_0 ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('guest', 'listing', 'user') identity_verifications ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('guest', 'listing', 'user') instant_booking_fraction_of_max_value ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('guest', 'listing', 'user') instant_booking_value ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('guest', 'listing', 'user') instant_booking_value_ratio ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('guest', 'listing', 'user') instant_bookings ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('guest', 'listing', 'user') instant_lux_booking_value_rate ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('guest', 'listing', 'user') instant_plus_non_referred_bookings_pct ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('guest', 'listing', 'user') largest_listing ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('guest', 'listing', 'user') listings ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('guest', 'listing', 'user') lux_booking_fraction_of_max_value ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('guest', 'listing', 'user') lux_booking_value_rate_expr ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('guest', 'listing', 'user') lux_listings ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('guest', 'listing', 'user') max_booking_value ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('guest', 'listing', 'user') median_booking_value ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('guest', 'listing', 'user') min_booking_value ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('guest', 'listing', 'user') nested_fill_nulls_without_time_spine ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('guest', 'listing', 'user') non_referred_bookings_pct ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('guest', 'listing', 'user') referred_bookings ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('guest', 'listing', 'user') regional_starting_balance_ratios ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('guest', 'listing', 'user') revenue ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('guest', 'listing', 'user') revenue_all_time ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('guest', 'listing', 'user') revenue_mtd ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('guest', 'listing', 'user') smallest_listing ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('guest', 'listing', 'user') total_account_balance_first_day ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('guest', 'listing', 'user') trailing_2_months_revenue ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('guest', 'listing', 'user') trailing_2_months_revenue_sub_10 ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('guest', 'listing', 'user') twice_bookings_fill_nulls_with_0_without_time_spine ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('guest', 'listing', 'user') views ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('guest', 'listing', 'user') views_times_booking_value ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('guest', 'listing', 'user') visit_buy_conversion_rate ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('guest', 'listing', 'user') visit_buy_conversion_rate_7days ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('guest', 'listing', 'user') visit_buy_conversion_rate_7days_fill_nulls_with_0 ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('guest', 'listing', 'user') visit_buy_conversion_rate_by_session ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('guest', 'listing', 'user') visit_buy_conversions ['JOINED', 'METRIC', 'MULTI_HOP'] diff --git a/tests/snapshots/test_semantic_model_container.py/str/test_linkable_elements_for_measure__result0.txt b/tests/snapshots/test_semantic_model_container.py/str/test_linkable_elements_for_measure__result0.txt index 621ec2889e..9c91598cd6 100644 --- a/tests/snapshots/test_semantic_model_container.py/str/test_linkable_elements_for_measure__result0.txt +++ b/tests/snapshots/test_semantic_model_container.py/str/test_linkable_elements_for_measure__result0.txt @@ -1,417 +1,431 @@ -Semantic Model Entity Links Name Time Granularity Date Part Properties -------------------- -------------- -------------------------------------------------------- ------------------ ----------- ------------------------------------------- -companies ('user',) active_listings ['JOINED', 'METRIC'] -companies ('user',) approximate_continuous_booking_value_p99 ['JOINED', 'METRIC'] -companies ('user',) approximate_discrete_booking_value_p99 ['JOINED', 'METRIC'] -companies ('user',) average_booking_value ['JOINED', 'METRIC'] -companies ('user',) average_instant_booking_value ['JOINED', 'METRIC'] -companies ('user',) bookers ['JOINED', 'METRIC'] -companies ('user',) booking_fees ['JOINED', 'METRIC'] -companies ('user',) booking_fees_last_week_per_booker_this_week ['JOINED', 'METRIC'] -companies ('user',) booking_fees_per_booker ['JOINED', 'METRIC'] -companies ('user',) booking_fees_since_start_of_month ['JOINED', 'METRIC'] -companies ('user',) booking_payments ['JOINED', 'METRIC'] -companies ('user',) booking_value ['JOINED', 'METRIC'] -companies ('user',) booking_value_for_non_null_listing_id ['JOINED', 'METRIC'] -companies ('user',) booking_value_p99 ['JOINED', 'METRIC'] -companies ('user',) booking_value_per_view ['JOINED', 'METRIC'] -companies ('user',) booking_value_sub_instant ['JOINED', 'METRIC'] -companies ('user',) booking_value_sub_instant_add_10 ['JOINED', 'METRIC'] -companies ('user',) bookings ['JOINED', 'METRIC'] -companies ('user',) bookings_5_day_lag ['JOINED', 'METRIC'] -companies ('user',) bookings_at_start_of_month ['JOINED', 'METRIC'] -companies ('user',) bookings_fill_nulls_with_0 ['JOINED', 'METRIC'] -companies ('user',) bookings_fill_nulls_with_0_without_time_spine ['JOINED', 'METRIC'] -companies ('user',) bookings_growth_2_weeks ['JOINED', 'METRIC'] -companies ('user',) bookings_growth_2_weeks_fill_nulls_with_0 ['JOINED', 'METRIC'] -companies ('user',) bookings_growth_2_weeks_fill_nulls_with_0_for_non_offset ['JOINED', 'METRIC'] -companies ('user',) bookings_growth_since_start_of_month ['JOINED', 'METRIC'] -companies ('user',) bookings_join_to_time_spine ['JOINED', 'METRIC'] -companies ('user',) bookings_month_start_compared_to_1_month_prior ['JOINED', 'METRIC'] -companies ('user',) bookings_offset_once ['JOINED', 'METRIC'] -companies ('user',) bookings_offset_twice ['JOINED', 'METRIC'] -companies ('user',) bookings_per_booker ['JOINED', 'METRIC'] -companies ('user',) bookings_per_dollar ['JOINED', 'METRIC'] -companies ('user',) bookings_per_view ['JOINED', 'METRIC'] -companies ('user',) company ['ENTITY', 'JOINED'] -companies ('user',) company_name ['JOINED'] -companies ('user',) current_account_balance_by_user ['JOINED', 'METRIC'] -companies ('user',) derived_bookings_0 ['JOINED', 'METRIC'] -companies ('user',) derived_bookings_1 ['JOINED', 'METRIC'] -companies ('user',) discrete_booking_value_p99 ['JOINED', 'METRIC'] -companies ('user',) double_counted_delayed_bookings ['JOINED', 'METRIC'] -companies ('user',) every_2_days_bookers_2_days_ago ['JOINED', 'METRIC'] -companies ('user',) every_two_days_bookers ['JOINED', 'METRIC'] -companies ('user',) every_two_days_bookers_fill_nulls_with_0 ['JOINED', 'METRIC'] -companies ('user',) identity_verifications ['JOINED', 'METRIC'] -companies ('user',) instant_booking_fraction_of_max_value ['JOINED', 'METRIC'] -companies ('user',) instant_booking_value ['JOINED', 'METRIC'] -companies ('user',) instant_booking_value_ratio ['JOINED', 'METRIC'] -companies ('user',) instant_bookings ['JOINED', 'METRIC'] -companies ('user',) instant_lux_booking_value_rate ['JOINED', 'METRIC'] -companies ('user',) instant_plus_non_referred_bookings_pct ['JOINED', 'METRIC'] -companies ('user',) largest_listing ['JOINED', 'METRIC'] -companies ('user',) listings ['JOINED', 'METRIC'] -companies ('user',) lux_booking_fraction_of_max_value ['JOINED', 'METRIC'] -companies ('user',) lux_booking_value_rate_expr ['JOINED', 'METRIC'] -companies ('user',) lux_listings ['JOINED', 'METRIC'] -companies ('user',) max_booking_value ['JOINED', 'METRIC'] -companies ('user',) median_booking_value ['JOINED', 'METRIC'] -companies ('user',) min_booking_value ['JOINED', 'METRIC'] -companies ('user',) nested_fill_nulls_without_time_spine ['JOINED', 'METRIC'] -companies ('user',) non_referred_bookings_pct ['JOINED', 'METRIC'] -companies ('user',) referred_bookings ['JOINED', 'METRIC'] -companies ('user',) regional_starting_balance_ratios ['JOINED', 'METRIC'] -companies ('user',) revenue ['JOINED', 'METRIC'] -companies ('user',) revenue_all_time ['JOINED', 'METRIC'] -companies ('user',) revenue_mtd ['JOINED', 'METRIC'] -companies ('user',) smallest_listing ['JOINED', 'METRIC'] -companies ('user',) total_account_balance_first_day ['JOINED', 'METRIC'] -companies ('user',) trailing_2_months_revenue ['JOINED', 'METRIC'] -companies ('user',) trailing_2_months_revenue_sub_10 ['JOINED', 'METRIC'] -companies ('user',) twice_bookings_fill_nulls_with_0_without_time_spine ['JOINED', 'METRIC'] -companies ('user',) views ['JOINED', 'METRIC'] -companies ('user',) views_times_booking_value ['JOINED', 'METRIC'] -companies ('user',) visit_buy_conversion_rate ['JOINED', 'METRIC'] -companies ('user',) visit_buy_conversion_rate_7days ['JOINED', 'METRIC'] -companies ('user',) visit_buy_conversion_rate_7days_fill_nulls_with_0 ['JOINED', 'METRIC'] -companies ('user',) visit_buy_conversion_rate_by_session ['JOINED', 'METRIC'] -companies ('user',) visit_buy_conversions ['JOINED', 'METRIC'] -listings_latest () listing ['ENTITY', 'LOCAL'] -listings_latest () metric_time DAY ['METRIC_TIME'] -listings_latest () metric_time DAY DAY ['DERIVED_TIME_GRANULARITY', 'METRIC_TIME'] -listings_latest () metric_time DAY DOW ['DERIVED_TIME_GRANULARITY', 'METRIC_TIME'] -listings_latest () metric_time DAY DOY ['DERIVED_TIME_GRANULARITY', 'METRIC_TIME'] -listings_latest () metric_time DAY MONTH ['DERIVED_TIME_GRANULARITY', 'METRIC_TIME'] -listings_latest () metric_time DAY QUARTER ['DERIVED_TIME_GRANULARITY', 'METRIC_TIME'] -listings_latest () metric_time DAY YEAR ['DERIVED_TIME_GRANULARITY', 'METRIC_TIME'] -listings_latest () metric_time MONTH ['DERIVED_TIME_GRANULARITY', 'METRIC_TIME'] -listings_latest () metric_time MONTH MONTH ['DERIVED_TIME_GRANULARITY', 'METRIC_TIME'] -listings_latest () metric_time MONTH QUARTER ['DERIVED_TIME_GRANULARITY', 'METRIC_TIME'] -listings_latest () metric_time MONTH YEAR ['DERIVED_TIME_GRANULARITY', 'METRIC_TIME'] -listings_latest () metric_time QUARTER ['DERIVED_TIME_GRANULARITY', 'METRIC_TIME'] -listings_latest () metric_time QUARTER QUARTER ['DERIVED_TIME_GRANULARITY', 'METRIC_TIME'] -listings_latest () metric_time QUARTER YEAR ['DERIVED_TIME_GRANULARITY', 'METRIC_TIME'] -listings_latest () metric_time WEEK ['DERIVED_TIME_GRANULARITY', 'METRIC_TIME'] -listings_latest () metric_time WEEK MONTH ['DERIVED_TIME_GRANULARITY', 'METRIC_TIME'] -listings_latest () metric_time WEEK QUARTER ['DERIVED_TIME_GRANULARITY', 'METRIC_TIME'] -listings_latest () metric_time WEEK YEAR ['DERIVED_TIME_GRANULARITY', 'METRIC_TIME'] -listings_latest () metric_time YEAR ['DERIVED_TIME_GRANULARITY', 'METRIC_TIME'] -listings_latest () metric_time YEAR YEAR ['DERIVED_TIME_GRANULARITY', 'METRIC_TIME'] -listings_latest () user ['ENTITY', 'LOCAL'] -listings_latest ('listing',) capacity_latest ['LOCAL'] -listings_latest ('listing',) country_latest ['LOCAL'] -listings_latest ('listing',) created_at DAY ['LOCAL'] -listings_latest ('listing',) created_at DAY DAY ['LOCAL'] -listings_latest ('listing',) created_at DAY DOW ['LOCAL'] -listings_latest ('listing',) created_at DAY DOY ['LOCAL'] -listings_latest ('listing',) created_at DAY MONTH ['LOCAL'] -listings_latest ('listing',) created_at DAY QUARTER ['LOCAL'] -listings_latest ('listing',) created_at DAY YEAR ['LOCAL'] -listings_latest ('listing',) created_at MONTH ['DERIVED_TIME_GRANULARITY', 'LOCAL'] -listings_latest ('listing',) created_at MONTH MONTH ['DERIVED_TIME_GRANULARITY', 'LOCAL'] -listings_latest ('listing',) created_at MONTH QUARTER ['DERIVED_TIME_GRANULARITY', 'LOCAL'] -listings_latest ('listing',) created_at MONTH YEAR ['DERIVED_TIME_GRANULARITY', 'LOCAL'] -listings_latest ('listing',) created_at QUARTER ['DERIVED_TIME_GRANULARITY', 'LOCAL'] -listings_latest ('listing',) created_at QUARTER QUARTER ['DERIVED_TIME_GRANULARITY', 'LOCAL'] -listings_latest ('listing',) created_at QUARTER YEAR ['DERIVED_TIME_GRANULARITY', 'LOCAL'] -listings_latest ('listing',) created_at WEEK ['DERIVED_TIME_GRANULARITY', 'LOCAL'] -listings_latest ('listing',) created_at WEEK MONTH ['DERIVED_TIME_GRANULARITY', 'LOCAL'] -listings_latest ('listing',) created_at WEEK QUARTER ['DERIVED_TIME_GRANULARITY', 'LOCAL'] -listings_latest ('listing',) created_at WEEK YEAR ['DERIVED_TIME_GRANULARITY', 'LOCAL'] -listings_latest ('listing',) created_at YEAR ['DERIVED_TIME_GRANULARITY', 'LOCAL'] -listings_latest ('listing',) created_at YEAR YEAR ['DERIVED_TIME_GRANULARITY', 'LOCAL'] -listings_latest ('listing',) ds DAY ['LOCAL'] -listings_latest ('listing',) ds DAY DAY ['LOCAL'] -listings_latest ('listing',) ds DAY DOW ['LOCAL'] -listings_latest ('listing',) ds DAY DOY ['LOCAL'] -listings_latest ('listing',) ds DAY MONTH ['LOCAL'] -listings_latest ('listing',) ds DAY QUARTER ['LOCAL'] -listings_latest ('listing',) ds DAY YEAR ['LOCAL'] -listings_latest ('listing',) ds MONTH ['DERIVED_TIME_GRANULARITY', 'LOCAL'] -listings_latest ('listing',) ds MONTH MONTH ['DERIVED_TIME_GRANULARITY', 'LOCAL'] -listings_latest ('listing',) ds MONTH QUARTER ['DERIVED_TIME_GRANULARITY', 'LOCAL'] -listings_latest ('listing',) ds MONTH YEAR ['DERIVED_TIME_GRANULARITY', 'LOCAL'] -listings_latest ('listing',) ds QUARTER ['DERIVED_TIME_GRANULARITY', 'LOCAL'] -listings_latest ('listing',) ds QUARTER QUARTER ['DERIVED_TIME_GRANULARITY', 'LOCAL'] -listings_latest ('listing',) ds QUARTER YEAR ['DERIVED_TIME_GRANULARITY', 'LOCAL'] -listings_latest ('listing',) ds WEEK ['DERIVED_TIME_GRANULARITY', 'LOCAL'] -listings_latest ('listing',) ds WEEK MONTH ['DERIVED_TIME_GRANULARITY', 'LOCAL'] -listings_latest ('listing',) ds WEEK QUARTER ['DERIVED_TIME_GRANULARITY', 'LOCAL'] -listings_latest ('listing',) ds WEEK YEAR ['DERIVED_TIME_GRANULARITY', 'LOCAL'] -listings_latest ('listing',) ds YEAR ['DERIVED_TIME_GRANULARITY', 'LOCAL'] -listings_latest ('listing',) ds YEAR YEAR ['DERIVED_TIME_GRANULARITY', 'LOCAL'] -listings_latest ('listing',) is_lux_latest ['LOCAL'] -listings_latest ('listing',) user ['ENTITY', 'LOCAL'] -listings_latest ('user',) active_listings ['METRIC'] -listings_latest ('user',) active_listings ['METRIC'] -listings_latest ('user',) approximate_continuous_booking_value_p99 ['METRIC'] -listings_latest ('user',) approximate_continuous_booking_value_p99 ['METRIC'] -listings_latest ('user',) approximate_discrete_booking_value_p99 ['METRIC'] -listings_latest ('user',) approximate_discrete_booking_value_p99 ['METRIC'] -listings_latest ('user',) average_booking_value ['METRIC'] -listings_latest ('user',) average_booking_value ['METRIC'] -listings_latest ('user',) average_instant_booking_value ['METRIC'] -listings_latest ('user',) average_instant_booking_value ['METRIC'] -listings_latest ('user',) bookers ['METRIC'] -listings_latest ('user',) bookers ['METRIC'] -listings_latest ('user',) booking_fees ['METRIC'] -listings_latest ('user',) booking_fees ['METRIC'] -listings_latest ('user',) booking_fees_last_week_per_booker_this_week ['METRIC'] -listings_latest ('user',) booking_fees_last_week_per_booker_this_week ['METRIC'] -listings_latest ('user',) booking_fees_per_booker ['METRIC'] -listings_latest ('user',) booking_fees_per_booker ['METRIC'] -listings_latest ('user',) booking_fees_since_start_of_month ['METRIC'] -listings_latest ('user',) booking_fees_since_start_of_month ['METRIC'] -listings_latest ('user',) booking_payments ['METRIC'] -listings_latest ('user',) booking_payments ['METRIC'] -listings_latest ('user',) booking_value ['METRIC'] -listings_latest ('user',) booking_value ['METRIC'] -listings_latest ('user',) booking_value_for_non_null_listing_id ['METRIC'] -listings_latest ('user',) booking_value_for_non_null_listing_id ['METRIC'] -listings_latest ('user',) booking_value_p99 ['METRIC'] -listings_latest ('user',) booking_value_p99 ['METRIC'] -listings_latest ('user',) booking_value_per_view ['METRIC'] -listings_latest ('user',) booking_value_per_view ['METRIC'] -listings_latest ('user',) booking_value_sub_instant ['METRIC'] -listings_latest ('user',) booking_value_sub_instant ['METRIC'] -listings_latest ('user',) booking_value_sub_instant_add_10 ['METRIC'] -listings_latest ('user',) booking_value_sub_instant_add_10 ['METRIC'] -listings_latest ('user',) bookings ['METRIC'] -listings_latest ('user',) bookings ['METRIC'] -listings_latest ('user',) bookings_5_day_lag ['METRIC'] -listings_latest ('user',) bookings_5_day_lag ['METRIC'] -listings_latest ('user',) bookings_at_start_of_month ['METRIC'] -listings_latest ('user',) bookings_at_start_of_month ['METRIC'] -listings_latest ('user',) bookings_fill_nulls_with_0 ['METRIC'] -listings_latest ('user',) bookings_fill_nulls_with_0 ['METRIC'] -listings_latest ('user',) bookings_fill_nulls_with_0_without_time_spine ['METRIC'] -listings_latest ('user',) bookings_fill_nulls_with_0_without_time_spine ['METRIC'] -listings_latest ('user',) bookings_growth_2_weeks ['METRIC'] -listings_latest ('user',) bookings_growth_2_weeks ['METRIC'] -listings_latest ('user',) bookings_growth_2_weeks_fill_nulls_with_0 ['METRIC'] -listings_latest ('user',) bookings_growth_2_weeks_fill_nulls_with_0 ['METRIC'] -listings_latest ('user',) bookings_growth_2_weeks_fill_nulls_with_0_for_non_offset ['METRIC'] -listings_latest ('user',) bookings_growth_2_weeks_fill_nulls_with_0_for_non_offset ['METRIC'] -listings_latest ('user',) bookings_growth_since_start_of_month ['METRIC'] -listings_latest ('user',) bookings_growth_since_start_of_month ['METRIC'] -listings_latest ('user',) bookings_join_to_time_spine ['METRIC'] -listings_latest ('user',) bookings_join_to_time_spine ['METRIC'] -listings_latest ('user',) bookings_month_start_compared_to_1_month_prior ['METRIC'] -listings_latest ('user',) bookings_month_start_compared_to_1_month_prior ['METRIC'] -listings_latest ('user',) bookings_offset_once ['METRIC'] -listings_latest ('user',) bookings_offset_once ['METRIC'] -listings_latest ('user',) bookings_offset_twice ['METRIC'] -listings_latest ('user',) bookings_offset_twice ['METRIC'] -listings_latest ('user',) bookings_per_booker ['METRIC'] -listings_latest ('user',) bookings_per_booker ['METRIC'] -listings_latest ('user',) bookings_per_dollar ['METRIC'] -listings_latest ('user',) bookings_per_dollar ['METRIC'] -listings_latest ('user',) bookings_per_listing ['METRIC'] -listings_latest ('user',) bookings_per_listing ['METRIC'] -listings_latest ('user',) bookings_per_lux_listing_derived ['METRIC'] -listings_latest ('user',) bookings_per_lux_listing_derived ['METRIC'] -listings_latest ('user',) bookings_per_view ['METRIC'] -listings_latest ('user',) bookings_per_view ['METRIC'] -listings_latest ('user',) derived_bookings_0 ['METRIC'] -listings_latest ('user',) derived_bookings_0 ['METRIC'] -listings_latest ('user',) derived_bookings_1 ['METRIC'] -listings_latest ('user',) derived_bookings_1 ['METRIC'] -listings_latest ('user',) discrete_booking_value_p99 ['METRIC'] -listings_latest ('user',) discrete_booking_value_p99 ['METRIC'] -listings_latest ('user',) double_counted_delayed_bookings ['METRIC'] -listings_latest ('user',) double_counted_delayed_bookings ['METRIC'] -listings_latest ('user',) every_2_days_bookers_2_days_ago ['METRIC'] -listings_latest ('user',) every_2_days_bookers_2_days_ago ['METRIC'] -listings_latest ('user',) every_two_days_bookers ['METRIC'] -listings_latest ('user',) every_two_days_bookers ['METRIC'] -listings_latest ('user',) every_two_days_bookers_fill_nulls_with_0 ['METRIC'] -listings_latest ('user',) every_two_days_bookers_fill_nulls_with_0 ['METRIC'] -listings_latest ('user',) instant_booking_fraction_of_max_value ['METRIC'] -listings_latest ('user',) instant_booking_fraction_of_max_value ['METRIC'] -listings_latest ('user',) instant_booking_value ['METRIC'] -listings_latest ('user',) instant_booking_value ['METRIC'] -listings_latest ('user',) instant_booking_value_ratio ['METRIC'] -listings_latest ('user',) instant_booking_value_ratio ['METRIC'] -listings_latest ('user',) instant_bookings ['METRIC'] -listings_latest ('user',) instant_bookings ['METRIC'] -listings_latest ('user',) instant_lux_booking_value_rate ['METRIC'] -listings_latest ('user',) instant_lux_booking_value_rate ['METRIC'] -listings_latest ('user',) instant_plus_non_referred_bookings_pct ['METRIC'] -listings_latest ('user',) instant_plus_non_referred_bookings_pct ['METRIC'] -listings_latest ('user',) largest_listing ['METRIC'] -listings_latest ('user',) largest_listing ['METRIC'] -listings_latest ('user',) listings ['METRIC'] -listings_latest ('user',) listings ['METRIC'] -listings_latest ('user',) lux_booking_fraction_of_max_value ['METRIC'] -listings_latest ('user',) lux_booking_fraction_of_max_value ['METRIC'] -listings_latest ('user',) lux_booking_value_rate_expr ['METRIC'] -listings_latest ('user',) lux_booking_value_rate_expr ['METRIC'] -listings_latest ('user',) lux_listings ['METRIC'] -listings_latest ('user',) lux_listings ['METRIC'] -listings_latest ('user',) max_booking_value ['METRIC'] -listings_latest ('user',) max_booking_value ['METRIC'] -listings_latest ('user',) median_booking_value ['METRIC'] -listings_latest ('user',) median_booking_value ['METRIC'] -listings_latest ('user',) min_booking_value ['METRIC'] -listings_latest ('user',) min_booking_value ['METRIC'] -listings_latest ('user',) nested_fill_nulls_without_time_spine ['METRIC'] -listings_latest ('user',) nested_fill_nulls_without_time_spine ['METRIC'] -listings_latest ('user',) non_referred_bookings_pct ['METRIC'] -listings_latest ('user',) non_referred_bookings_pct ['METRIC'] -listings_latest ('user',) referred_bookings ['METRIC'] -listings_latest ('user',) referred_bookings ['METRIC'] -listings_latest ('user',) smallest_listing ['METRIC'] -listings_latest ('user',) smallest_listing ['METRIC'] -listings_latest ('user',) twice_bookings_fill_nulls_with_0_without_time_spine ['METRIC'] -listings_latest ('user',) twice_bookings_fill_nulls_with_0_without_time_spine ['METRIC'] -listings_latest ('user',) views ['METRIC'] -listings_latest ('user',) views ['METRIC'] -listings_latest ('user',) views_times_booking_value ['METRIC'] -listings_latest ('user',) views_times_booking_value ['METRIC'] -lux_listing_mapping ('listing',) lux_listing ['ENTITY', 'JOINED'] -lux_listing_mapping ('user',) active_listings ['JOINED', 'METRIC'] -lux_listing_mapping ('user',) approximate_continuous_booking_value_p99 ['JOINED', 'METRIC'] -lux_listing_mapping ('user',) approximate_discrete_booking_value_p99 ['JOINED', 'METRIC'] -lux_listing_mapping ('user',) average_booking_value ['JOINED', 'METRIC'] -lux_listing_mapping ('user',) average_instant_booking_value ['JOINED', 'METRIC'] -lux_listing_mapping ('user',) bookers ['JOINED', 'METRIC'] -lux_listing_mapping ('user',) booking_fees ['JOINED', 'METRIC'] -lux_listing_mapping ('user',) booking_fees_last_week_per_booker_this_week ['JOINED', 'METRIC'] -lux_listing_mapping ('user',) booking_fees_per_booker ['JOINED', 'METRIC'] -lux_listing_mapping ('user',) booking_fees_since_start_of_month ['JOINED', 'METRIC'] -lux_listing_mapping ('user',) booking_payments ['JOINED', 'METRIC'] -lux_listing_mapping ('user',) booking_value ['JOINED', 'METRIC'] -lux_listing_mapping ('user',) booking_value_for_non_null_listing_id ['JOINED', 'METRIC'] -lux_listing_mapping ('user',) booking_value_p99 ['JOINED', 'METRIC'] -lux_listing_mapping ('user',) booking_value_per_view ['JOINED', 'METRIC'] -lux_listing_mapping ('user',) booking_value_sub_instant ['JOINED', 'METRIC'] -lux_listing_mapping ('user',) booking_value_sub_instant_add_10 ['JOINED', 'METRIC'] -lux_listing_mapping ('user',) bookings ['JOINED', 'METRIC'] -lux_listing_mapping ('user',) bookings_5_day_lag ['JOINED', 'METRIC'] -lux_listing_mapping ('user',) bookings_at_start_of_month ['JOINED', 'METRIC'] -lux_listing_mapping ('user',) bookings_fill_nulls_with_0 ['JOINED', 'METRIC'] -lux_listing_mapping ('user',) bookings_fill_nulls_with_0_without_time_spine ['JOINED', 'METRIC'] -lux_listing_mapping ('user',) bookings_growth_2_weeks ['JOINED', 'METRIC'] -lux_listing_mapping ('user',) bookings_growth_2_weeks_fill_nulls_with_0 ['JOINED', 'METRIC'] -lux_listing_mapping ('user',) bookings_growth_2_weeks_fill_nulls_with_0_for_non_offset ['JOINED', 'METRIC'] -lux_listing_mapping ('user',) bookings_growth_since_start_of_month ['JOINED', 'METRIC'] -lux_listing_mapping ('user',) bookings_join_to_time_spine ['JOINED', 'METRIC'] -lux_listing_mapping ('user',) bookings_month_start_compared_to_1_month_prior ['JOINED', 'METRIC'] -lux_listing_mapping ('user',) bookings_offset_once ['JOINED', 'METRIC'] -lux_listing_mapping ('user',) bookings_offset_twice ['JOINED', 'METRIC'] -lux_listing_mapping ('user',) bookings_per_booker ['JOINED', 'METRIC'] -lux_listing_mapping ('user',) bookings_per_dollar ['JOINED', 'METRIC'] -lux_listing_mapping ('user',) bookings_per_listing ['JOINED', 'METRIC'] -lux_listing_mapping ('user',) bookings_per_lux_listing_derived ['JOINED', 'METRIC'] -lux_listing_mapping ('user',) bookings_per_view ['JOINED', 'METRIC'] -lux_listing_mapping ('user',) derived_bookings_0 ['JOINED', 'METRIC'] -lux_listing_mapping ('user',) derived_bookings_1 ['JOINED', 'METRIC'] -lux_listing_mapping ('user',) discrete_booking_value_p99 ['JOINED', 'METRIC'] -lux_listing_mapping ('user',) double_counted_delayed_bookings ['JOINED', 'METRIC'] -lux_listing_mapping ('user',) every_2_days_bookers_2_days_ago ['JOINED', 'METRIC'] -lux_listing_mapping ('user',) every_two_days_bookers ['JOINED', 'METRIC'] -lux_listing_mapping ('user',) every_two_days_bookers_fill_nulls_with_0 ['JOINED', 'METRIC'] -lux_listing_mapping ('user',) instant_booking_fraction_of_max_value ['JOINED', 'METRIC'] -lux_listing_mapping ('user',) instant_booking_value ['JOINED', 'METRIC'] -lux_listing_mapping ('user',) instant_booking_value_ratio ['JOINED', 'METRIC'] -lux_listing_mapping ('user',) instant_bookings ['JOINED', 'METRIC'] -lux_listing_mapping ('user',) instant_lux_booking_value_rate ['JOINED', 'METRIC'] -lux_listing_mapping ('user',) instant_plus_non_referred_bookings_pct ['JOINED', 'METRIC'] -lux_listing_mapping ('user',) largest_listing ['JOINED', 'METRIC'] -lux_listing_mapping ('user',) listings ['JOINED', 'METRIC'] -lux_listing_mapping ('user',) lux_booking_fraction_of_max_value ['JOINED', 'METRIC'] -lux_listing_mapping ('user',) lux_booking_value_rate_expr ['JOINED', 'METRIC'] -lux_listing_mapping ('user',) lux_listings ['JOINED', 'METRIC'] -lux_listing_mapping ('user',) max_booking_value ['JOINED', 'METRIC'] -lux_listing_mapping ('user',) median_booking_value ['JOINED', 'METRIC'] -lux_listing_mapping ('user',) min_booking_value ['JOINED', 'METRIC'] -lux_listing_mapping ('user',) nested_fill_nulls_without_time_spine ['JOINED', 'METRIC'] -lux_listing_mapping ('user',) non_referred_bookings_pct ['JOINED', 'METRIC'] -lux_listing_mapping ('user',) referred_bookings ['JOINED', 'METRIC'] -lux_listing_mapping ('user',) smallest_listing ['JOINED', 'METRIC'] -lux_listing_mapping ('user',) twice_bookings_fill_nulls_with_0_without_time_spine ['JOINED', 'METRIC'] -lux_listing_mapping ('user',) views ['JOINED', 'METRIC'] -lux_listing_mapping ('user',) views_times_booking_value ['JOINED', 'METRIC'] -users_ds_source ('user',) created_at DAY ['JOINED'] -users_ds_source ('user',) created_at DAY DAY ['JOINED'] -users_ds_source ('user',) created_at DAY DOW ['JOINED'] -users_ds_source ('user',) created_at DAY DOY ['JOINED'] -users_ds_source ('user',) created_at DAY MONTH ['JOINED'] -users_ds_source ('user',) created_at DAY QUARTER ['JOINED'] -users_ds_source ('user',) created_at DAY YEAR ['JOINED'] -users_ds_source ('user',) created_at MONTH ['DERIVED_TIME_GRANULARITY', 'JOINED'] -users_ds_source ('user',) created_at MONTH MONTH ['DERIVED_TIME_GRANULARITY', 'JOINED'] -users_ds_source ('user',) created_at MONTH QUARTER ['DERIVED_TIME_GRANULARITY', 'JOINED'] -users_ds_source ('user',) created_at MONTH YEAR ['DERIVED_TIME_GRANULARITY', 'JOINED'] -users_ds_source ('user',) created_at QUARTER ['DERIVED_TIME_GRANULARITY', 'JOINED'] -users_ds_source ('user',) created_at QUARTER QUARTER ['DERIVED_TIME_GRANULARITY', 'JOINED'] -users_ds_source ('user',) created_at QUARTER YEAR ['DERIVED_TIME_GRANULARITY', 'JOINED'] -users_ds_source ('user',) created_at WEEK ['DERIVED_TIME_GRANULARITY', 'JOINED'] -users_ds_source ('user',) created_at WEEK MONTH ['DERIVED_TIME_GRANULARITY', 'JOINED'] -users_ds_source ('user',) created_at WEEK QUARTER ['DERIVED_TIME_GRANULARITY', 'JOINED'] -users_ds_source ('user',) created_at WEEK YEAR ['DERIVED_TIME_GRANULARITY', 'JOINED'] -users_ds_source ('user',) created_at YEAR ['DERIVED_TIME_GRANULARITY', 'JOINED'] -users_ds_source ('user',) created_at YEAR YEAR ['DERIVED_TIME_GRANULARITY', 'JOINED'] -users_ds_source ('user',) ds DAY ['JOINED'] -users_ds_source ('user',) ds DAY DAY ['JOINED'] -users_ds_source ('user',) ds DAY DOW ['JOINED'] -users_ds_source ('user',) ds DAY DOY ['JOINED'] -users_ds_source ('user',) ds DAY MONTH ['JOINED'] -users_ds_source ('user',) ds DAY QUARTER ['JOINED'] -users_ds_source ('user',) ds DAY YEAR ['JOINED'] -users_ds_source ('user',) ds MONTH ['DERIVED_TIME_GRANULARITY', 'JOINED'] -users_ds_source ('user',) ds MONTH MONTH ['DERIVED_TIME_GRANULARITY', 'JOINED'] -users_ds_source ('user',) ds MONTH QUARTER ['DERIVED_TIME_GRANULARITY', 'JOINED'] -users_ds_source ('user',) ds MONTH YEAR ['DERIVED_TIME_GRANULARITY', 'JOINED'] -users_ds_source ('user',) ds QUARTER ['DERIVED_TIME_GRANULARITY', 'JOINED'] -users_ds_source ('user',) ds QUARTER QUARTER ['DERIVED_TIME_GRANULARITY', 'JOINED'] -users_ds_source ('user',) ds QUARTER YEAR ['DERIVED_TIME_GRANULARITY', 'JOINED'] -users_ds_source ('user',) ds WEEK ['DERIVED_TIME_GRANULARITY', 'JOINED'] -users_ds_source ('user',) ds WEEK MONTH ['DERIVED_TIME_GRANULARITY', 'JOINED'] -users_ds_source ('user',) ds WEEK QUARTER ['DERIVED_TIME_GRANULARITY', 'JOINED'] -users_ds_source ('user',) ds WEEK YEAR ['DERIVED_TIME_GRANULARITY', 'JOINED'] -users_ds_source ('user',) ds YEAR ['DERIVED_TIME_GRANULARITY', 'JOINED'] -users_ds_source ('user',) ds YEAR YEAR ['DERIVED_TIME_GRANULARITY', 'JOINED'] -users_ds_source ('user',) ds_partitioned DAY ['JOINED'] -users_ds_source ('user',) ds_partitioned DAY DAY ['JOINED'] -users_ds_source ('user',) ds_partitioned DAY DOW ['JOINED'] -users_ds_source ('user',) ds_partitioned DAY DOY ['JOINED'] -users_ds_source ('user',) ds_partitioned DAY MONTH ['JOINED'] -users_ds_source ('user',) ds_partitioned DAY QUARTER ['JOINED'] -users_ds_source ('user',) ds_partitioned DAY YEAR ['JOINED'] -users_ds_source ('user',) ds_partitioned MONTH ['DERIVED_TIME_GRANULARITY', 'JOINED'] -users_ds_source ('user',) ds_partitioned MONTH MONTH ['DERIVED_TIME_GRANULARITY', 'JOINED'] -users_ds_source ('user',) ds_partitioned MONTH QUARTER ['DERIVED_TIME_GRANULARITY', 'JOINED'] -users_ds_source ('user',) ds_partitioned MONTH YEAR ['DERIVED_TIME_GRANULARITY', 'JOINED'] -users_ds_source ('user',) ds_partitioned QUARTER ['DERIVED_TIME_GRANULARITY', 'JOINED'] -users_ds_source ('user',) ds_partitioned QUARTER QUARTER ['DERIVED_TIME_GRANULARITY', 'JOINED'] -users_ds_source ('user',) ds_partitioned QUARTER YEAR ['DERIVED_TIME_GRANULARITY', 'JOINED'] -users_ds_source ('user',) ds_partitioned WEEK ['DERIVED_TIME_GRANULARITY', 'JOINED'] -users_ds_source ('user',) ds_partitioned WEEK MONTH ['DERIVED_TIME_GRANULARITY', 'JOINED'] -users_ds_source ('user',) ds_partitioned WEEK QUARTER ['DERIVED_TIME_GRANULARITY', 'JOINED'] -users_ds_source ('user',) ds_partitioned WEEK YEAR ['DERIVED_TIME_GRANULARITY', 'JOINED'] -users_ds_source ('user',) ds_partitioned YEAR ['DERIVED_TIME_GRANULARITY', 'JOINED'] -users_ds_source ('user',) ds_partitioned YEAR YEAR ['DERIVED_TIME_GRANULARITY', 'JOINED'] -users_ds_source ('user',) home_state ['JOINED'] -users_latest ('user',) ds_latest DAY ['JOINED'] -users_latest ('user',) ds_latest DAY DAY ['JOINED'] -users_latest ('user',) ds_latest DAY DOW ['JOINED'] -users_latest ('user',) ds_latest DAY DOY ['JOINED'] -users_latest ('user',) ds_latest DAY MONTH ['JOINED'] -users_latest ('user',) ds_latest DAY QUARTER ['JOINED'] -users_latest ('user',) ds_latest DAY YEAR ['JOINED'] -users_latest ('user',) ds_latest MONTH ['DERIVED_TIME_GRANULARITY', 'JOINED'] -users_latest ('user',) ds_latest MONTH MONTH ['DERIVED_TIME_GRANULARITY', 'JOINED'] -users_latest ('user',) ds_latest MONTH QUARTER ['DERIVED_TIME_GRANULARITY', 'JOINED'] -users_latest ('user',) ds_latest MONTH YEAR ['DERIVED_TIME_GRANULARITY', 'JOINED'] -users_latest ('user',) ds_latest QUARTER ['DERIVED_TIME_GRANULARITY', 'JOINED'] -users_latest ('user',) ds_latest QUARTER QUARTER ['DERIVED_TIME_GRANULARITY', 'JOINED'] -users_latest ('user',) ds_latest QUARTER YEAR ['DERIVED_TIME_GRANULARITY', 'JOINED'] -users_latest ('user',) ds_latest WEEK ['DERIVED_TIME_GRANULARITY', 'JOINED'] -users_latest ('user',) ds_latest WEEK MONTH ['DERIVED_TIME_GRANULARITY', 'JOINED'] -users_latest ('user',) ds_latest WEEK QUARTER ['DERIVED_TIME_GRANULARITY', 'JOINED'] -users_latest ('user',) ds_latest WEEK YEAR ['DERIVED_TIME_GRANULARITY', 'JOINED'] -users_latest ('user',) ds_latest YEAR ['DERIVED_TIME_GRANULARITY', 'JOINED'] -users_latest ('user',) ds_latest YEAR YEAR ['DERIVED_TIME_GRANULARITY', 'JOINED'] -users_latest ('user',) home_state_latest ['JOINED'] +Semantic Model Entity Links Name Time Granularity Date Part Properties +------------------- -------------------------- -------------------------------------------------------- ------------------ ----------- ------------------------------------------- + ('listing',) active_listings ['JOINED', 'METRIC'] + ('listing',) approximate_continuous_booking_value_p99 ['JOINED', 'METRIC'] + ('listing',) approximate_discrete_booking_value_p99 ['JOINED', 'METRIC'] + ('listing',) average_booking_value ['JOINED', 'METRIC'] + ('listing',) average_instant_booking_value ['JOINED', 'METRIC'] + ('listing',) bookers ['JOINED', 'METRIC'] + ('listing',) booking_fees ['JOINED', 'METRIC'] + ('listing',) booking_fees_last_week_per_booker_this_week ['JOINED', 'METRIC'] + ('listing',) booking_fees_per_booker ['JOINED', 'METRIC'] + ('listing',) booking_fees_since_start_of_month ['JOINED', 'METRIC'] + ('listing',) booking_payments ['JOINED', 'METRIC'] + ('listing',) booking_value ['JOINED', 'METRIC'] + ('listing',) booking_value_for_non_null_listing_id ['JOINED', 'METRIC'] + ('listing',) booking_value_p99 ['JOINED', 'METRIC'] + ('listing',) booking_value_per_view ['JOINED', 'METRIC'] + ('listing',) booking_value_sub_instant ['JOINED', 'METRIC'] + ('listing',) booking_value_sub_instant_add_10 ['JOINED', 'METRIC'] + ('listing',) bookings ['JOINED', 'METRIC'] + ('listing',) bookings_5_day_lag ['JOINED', 'METRIC'] + ('listing',) bookings_at_start_of_month ['JOINED', 'METRIC'] + ('listing',) bookings_fill_nulls_with_0 ['JOINED', 'METRIC'] + ('listing',) bookings_fill_nulls_with_0_without_time_spine ['JOINED', 'METRIC'] + ('listing',) bookings_growth_2_weeks ['JOINED', 'METRIC'] + ('listing',) bookings_growth_2_weeks_fill_nulls_with_0 ['JOINED', 'METRIC'] + ('listing',) bookings_growth_2_weeks_fill_nulls_with_0_for_non_offset ['JOINED', 'METRIC'] + ('listing',) bookings_growth_since_start_of_month ['JOINED', 'METRIC'] + ('listing',) bookings_join_to_time_spine ['JOINED', 'METRIC'] + ('listing',) bookings_month_start_compared_to_1_month_prior ['JOINED', 'METRIC'] + ('listing',) bookings_offset_once ['JOINED', 'METRIC'] + ('listing',) bookings_offset_twice ['JOINED', 'METRIC'] + ('listing',) bookings_per_booker ['JOINED', 'METRIC'] + ('listing',) bookings_per_dollar ['JOINED', 'METRIC'] + ('listing',) bookings_per_listing ['JOINED', 'METRIC'] + ('listing',) bookings_per_lux_listing_derived ['JOINED', 'METRIC'] + ('listing',) bookings_per_view ['JOINED', 'METRIC'] + ('listing',) derived_bookings_0 ['JOINED', 'METRIC'] + ('listing',) derived_bookings_1 ['JOINED', 'METRIC'] + ('listing',) discrete_booking_value_p99 ['JOINED', 'METRIC'] + ('listing',) double_counted_delayed_bookings ['JOINED', 'METRIC'] + ('listing',) every_2_days_bookers_2_days_ago ['JOINED', 'METRIC'] + ('listing',) every_two_days_bookers ['JOINED', 'METRIC'] + ('listing',) every_two_days_bookers_fill_nulls_with_0 ['JOINED', 'METRIC'] + ('listing',) instant_booking_fraction_of_max_value ['JOINED', 'METRIC'] + ('listing',) instant_booking_value ['JOINED', 'METRIC'] + ('listing',) instant_booking_value_ratio ['JOINED', 'METRIC'] + ('listing',) instant_bookings ['JOINED', 'METRIC'] + ('listing',) instant_lux_booking_value_rate ['JOINED', 'METRIC'] + ('listing',) instant_plus_non_referred_bookings_pct ['JOINED', 'METRIC'] + ('listing',) largest_listing ['JOINED', 'METRIC'] + ('listing',) listings ['JOINED', 'METRIC'] + ('listing',) lux_booking_fraction_of_max_value ['JOINED', 'METRIC'] + ('listing',) lux_booking_value_rate_expr ['JOINED', 'METRIC'] + ('listing',) lux_listings ['JOINED', 'METRIC'] + ('listing',) max_booking_value ['JOINED', 'METRIC'] + ('listing',) median_booking_value ['JOINED', 'METRIC'] + ('listing',) min_booking_value ['JOINED', 'METRIC'] + ('listing',) nested_fill_nulls_without_time_spine ['JOINED', 'METRIC'] + ('listing',) non_referred_bookings_pct ['JOINED', 'METRIC'] + ('listing',) referred_bookings ['JOINED', 'METRIC'] + ('listing',) smallest_listing ['JOINED', 'METRIC'] + ('listing',) twice_bookings_fill_nulls_with_0_without_time_spine ['JOINED', 'METRIC'] + ('listing',) views ['JOINED', 'METRIC'] + ('listing',) views_times_booking_value ['JOINED', 'METRIC'] + ('user',) active_listings ['JOINED', 'METRIC'] + ('user',) approximate_continuous_booking_value_p99 ['JOINED', 'METRIC'] + ('user',) approximate_discrete_booking_value_p99 ['JOINED', 'METRIC'] + ('user',) average_booking_value ['JOINED', 'METRIC'] + ('user',) average_instant_booking_value ['JOINED', 'METRIC'] + ('user',) bookers ['JOINED', 'METRIC'] + ('user',) booking_fees ['JOINED', 'METRIC'] + ('user',) booking_fees_last_week_per_booker_this_week ['JOINED', 'METRIC'] + ('user',) booking_fees_per_booker ['JOINED', 'METRIC'] + ('user',) booking_fees_since_start_of_month ['JOINED', 'METRIC'] + ('user',) booking_payments ['JOINED', 'METRIC'] + ('user',) booking_value ['JOINED', 'METRIC'] + ('user',) booking_value_for_non_null_listing_id ['JOINED', 'METRIC'] + ('user',) booking_value_p99 ['JOINED', 'METRIC'] + ('user',) booking_value_per_view ['JOINED', 'METRIC'] + ('user',) booking_value_sub_instant ['JOINED', 'METRIC'] + ('user',) booking_value_sub_instant_add_10 ['JOINED', 'METRIC'] + ('user',) bookings ['JOINED', 'METRIC'] + ('user',) bookings_5_day_lag ['JOINED', 'METRIC'] + ('user',) bookings_at_start_of_month ['JOINED', 'METRIC'] + ('user',) bookings_fill_nulls_with_0 ['JOINED', 'METRIC'] + ('user',) bookings_fill_nulls_with_0_without_time_spine ['JOINED', 'METRIC'] + ('user',) bookings_growth_2_weeks ['JOINED', 'METRIC'] + ('user',) bookings_growth_2_weeks_fill_nulls_with_0 ['JOINED', 'METRIC'] + ('user',) bookings_growth_2_weeks_fill_nulls_with_0_for_non_offset ['JOINED', 'METRIC'] + ('user',) bookings_growth_since_start_of_month ['JOINED', 'METRIC'] + ('user',) bookings_join_to_time_spine ['JOINED', 'METRIC'] + ('user',) bookings_month_start_compared_to_1_month_prior ['JOINED', 'METRIC'] + ('user',) bookings_offset_once ['JOINED', 'METRIC'] + ('user',) bookings_offset_twice ['JOINED', 'METRIC'] + ('user',) bookings_per_booker ['JOINED', 'METRIC'] + ('user',) bookings_per_dollar ['JOINED', 'METRIC'] + ('user',) bookings_per_listing ['JOINED', 'METRIC'] + ('user',) bookings_per_lux_listing_derived ['JOINED', 'METRIC'] + ('user',) bookings_per_view ['JOINED', 'METRIC'] + ('user',) current_account_balance_by_user ['JOINED', 'METRIC'] + ('user',) derived_bookings_0 ['JOINED', 'METRIC'] + ('user',) derived_bookings_1 ['JOINED', 'METRIC'] + ('user',) discrete_booking_value_p99 ['JOINED', 'METRIC'] + ('user',) double_counted_delayed_bookings ['JOINED', 'METRIC'] + ('user',) every_2_days_bookers_2_days_ago ['JOINED', 'METRIC'] + ('user',) every_two_days_bookers ['JOINED', 'METRIC'] + ('user',) every_two_days_bookers_fill_nulls_with_0 ['JOINED', 'METRIC'] + ('user',) identity_verifications ['JOINED', 'METRIC'] + ('user',) instant_booking_fraction_of_max_value ['JOINED', 'METRIC'] + ('user',) instant_booking_value ['JOINED', 'METRIC'] + ('user',) instant_booking_value_ratio ['JOINED', 'METRIC'] + ('user',) instant_bookings ['JOINED', 'METRIC'] + ('user',) instant_lux_booking_value_rate ['JOINED', 'METRIC'] + ('user',) instant_plus_non_referred_bookings_pct ['JOINED', 'METRIC'] + ('user',) largest_listing ['JOINED', 'METRIC'] + ('user',) listings ['JOINED', 'METRIC'] + ('user',) lux_booking_fraction_of_max_value ['JOINED', 'METRIC'] + ('user',) lux_booking_value_rate_expr ['JOINED', 'METRIC'] + ('user',) lux_listings ['JOINED', 'METRIC'] + ('user',) max_booking_value ['JOINED', 'METRIC'] + ('user',) median_booking_value ['JOINED', 'METRIC'] + ('user',) min_booking_value ['JOINED', 'METRIC'] + ('user',) nested_fill_nulls_without_time_spine ['JOINED', 'METRIC'] + ('user',) non_referred_bookings_pct ['JOINED', 'METRIC'] + ('user',) referred_bookings ['JOINED', 'METRIC'] + ('user',) regional_starting_balance_ratios ['JOINED', 'METRIC'] + ('user',) revenue ['JOINED', 'METRIC'] + ('user',) revenue_all_time ['JOINED', 'METRIC'] + ('user',) revenue_mtd ['JOINED', 'METRIC'] + ('user',) smallest_listing ['JOINED', 'METRIC'] + ('user',) total_account_balance_first_day ['JOINED', 'METRIC'] + ('user',) trailing_2_months_revenue ['JOINED', 'METRIC'] + ('user',) trailing_2_months_revenue_sub_10 ['JOINED', 'METRIC'] + ('user',) twice_bookings_fill_nulls_with_0_without_time_spine ['JOINED', 'METRIC'] + ('user',) views ['JOINED', 'METRIC'] + ('user',) views_times_booking_value ['JOINED', 'METRIC'] + ('user',) visit_buy_conversion_rate ['JOINED', 'METRIC'] + ('user',) visit_buy_conversion_rate_7days ['JOINED', 'METRIC'] + ('user',) visit_buy_conversion_rate_7days_fill_nulls_with_0 ['JOINED', 'METRIC'] + ('user',) visit_buy_conversion_rate_by_session ['JOINED', 'METRIC'] + ('user',) visit_buy_conversions ['JOINED', 'METRIC'] +companies ('user',) company ['ENTITY', 'JOINED'] +companies ('user',) company_name ['JOINED'] +companies ('user', 'company') active_listings ['JOINED', 'METRIC', 'MULTI_HOP'] +companies ('user', 'company') approximate_continuous_booking_value_p99 ['JOINED', 'METRIC', 'MULTI_HOP'] +companies ('user', 'company') approximate_discrete_booking_value_p99 ['JOINED', 'METRIC', 'MULTI_HOP'] +companies ('user', 'company') average_booking_value ['JOINED', 'METRIC', 'MULTI_HOP'] +companies ('user', 'company') average_instant_booking_value ['JOINED', 'METRIC', 'MULTI_HOP'] +companies ('user', 'company') bookers ['JOINED', 'METRIC', 'MULTI_HOP'] +companies ('user', 'company') booking_fees ['JOINED', 'METRIC', 'MULTI_HOP'] +companies ('user', 'company') booking_fees_last_week_per_booker_this_week ['JOINED', 'METRIC', 'MULTI_HOP'] +companies ('user', 'company') booking_fees_per_booker ['JOINED', 'METRIC', 'MULTI_HOP'] +companies ('user', 'company') booking_fees_since_start_of_month ['JOINED', 'METRIC', 'MULTI_HOP'] +companies ('user', 'company') booking_payments ['JOINED', 'METRIC', 'MULTI_HOP'] +companies ('user', 'company') booking_value ['JOINED', 'METRIC', 'MULTI_HOP'] +companies ('user', 'company') booking_value_for_non_null_listing_id ['JOINED', 'METRIC', 'MULTI_HOP'] +companies ('user', 'company') booking_value_p99 ['JOINED', 'METRIC', 'MULTI_HOP'] +companies ('user', 'company') booking_value_per_view ['JOINED', 'METRIC', 'MULTI_HOP'] +companies ('user', 'company') booking_value_sub_instant ['JOINED', 'METRIC', 'MULTI_HOP'] +companies ('user', 'company') booking_value_sub_instant_add_10 ['JOINED', 'METRIC', 'MULTI_HOP'] +companies ('user', 'company') bookings ['JOINED', 'METRIC', 'MULTI_HOP'] +companies ('user', 'company') bookings_5_day_lag ['JOINED', 'METRIC', 'MULTI_HOP'] +companies ('user', 'company') bookings_at_start_of_month ['JOINED', 'METRIC', 'MULTI_HOP'] +companies ('user', 'company') bookings_fill_nulls_with_0 ['JOINED', 'METRIC', 'MULTI_HOP'] +companies ('user', 'company') bookings_fill_nulls_with_0_without_time_spine ['JOINED', 'METRIC', 'MULTI_HOP'] +companies ('user', 'company') bookings_growth_2_weeks ['JOINED', 'METRIC', 'MULTI_HOP'] +companies ('user', 'company') bookings_growth_2_weeks_fill_nulls_with_0 ['JOINED', 'METRIC', 'MULTI_HOP'] +companies ('user', 'company') bookings_growth_2_weeks_fill_nulls_with_0_for_non_offset ['JOINED', 'METRIC', 'MULTI_HOP'] +companies ('user', 'company') bookings_growth_since_start_of_month ['JOINED', 'METRIC', 'MULTI_HOP'] +companies ('user', 'company') bookings_join_to_time_spine ['JOINED', 'METRIC', 'MULTI_HOP'] +companies ('user', 'company') bookings_month_start_compared_to_1_month_prior ['JOINED', 'METRIC', 'MULTI_HOP'] +companies ('user', 'company') bookings_offset_once ['JOINED', 'METRIC', 'MULTI_HOP'] +companies ('user', 'company') bookings_offset_twice ['JOINED', 'METRIC', 'MULTI_HOP'] +companies ('user', 'company') bookings_per_booker ['JOINED', 'METRIC', 'MULTI_HOP'] +companies ('user', 'company') bookings_per_dollar ['JOINED', 'METRIC', 'MULTI_HOP'] +companies ('user', 'company') bookings_per_view ['JOINED', 'METRIC', 'MULTI_HOP'] +companies ('user', 'company') current_account_balance_by_user ['JOINED', 'METRIC', 'MULTI_HOP'] +companies ('user', 'company') derived_bookings_0 ['JOINED', 'METRIC', 'MULTI_HOP'] +companies ('user', 'company') derived_bookings_1 ['JOINED', 'METRIC', 'MULTI_HOP'] +companies ('user', 'company') discrete_booking_value_p99 ['JOINED', 'METRIC', 'MULTI_HOP'] +companies ('user', 'company') double_counted_delayed_bookings ['JOINED', 'METRIC', 'MULTI_HOP'] +companies ('user', 'company') every_2_days_bookers_2_days_ago ['JOINED', 'METRIC', 'MULTI_HOP'] +companies ('user', 'company') every_two_days_bookers ['JOINED', 'METRIC', 'MULTI_HOP'] +companies ('user', 'company') every_two_days_bookers_fill_nulls_with_0 ['JOINED', 'METRIC', 'MULTI_HOP'] +companies ('user', 'company') identity_verifications ['JOINED', 'METRIC', 'MULTI_HOP'] +companies ('user', 'company') instant_booking_fraction_of_max_value ['JOINED', 'METRIC', 'MULTI_HOP'] +companies ('user', 'company') instant_booking_value ['JOINED', 'METRIC', 'MULTI_HOP'] +companies ('user', 'company') instant_booking_value_ratio ['JOINED', 'METRIC', 'MULTI_HOP'] +companies ('user', 'company') instant_bookings ['JOINED', 'METRIC', 'MULTI_HOP'] +companies ('user', 'company') instant_lux_booking_value_rate ['JOINED', 'METRIC', 'MULTI_HOP'] +companies ('user', 'company') instant_plus_non_referred_bookings_pct ['JOINED', 'METRIC', 'MULTI_HOP'] +companies ('user', 'company') largest_listing ['JOINED', 'METRIC', 'MULTI_HOP'] +companies ('user', 'company') listings ['JOINED', 'METRIC', 'MULTI_HOP'] +companies ('user', 'company') lux_booking_fraction_of_max_value ['JOINED', 'METRIC', 'MULTI_HOP'] +companies ('user', 'company') lux_booking_value_rate_expr ['JOINED', 'METRIC', 'MULTI_HOP'] +companies ('user', 'company') lux_listings ['JOINED', 'METRIC', 'MULTI_HOP'] +companies ('user', 'company') max_booking_value ['JOINED', 'METRIC', 'MULTI_HOP'] +companies ('user', 'company') median_booking_value ['JOINED', 'METRIC', 'MULTI_HOP'] +companies ('user', 'company') min_booking_value ['JOINED', 'METRIC', 'MULTI_HOP'] +companies ('user', 'company') nested_fill_nulls_without_time_spine ['JOINED', 'METRIC', 'MULTI_HOP'] +companies ('user', 'company') non_referred_bookings_pct ['JOINED', 'METRIC', 'MULTI_HOP'] +companies ('user', 'company') referred_bookings ['JOINED', 'METRIC', 'MULTI_HOP'] +companies ('user', 'company') regional_starting_balance_ratios ['JOINED', 'METRIC', 'MULTI_HOP'] +companies ('user', 'company') revenue ['JOINED', 'METRIC', 'MULTI_HOP'] +companies ('user', 'company') revenue_all_time ['JOINED', 'METRIC', 'MULTI_HOP'] +companies ('user', 'company') revenue_mtd ['JOINED', 'METRIC', 'MULTI_HOP'] +companies ('user', 'company') smallest_listing ['JOINED', 'METRIC', 'MULTI_HOP'] +companies ('user', 'company') total_account_balance_first_day ['JOINED', 'METRIC', 'MULTI_HOP'] +companies ('user', 'company') trailing_2_months_revenue ['JOINED', 'METRIC', 'MULTI_HOP'] +companies ('user', 'company') trailing_2_months_revenue_sub_10 ['JOINED', 'METRIC', 'MULTI_HOP'] +companies ('user', 'company') twice_bookings_fill_nulls_with_0_without_time_spine ['JOINED', 'METRIC', 'MULTI_HOP'] +companies ('user', 'company') views ['JOINED', 'METRIC', 'MULTI_HOP'] +companies ('user', 'company') views_times_booking_value ['JOINED', 'METRIC', 'MULTI_HOP'] +companies ('user', 'company') visit_buy_conversion_rate ['JOINED', 'METRIC', 'MULTI_HOP'] +companies ('user', 'company') visit_buy_conversion_rate_7days ['JOINED', 'METRIC', 'MULTI_HOP'] +companies ('user', 'company') visit_buy_conversion_rate_7days_fill_nulls_with_0 ['JOINED', 'METRIC', 'MULTI_HOP'] +companies ('user', 'company') visit_buy_conversion_rate_by_session ['JOINED', 'METRIC', 'MULTI_HOP'] +companies ('user', 'company') visit_buy_conversions ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest () listing ['ENTITY', 'LOCAL'] +listings_latest () metric_time DAY ['METRIC_TIME'] +listings_latest () metric_time DAY DAY ['DERIVED_TIME_GRANULARITY', 'METRIC_TIME'] +listings_latest () metric_time DAY DOW ['DERIVED_TIME_GRANULARITY', 'METRIC_TIME'] +listings_latest () metric_time DAY DOY ['DERIVED_TIME_GRANULARITY', 'METRIC_TIME'] +listings_latest () metric_time DAY MONTH ['DERIVED_TIME_GRANULARITY', 'METRIC_TIME'] +listings_latest () metric_time DAY QUARTER ['DERIVED_TIME_GRANULARITY', 'METRIC_TIME'] +listings_latest () metric_time DAY YEAR ['DERIVED_TIME_GRANULARITY', 'METRIC_TIME'] +listings_latest () metric_time MONTH ['DERIVED_TIME_GRANULARITY', 'METRIC_TIME'] +listings_latest () metric_time MONTH MONTH ['DERIVED_TIME_GRANULARITY', 'METRIC_TIME'] +listings_latest () metric_time MONTH QUARTER ['DERIVED_TIME_GRANULARITY', 'METRIC_TIME'] +listings_latest () metric_time MONTH YEAR ['DERIVED_TIME_GRANULARITY', 'METRIC_TIME'] +listings_latest () metric_time QUARTER ['DERIVED_TIME_GRANULARITY', 'METRIC_TIME'] +listings_latest () metric_time QUARTER QUARTER ['DERIVED_TIME_GRANULARITY', 'METRIC_TIME'] +listings_latest () metric_time QUARTER YEAR ['DERIVED_TIME_GRANULARITY', 'METRIC_TIME'] +listings_latest () metric_time WEEK ['DERIVED_TIME_GRANULARITY', 'METRIC_TIME'] +listings_latest () metric_time WEEK MONTH ['DERIVED_TIME_GRANULARITY', 'METRIC_TIME'] +listings_latest () metric_time WEEK QUARTER ['DERIVED_TIME_GRANULARITY', 'METRIC_TIME'] +listings_latest () metric_time WEEK YEAR ['DERIVED_TIME_GRANULARITY', 'METRIC_TIME'] +listings_latest () metric_time YEAR ['DERIVED_TIME_GRANULARITY', 'METRIC_TIME'] +listings_latest () metric_time YEAR YEAR ['DERIVED_TIME_GRANULARITY', 'METRIC_TIME'] +listings_latest () user ['ENTITY', 'LOCAL'] +listings_latest ('listing',) capacity_latest ['LOCAL'] +listings_latest ('listing',) country_latest ['LOCAL'] +listings_latest ('listing',) created_at DAY ['LOCAL'] +listings_latest ('listing',) created_at DAY DAY ['LOCAL'] +listings_latest ('listing',) created_at DAY DOW ['LOCAL'] +listings_latest ('listing',) created_at DAY DOY ['LOCAL'] +listings_latest ('listing',) created_at DAY MONTH ['LOCAL'] +listings_latest ('listing',) created_at DAY QUARTER ['LOCAL'] +listings_latest ('listing',) created_at DAY YEAR ['LOCAL'] +listings_latest ('listing',) created_at MONTH ['DERIVED_TIME_GRANULARITY', 'LOCAL'] +listings_latest ('listing',) created_at MONTH MONTH ['DERIVED_TIME_GRANULARITY', 'LOCAL'] +listings_latest ('listing',) created_at MONTH QUARTER ['DERIVED_TIME_GRANULARITY', 'LOCAL'] +listings_latest ('listing',) created_at MONTH YEAR ['DERIVED_TIME_GRANULARITY', 'LOCAL'] +listings_latest ('listing',) created_at QUARTER ['DERIVED_TIME_GRANULARITY', 'LOCAL'] +listings_latest ('listing',) created_at QUARTER QUARTER ['DERIVED_TIME_GRANULARITY', 'LOCAL'] +listings_latest ('listing',) created_at QUARTER YEAR ['DERIVED_TIME_GRANULARITY', 'LOCAL'] +listings_latest ('listing',) created_at WEEK ['DERIVED_TIME_GRANULARITY', 'LOCAL'] +listings_latest ('listing',) created_at WEEK MONTH ['DERIVED_TIME_GRANULARITY', 'LOCAL'] +listings_latest ('listing',) created_at WEEK QUARTER ['DERIVED_TIME_GRANULARITY', 'LOCAL'] +listings_latest ('listing',) created_at WEEK YEAR ['DERIVED_TIME_GRANULARITY', 'LOCAL'] +listings_latest ('listing',) created_at YEAR ['DERIVED_TIME_GRANULARITY', 'LOCAL'] +listings_latest ('listing',) created_at YEAR YEAR ['DERIVED_TIME_GRANULARITY', 'LOCAL'] +listings_latest ('listing',) ds DAY ['LOCAL'] +listings_latest ('listing',) ds DAY DAY ['LOCAL'] +listings_latest ('listing',) ds DAY DOW ['LOCAL'] +listings_latest ('listing',) ds DAY DOY ['LOCAL'] +listings_latest ('listing',) ds DAY MONTH ['LOCAL'] +listings_latest ('listing',) ds DAY QUARTER ['LOCAL'] +listings_latest ('listing',) ds DAY YEAR ['LOCAL'] +listings_latest ('listing',) ds MONTH ['DERIVED_TIME_GRANULARITY', 'LOCAL'] +listings_latest ('listing',) ds MONTH MONTH ['DERIVED_TIME_GRANULARITY', 'LOCAL'] +listings_latest ('listing',) ds MONTH QUARTER ['DERIVED_TIME_GRANULARITY', 'LOCAL'] +listings_latest ('listing',) ds MONTH YEAR ['DERIVED_TIME_GRANULARITY', 'LOCAL'] +listings_latest ('listing',) ds QUARTER ['DERIVED_TIME_GRANULARITY', 'LOCAL'] +listings_latest ('listing',) ds QUARTER QUARTER ['DERIVED_TIME_GRANULARITY', 'LOCAL'] +listings_latest ('listing',) ds QUARTER YEAR ['DERIVED_TIME_GRANULARITY', 'LOCAL'] +listings_latest ('listing',) ds WEEK ['DERIVED_TIME_GRANULARITY', 'LOCAL'] +listings_latest ('listing',) ds WEEK MONTH ['DERIVED_TIME_GRANULARITY', 'LOCAL'] +listings_latest ('listing',) ds WEEK QUARTER ['DERIVED_TIME_GRANULARITY', 'LOCAL'] +listings_latest ('listing',) ds WEEK YEAR ['DERIVED_TIME_GRANULARITY', 'LOCAL'] +listings_latest ('listing',) ds YEAR ['DERIVED_TIME_GRANULARITY', 'LOCAL'] +listings_latest ('listing',) ds YEAR YEAR ['DERIVED_TIME_GRANULARITY', 'LOCAL'] +listings_latest ('listing',) is_lux_latest ['LOCAL'] +listings_latest ('listing',) user ['ENTITY', 'LOCAL'] +lux_listing_mapping ('listing',) lux_listing ['ENTITY', 'JOINED'] +lux_listing_mapping ('listing', 'lux_listing') active_listings ['JOINED', 'METRIC', 'MULTI_HOP'] +lux_listing_mapping ('listing', 'lux_listing') approximate_continuous_booking_value_p99 ['JOINED', 'METRIC', 'MULTI_HOP'] +lux_listing_mapping ('listing', 'lux_listing') approximate_discrete_booking_value_p99 ['JOINED', 'METRIC', 'MULTI_HOP'] +lux_listing_mapping ('listing', 'lux_listing') average_booking_value ['JOINED', 'METRIC', 'MULTI_HOP'] +lux_listing_mapping ('listing', 'lux_listing') average_instant_booking_value ['JOINED', 'METRIC', 'MULTI_HOP'] +lux_listing_mapping ('listing', 'lux_listing') bookers ['JOINED', 'METRIC', 'MULTI_HOP'] +lux_listing_mapping ('listing', 'lux_listing') booking_fees ['JOINED', 'METRIC', 'MULTI_HOP'] +lux_listing_mapping ('listing', 'lux_listing') booking_fees_last_week_per_booker_this_week ['JOINED', 'METRIC', 'MULTI_HOP'] +lux_listing_mapping ('listing', 'lux_listing') booking_fees_per_booker ['JOINED', 'METRIC', 'MULTI_HOP'] +lux_listing_mapping ('listing', 'lux_listing') booking_fees_since_start_of_month ['JOINED', 'METRIC', 'MULTI_HOP'] +lux_listing_mapping ('listing', 'lux_listing') booking_payments ['JOINED', 'METRIC', 'MULTI_HOP'] +lux_listing_mapping ('listing', 'lux_listing') booking_value ['JOINED', 'METRIC', 'MULTI_HOP'] +lux_listing_mapping ('listing', 'lux_listing') booking_value_for_non_null_listing_id ['JOINED', 'METRIC', 'MULTI_HOP'] +lux_listing_mapping ('listing', 'lux_listing') booking_value_p99 ['JOINED', 'METRIC', 'MULTI_HOP'] +lux_listing_mapping ('listing', 'lux_listing') booking_value_per_view ['JOINED', 'METRIC', 'MULTI_HOP'] +lux_listing_mapping ('listing', 'lux_listing') booking_value_sub_instant ['JOINED', 'METRIC', 'MULTI_HOP'] +lux_listing_mapping ('listing', 'lux_listing') booking_value_sub_instant_add_10 ['JOINED', 'METRIC', 'MULTI_HOP'] +lux_listing_mapping ('listing', 'lux_listing') bookings ['JOINED', 'METRIC', 'MULTI_HOP'] +lux_listing_mapping ('listing', 'lux_listing') bookings_5_day_lag ['JOINED', 'METRIC', 'MULTI_HOP'] +lux_listing_mapping ('listing', 'lux_listing') bookings_at_start_of_month ['JOINED', 'METRIC', 'MULTI_HOP'] +lux_listing_mapping ('listing', 'lux_listing') bookings_fill_nulls_with_0 ['JOINED', 'METRIC', 'MULTI_HOP'] +lux_listing_mapping ('listing', 'lux_listing') bookings_fill_nulls_with_0_without_time_spine ['JOINED', 'METRIC', 'MULTI_HOP'] +lux_listing_mapping ('listing', 'lux_listing') bookings_growth_2_weeks ['JOINED', 'METRIC', 'MULTI_HOP'] +lux_listing_mapping ('listing', 'lux_listing') bookings_growth_2_weeks_fill_nulls_with_0 ['JOINED', 'METRIC', 'MULTI_HOP'] +lux_listing_mapping ('listing', 'lux_listing') bookings_growth_2_weeks_fill_nulls_with_0_for_non_offset ['JOINED', 'METRIC', 'MULTI_HOP'] +lux_listing_mapping ('listing', 'lux_listing') bookings_growth_since_start_of_month ['JOINED', 'METRIC', 'MULTI_HOP'] +lux_listing_mapping ('listing', 'lux_listing') bookings_join_to_time_spine ['JOINED', 'METRIC', 'MULTI_HOP'] +lux_listing_mapping ('listing', 'lux_listing') bookings_month_start_compared_to_1_month_prior ['JOINED', 'METRIC', 'MULTI_HOP'] +lux_listing_mapping ('listing', 'lux_listing') bookings_offset_once ['JOINED', 'METRIC', 'MULTI_HOP'] +lux_listing_mapping ('listing', 'lux_listing') bookings_offset_twice ['JOINED', 'METRIC', 'MULTI_HOP'] +lux_listing_mapping ('listing', 'lux_listing') bookings_per_booker ['JOINED', 'METRIC', 'MULTI_HOP'] +lux_listing_mapping ('listing', 'lux_listing') bookings_per_dollar ['JOINED', 'METRIC', 'MULTI_HOP'] +lux_listing_mapping ('listing', 'lux_listing') bookings_per_listing ['JOINED', 'METRIC', 'MULTI_HOP'] +lux_listing_mapping ('listing', 'lux_listing') bookings_per_lux_listing_derived ['JOINED', 'METRIC', 'MULTI_HOP'] +lux_listing_mapping ('listing', 'lux_listing') bookings_per_view ['JOINED', 'METRIC', 'MULTI_HOP'] +lux_listing_mapping ('listing', 'lux_listing') derived_bookings_0 ['JOINED', 'METRIC', 'MULTI_HOP'] +lux_listing_mapping ('listing', 'lux_listing') derived_bookings_1 ['JOINED', 'METRIC', 'MULTI_HOP'] +lux_listing_mapping ('listing', 'lux_listing') discrete_booking_value_p99 ['JOINED', 'METRIC', 'MULTI_HOP'] +lux_listing_mapping ('listing', 'lux_listing') double_counted_delayed_bookings ['JOINED', 'METRIC', 'MULTI_HOP'] +lux_listing_mapping ('listing', 'lux_listing') every_2_days_bookers_2_days_ago ['JOINED', 'METRIC', 'MULTI_HOP'] +lux_listing_mapping ('listing', 'lux_listing') every_two_days_bookers ['JOINED', 'METRIC', 'MULTI_HOP'] +lux_listing_mapping ('listing', 'lux_listing') every_two_days_bookers_fill_nulls_with_0 ['JOINED', 'METRIC', 'MULTI_HOP'] +lux_listing_mapping ('listing', 'lux_listing') instant_booking_fraction_of_max_value ['JOINED', 'METRIC', 'MULTI_HOP'] +lux_listing_mapping ('listing', 'lux_listing') instant_booking_value ['JOINED', 'METRIC', 'MULTI_HOP'] +lux_listing_mapping ('listing', 'lux_listing') instant_booking_value_ratio ['JOINED', 'METRIC', 'MULTI_HOP'] +lux_listing_mapping ('listing', 'lux_listing') instant_bookings ['JOINED', 'METRIC', 'MULTI_HOP'] +lux_listing_mapping ('listing', 'lux_listing') instant_lux_booking_value_rate ['JOINED', 'METRIC', 'MULTI_HOP'] +lux_listing_mapping ('listing', 'lux_listing') instant_plus_non_referred_bookings_pct ['JOINED', 'METRIC', 'MULTI_HOP'] +lux_listing_mapping ('listing', 'lux_listing') largest_listing ['JOINED', 'METRIC', 'MULTI_HOP'] +lux_listing_mapping ('listing', 'lux_listing') listings ['JOINED', 'METRIC', 'MULTI_HOP'] +lux_listing_mapping ('listing', 'lux_listing') lux_booking_fraction_of_max_value ['JOINED', 'METRIC', 'MULTI_HOP'] +lux_listing_mapping ('listing', 'lux_listing') lux_booking_value_rate_expr ['JOINED', 'METRIC', 'MULTI_HOP'] +lux_listing_mapping ('listing', 'lux_listing') lux_listings ['JOINED', 'METRIC', 'MULTI_HOP'] +lux_listing_mapping ('listing', 'lux_listing') max_booking_value ['JOINED', 'METRIC', 'MULTI_HOP'] +lux_listing_mapping ('listing', 'lux_listing') median_booking_value ['JOINED', 'METRIC', 'MULTI_HOP'] +lux_listing_mapping ('listing', 'lux_listing') min_booking_value ['JOINED', 'METRIC', 'MULTI_HOP'] +lux_listing_mapping ('listing', 'lux_listing') nested_fill_nulls_without_time_spine ['JOINED', 'METRIC', 'MULTI_HOP'] +lux_listing_mapping ('listing', 'lux_listing') non_referred_bookings_pct ['JOINED', 'METRIC', 'MULTI_HOP'] +lux_listing_mapping ('listing', 'lux_listing') referred_bookings ['JOINED', 'METRIC', 'MULTI_HOP'] +lux_listing_mapping ('listing', 'lux_listing') smallest_listing ['JOINED', 'METRIC', 'MULTI_HOP'] +lux_listing_mapping ('listing', 'lux_listing') twice_bookings_fill_nulls_with_0_without_time_spine ['JOINED', 'METRIC', 'MULTI_HOP'] +lux_listing_mapping ('listing', 'lux_listing') views ['JOINED', 'METRIC', 'MULTI_HOP'] +lux_listing_mapping ('listing', 'lux_listing') views_times_booking_value ['JOINED', 'METRIC', 'MULTI_HOP'] +users_ds_source ('user',) created_at DAY ['JOINED'] +users_ds_source ('user',) created_at DAY DAY ['JOINED'] +users_ds_source ('user',) created_at DAY DOW ['JOINED'] +users_ds_source ('user',) created_at DAY DOY ['JOINED'] +users_ds_source ('user',) created_at DAY MONTH ['JOINED'] +users_ds_source ('user',) created_at DAY QUARTER ['JOINED'] +users_ds_source ('user',) created_at DAY YEAR ['JOINED'] +users_ds_source ('user',) created_at MONTH ['DERIVED_TIME_GRANULARITY', 'JOINED'] +users_ds_source ('user',) created_at MONTH MONTH ['DERIVED_TIME_GRANULARITY', 'JOINED'] +users_ds_source ('user',) created_at MONTH QUARTER ['DERIVED_TIME_GRANULARITY', 'JOINED'] +users_ds_source ('user',) created_at MONTH YEAR ['DERIVED_TIME_GRANULARITY', 'JOINED'] +users_ds_source ('user',) created_at QUARTER ['DERIVED_TIME_GRANULARITY', 'JOINED'] +users_ds_source ('user',) created_at QUARTER QUARTER ['DERIVED_TIME_GRANULARITY', 'JOINED'] +users_ds_source ('user',) created_at QUARTER YEAR ['DERIVED_TIME_GRANULARITY', 'JOINED'] +users_ds_source ('user',) created_at WEEK ['DERIVED_TIME_GRANULARITY', 'JOINED'] +users_ds_source ('user',) created_at WEEK MONTH ['DERIVED_TIME_GRANULARITY', 'JOINED'] +users_ds_source ('user',) created_at WEEK QUARTER ['DERIVED_TIME_GRANULARITY', 'JOINED'] +users_ds_source ('user',) created_at WEEK YEAR ['DERIVED_TIME_GRANULARITY', 'JOINED'] +users_ds_source ('user',) created_at YEAR ['DERIVED_TIME_GRANULARITY', 'JOINED'] +users_ds_source ('user',) created_at YEAR YEAR ['DERIVED_TIME_GRANULARITY', 'JOINED'] +users_ds_source ('user',) ds DAY ['JOINED'] +users_ds_source ('user',) ds DAY DAY ['JOINED'] +users_ds_source ('user',) ds DAY DOW ['JOINED'] +users_ds_source ('user',) ds DAY DOY ['JOINED'] +users_ds_source ('user',) ds DAY MONTH ['JOINED'] +users_ds_source ('user',) ds DAY QUARTER ['JOINED'] +users_ds_source ('user',) ds DAY YEAR ['JOINED'] +users_ds_source ('user',) ds MONTH ['DERIVED_TIME_GRANULARITY', 'JOINED'] +users_ds_source ('user',) ds MONTH MONTH ['DERIVED_TIME_GRANULARITY', 'JOINED'] +users_ds_source ('user',) ds MONTH QUARTER ['DERIVED_TIME_GRANULARITY', 'JOINED'] +users_ds_source ('user',) ds MONTH YEAR ['DERIVED_TIME_GRANULARITY', 'JOINED'] +users_ds_source ('user',) ds QUARTER ['DERIVED_TIME_GRANULARITY', 'JOINED'] +users_ds_source ('user',) ds QUARTER QUARTER ['DERIVED_TIME_GRANULARITY', 'JOINED'] +users_ds_source ('user',) ds QUARTER YEAR ['DERIVED_TIME_GRANULARITY', 'JOINED'] +users_ds_source ('user',) ds WEEK ['DERIVED_TIME_GRANULARITY', 'JOINED'] +users_ds_source ('user',) ds WEEK MONTH ['DERIVED_TIME_GRANULARITY', 'JOINED'] +users_ds_source ('user',) ds WEEK QUARTER ['DERIVED_TIME_GRANULARITY', 'JOINED'] +users_ds_source ('user',) ds WEEK YEAR ['DERIVED_TIME_GRANULARITY', 'JOINED'] +users_ds_source ('user',) ds YEAR ['DERIVED_TIME_GRANULARITY', 'JOINED'] +users_ds_source ('user',) ds YEAR YEAR ['DERIVED_TIME_GRANULARITY', 'JOINED'] +users_ds_source ('user',) ds_partitioned DAY ['JOINED'] +users_ds_source ('user',) ds_partitioned DAY DAY ['JOINED'] +users_ds_source ('user',) ds_partitioned DAY DOW ['JOINED'] +users_ds_source ('user',) ds_partitioned DAY DOY ['JOINED'] +users_ds_source ('user',) ds_partitioned DAY MONTH ['JOINED'] +users_ds_source ('user',) ds_partitioned DAY QUARTER ['JOINED'] +users_ds_source ('user',) ds_partitioned DAY YEAR ['JOINED'] +users_ds_source ('user',) ds_partitioned MONTH ['DERIVED_TIME_GRANULARITY', 'JOINED'] +users_ds_source ('user',) ds_partitioned MONTH MONTH ['DERIVED_TIME_GRANULARITY', 'JOINED'] +users_ds_source ('user',) ds_partitioned MONTH QUARTER ['DERIVED_TIME_GRANULARITY', 'JOINED'] +users_ds_source ('user',) ds_partitioned MONTH YEAR ['DERIVED_TIME_GRANULARITY', 'JOINED'] +users_ds_source ('user',) ds_partitioned QUARTER ['DERIVED_TIME_GRANULARITY', 'JOINED'] +users_ds_source ('user',) ds_partitioned QUARTER QUARTER ['DERIVED_TIME_GRANULARITY', 'JOINED'] +users_ds_source ('user',) ds_partitioned QUARTER YEAR ['DERIVED_TIME_GRANULARITY', 'JOINED'] +users_ds_source ('user',) ds_partitioned WEEK ['DERIVED_TIME_GRANULARITY', 'JOINED'] +users_ds_source ('user',) ds_partitioned WEEK MONTH ['DERIVED_TIME_GRANULARITY', 'JOINED'] +users_ds_source ('user',) ds_partitioned WEEK QUARTER ['DERIVED_TIME_GRANULARITY', 'JOINED'] +users_ds_source ('user',) ds_partitioned WEEK YEAR ['DERIVED_TIME_GRANULARITY', 'JOINED'] +users_ds_source ('user',) ds_partitioned YEAR ['DERIVED_TIME_GRANULARITY', 'JOINED'] +users_ds_source ('user',) ds_partitioned YEAR YEAR ['DERIVED_TIME_GRANULARITY', 'JOINED'] +users_ds_source ('user',) home_state ['JOINED'] +users_latest ('user',) ds_latest DAY ['JOINED'] +users_latest ('user',) ds_latest DAY DAY ['JOINED'] +users_latest ('user',) ds_latest DAY DOW ['JOINED'] +users_latest ('user',) ds_latest DAY DOY ['JOINED'] +users_latest ('user',) ds_latest DAY MONTH ['JOINED'] +users_latest ('user',) ds_latest DAY QUARTER ['JOINED'] +users_latest ('user',) ds_latest DAY YEAR ['JOINED'] +users_latest ('user',) ds_latest MONTH ['DERIVED_TIME_GRANULARITY', 'JOINED'] +users_latest ('user',) ds_latest MONTH MONTH ['DERIVED_TIME_GRANULARITY', 'JOINED'] +users_latest ('user',) ds_latest MONTH QUARTER ['DERIVED_TIME_GRANULARITY', 'JOINED'] +users_latest ('user',) ds_latest MONTH YEAR ['DERIVED_TIME_GRANULARITY', 'JOINED'] +users_latest ('user',) ds_latest QUARTER ['DERIVED_TIME_GRANULARITY', 'JOINED'] +users_latest ('user',) ds_latest QUARTER QUARTER ['DERIVED_TIME_GRANULARITY', 'JOINED'] +users_latest ('user',) ds_latest QUARTER YEAR ['DERIVED_TIME_GRANULARITY', 'JOINED'] +users_latest ('user',) ds_latest WEEK ['DERIVED_TIME_GRANULARITY', 'JOINED'] +users_latest ('user',) ds_latest WEEK MONTH ['DERIVED_TIME_GRANULARITY', 'JOINED'] +users_latest ('user',) ds_latest WEEK QUARTER ['DERIVED_TIME_GRANULARITY', 'JOINED'] +users_latest ('user',) ds_latest WEEK YEAR ['DERIVED_TIME_GRANULARITY', 'JOINED'] +users_latest ('user',) ds_latest YEAR ['DERIVED_TIME_GRANULARITY', 'JOINED'] +users_latest ('user',) ds_latest YEAR YEAR ['DERIVED_TIME_GRANULARITY', 'JOINED'] +users_latest ('user',) home_state_latest ['JOINED'] diff --git a/tests/snapshots/test_semantic_model_container.py/tuple/test_linkable_elements_for_no_metrics_query__result0.txt b/tests/snapshots/test_semantic_model_container.py/tuple/test_linkable_elements_for_no_metrics_query__result0.txt index 429571e7de..5e869224b7 100644 --- a/tests/snapshots/test_semantic_model_container.py/tuple/test_linkable_elements_for_no_metrics_query__result0.txt +++ b/tests/snapshots/test_semantic_model_container.py/tuple/test_linkable_elements_for_no_metrics_query__result0.txt @@ -134,7 +134,6 @@ 'guest__booking_value', 'guest__booking_value_for_non_null_listing_id', 'guest__booking_value_p99', - 'guest__booking_value_per_view', 'guest__booking_value_sub_instant', 'guest__booking_value_sub_instant_add_10', 'guest__bookings', @@ -152,9 +151,6 @@ 'guest__bookings_offset_twice', 'guest__bookings_per_booker', 'guest__bookings_per_dollar', - 'guest__bookings_per_listing', - 'guest__bookings_per_lux_listing_derived', - 'guest__bookings_per_view', 'guest__derived_bookings_0', 'guest__derived_bookings_1', 'guest__discrete_booking_value_p99', @@ -177,7 +173,6 @@ 'guest__non_referred_bookings_pct', 'guest__referred_bookings', 'guest__twice_bookings_fill_nulls_with_0_without_time_spine', - 'guest__views_times_booking_value', 'host', 'host__approximate_continuous_booking_value_p99', 'host__approximate_discrete_booking_value_p99', @@ -192,7 +187,6 @@ 'host__booking_value', 'host__booking_value_for_non_null_listing_id', 'host__booking_value_p99', - 'host__booking_value_per_view', 'host__booking_value_sub_instant', 'host__booking_value_sub_instant_add_10', 'host__bookings', @@ -210,9 +204,6 @@ 'host__bookings_offset_twice', 'host__bookings_per_booker', 'host__bookings_per_dollar', - 'host__bookings_per_listing', - 'host__bookings_per_lux_listing_derived', - 'host__bookings_per_view', 'host__derived_bookings_0', 'host__derived_bookings_1', 'host__discrete_booking_value_p99', @@ -235,7 +226,6 @@ 'host__non_referred_bookings_pct', 'host__referred_bookings', 'host__twice_bookings_fill_nulls_with_0_without_time_spine', - 'host__views_times_booking_value', 'listing', 'listing__active_listings', 'listing__approximate_continuous_booking_value_p99', From 4f4c45a9c5edcffc5719025da56ed21b465615c7 Mon Sep 17 00:00:00 2001 From: Courtney Holcomb Date: Thu, 18 Apr 2024 16:42:59 -0700 Subject: [PATCH 17/37] Add test with multi-hop join manifest --- tests/fixtures/manifest_fixtures.py | 8 +++ tests/model/test_semantic_model_container.py | 33 ++++++++++++ ...s_for_measure_multi_hop_model__result0.txt | 53 +++++++++++++++++++ 3 files changed, 94 insertions(+) create mode 100644 tests/snapshots/test_semantic_model_container.py/str/test_linkable_elements_for_measure_multi_hop_model__result0.txt diff --git a/tests/fixtures/manifest_fixtures.py b/tests/fixtures/manifest_fixtures.py index 28c04219d4..5e9285803d 100644 --- a/tests/fixtures/manifest_fixtures.py +++ b/tests/fixtures/manifest_fixtures.py @@ -294,6 +294,14 @@ def simple_semantic_manifest( return mf_engine_test_fixture_mapping[SemanticManifestSetup.SIMPLE_MANIFEST].semantic_manifest +@pytest.fixture(scope="session") +def multi_hop_join_semantic_manifest( + mf_engine_test_fixture_mapping: Mapping[SemanticManifestSetup, MetricFlowEngineTestFixture] +) -> PydanticSemanticManifest: + """Model used for many tests.""" + return mf_engine_test_fixture_mapping[SemanticManifestSetup.MULTI_HOP_JOIN_MANIFEST].semantic_manifest + + @pytest.fixture(scope="session") def extended_date_semantic_manifest_lookup( # noqa: D103 mf_engine_test_fixture_mapping: Mapping[SemanticManifestSetup, MetricFlowEngineTestFixture] diff --git a/tests/model/test_semantic_model_container.py b/tests/model/test_semantic_model_container.py index 9f22fb3ac0..e372407f2e 100644 --- a/tests/model/test_semantic_model_container.py +++ b/tests/model/test_semantic_model_container.py @@ -23,6 +23,13 @@ def semantic_model_lookup(simple_semantic_manifest: SemanticManifest) -> Semanti ) +@pytest.fixture +def multi_hop_semantic_model_lookup( # noqa: D103 + multi_hop_join_semantic_manifest: SemanticManifest, +) -> SemanticModelLookup: + return SemanticModelLookup(model=multi_hop_join_semantic_manifest) + + @pytest.fixture def metric_lookup( # noqa: D103 simple_semantic_manifest: SemanticManifest, semantic_model_lookup: SemanticModelLookup @@ -30,6 +37,16 @@ def metric_lookup( # noqa: D103 return MetricLookup(semantic_manifest=simple_semantic_manifest, semantic_model_lookup=semantic_model_lookup) +@pytest.fixture +def multi_hop_metric_lookup( # noqa: D103 + multi_hop_join_semantic_manifest: SemanticManifest, multi_hop_semantic_model_lookup: SemanticModelLookup +) -> MetricLookup: + return MetricLookup( + semantic_manifest=multi_hop_join_semantic_manifest, + semantic_model_lookup=multi_hop_semantic_model_lookup, + ) + + def test_get_names( # noqa: D103 request: FixtureRequest, mf_test_configuration: MetricFlowTestConfiguration, @@ -127,6 +144,22 @@ def test_linkable_elements_for_measure( ) +def test_linkable_elements_for_measure_multi_hop_model( + request: FixtureRequest, + mf_test_configuration: MetricFlowTestConfiguration, + multi_hop_metric_lookup: MetricLookup, +) -> None: + """Tests extracting linkable elements for a given measure input.""" + assert_linkable_element_set_snapshot_equal( + request=request, + mf_test_configuration=mf_test_configuration, + set_id="result0", + linkable_element_set=multi_hop_metric_lookup.linkable_elements_for_measure( + measure_reference=MeasureReference(element_name="txn_count"), + ), + ) + + def test_linkable_elements_for_no_metrics_query( request: FixtureRequest, mf_test_configuration: MetricFlowTestConfiguration, diff --git a/tests/snapshots/test_semantic_model_container.py/str/test_linkable_elements_for_measure_multi_hop_model__result0.txt b/tests/snapshots/test_semantic_model_container.py/str/test_linkable_elements_for_measure_multi_hop_model__result0.txt new file mode 100644 index 0000000000..dd34b7cf9f --- /dev/null +++ b/tests/snapshots/test_semantic_model_container.py/str/test_linkable_elements_for_measure_multi_hop_model__result0.txt @@ -0,0 +1,53 @@ +Semantic Model Entity Links Name Time Granularity Date Part Properties +------------------- ------------------------------------------------------ ---------------------- ------------------ ----------- ------------------------------------------- + ('account_id',) txn_count ['JOINED', 'METRIC'] +account_month_txns () account_id ['ENTITY', 'LOCAL'] +account_month_txns () metric_time DAY ['METRIC_TIME'] +account_month_txns () metric_time DAY DAY ['DERIVED_TIME_GRANULARITY', 'METRIC_TIME'] +account_month_txns () metric_time DAY DOW ['DERIVED_TIME_GRANULARITY', 'METRIC_TIME'] +account_month_txns () metric_time DAY DOY ['DERIVED_TIME_GRANULARITY', 'METRIC_TIME'] +account_month_txns () metric_time DAY MONTH ['DERIVED_TIME_GRANULARITY', 'METRIC_TIME'] +account_month_txns () metric_time DAY QUARTER ['DERIVED_TIME_GRANULARITY', 'METRIC_TIME'] +account_month_txns () metric_time DAY YEAR ['DERIVED_TIME_GRANULARITY', 'METRIC_TIME'] +account_month_txns () metric_time MONTH ['DERIVED_TIME_GRANULARITY', 'METRIC_TIME'] +account_month_txns () metric_time MONTH MONTH ['DERIVED_TIME_GRANULARITY', 'METRIC_TIME'] +account_month_txns () metric_time MONTH QUARTER ['DERIVED_TIME_GRANULARITY', 'METRIC_TIME'] +account_month_txns () metric_time MONTH YEAR ['DERIVED_TIME_GRANULARITY', 'METRIC_TIME'] +account_month_txns () metric_time QUARTER ['DERIVED_TIME_GRANULARITY', 'METRIC_TIME'] +account_month_txns () metric_time QUARTER QUARTER ['DERIVED_TIME_GRANULARITY', 'METRIC_TIME'] +account_month_txns () metric_time QUARTER YEAR ['DERIVED_TIME_GRANULARITY', 'METRIC_TIME'] +account_month_txns () metric_time WEEK ['DERIVED_TIME_GRANULARITY', 'METRIC_TIME'] +account_month_txns () metric_time WEEK MONTH ['DERIVED_TIME_GRANULARITY', 'METRIC_TIME'] +account_month_txns () metric_time WEEK QUARTER ['DERIVED_TIME_GRANULARITY', 'METRIC_TIME'] +account_month_txns () metric_time WEEK YEAR ['DERIVED_TIME_GRANULARITY', 'METRIC_TIME'] +account_month_txns () metric_time YEAR ['DERIVED_TIME_GRANULARITY', 'METRIC_TIME'] +account_month_txns () metric_time YEAR YEAR ['DERIVED_TIME_GRANULARITY', 'METRIC_TIME'] +account_month_txns ('account_id',) account_month ['LOCAL'] +account_month_txns ('account_id',) ds DAY ['LOCAL'] +account_month_txns ('account_id',) ds DAY DAY ['LOCAL'] +account_month_txns ('account_id',) ds DAY DOW ['LOCAL'] +account_month_txns ('account_id',) ds DAY DOY ['LOCAL'] +account_month_txns ('account_id',) ds DAY MONTH ['LOCAL'] +account_month_txns ('account_id',) ds DAY QUARTER ['LOCAL'] +account_month_txns ('account_id',) ds DAY YEAR ['LOCAL'] +account_month_txns ('account_id',) ds MONTH ['DERIVED_TIME_GRANULARITY', 'LOCAL'] +account_month_txns ('account_id',) ds MONTH MONTH ['DERIVED_TIME_GRANULARITY', 'LOCAL'] +account_month_txns ('account_id',) ds MONTH QUARTER ['DERIVED_TIME_GRANULARITY', 'LOCAL'] +account_month_txns ('account_id',) ds MONTH YEAR ['DERIVED_TIME_GRANULARITY', 'LOCAL'] +account_month_txns ('account_id',) ds QUARTER ['DERIVED_TIME_GRANULARITY', 'LOCAL'] +account_month_txns ('account_id',) ds QUARTER QUARTER ['DERIVED_TIME_GRANULARITY', 'LOCAL'] +account_month_txns ('account_id',) ds QUARTER YEAR ['DERIVED_TIME_GRANULARITY', 'LOCAL'] +account_month_txns ('account_id',) ds WEEK ['DERIVED_TIME_GRANULARITY', 'LOCAL'] +account_month_txns ('account_id',) ds WEEK MONTH ['DERIVED_TIME_GRANULARITY', 'LOCAL'] +account_month_txns ('account_id',) ds WEEK QUARTER ['DERIVED_TIME_GRANULARITY', 'LOCAL'] +account_month_txns ('account_id',) ds WEEK YEAR ['DERIVED_TIME_GRANULARITY', 'LOCAL'] +account_month_txns ('account_id',) ds YEAR ['DERIVED_TIME_GRANULARITY', 'LOCAL'] +account_month_txns ('account_id',) ds YEAR YEAR ['DERIVED_TIME_GRANULARITY', 'LOCAL'] +bridge_table ('account_id',) customer_id ['ENTITY', 'JOINED'] +bridge_table ('account_id',) extra_dim ['JOINED'] +bridge_table ('account_id', 'customer_id') txn_count ['JOINED', 'METRIC', 'MULTI_HOP'] +customer_other_data ('account_id', 'customer_id') country ['JOINED', 'MULTI_HOP'] +customer_other_data ('account_id', 'customer_id') customer_third_hop_id ['ENTITY', 'JOINED', 'MULTI_HOP'] +customer_other_data ('account_id', 'customer_id', 'customer_third_hop_id') txn_count ['JOINED', 'METRIC', 'MULTI_HOP'] +customer_table ('account_id', 'customer_id') customer_atomic_weight ['JOINED', 'MULTI_HOP'] +customer_table ('account_id', 'customer_id') customer_name ['JOINED', 'MULTI_HOP'] From 054e26fbe2c9dd8882174f0e1f8ef8ec6a104244 Mon Sep 17 00:00:00 2001 From: Courtney Holcomb Date: Thu, 18 Apr 2024 16:48:35 -0700 Subject: [PATCH 18/37] Update documentation --- metricflow/model/semantics/linkable_spec_resolver.py | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/metricflow/model/semantics/linkable_spec_resolver.py b/metricflow/model/semantics/linkable_spec_resolver.py index 7cb75d28a2..d5e2cb8bbd 100644 --- a/metricflow/model/semantics/linkable_spec_resolver.py +++ b/metricflow/model/semantics/linkable_spec_resolver.py @@ -630,9 +630,12 @@ def _get_joinable_metrics_for_semantic_model( """Get the set of linkable metrics that can be joined to this semantic model.""" properties = frozenset({LinkableElementProperty.METRIC, LinkableElementProperty.JOINED}) if using_join_path: - assert ( - semantic_model.reference == using_join_path.last_semantic_model_reference - ), "Last join path element should match semantic model when building LinkableMetrics." + assert semantic_model.reference == using_join_path.last_semantic_model_reference, ( + "Last join path element should match semantic model when building LinkableMetrics. " + f"Got semantic model: {semantic_model.reference.semantic_model_name}; " + f"last join path element: {using_join_path.last_semantic_model_reference.semantic_model_name}", + ) + # TODO: confirm that this is what we internally consider multi-hop properties = properties.union(frozenset({LinkableElementProperty.MULTI_HOP})) path_key_to_linkable_metrics: Dict[ElementPathKey, Tuple[LinkableMetric, ...]] = {} @@ -657,6 +660,7 @@ def _get_elements_in_semantic_model(self, semantic_model: SemanticModel) -> Link """Gets the elements in the semantic model, without requiring any joins. Elements related to metric_time are handled separately in _get_metric_time_elements(). + Linkable metrics are not considered local to the semantic model since they always require a join. """ linkable_dimensions = [] linkable_entities = [] From c4487f448e9ed81ec1ed3242f6a780af3c1b2138 Mon Sep 17 00:00:00 2001 From: Courtney Holcomb Date: Mon, 22 Apr 2024 18:42:44 -0700 Subject: [PATCH 19/37] Update changelog to be more specific --- .changes/unreleased/Fixes-20240416-202600.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.changes/unreleased/Fixes-20240416-202600.yaml b/.changes/unreleased/Fixes-20240416-202600.yaml index 006c4b440c..4a6df9698a 100644 --- a/.changes/unreleased/Fixes-20240416-202600.yaml +++ b/.changes/unreleased/Fixes-20240416-202600.yaml @@ -1,5 +1,5 @@ kind: Fixes -body: Refactor group by resolution for group by metrics. +body: Refactor group by resolution for metric filters to allow options that were previously excluded inadvertently. time: 2024-04-16T20:26:00.637184-07:00 custom: Author: courtneyholcomb From 96408a8e218dbe69a993df7f7878adaf990af686 Mon Sep 17 00:00:00 2001 From: Courtney Holcomb Date: Mon, 22 Apr 2024 20:20:26 -0700 Subject: [PATCH 20/37] Add test for filtering by the same metric you're querying --- .../model/semantics/linkable_spec_resolver.py | 1 - .../test_metric_filter_rendering.py | 26 +- .../test_metric_filtered_by_itself__plan0.sql | 457 ++++++++++++++++++ ...ic_filtered_by_itself__plan0_optimized.sql | 39 ++ 4 files changed, 521 insertions(+), 2 deletions(-) create mode 100644 tests/snapshots/test_metric_filter_rendering.py/SqlQueryPlan/DuckDB/test_metric_filtered_by_itself__plan0.sql create mode 100644 tests/snapshots/test_metric_filter_rendering.py/SqlQueryPlan/DuckDB/test_metric_filtered_by_itself__plan0_optimized.sql diff --git a/metricflow/model/semantics/linkable_spec_resolver.py b/metricflow/model/semantics/linkable_spec_resolver.py index d5e2cb8bbd..cac65fd2e5 100644 --- a/metricflow/model/semantics/linkable_spec_resolver.py +++ b/metricflow/model/semantics/linkable_spec_resolver.py @@ -635,7 +635,6 @@ def _get_joinable_metrics_for_semantic_model( f"Got semantic model: {semantic_model.reference.semantic_model_name}; " f"last join path element: {using_join_path.last_semantic_model_reference.semantic_model_name}", ) - # TODO: confirm that this is what we internally consider multi-hop properties = properties.union(frozenset({LinkableElementProperty.MULTI_HOP})) path_key_to_linkable_metrics: Dict[ElementPathKey, Tuple[LinkableMetric, ...]] = {} diff --git a/tests/query_rendering/test_metric_filter_rendering.py b/tests/query_rendering/test_metric_filter_rendering.py index 9d1a14581e..d0594d2862 100644 --- a/tests/query_rendering/test_metric_filter_rendering.py +++ b/tests/query_rendering/test_metric_filter_rendering.py @@ -229,4 +229,28 @@ def test_distinct_values_query_with_metric_filter( ) -# TODO: tests for filters with conversion metrics +@pytest.mark.sql_engine_snapshot +def test_metric_filtered_by_itself( + request: FixtureRequest, + mf_test_configuration: MetricFlowTestConfiguration, + dataflow_plan_builder: DataflowPlanBuilder, + sql_client: SqlClient, + dataflow_to_sql_converter: DataflowToSqlQueryPlanConverter, + query_parser: MetricFlowQueryParser, +) -> None: + """Tests a query for a metric that filters by the same metric.""" + query_spec = query_parser.parse_and_validate_query( + metric_names=("bookers",), + where_constraint=PydanticWhereFilter( + where_sql_template="{{ Metric('bookers', ['guest']) }} > 1.00", + ), + ) + dataflow_plan = dataflow_plan_builder.build_plan(query_spec) + + convert_and_check( + request=request, + mf_test_configuration=mf_test_configuration, + dataflow_to_sql_converter=dataflow_to_sql_converter, + sql_client=sql_client, + node=dataflow_plan.sink_output_nodes[0].parent_node, + ) diff --git a/tests/snapshots/test_metric_filter_rendering.py/SqlQueryPlan/DuckDB/test_metric_filtered_by_itself__plan0.sql b/tests/snapshots/test_metric_filter_rendering.py/SqlQueryPlan/DuckDB/test_metric_filtered_by_itself__plan0.sql new file mode 100644 index 0000000000..09749c68b5 --- /dev/null +++ b/tests/snapshots/test_metric_filter_rendering.py/SqlQueryPlan/DuckDB/test_metric_filtered_by_itself__plan0.sql @@ -0,0 +1,457 @@ +-- Compute Metrics via Expressions +SELECT + subq_17.bookers +FROM ( + -- Aggregate Measures + SELECT + COUNT(DISTINCT subq_16.bookers) AS bookers + FROM ( + -- Pass Only Elements: ['bookers',] + SELECT + subq_15.bookers + FROM ( + -- Constrain Output with WHERE + SELECT + subq_14.guest__bookers + , subq_14.bookers + FROM ( + -- Pass Only Elements: ['bookers', 'guest__bookers'] + SELECT + subq_13.guest__bookers + , subq_13.bookers + FROM ( + -- Join Standard Outputs + SELECT + subq_6.guest AS guest + , subq_12.bookers AS guest__bookers + , subq_6.bookers AS bookers + FROM ( + -- Pass Only Elements: ['bookers', 'guest'] + SELECT + subq_5.guest + , subq_5.bookers + FROM ( + -- Metric Time Dimension 'ds' + SELECT + subq_4.ds__day + , subq_4.ds__week + , subq_4.ds__month + , subq_4.ds__quarter + , subq_4.ds__year + , subq_4.ds__extract_year + , subq_4.ds__extract_quarter + , subq_4.ds__extract_month + , subq_4.ds__extract_day + , subq_4.ds__extract_dow + , subq_4.ds__extract_doy + , subq_4.ds_partitioned__day + , subq_4.ds_partitioned__week + , subq_4.ds_partitioned__month + , subq_4.ds_partitioned__quarter + , subq_4.ds_partitioned__year + , subq_4.ds_partitioned__extract_year + , subq_4.ds_partitioned__extract_quarter + , subq_4.ds_partitioned__extract_month + , subq_4.ds_partitioned__extract_day + , subq_4.ds_partitioned__extract_dow + , subq_4.ds_partitioned__extract_doy + , subq_4.paid_at__day + , subq_4.paid_at__week + , subq_4.paid_at__month + , subq_4.paid_at__quarter + , subq_4.paid_at__year + , subq_4.paid_at__extract_year + , subq_4.paid_at__extract_quarter + , subq_4.paid_at__extract_month + , subq_4.paid_at__extract_day + , subq_4.paid_at__extract_dow + , subq_4.paid_at__extract_doy + , subq_4.booking__ds__day + , subq_4.booking__ds__week + , subq_4.booking__ds__month + , subq_4.booking__ds__quarter + , subq_4.booking__ds__year + , subq_4.booking__ds__extract_year + , subq_4.booking__ds__extract_quarter + , subq_4.booking__ds__extract_month + , subq_4.booking__ds__extract_day + , subq_4.booking__ds__extract_dow + , subq_4.booking__ds__extract_doy + , subq_4.booking__ds_partitioned__day + , subq_4.booking__ds_partitioned__week + , subq_4.booking__ds_partitioned__month + , subq_4.booking__ds_partitioned__quarter + , subq_4.booking__ds_partitioned__year + , subq_4.booking__ds_partitioned__extract_year + , subq_4.booking__ds_partitioned__extract_quarter + , subq_4.booking__ds_partitioned__extract_month + , subq_4.booking__ds_partitioned__extract_day + , subq_4.booking__ds_partitioned__extract_dow + , subq_4.booking__ds_partitioned__extract_doy + , subq_4.booking__paid_at__day + , subq_4.booking__paid_at__week + , subq_4.booking__paid_at__month + , subq_4.booking__paid_at__quarter + , subq_4.booking__paid_at__year + , subq_4.booking__paid_at__extract_year + , subq_4.booking__paid_at__extract_quarter + , subq_4.booking__paid_at__extract_month + , subq_4.booking__paid_at__extract_day + , subq_4.booking__paid_at__extract_dow + , subq_4.booking__paid_at__extract_doy + , subq_4.ds__day AS metric_time__day + , subq_4.ds__week AS metric_time__week + , subq_4.ds__month AS metric_time__month + , subq_4.ds__quarter AS metric_time__quarter + , subq_4.ds__year AS metric_time__year + , subq_4.ds__extract_year AS metric_time__extract_year + , subq_4.ds__extract_quarter AS metric_time__extract_quarter + , subq_4.ds__extract_month AS metric_time__extract_month + , subq_4.ds__extract_day AS metric_time__extract_day + , subq_4.ds__extract_dow AS metric_time__extract_dow + , subq_4.ds__extract_doy AS metric_time__extract_doy + , subq_4.listing + , subq_4.guest + , subq_4.host + , subq_4.booking__listing + , subq_4.booking__guest + , subq_4.booking__host + , subq_4.is_instant + , subq_4.booking__is_instant + , subq_4.bookings + , subq_4.instant_bookings + , subq_4.booking_value + , subq_4.max_booking_value + , subq_4.min_booking_value + , subq_4.bookers + , subq_4.average_booking_value + , subq_4.referred_bookings + , subq_4.median_booking_value + , subq_4.booking_value_p99 + , subq_4.discrete_booking_value_p99 + , subq_4.approximate_continuous_booking_value_p99 + , subq_4.approximate_discrete_booking_value_p99 + FROM ( + -- Read Elements From Semantic Model 'bookings_source' + SELECT + 1 AS bookings + , CASE WHEN is_instant THEN 1 ELSE 0 END AS instant_bookings + , bookings_source_src_28000.booking_value + , bookings_source_src_28000.booking_value AS max_booking_value + , bookings_source_src_28000.booking_value AS min_booking_value + , bookings_source_src_28000.guest_id AS bookers + , bookings_source_src_28000.booking_value AS average_booking_value + , bookings_source_src_28000.booking_value AS booking_payments + , CASE WHEN referrer_id IS NOT NULL THEN 1 ELSE 0 END AS referred_bookings + , bookings_source_src_28000.booking_value AS median_booking_value + , bookings_source_src_28000.booking_value AS booking_value_p99 + , bookings_source_src_28000.booking_value AS discrete_booking_value_p99 + , bookings_source_src_28000.booking_value AS approximate_continuous_booking_value_p99 + , bookings_source_src_28000.booking_value AS approximate_discrete_booking_value_p99 + , bookings_source_src_28000.is_instant + , DATE_TRUNC('day', bookings_source_src_28000.ds) AS ds__day + , DATE_TRUNC('week', bookings_source_src_28000.ds) AS ds__week + , DATE_TRUNC('month', bookings_source_src_28000.ds) AS ds__month + , DATE_TRUNC('quarter', bookings_source_src_28000.ds) AS ds__quarter + , DATE_TRUNC('year', bookings_source_src_28000.ds) AS ds__year + , EXTRACT(year FROM bookings_source_src_28000.ds) AS ds__extract_year + , EXTRACT(quarter FROM bookings_source_src_28000.ds) AS ds__extract_quarter + , EXTRACT(month FROM bookings_source_src_28000.ds) AS ds__extract_month + , EXTRACT(day FROM bookings_source_src_28000.ds) AS ds__extract_day + , EXTRACT(isodow FROM bookings_source_src_28000.ds) AS ds__extract_dow + , EXTRACT(doy FROM bookings_source_src_28000.ds) AS ds__extract_doy + , DATE_TRUNC('day', bookings_source_src_28000.ds_partitioned) AS ds_partitioned__day + , DATE_TRUNC('week', bookings_source_src_28000.ds_partitioned) AS ds_partitioned__week + , DATE_TRUNC('month', bookings_source_src_28000.ds_partitioned) AS ds_partitioned__month + , DATE_TRUNC('quarter', bookings_source_src_28000.ds_partitioned) AS ds_partitioned__quarter + , DATE_TRUNC('year', bookings_source_src_28000.ds_partitioned) AS ds_partitioned__year + , EXTRACT(year FROM bookings_source_src_28000.ds_partitioned) AS ds_partitioned__extract_year + , EXTRACT(quarter FROM bookings_source_src_28000.ds_partitioned) AS ds_partitioned__extract_quarter + , EXTRACT(month FROM bookings_source_src_28000.ds_partitioned) AS ds_partitioned__extract_month + , EXTRACT(day FROM bookings_source_src_28000.ds_partitioned) AS ds_partitioned__extract_day + , EXTRACT(isodow FROM bookings_source_src_28000.ds_partitioned) AS ds_partitioned__extract_dow + , EXTRACT(doy FROM bookings_source_src_28000.ds_partitioned) AS ds_partitioned__extract_doy + , DATE_TRUNC('day', bookings_source_src_28000.paid_at) AS paid_at__day + , DATE_TRUNC('week', bookings_source_src_28000.paid_at) AS paid_at__week + , DATE_TRUNC('month', bookings_source_src_28000.paid_at) AS paid_at__month + , DATE_TRUNC('quarter', bookings_source_src_28000.paid_at) AS paid_at__quarter + , DATE_TRUNC('year', bookings_source_src_28000.paid_at) AS paid_at__year + , EXTRACT(year FROM bookings_source_src_28000.paid_at) AS paid_at__extract_year + , EXTRACT(quarter FROM bookings_source_src_28000.paid_at) AS paid_at__extract_quarter + , EXTRACT(month FROM bookings_source_src_28000.paid_at) AS paid_at__extract_month + , EXTRACT(day FROM bookings_source_src_28000.paid_at) AS paid_at__extract_day + , EXTRACT(isodow FROM bookings_source_src_28000.paid_at) AS paid_at__extract_dow + , EXTRACT(doy FROM bookings_source_src_28000.paid_at) AS paid_at__extract_doy + , bookings_source_src_28000.is_instant AS booking__is_instant + , DATE_TRUNC('day', bookings_source_src_28000.ds) AS booking__ds__day + , DATE_TRUNC('week', bookings_source_src_28000.ds) AS booking__ds__week + , DATE_TRUNC('month', bookings_source_src_28000.ds) AS booking__ds__month + , DATE_TRUNC('quarter', bookings_source_src_28000.ds) AS booking__ds__quarter + , DATE_TRUNC('year', bookings_source_src_28000.ds) AS booking__ds__year + , EXTRACT(year FROM bookings_source_src_28000.ds) AS booking__ds__extract_year + , EXTRACT(quarter FROM bookings_source_src_28000.ds) AS booking__ds__extract_quarter + , EXTRACT(month FROM bookings_source_src_28000.ds) AS booking__ds__extract_month + , EXTRACT(day FROM bookings_source_src_28000.ds) AS booking__ds__extract_day + , EXTRACT(isodow FROM bookings_source_src_28000.ds) AS booking__ds__extract_dow + , EXTRACT(doy FROM bookings_source_src_28000.ds) AS booking__ds__extract_doy + , DATE_TRUNC('day', bookings_source_src_28000.ds_partitioned) AS booking__ds_partitioned__day + , DATE_TRUNC('week', bookings_source_src_28000.ds_partitioned) AS booking__ds_partitioned__week + , DATE_TRUNC('month', bookings_source_src_28000.ds_partitioned) AS booking__ds_partitioned__month + , DATE_TRUNC('quarter', bookings_source_src_28000.ds_partitioned) AS booking__ds_partitioned__quarter + , DATE_TRUNC('year', bookings_source_src_28000.ds_partitioned) AS booking__ds_partitioned__year + , EXTRACT(year FROM bookings_source_src_28000.ds_partitioned) AS booking__ds_partitioned__extract_year + , EXTRACT(quarter FROM bookings_source_src_28000.ds_partitioned) AS booking__ds_partitioned__extract_quarter + , EXTRACT(month FROM bookings_source_src_28000.ds_partitioned) AS booking__ds_partitioned__extract_month + , EXTRACT(day FROM bookings_source_src_28000.ds_partitioned) AS booking__ds_partitioned__extract_day + , EXTRACT(isodow FROM bookings_source_src_28000.ds_partitioned) AS booking__ds_partitioned__extract_dow + , EXTRACT(doy FROM bookings_source_src_28000.ds_partitioned) AS booking__ds_partitioned__extract_doy + , DATE_TRUNC('day', bookings_source_src_28000.paid_at) AS booking__paid_at__day + , DATE_TRUNC('week', bookings_source_src_28000.paid_at) AS booking__paid_at__week + , DATE_TRUNC('month', bookings_source_src_28000.paid_at) AS booking__paid_at__month + , DATE_TRUNC('quarter', bookings_source_src_28000.paid_at) AS booking__paid_at__quarter + , DATE_TRUNC('year', bookings_source_src_28000.paid_at) AS booking__paid_at__year + , EXTRACT(year FROM bookings_source_src_28000.paid_at) AS booking__paid_at__extract_year + , EXTRACT(quarter FROM bookings_source_src_28000.paid_at) AS booking__paid_at__extract_quarter + , EXTRACT(month FROM bookings_source_src_28000.paid_at) AS booking__paid_at__extract_month + , EXTRACT(day FROM bookings_source_src_28000.paid_at) AS booking__paid_at__extract_day + , EXTRACT(isodow FROM bookings_source_src_28000.paid_at) AS booking__paid_at__extract_dow + , EXTRACT(doy FROM bookings_source_src_28000.paid_at) AS booking__paid_at__extract_doy + , bookings_source_src_28000.listing_id AS listing + , bookings_source_src_28000.guest_id AS guest + , bookings_source_src_28000.host_id AS host + , bookings_source_src_28000.listing_id AS booking__listing + , bookings_source_src_28000.guest_id AS booking__guest + , bookings_source_src_28000.host_id AS booking__host + FROM ***************************.fct_bookings bookings_source_src_28000 + ) subq_4 + ) subq_5 + ) subq_6 + LEFT OUTER JOIN ( + -- Pass Only Elements: ['guest', 'bookers'] + SELECT + subq_11.guest + , subq_11.bookers + FROM ( + -- Compute Metrics via Expressions + SELECT + subq_10.guest + , subq_10.bookers + FROM ( + -- Aggregate Measures + SELECT + subq_9.guest + , COUNT(DISTINCT subq_9.bookers) AS bookers + FROM ( + -- Pass Only Elements: ['bookers', 'guest'] + SELECT + subq_8.guest + , subq_8.bookers + FROM ( + -- Metric Time Dimension 'ds' + SELECT + subq_7.ds__day + , subq_7.ds__week + , subq_7.ds__month + , subq_7.ds__quarter + , subq_7.ds__year + , subq_7.ds__extract_year + , subq_7.ds__extract_quarter + , subq_7.ds__extract_month + , subq_7.ds__extract_day + , subq_7.ds__extract_dow + , subq_7.ds__extract_doy + , subq_7.ds_partitioned__day + , subq_7.ds_partitioned__week + , subq_7.ds_partitioned__month + , subq_7.ds_partitioned__quarter + , subq_7.ds_partitioned__year + , subq_7.ds_partitioned__extract_year + , subq_7.ds_partitioned__extract_quarter + , subq_7.ds_partitioned__extract_month + , subq_7.ds_partitioned__extract_day + , subq_7.ds_partitioned__extract_dow + , subq_7.ds_partitioned__extract_doy + , subq_7.paid_at__day + , subq_7.paid_at__week + , subq_7.paid_at__month + , subq_7.paid_at__quarter + , subq_7.paid_at__year + , subq_7.paid_at__extract_year + , subq_7.paid_at__extract_quarter + , subq_7.paid_at__extract_month + , subq_7.paid_at__extract_day + , subq_7.paid_at__extract_dow + , subq_7.paid_at__extract_doy + , subq_7.booking__ds__day + , subq_7.booking__ds__week + , subq_7.booking__ds__month + , subq_7.booking__ds__quarter + , subq_7.booking__ds__year + , subq_7.booking__ds__extract_year + , subq_7.booking__ds__extract_quarter + , subq_7.booking__ds__extract_month + , subq_7.booking__ds__extract_day + , subq_7.booking__ds__extract_dow + , subq_7.booking__ds__extract_doy + , subq_7.booking__ds_partitioned__day + , subq_7.booking__ds_partitioned__week + , subq_7.booking__ds_partitioned__month + , subq_7.booking__ds_partitioned__quarter + , subq_7.booking__ds_partitioned__year + , subq_7.booking__ds_partitioned__extract_year + , subq_7.booking__ds_partitioned__extract_quarter + , subq_7.booking__ds_partitioned__extract_month + , subq_7.booking__ds_partitioned__extract_day + , subq_7.booking__ds_partitioned__extract_dow + , subq_7.booking__ds_partitioned__extract_doy + , subq_7.booking__paid_at__day + , subq_7.booking__paid_at__week + , subq_7.booking__paid_at__month + , subq_7.booking__paid_at__quarter + , subq_7.booking__paid_at__year + , subq_7.booking__paid_at__extract_year + , subq_7.booking__paid_at__extract_quarter + , subq_7.booking__paid_at__extract_month + , subq_7.booking__paid_at__extract_day + , subq_7.booking__paid_at__extract_dow + , subq_7.booking__paid_at__extract_doy + , subq_7.ds__day AS metric_time__day + , subq_7.ds__week AS metric_time__week + , subq_7.ds__month AS metric_time__month + , subq_7.ds__quarter AS metric_time__quarter + , subq_7.ds__year AS metric_time__year + , subq_7.ds__extract_year AS metric_time__extract_year + , subq_7.ds__extract_quarter AS metric_time__extract_quarter + , subq_7.ds__extract_month AS metric_time__extract_month + , subq_7.ds__extract_day AS metric_time__extract_day + , subq_7.ds__extract_dow AS metric_time__extract_dow + , subq_7.ds__extract_doy AS metric_time__extract_doy + , subq_7.listing + , subq_7.guest + , subq_7.host + , subq_7.booking__listing + , subq_7.booking__guest + , subq_7.booking__host + , subq_7.is_instant + , subq_7.booking__is_instant + , subq_7.bookings + , subq_7.instant_bookings + , subq_7.booking_value + , subq_7.max_booking_value + , subq_7.min_booking_value + , subq_7.bookers + , subq_7.average_booking_value + , subq_7.referred_bookings + , subq_7.median_booking_value + , subq_7.booking_value_p99 + , subq_7.discrete_booking_value_p99 + , subq_7.approximate_continuous_booking_value_p99 + , subq_7.approximate_discrete_booking_value_p99 + FROM ( + -- Read Elements From Semantic Model 'bookings_source' + SELECT + 1 AS bookings + , CASE WHEN is_instant THEN 1 ELSE 0 END AS instant_bookings + , bookings_source_src_28000.booking_value + , bookings_source_src_28000.booking_value AS max_booking_value + , bookings_source_src_28000.booking_value AS min_booking_value + , bookings_source_src_28000.guest_id AS bookers + , bookings_source_src_28000.booking_value AS average_booking_value + , bookings_source_src_28000.booking_value AS booking_payments + , CASE WHEN referrer_id IS NOT NULL THEN 1 ELSE 0 END AS referred_bookings + , bookings_source_src_28000.booking_value AS median_booking_value + , bookings_source_src_28000.booking_value AS booking_value_p99 + , bookings_source_src_28000.booking_value AS discrete_booking_value_p99 + , bookings_source_src_28000.booking_value AS approximate_continuous_booking_value_p99 + , bookings_source_src_28000.booking_value AS approximate_discrete_booking_value_p99 + , bookings_source_src_28000.is_instant + , DATE_TRUNC('day', bookings_source_src_28000.ds) AS ds__day + , DATE_TRUNC('week', bookings_source_src_28000.ds) AS ds__week + , DATE_TRUNC('month', bookings_source_src_28000.ds) AS ds__month + , DATE_TRUNC('quarter', bookings_source_src_28000.ds) AS ds__quarter + , DATE_TRUNC('year', bookings_source_src_28000.ds) AS ds__year + , EXTRACT(year FROM bookings_source_src_28000.ds) AS ds__extract_year + , EXTRACT(quarter FROM bookings_source_src_28000.ds) AS ds__extract_quarter + , EXTRACT(month FROM bookings_source_src_28000.ds) AS ds__extract_month + , EXTRACT(day FROM bookings_source_src_28000.ds) AS ds__extract_day + , EXTRACT(isodow FROM bookings_source_src_28000.ds) AS ds__extract_dow + , EXTRACT(doy FROM bookings_source_src_28000.ds) AS ds__extract_doy + , DATE_TRUNC('day', bookings_source_src_28000.ds_partitioned) AS ds_partitioned__day + , DATE_TRUNC('week', bookings_source_src_28000.ds_partitioned) AS ds_partitioned__week + , DATE_TRUNC('month', bookings_source_src_28000.ds_partitioned) AS ds_partitioned__month + , DATE_TRUNC('quarter', bookings_source_src_28000.ds_partitioned) AS ds_partitioned__quarter + , DATE_TRUNC('year', bookings_source_src_28000.ds_partitioned) AS ds_partitioned__year + , EXTRACT(year FROM bookings_source_src_28000.ds_partitioned) AS ds_partitioned__extract_year + , EXTRACT(quarter FROM bookings_source_src_28000.ds_partitioned) AS ds_partitioned__extract_quarter + , EXTRACT(month FROM bookings_source_src_28000.ds_partitioned) AS ds_partitioned__extract_month + , EXTRACT(day FROM bookings_source_src_28000.ds_partitioned) AS ds_partitioned__extract_day + , EXTRACT(isodow FROM bookings_source_src_28000.ds_partitioned) AS ds_partitioned__extract_dow + , EXTRACT(doy FROM bookings_source_src_28000.ds_partitioned) AS ds_partitioned__extract_doy + , DATE_TRUNC('day', bookings_source_src_28000.paid_at) AS paid_at__day + , DATE_TRUNC('week', bookings_source_src_28000.paid_at) AS paid_at__week + , DATE_TRUNC('month', bookings_source_src_28000.paid_at) AS paid_at__month + , DATE_TRUNC('quarter', bookings_source_src_28000.paid_at) AS paid_at__quarter + , DATE_TRUNC('year', bookings_source_src_28000.paid_at) AS paid_at__year + , EXTRACT(year FROM bookings_source_src_28000.paid_at) AS paid_at__extract_year + , EXTRACT(quarter FROM bookings_source_src_28000.paid_at) AS paid_at__extract_quarter + , EXTRACT(month FROM bookings_source_src_28000.paid_at) AS paid_at__extract_month + , EXTRACT(day FROM bookings_source_src_28000.paid_at) AS paid_at__extract_day + , EXTRACT(isodow FROM bookings_source_src_28000.paid_at) AS paid_at__extract_dow + , EXTRACT(doy FROM bookings_source_src_28000.paid_at) AS paid_at__extract_doy + , bookings_source_src_28000.is_instant AS booking__is_instant + , DATE_TRUNC('day', bookings_source_src_28000.ds) AS booking__ds__day + , DATE_TRUNC('week', bookings_source_src_28000.ds) AS booking__ds__week + , DATE_TRUNC('month', bookings_source_src_28000.ds) AS booking__ds__month + , DATE_TRUNC('quarter', bookings_source_src_28000.ds) AS booking__ds__quarter + , DATE_TRUNC('year', bookings_source_src_28000.ds) AS booking__ds__year + , EXTRACT(year FROM bookings_source_src_28000.ds) AS booking__ds__extract_year + , EXTRACT(quarter FROM bookings_source_src_28000.ds) AS booking__ds__extract_quarter + , EXTRACT(month FROM bookings_source_src_28000.ds) AS booking__ds__extract_month + , EXTRACT(day FROM bookings_source_src_28000.ds) AS booking__ds__extract_day + , EXTRACT(isodow FROM bookings_source_src_28000.ds) AS booking__ds__extract_dow + , EXTRACT(doy FROM bookings_source_src_28000.ds) AS booking__ds__extract_doy + , DATE_TRUNC('day', bookings_source_src_28000.ds_partitioned) AS booking__ds_partitioned__day + , DATE_TRUNC('week', bookings_source_src_28000.ds_partitioned) AS booking__ds_partitioned__week + , DATE_TRUNC('month', bookings_source_src_28000.ds_partitioned) AS booking__ds_partitioned__month + , DATE_TRUNC('quarter', bookings_source_src_28000.ds_partitioned) AS booking__ds_partitioned__quarter + , DATE_TRUNC('year', bookings_source_src_28000.ds_partitioned) AS booking__ds_partitioned__year + , EXTRACT(year FROM bookings_source_src_28000.ds_partitioned) AS booking__ds_partitioned__extract_year + , EXTRACT(quarter FROM bookings_source_src_28000.ds_partitioned) AS booking__ds_partitioned__extract_quarter + , EXTRACT(month FROM bookings_source_src_28000.ds_partitioned) AS booking__ds_partitioned__extract_month + , EXTRACT(day FROM bookings_source_src_28000.ds_partitioned) AS booking__ds_partitioned__extract_day + , EXTRACT(isodow FROM bookings_source_src_28000.ds_partitioned) AS booking__ds_partitioned__extract_dow + , EXTRACT(doy FROM bookings_source_src_28000.ds_partitioned) AS booking__ds_partitioned__extract_doy + , DATE_TRUNC('day', bookings_source_src_28000.paid_at) AS booking__paid_at__day + , DATE_TRUNC('week', bookings_source_src_28000.paid_at) AS booking__paid_at__week + , DATE_TRUNC('month', bookings_source_src_28000.paid_at) AS booking__paid_at__month + , DATE_TRUNC('quarter', bookings_source_src_28000.paid_at) AS booking__paid_at__quarter + , DATE_TRUNC('year', bookings_source_src_28000.paid_at) AS booking__paid_at__year + , EXTRACT(year FROM bookings_source_src_28000.paid_at) AS booking__paid_at__extract_year + , EXTRACT(quarter FROM bookings_source_src_28000.paid_at) AS booking__paid_at__extract_quarter + , EXTRACT(month FROM bookings_source_src_28000.paid_at) AS booking__paid_at__extract_month + , EXTRACT(day FROM bookings_source_src_28000.paid_at) AS booking__paid_at__extract_day + , EXTRACT(isodow FROM bookings_source_src_28000.paid_at) AS booking__paid_at__extract_dow + , EXTRACT(doy FROM bookings_source_src_28000.paid_at) AS booking__paid_at__extract_doy + , bookings_source_src_28000.listing_id AS listing + , bookings_source_src_28000.guest_id AS guest + , bookings_source_src_28000.host_id AS host + , bookings_source_src_28000.listing_id AS booking__listing + , bookings_source_src_28000.guest_id AS booking__guest + , bookings_source_src_28000.host_id AS booking__host + FROM ***************************.fct_bookings bookings_source_src_28000 + ) subq_7 + ) subq_8 + ) subq_9 + GROUP BY + subq_9.guest + ) subq_10 + ) subq_11 + ) subq_12 + ON + subq_6.guest = subq_12.guest + ) subq_13 + ) subq_14 + WHERE guest__bookers > 1.00 + ) subq_15 + ) subq_16 +) subq_17 diff --git a/tests/snapshots/test_metric_filter_rendering.py/SqlQueryPlan/DuckDB/test_metric_filtered_by_itself__plan0_optimized.sql b/tests/snapshots/test_metric_filter_rendering.py/SqlQueryPlan/DuckDB/test_metric_filtered_by_itself__plan0_optimized.sql new file mode 100644 index 0000000000..eb7a693290 --- /dev/null +++ b/tests/snapshots/test_metric_filter_rendering.py/SqlQueryPlan/DuckDB/test_metric_filtered_by_itself__plan0_optimized.sql @@ -0,0 +1,39 @@ +-- Constrain Output with WHERE +-- Pass Only Elements: ['bookers',] +-- Aggregate Measures +-- Compute Metrics via Expressions +SELECT + COUNT(DISTINCT bookers) AS bookers +FROM ( + -- Join Standard Outputs + -- Pass Only Elements: ['bookers', 'guest__bookers'] + SELECT + subq_26.bookers AS guest__bookers + , subq_20.bookers AS bookers + FROM ( + -- Read Elements From Semantic Model 'bookings_source' + -- Metric Time Dimension 'ds' + -- Pass Only Elements: ['bookers', 'guest'] + SELECT + guest_id AS guest + , guest_id AS bookers + FROM ***************************.fct_bookings bookings_source_src_28000 + ) subq_20 + LEFT OUTER JOIN ( + -- Read Elements From Semantic Model 'bookings_source' + -- Metric Time Dimension 'ds' + -- Pass Only Elements: ['bookers', 'guest'] + -- Aggregate Measures + -- Compute Metrics via Expressions + -- Pass Only Elements: ['guest', 'bookers'] + SELECT + guest_id AS guest + , COUNT(DISTINCT guest_id) AS bookers + FROM ***************************.fct_bookings bookings_source_src_28000 + GROUP BY + guest_id + ) subq_26 + ON + subq_20.guest = subq_26.guest +) subq_28 +WHERE guest__bookers > 1.00 From 468a7d9b81cc9cd8aa93f9d86cf115551a27334e Mon Sep 17 00:00:00 2001 From: Courtney Holcomb Date: Mon, 22 Apr 2024 20:43:01 -0700 Subject: [PATCH 21/37] Update SQL engine snapshots --- .../test_metric_filtered_by_itself__plan0.sql | 457 ++++++++++++++++++ ...ic_filtered_by_itself__plan0_optimized.sql | 39 ++ .../test_metric_filtered_by_itself__plan0.sql | 457 ++++++++++++++++++ ...ic_filtered_by_itself__plan0_optimized.sql | 39 ++ .../test_metric_filtered_by_itself__plan0.sql | 457 ++++++++++++++++++ ...ic_filtered_by_itself__plan0_optimized.sql | 39 ++ .../test_metric_filtered_by_itself__plan0.sql | 457 ++++++++++++++++++ ...ic_filtered_by_itself__plan0_optimized.sql | 39 ++ .../test_metric_filtered_by_itself__plan0.sql | 457 ++++++++++++++++++ ...ic_filtered_by_itself__plan0_optimized.sql | 39 ++ .../test_metric_filtered_by_itself__plan0.sql | 457 ++++++++++++++++++ ...ic_filtered_by_itself__plan0_optimized.sql | 39 ++ 12 files changed, 2976 insertions(+) create mode 100644 tests/snapshots/test_metric_filter_rendering.py/SqlQueryPlan/BigQuery/test_metric_filtered_by_itself__plan0.sql create mode 100644 tests/snapshots/test_metric_filter_rendering.py/SqlQueryPlan/BigQuery/test_metric_filtered_by_itself__plan0_optimized.sql create mode 100644 tests/snapshots/test_metric_filter_rendering.py/SqlQueryPlan/Databricks/test_metric_filtered_by_itself__plan0.sql create mode 100644 tests/snapshots/test_metric_filter_rendering.py/SqlQueryPlan/Databricks/test_metric_filtered_by_itself__plan0_optimized.sql create mode 100644 tests/snapshots/test_metric_filter_rendering.py/SqlQueryPlan/Postgres/test_metric_filtered_by_itself__plan0.sql create mode 100644 tests/snapshots/test_metric_filter_rendering.py/SqlQueryPlan/Postgres/test_metric_filtered_by_itself__plan0_optimized.sql create mode 100644 tests/snapshots/test_metric_filter_rendering.py/SqlQueryPlan/Redshift/test_metric_filtered_by_itself__plan0.sql create mode 100644 tests/snapshots/test_metric_filter_rendering.py/SqlQueryPlan/Redshift/test_metric_filtered_by_itself__plan0_optimized.sql create mode 100644 tests/snapshots/test_metric_filter_rendering.py/SqlQueryPlan/Snowflake/test_metric_filtered_by_itself__plan0.sql create mode 100644 tests/snapshots/test_metric_filter_rendering.py/SqlQueryPlan/Snowflake/test_metric_filtered_by_itself__plan0_optimized.sql create mode 100644 tests/snapshots/test_metric_filter_rendering.py/SqlQueryPlan/Trino/test_metric_filtered_by_itself__plan0.sql create mode 100644 tests/snapshots/test_metric_filter_rendering.py/SqlQueryPlan/Trino/test_metric_filtered_by_itself__plan0_optimized.sql diff --git a/tests/snapshots/test_metric_filter_rendering.py/SqlQueryPlan/BigQuery/test_metric_filtered_by_itself__plan0.sql b/tests/snapshots/test_metric_filter_rendering.py/SqlQueryPlan/BigQuery/test_metric_filtered_by_itself__plan0.sql new file mode 100644 index 0000000000..790b564b23 --- /dev/null +++ b/tests/snapshots/test_metric_filter_rendering.py/SqlQueryPlan/BigQuery/test_metric_filtered_by_itself__plan0.sql @@ -0,0 +1,457 @@ +-- Compute Metrics via Expressions +SELECT + subq_17.bookers +FROM ( + -- Aggregate Measures + SELECT + COUNT(DISTINCT subq_16.bookers) AS bookers + FROM ( + -- Pass Only Elements: ['bookers',] + SELECT + subq_15.bookers + FROM ( + -- Constrain Output with WHERE + SELECT + subq_14.guest__bookers + , subq_14.bookers + FROM ( + -- Pass Only Elements: ['bookers', 'guest__bookers'] + SELECT + subq_13.guest__bookers + , subq_13.bookers + FROM ( + -- Join Standard Outputs + SELECT + subq_6.guest AS guest + , subq_12.bookers AS guest__bookers + , subq_6.bookers AS bookers + FROM ( + -- Pass Only Elements: ['bookers', 'guest'] + SELECT + subq_5.guest + , subq_5.bookers + FROM ( + -- Metric Time Dimension 'ds' + SELECT + subq_4.ds__day + , subq_4.ds__week + , subq_4.ds__month + , subq_4.ds__quarter + , subq_4.ds__year + , subq_4.ds__extract_year + , subq_4.ds__extract_quarter + , subq_4.ds__extract_month + , subq_4.ds__extract_day + , subq_4.ds__extract_dow + , subq_4.ds__extract_doy + , subq_4.ds_partitioned__day + , subq_4.ds_partitioned__week + , subq_4.ds_partitioned__month + , subq_4.ds_partitioned__quarter + , subq_4.ds_partitioned__year + , subq_4.ds_partitioned__extract_year + , subq_4.ds_partitioned__extract_quarter + , subq_4.ds_partitioned__extract_month + , subq_4.ds_partitioned__extract_day + , subq_4.ds_partitioned__extract_dow + , subq_4.ds_partitioned__extract_doy + , subq_4.paid_at__day + , subq_4.paid_at__week + , subq_4.paid_at__month + , subq_4.paid_at__quarter + , subq_4.paid_at__year + , subq_4.paid_at__extract_year + , subq_4.paid_at__extract_quarter + , subq_4.paid_at__extract_month + , subq_4.paid_at__extract_day + , subq_4.paid_at__extract_dow + , subq_4.paid_at__extract_doy + , subq_4.booking__ds__day + , subq_4.booking__ds__week + , subq_4.booking__ds__month + , subq_4.booking__ds__quarter + , subq_4.booking__ds__year + , subq_4.booking__ds__extract_year + , subq_4.booking__ds__extract_quarter + , subq_4.booking__ds__extract_month + , subq_4.booking__ds__extract_day + , subq_4.booking__ds__extract_dow + , subq_4.booking__ds__extract_doy + , subq_4.booking__ds_partitioned__day + , subq_4.booking__ds_partitioned__week + , subq_4.booking__ds_partitioned__month + , subq_4.booking__ds_partitioned__quarter + , subq_4.booking__ds_partitioned__year + , subq_4.booking__ds_partitioned__extract_year + , subq_4.booking__ds_partitioned__extract_quarter + , subq_4.booking__ds_partitioned__extract_month + , subq_4.booking__ds_partitioned__extract_day + , subq_4.booking__ds_partitioned__extract_dow + , subq_4.booking__ds_partitioned__extract_doy + , subq_4.booking__paid_at__day + , subq_4.booking__paid_at__week + , subq_4.booking__paid_at__month + , subq_4.booking__paid_at__quarter + , subq_4.booking__paid_at__year + , subq_4.booking__paid_at__extract_year + , subq_4.booking__paid_at__extract_quarter + , subq_4.booking__paid_at__extract_month + , subq_4.booking__paid_at__extract_day + , subq_4.booking__paid_at__extract_dow + , subq_4.booking__paid_at__extract_doy + , subq_4.ds__day AS metric_time__day + , subq_4.ds__week AS metric_time__week + , subq_4.ds__month AS metric_time__month + , subq_4.ds__quarter AS metric_time__quarter + , subq_4.ds__year AS metric_time__year + , subq_4.ds__extract_year AS metric_time__extract_year + , subq_4.ds__extract_quarter AS metric_time__extract_quarter + , subq_4.ds__extract_month AS metric_time__extract_month + , subq_4.ds__extract_day AS metric_time__extract_day + , subq_4.ds__extract_dow AS metric_time__extract_dow + , subq_4.ds__extract_doy AS metric_time__extract_doy + , subq_4.listing + , subq_4.guest + , subq_4.host + , subq_4.booking__listing + , subq_4.booking__guest + , subq_4.booking__host + , subq_4.is_instant + , subq_4.booking__is_instant + , subq_4.bookings + , subq_4.instant_bookings + , subq_4.booking_value + , subq_4.max_booking_value + , subq_4.min_booking_value + , subq_4.bookers + , subq_4.average_booking_value + , subq_4.referred_bookings + , subq_4.median_booking_value + , subq_4.booking_value_p99 + , subq_4.discrete_booking_value_p99 + , subq_4.approximate_continuous_booking_value_p99 + , subq_4.approximate_discrete_booking_value_p99 + FROM ( + -- Read Elements From Semantic Model 'bookings_source' + SELECT + 1 AS bookings + , CASE WHEN is_instant THEN 1 ELSE 0 END AS instant_bookings + , bookings_source_src_28000.booking_value + , bookings_source_src_28000.booking_value AS max_booking_value + , bookings_source_src_28000.booking_value AS min_booking_value + , bookings_source_src_28000.guest_id AS bookers + , bookings_source_src_28000.booking_value AS average_booking_value + , bookings_source_src_28000.booking_value AS booking_payments + , CASE WHEN referrer_id IS NOT NULL THEN 1 ELSE 0 END AS referred_bookings + , bookings_source_src_28000.booking_value AS median_booking_value + , bookings_source_src_28000.booking_value AS booking_value_p99 + , bookings_source_src_28000.booking_value AS discrete_booking_value_p99 + , bookings_source_src_28000.booking_value AS approximate_continuous_booking_value_p99 + , bookings_source_src_28000.booking_value AS approximate_discrete_booking_value_p99 + , bookings_source_src_28000.is_instant + , DATE_TRUNC(bookings_source_src_28000.ds, day) AS ds__day + , DATE_TRUNC(bookings_source_src_28000.ds, isoweek) AS ds__week + , DATE_TRUNC(bookings_source_src_28000.ds, month) AS ds__month + , DATE_TRUNC(bookings_source_src_28000.ds, quarter) AS ds__quarter + , DATE_TRUNC(bookings_source_src_28000.ds, year) AS ds__year + , EXTRACT(year FROM bookings_source_src_28000.ds) AS ds__extract_year + , EXTRACT(quarter FROM bookings_source_src_28000.ds) AS ds__extract_quarter + , EXTRACT(month FROM bookings_source_src_28000.ds) AS ds__extract_month + , EXTRACT(day FROM bookings_source_src_28000.ds) AS ds__extract_day + , IF(EXTRACT(dayofweek FROM bookings_source_src_28000.ds) = 1, 7, EXTRACT(dayofweek FROM bookings_source_src_28000.ds) - 1) AS ds__extract_dow + , EXTRACT(dayofyear FROM bookings_source_src_28000.ds) AS ds__extract_doy + , DATE_TRUNC(bookings_source_src_28000.ds_partitioned, day) AS ds_partitioned__day + , DATE_TRUNC(bookings_source_src_28000.ds_partitioned, isoweek) AS ds_partitioned__week + , DATE_TRUNC(bookings_source_src_28000.ds_partitioned, month) AS ds_partitioned__month + , DATE_TRUNC(bookings_source_src_28000.ds_partitioned, quarter) AS ds_partitioned__quarter + , DATE_TRUNC(bookings_source_src_28000.ds_partitioned, year) AS ds_partitioned__year + , EXTRACT(year FROM bookings_source_src_28000.ds_partitioned) AS ds_partitioned__extract_year + , EXTRACT(quarter FROM bookings_source_src_28000.ds_partitioned) AS ds_partitioned__extract_quarter + , EXTRACT(month FROM bookings_source_src_28000.ds_partitioned) AS ds_partitioned__extract_month + , EXTRACT(day FROM bookings_source_src_28000.ds_partitioned) AS ds_partitioned__extract_day + , IF(EXTRACT(dayofweek FROM bookings_source_src_28000.ds_partitioned) = 1, 7, EXTRACT(dayofweek FROM bookings_source_src_28000.ds_partitioned) - 1) AS ds_partitioned__extract_dow + , EXTRACT(dayofyear FROM bookings_source_src_28000.ds_partitioned) AS ds_partitioned__extract_doy + , DATE_TRUNC(bookings_source_src_28000.paid_at, day) AS paid_at__day + , DATE_TRUNC(bookings_source_src_28000.paid_at, isoweek) AS paid_at__week + , DATE_TRUNC(bookings_source_src_28000.paid_at, month) AS paid_at__month + , DATE_TRUNC(bookings_source_src_28000.paid_at, quarter) AS paid_at__quarter + , DATE_TRUNC(bookings_source_src_28000.paid_at, year) AS paid_at__year + , EXTRACT(year FROM bookings_source_src_28000.paid_at) AS paid_at__extract_year + , EXTRACT(quarter FROM bookings_source_src_28000.paid_at) AS paid_at__extract_quarter + , EXTRACT(month FROM bookings_source_src_28000.paid_at) AS paid_at__extract_month + , EXTRACT(day FROM bookings_source_src_28000.paid_at) AS paid_at__extract_day + , IF(EXTRACT(dayofweek FROM bookings_source_src_28000.paid_at) = 1, 7, EXTRACT(dayofweek FROM bookings_source_src_28000.paid_at) - 1) AS paid_at__extract_dow + , EXTRACT(dayofyear FROM bookings_source_src_28000.paid_at) AS paid_at__extract_doy + , bookings_source_src_28000.is_instant AS booking__is_instant + , DATE_TRUNC(bookings_source_src_28000.ds, day) AS booking__ds__day + , DATE_TRUNC(bookings_source_src_28000.ds, isoweek) AS booking__ds__week + , DATE_TRUNC(bookings_source_src_28000.ds, month) AS booking__ds__month + , DATE_TRUNC(bookings_source_src_28000.ds, quarter) AS booking__ds__quarter + , DATE_TRUNC(bookings_source_src_28000.ds, year) AS booking__ds__year + , EXTRACT(year FROM bookings_source_src_28000.ds) AS booking__ds__extract_year + , EXTRACT(quarter FROM bookings_source_src_28000.ds) AS booking__ds__extract_quarter + , EXTRACT(month FROM bookings_source_src_28000.ds) AS booking__ds__extract_month + , EXTRACT(day FROM bookings_source_src_28000.ds) AS booking__ds__extract_day + , IF(EXTRACT(dayofweek FROM bookings_source_src_28000.ds) = 1, 7, EXTRACT(dayofweek FROM bookings_source_src_28000.ds) - 1) AS booking__ds__extract_dow + , EXTRACT(dayofyear FROM bookings_source_src_28000.ds) AS booking__ds__extract_doy + , DATE_TRUNC(bookings_source_src_28000.ds_partitioned, day) AS booking__ds_partitioned__day + , DATE_TRUNC(bookings_source_src_28000.ds_partitioned, isoweek) AS booking__ds_partitioned__week + , DATE_TRUNC(bookings_source_src_28000.ds_partitioned, month) AS booking__ds_partitioned__month + , DATE_TRUNC(bookings_source_src_28000.ds_partitioned, quarter) AS booking__ds_partitioned__quarter + , DATE_TRUNC(bookings_source_src_28000.ds_partitioned, year) AS booking__ds_partitioned__year + , EXTRACT(year FROM bookings_source_src_28000.ds_partitioned) AS booking__ds_partitioned__extract_year + , EXTRACT(quarter FROM bookings_source_src_28000.ds_partitioned) AS booking__ds_partitioned__extract_quarter + , EXTRACT(month FROM bookings_source_src_28000.ds_partitioned) AS booking__ds_partitioned__extract_month + , EXTRACT(day FROM bookings_source_src_28000.ds_partitioned) AS booking__ds_partitioned__extract_day + , IF(EXTRACT(dayofweek FROM bookings_source_src_28000.ds_partitioned) = 1, 7, EXTRACT(dayofweek FROM bookings_source_src_28000.ds_partitioned) - 1) AS booking__ds_partitioned__extract_dow + , EXTRACT(dayofyear FROM bookings_source_src_28000.ds_partitioned) AS booking__ds_partitioned__extract_doy + , DATE_TRUNC(bookings_source_src_28000.paid_at, day) AS booking__paid_at__day + , DATE_TRUNC(bookings_source_src_28000.paid_at, isoweek) AS booking__paid_at__week + , DATE_TRUNC(bookings_source_src_28000.paid_at, month) AS booking__paid_at__month + , DATE_TRUNC(bookings_source_src_28000.paid_at, quarter) AS booking__paid_at__quarter + , DATE_TRUNC(bookings_source_src_28000.paid_at, year) AS booking__paid_at__year + , EXTRACT(year FROM bookings_source_src_28000.paid_at) AS booking__paid_at__extract_year + , EXTRACT(quarter FROM bookings_source_src_28000.paid_at) AS booking__paid_at__extract_quarter + , EXTRACT(month FROM bookings_source_src_28000.paid_at) AS booking__paid_at__extract_month + , EXTRACT(day FROM bookings_source_src_28000.paid_at) AS booking__paid_at__extract_day + , IF(EXTRACT(dayofweek FROM bookings_source_src_28000.paid_at) = 1, 7, EXTRACT(dayofweek FROM bookings_source_src_28000.paid_at) - 1) AS booking__paid_at__extract_dow + , EXTRACT(dayofyear FROM bookings_source_src_28000.paid_at) AS booking__paid_at__extract_doy + , bookings_source_src_28000.listing_id AS listing + , bookings_source_src_28000.guest_id AS guest + , bookings_source_src_28000.host_id AS host + , bookings_source_src_28000.listing_id AS booking__listing + , bookings_source_src_28000.guest_id AS booking__guest + , bookings_source_src_28000.host_id AS booking__host + FROM ***************************.fct_bookings bookings_source_src_28000 + ) subq_4 + ) subq_5 + ) subq_6 + LEFT OUTER JOIN ( + -- Pass Only Elements: ['guest', 'bookers'] + SELECT + subq_11.guest + , subq_11.bookers + FROM ( + -- Compute Metrics via Expressions + SELECT + subq_10.guest + , subq_10.bookers + FROM ( + -- Aggregate Measures + SELECT + subq_9.guest + , COUNT(DISTINCT subq_9.bookers) AS bookers + FROM ( + -- Pass Only Elements: ['bookers', 'guest'] + SELECT + subq_8.guest + , subq_8.bookers + FROM ( + -- Metric Time Dimension 'ds' + SELECT + subq_7.ds__day + , subq_7.ds__week + , subq_7.ds__month + , subq_7.ds__quarter + , subq_7.ds__year + , subq_7.ds__extract_year + , subq_7.ds__extract_quarter + , subq_7.ds__extract_month + , subq_7.ds__extract_day + , subq_7.ds__extract_dow + , subq_7.ds__extract_doy + , subq_7.ds_partitioned__day + , subq_7.ds_partitioned__week + , subq_7.ds_partitioned__month + , subq_7.ds_partitioned__quarter + , subq_7.ds_partitioned__year + , subq_7.ds_partitioned__extract_year + , subq_7.ds_partitioned__extract_quarter + , subq_7.ds_partitioned__extract_month + , subq_7.ds_partitioned__extract_day + , subq_7.ds_partitioned__extract_dow + , subq_7.ds_partitioned__extract_doy + , subq_7.paid_at__day + , subq_7.paid_at__week + , subq_7.paid_at__month + , subq_7.paid_at__quarter + , subq_7.paid_at__year + , subq_7.paid_at__extract_year + , subq_7.paid_at__extract_quarter + , subq_7.paid_at__extract_month + , subq_7.paid_at__extract_day + , subq_7.paid_at__extract_dow + , subq_7.paid_at__extract_doy + , subq_7.booking__ds__day + , subq_7.booking__ds__week + , subq_7.booking__ds__month + , subq_7.booking__ds__quarter + , subq_7.booking__ds__year + , subq_7.booking__ds__extract_year + , subq_7.booking__ds__extract_quarter + , subq_7.booking__ds__extract_month + , subq_7.booking__ds__extract_day + , subq_7.booking__ds__extract_dow + , subq_7.booking__ds__extract_doy + , subq_7.booking__ds_partitioned__day + , subq_7.booking__ds_partitioned__week + , subq_7.booking__ds_partitioned__month + , subq_7.booking__ds_partitioned__quarter + , subq_7.booking__ds_partitioned__year + , subq_7.booking__ds_partitioned__extract_year + , subq_7.booking__ds_partitioned__extract_quarter + , subq_7.booking__ds_partitioned__extract_month + , subq_7.booking__ds_partitioned__extract_day + , subq_7.booking__ds_partitioned__extract_dow + , subq_7.booking__ds_partitioned__extract_doy + , subq_7.booking__paid_at__day + , subq_7.booking__paid_at__week + , subq_7.booking__paid_at__month + , subq_7.booking__paid_at__quarter + , subq_7.booking__paid_at__year + , subq_7.booking__paid_at__extract_year + , subq_7.booking__paid_at__extract_quarter + , subq_7.booking__paid_at__extract_month + , subq_7.booking__paid_at__extract_day + , subq_7.booking__paid_at__extract_dow + , subq_7.booking__paid_at__extract_doy + , subq_7.ds__day AS metric_time__day + , subq_7.ds__week AS metric_time__week + , subq_7.ds__month AS metric_time__month + , subq_7.ds__quarter AS metric_time__quarter + , subq_7.ds__year AS metric_time__year + , subq_7.ds__extract_year AS metric_time__extract_year + , subq_7.ds__extract_quarter AS metric_time__extract_quarter + , subq_7.ds__extract_month AS metric_time__extract_month + , subq_7.ds__extract_day AS metric_time__extract_day + , subq_7.ds__extract_dow AS metric_time__extract_dow + , subq_7.ds__extract_doy AS metric_time__extract_doy + , subq_7.listing + , subq_7.guest + , subq_7.host + , subq_7.booking__listing + , subq_7.booking__guest + , subq_7.booking__host + , subq_7.is_instant + , subq_7.booking__is_instant + , subq_7.bookings + , subq_7.instant_bookings + , subq_7.booking_value + , subq_7.max_booking_value + , subq_7.min_booking_value + , subq_7.bookers + , subq_7.average_booking_value + , subq_7.referred_bookings + , subq_7.median_booking_value + , subq_7.booking_value_p99 + , subq_7.discrete_booking_value_p99 + , subq_7.approximate_continuous_booking_value_p99 + , subq_7.approximate_discrete_booking_value_p99 + FROM ( + -- Read Elements From Semantic Model 'bookings_source' + SELECT + 1 AS bookings + , CASE WHEN is_instant THEN 1 ELSE 0 END AS instant_bookings + , bookings_source_src_28000.booking_value + , bookings_source_src_28000.booking_value AS max_booking_value + , bookings_source_src_28000.booking_value AS min_booking_value + , bookings_source_src_28000.guest_id AS bookers + , bookings_source_src_28000.booking_value AS average_booking_value + , bookings_source_src_28000.booking_value AS booking_payments + , CASE WHEN referrer_id IS NOT NULL THEN 1 ELSE 0 END AS referred_bookings + , bookings_source_src_28000.booking_value AS median_booking_value + , bookings_source_src_28000.booking_value AS booking_value_p99 + , bookings_source_src_28000.booking_value AS discrete_booking_value_p99 + , bookings_source_src_28000.booking_value AS approximate_continuous_booking_value_p99 + , bookings_source_src_28000.booking_value AS approximate_discrete_booking_value_p99 + , bookings_source_src_28000.is_instant + , DATE_TRUNC(bookings_source_src_28000.ds, day) AS ds__day + , DATE_TRUNC(bookings_source_src_28000.ds, isoweek) AS ds__week + , DATE_TRUNC(bookings_source_src_28000.ds, month) AS ds__month + , DATE_TRUNC(bookings_source_src_28000.ds, quarter) AS ds__quarter + , DATE_TRUNC(bookings_source_src_28000.ds, year) AS ds__year + , EXTRACT(year FROM bookings_source_src_28000.ds) AS ds__extract_year + , EXTRACT(quarter FROM bookings_source_src_28000.ds) AS ds__extract_quarter + , EXTRACT(month FROM bookings_source_src_28000.ds) AS ds__extract_month + , EXTRACT(day FROM bookings_source_src_28000.ds) AS ds__extract_day + , IF(EXTRACT(dayofweek FROM bookings_source_src_28000.ds) = 1, 7, EXTRACT(dayofweek FROM bookings_source_src_28000.ds) - 1) AS ds__extract_dow + , EXTRACT(dayofyear FROM bookings_source_src_28000.ds) AS ds__extract_doy + , DATE_TRUNC(bookings_source_src_28000.ds_partitioned, day) AS ds_partitioned__day + , DATE_TRUNC(bookings_source_src_28000.ds_partitioned, isoweek) AS ds_partitioned__week + , DATE_TRUNC(bookings_source_src_28000.ds_partitioned, month) AS ds_partitioned__month + , DATE_TRUNC(bookings_source_src_28000.ds_partitioned, quarter) AS ds_partitioned__quarter + , DATE_TRUNC(bookings_source_src_28000.ds_partitioned, year) AS ds_partitioned__year + , EXTRACT(year FROM bookings_source_src_28000.ds_partitioned) AS ds_partitioned__extract_year + , EXTRACT(quarter FROM bookings_source_src_28000.ds_partitioned) AS ds_partitioned__extract_quarter + , EXTRACT(month FROM bookings_source_src_28000.ds_partitioned) AS ds_partitioned__extract_month + , EXTRACT(day FROM bookings_source_src_28000.ds_partitioned) AS ds_partitioned__extract_day + , IF(EXTRACT(dayofweek FROM bookings_source_src_28000.ds_partitioned) = 1, 7, EXTRACT(dayofweek FROM bookings_source_src_28000.ds_partitioned) - 1) AS ds_partitioned__extract_dow + , EXTRACT(dayofyear FROM bookings_source_src_28000.ds_partitioned) AS ds_partitioned__extract_doy + , DATE_TRUNC(bookings_source_src_28000.paid_at, day) AS paid_at__day + , DATE_TRUNC(bookings_source_src_28000.paid_at, isoweek) AS paid_at__week + , DATE_TRUNC(bookings_source_src_28000.paid_at, month) AS paid_at__month + , DATE_TRUNC(bookings_source_src_28000.paid_at, quarter) AS paid_at__quarter + , DATE_TRUNC(bookings_source_src_28000.paid_at, year) AS paid_at__year + , EXTRACT(year FROM bookings_source_src_28000.paid_at) AS paid_at__extract_year + , EXTRACT(quarter FROM bookings_source_src_28000.paid_at) AS paid_at__extract_quarter + , EXTRACT(month FROM bookings_source_src_28000.paid_at) AS paid_at__extract_month + , EXTRACT(day FROM bookings_source_src_28000.paid_at) AS paid_at__extract_day + , IF(EXTRACT(dayofweek FROM bookings_source_src_28000.paid_at) = 1, 7, EXTRACT(dayofweek FROM bookings_source_src_28000.paid_at) - 1) AS paid_at__extract_dow + , EXTRACT(dayofyear FROM bookings_source_src_28000.paid_at) AS paid_at__extract_doy + , bookings_source_src_28000.is_instant AS booking__is_instant + , DATE_TRUNC(bookings_source_src_28000.ds, day) AS booking__ds__day + , DATE_TRUNC(bookings_source_src_28000.ds, isoweek) AS booking__ds__week + , DATE_TRUNC(bookings_source_src_28000.ds, month) AS booking__ds__month + , DATE_TRUNC(bookings_source_src_28000.ds, quarter) AS booking__ds__quarter + , DATE_TRUNC(bookings_source_src_28000.ds, year) AS booking__ds__year + , EXTRACT(year FROM bookings_source_src_28000.ds) AS booking__ds__extract_year + , EXTRACT(quarter FROM bookings_source_src_28000.ds) AS booking__ds__extract_quarter + , EXTRACT(month FROM bookings_source_src_28000.ds) AS booking__ds__extract_month + , EXTRACT(day FROM bookings_source_src_28000.ds) AS booking__ds__extract_day + , IF(EXTRACT(dayofweek FROM bookings_source_src_28000.ds) = 1, 7, EXTRACT(dayofweek FROM bookings_source_src_28000.ds) - 1) AS booking__ds__extract_dow + , EXTRACT(dayofyear FROM bookings_source_src_28000.ds) AS booking__ds__extract_doy + , DATE_TRUNC(bookings_source_src_28000.ds_partitioned, day) AS booking__ds_partitioned__day + , DATE_TRUNC(bookings_source_src_28000.ds_partitioned, isoweek) AS booking__ds_partitioned__week + , DATE_TRUNC(bookings_source_src_28000.ds_partitioned, month) AS booking__ds_partitioned__month + , DATE_TRUNC(bookings_source_src_28000.ds_partitioned, quarter) AS booking__ds_partitioned__quarter + , DATE_TRUNC(bookings_source_src_28000.ds_partitioned, year) AS booking__ds_partitioned__year + , EXTRACT(year FROM bookings_source_src_28000.ds_partitioned) AS booking__ds_partitioned__extract_year + , EXTRACT(quarter FROM bookings_source_src_28000.ds_partitioned) AS booking__ds_partitioned__extract_quarter + , EXTRACT(month FROM bookings_source_src_28000.ds_partitioned) AS booking__ds_partitioned__extract_month + , EXTRACT(day FROM bookings_source_src_28000.ds_partitioned) AS booking__ds_partitioned__extract_day + , IF(EXTRACT(dayofweek FROM bookings_source_src_28000.ds_partitioned) = 1, 7, EXTRACT(dayofweek FROM bookings_source_src_28000.ds_partitioned) - 1) AS booking__ds_partitioned__extract_dow + , EXTRACT(dayofyear FROM bookings_source_src_28000.ds_partitioned) AS booking__ds_partitioned__extract_doy + , DATE_TRUNC(bookings_source_src_28000.paid_at, day) AS booking__paid_at__day + , DATE_TRUNC(bookings_source_src_28000.paid_at, isoweek) AS booking__paid_at__week + , DATE_TRUNC(bookings_source_src_28000.paid_at, month) AS booking__paid_at__month + , DATE_TRUNC(bookings_source_src_28000.paid_at, quarter) AS booking__paid_at__quarter + , DATE_TRUNC(bookings_source_src_28000.paid_at, year) AS booking__paid_at__year + , EXTRACT(year FROM bookings_source_src_28000.paid_at) AS booking__paid_at__extract_year + , EXTRACT(quarter FROM bookings_source_src_28000.paid_at) AS booking__paid_at__extract_quarter + , EXTRACT(month FROM bookings_source_src_28000.paid_at) AS booking__paid_at__extract_month + , EXTRACT(day FROM bookings_source_src_28000.paid_at) AS booking__paid_at__extract_day + , IF(EXTRACT(dayofweek FROM bookings_source_src_28000.paid_at) = 1, 7, EXTRACT(dayofweek FROM bookings_source_src_28000.paid_at) - 1) AS booking__paid_at__extract_dow + , EXTRACT(dayofyear FROM bookings_source_src_28000.paid_at) AS booking__paid_at__extract_doy + , bookings_source_src_28000.listing_id AS listing + , bookings_source_src_28000.guest_id AS guest + , bookings_source_src_28000.host_id AS host + , bookings_source_src_28000.listing_id AS booking__listing + , bookings_source_src_28000.guest_id AS booking__guest + , bookings_source_src_28000.host_id AS booking__host + FROM ***************************.fct_bookings bookings_source_src_28000 + ) subq_7 + ) subq_8 + ) subq_9 + GROUP BY + guest + ) subq_10 + ) subq_11 + ) subq_12 + ON + subq_6.guest = subq_12.guest + ) subq_13 + ) subq_14 + WHERE guest__bookers > 1.00 + ) subq_15 + ) subq_16 +) subq_17 diff --git a/tests/snapshots/test_metric_filter_rendering.py/SqlQueryPlan/BigQuery/test_metric_filtered_by_itself__plan0_optimized.sql b/tests/snapshots/test_metric_filter_rendering.py/SqlQueryPlan/BigQuery/test_metric_filtered_by_itself__plan0_optimized.sql new file mode 100644 index 0000000000..647794bd7b --- /dev/null +++ b/tests/snapshots/test_metric_filter_rendering.py/SqlQueryPlan/BigQuery/test_metric_filtered_by_itself__plan0_optimized.sql @@ -0,0 +1,39 @@ +-- Constrain Output with WHERE +-- Pass Only Elements: ['bookers',] +-- Aggregate Measures +-- Compute Metrics via Expressions +SELECT + COUNT(DISTINCT bookers) AS bookers +FROM ( + -- Join Standard Outputs + -- Pass Only Elements: ['bookers', 'guest__bookers'] + SELECT + subq_26.bookers AS guest__bookers + , subq_20.bookers AS bookers + FROM ( + -- Read Elements From Semantic Model 'bookings_source' + -- Metric Time Dimension 'ds' + -- Pass Only Elements: ['bookers', 'guest'] + SELECT + guest_id AS guest + , guest_id AS bookers + FROM ***************************.fct_bookings bookings_source_src_28000 + ) subq_20 + LEFT OUTER JOIN ( + -- Read Elements From Semantic Model 'bookings_source' + -- Metric Time Dimension 'ds' + -- Pass Only Elements: ['bookers', 'guest'] + -- Aggregate Measures + -- Compute Metrics via Expressions + -- Pass Only Elements: ['guest', 'bookers'] + SELECT + guest_id AS guest + , COUNT(DISTINCT guest_id) AS bookers + FROM ***************************.fct_bookings bookings_source_src_28000 + GROUP BY + guest + ) subq_26 + ON + subq_20.guest = subq_26.guest +) subq_28 +WHERE guest__bookers > 1.00 diff --git a/tests/snapshots/test_metric_filter_rendering.py/SqlQueryPlan/Databricks/test_metric_filtered_by_itself__plan0.sql b/tests/snapshots/test_metric_filter_rendering.py/SqlQueryPlan/Databricks/test_metric_filtered_by_itself__plan0.sql new file mode 100644 index 0000000000..3577152657 --- /dev/null +++ b/tests/snapshots/test_metric_filter_rendering.py/SqlQueryPlan/Databricks/test_metric_filtered_by_itself__plan0.sql @@ -0,0 +1,457 @@ +-- Compute Metrics via Expressions +SELECT + subq_17.bookers +FROM ( + -- Aggregate Measures + SELECT + COUNT(DISTINCT subq_16.bookers) AS bookers + FROM ( + -- Pass Only Elements: ['bookers',] + SELECT + subq_15.bookers + FROM ( + -- Constrain Output with WHERE + SELECT + subq_14.guest__bookers + , subq_14.bookers + FROM ( + -- Pass Only Elements: ['bookers', 'guest__bookers'] + SELECT + subq_13.guest__bookers + , subq_13.bookers + FROM ( + -- Join Standard Outputs + SELECT + subq_6.guest AS guest + , subq_12.bookers AS guest__bookers + , subq_6.bookers AS bookers + FROM ( + -- Pass Only Elements: ['bookers', 'guest'] + SELECT + subq_5.guest + , subq_5.bookers + FROM ( + -- Metric Time Dimension 'ds' + SELECT + subq_4.ds__day + , subq_4.ds__week + , subq_4.ds__month + , subq_4.ds__quarter + , subq_4.ds__year + , subq_4.ds__extract_year + , subq_4.ds__extract_quarter + , subq_4.ds__extract_month + , subq_4.ds__extract_day + , subq_4.ds__extract_dow + , subq_4.ds__extract_doy + , subq_4.ds_partitioned__day + , subq_4.ds_partitioned__week + , subq_4.ds_partitioned__month + , subq_4.ds_partitioned__quarter + , subq_4.ds_partitioned__year + , subq_4.ds_partitioned__extract_year + , subq_4.ds_partitioned__extract_quarter + , subq_4.ds_partitioned__extract_month + , subq_4.ds_partitioned__extract_day + , subq_4.ds_partitioned__extract_dow + , subq_4.ds_partitioned__extract_doy + , subq_4.paid_at__day + , subq_4.paid_at__week + , subq_4.paid_at__month + , subq_4.paid_at__quarter + , subq_4.paid_at__year + , subq_4.paid_at__extract_year + , subq_4.paid_at__extract_quarter + , subq_4.paid_at__extract_month + , subq_4.paid_at__extract_day + , subq_4.paid_at__extract_dow + , subq_4.paid_at__extract_doy + , subq_4.booking__ds__day + , subq_4.booking__ds__week + , subq_4.booking__ds__month + , subq_4.booking__ds__quarter + , subq_4.booking__ds__year + , subq_4.booking__ds__extract_year + , subq_4.booking__ds__extract_quarter + , subq_4.booking__ds__extract_month + , subq_4.booking__ds__extract_day + , subq_4.booking__ds__extract_dow + , subq_4.booking__ds__extract_doy + , subq_4.booking__ds_partitioned__day + , subq_4.booking__ds_partitioned__week + , subq_4.booking__ds_partitioned__month + , subq_4.booking__ds_partitioned__quarter + , subq_4.booking__ds_partitioned__year + , subq_4.booking__ds_partitioned__extract_year + , subq_4.booking__ds_partitioned__extract_quarter + , subq_4.booking__ds_partitioned__extract_month + , subq_4.booking__ds_partitioned__extract_day + , subq_4.booking__ds_partitioned__extract_dow + , subq_4.booking__ds_partitioned__extract_doy + , subq_4.booking__paid_at__day + , subq_4.booking__paid_at__week + , subq_4.booking__paid_at__month + , subq_4.booking__paid_at__quarter + , subq_4.booking__paid_at__year + , subq_4.booking__paid_at__extract_year + , subq_4.booking__paid_at__extract_quarter + , subq_4.booking__paid_at__extract_month + , subq_4.booking__paid_at__extract_day + , subq_4.booking__paid_at__extract_dow + , subq_4.booking__paid_at__extract_doy + , subq_4.ds__day AS metric_time__day + , subq_4.ds__week AS metric_time__week + , subq_4.ds__month AS metric_time__month + , subq_4.ds__quarter AS metric_time__quarter + , subq_4.ds__year AS metric_time__year + , subq_4.ds__extract_year AS metric_time__extract_year + , subq_4.ds__extract_quarter AS metric_time__extract_quarter + , subq_4.ds__extract_month AS metric_time__extract_month + , subq_4.ds__extract_day AS metric_time__extract_day + , subq_4.ds__extract_dow AS metric_time__extract_dow + , subq_4.ds__extract_doy AS metric_time__extract_doy + , subq_4.listing + , subq_4.guest + , subq_4.host + , subq_4.booking__listing + , subq_4.booking__guest + , subq_4.booking__host + , subq_4.is_instant + , subq_4.booking__is_instant + , subq_4.bookings + , subq_4.instant_bookings + , subq_4.booking_value + , subq_4.max_booking_value + , subq_4.min_booking_value + , subq_4.bookers + , subq_4.average_booking_value + , subq_4.referred_bookings + , subq_4.median_booking_value + , subq_4.booking_value_p99 + , subq_4.discrete_booking_value_p99 + , subq_4.approximate_continuous_booking_value_p99 + , subq_4.approximate_discrete_booking_value_p99 + FROM ( + -- Read Elements From Semantic Model 'bookings_source' + SELECT + 1 AS bookings + , CASE WHEN is_instant THEN 1 ELSE 0 END AS instant_bookings + , bookings_source_src_28000.booking_value + , bookings_source_src_28000.booking_value AS max_booking_value + , bookings_source_src_28000.booking_value AS min_booking_value + , bookings_source_src_28000.guest_id AS bookers + , bookings_source_src_28000.booking_value AS average_booking_value + , bookings_source_src_28000.booking_value AS booking_payments + , CASE WHEN referrer_id IS NOT NULL THEN 1 ELSE 0 END AS referred_bookings + , bookings_source_src_28000.booking_value AS median_booking_value + , bookings_source_src_28000.booking_value AS booking_value_p99 + , bookings_source_src_28000.booking_value AS discrete_booking_value_p99 + , bookings_source_src_28000.booking_value AS approximate_continuous_booking_value_p99 + , bookings_source_src_28000.booking_value AS approximate_discrete_booking_value_p99 + , bookings_source_src_28000.is_instant + , DATE_TRUNC('day', bookings_source_src_28000.ds) AS ds__day + , DATE_TRUNC('week', bookings_source_src_28000.ds) AS ds__week + , DATE_TRUNC('month', bookings_source_src_28000.ds) AS ds__month + , DATE_TRUNC('quarter', bookings_source_src_28000.ds) AS ds__quarter + , DATE_TRUNC('year', bookings_source_src_28000.ds) AS ds__year + , EXTRACT(year FROM bookings_source_src_28000.ds) AS ds__extract_year + , EXTRACT(quarter FROM bookings_source_src_28000.ds) AS ds__extract_quarter + , EXTRACT(month FROM bookings_source_src_28000.ds) AS ds__extract_month + , EXTRACT(day FROM bookings_source_src_28000.ds) AS ds__extract_day + , EXTRACT(DAYOFWEEK_ISO FROM bookings_source_src_28000.ds) AS ds__extract_dow + , EXTRACT(doy FROM bookings_source_src_28000.ds) AS ds__extract_doy + , DATE_TRUNC('day', bookings_source_src_28000.ds_partitioned) AS ds_partitioned__day + , DATE_TRUNC('week', bookings_source_src_28000.ds_partitioned) AS ds_partitioned__week + , DATE_TRUNC('month', bookings_source_src_28000.ds_partitioned) AS ds_partitioned__month + , DATE_TRUNC('quarter', bookings_source_src_28000.ds_partitioned) AS ds_partitioned__quarter + , DATE_TRUNC('year', bookings_source_src_28000.ds_partitioned) AS ds_partitioned__year + , EXTRACT(year FROM bookings_source_src_28000.ds_partitioned) AS ds_partitioned__extract_year + , EXTRACT(quarter FROM bookings_source_src_28000.ds_partitioned) AS ds_partitioned__extract_quarter + , EXTRACT(month FROM bookings_source_src_28000.ds_partitioned) AS ds_partitioned__extract_month + , EXTRACT(day FROM bookings_source_src_28000.ds_partitioned) AS ds_partitioned__extract_day + , EXTRACT(DAYOFWEEK_ISO FROM bookings_source_src_28000.ds_partitioned) AS ds_partitioned__extract_dow + , EXTRACT(doy FROM bookings_source_src_28000.ds_partitioned) AS ds_partitioned__extract_doy + , DATE_TRUNC('day', bookings_source_src_28000.paid_at) AS paid_at__day + , DATE_TRUNC('week', bookings_source_src_28000.paid_at) AS paid_at__week + , DATE_TRUNC('month', bookings_source_src_28000.paid_at) AS paid_at__month + , DATE_TRUNC('quarter', bookings_source_src_28000.paid_at) AS paid_at__quarter + , DATE_TRUNC('year', bookings_source_src_28000.paid_at) AS paid_at__year + , EXTRACT(year FROM bookings_source_src_28000.paid_at) AS paid_at__extract_year + , EXTRACT(quarter FROM bookings_source_src_28000.paid_at) AS paid_at__extract_quarter + , EXTRACT(month FROM bookings_source_src_28000.paid_at) AS paid_at__extract_month + , EXTRACT(day FROM bookings_source_src_28000.paid_at) AS paid_at__extract_day + , EXTRACT(DAYOFWEEK_ISO FROM bookings_source_src_28000.paid_at) AS paid_at__extract_dow + , EXTRACT(doy FROM bookings_source_src_28000.paid_at) AS paid_at__extract_doy + , bookings_source_src_28000.is_instant AS booking__is_instant + , DATE_TRUNC('day', bookings_source_src_28000.ds) AS booking__ds__day + , DATE_TRUNC('week', bookings_source_src_28000.ds) AS booking__ds__week + , DATE_TRUNC('month', bookings_source_src_28000.ds) AS booking__ds__month + , DATE_TRUNC('quarter', bookings_source_src_28000.ds) AS booking__ds__quarter + , DATE_TRUNC('year', bookings_source_src_28000.ds) AS booking__ds__year + , EXTRACT(year FROM bookings_source_src_28000.ds) AS booking__ds__extract_year + , EXTRACT(quarter FROM bookings_source_src_28000.ds) AS booking__ds__extract_quarter + , EXTRACT(month FROM bookings_source_src_28000.ds) AS booking__ds__extract_month + , EXTRACT(day FROM bookings_source_src_28000.ds) AS booking__ds__extract_day + , EXTRACT(DAYOFWEEK_ISO FROM bookings_source_src_28000.ds) AS booking__ds__extract_dow + , EXTRACT(doy FROM bookings_source_src_28000.ds) AS booking__ds__extract_doy + , DATE_TRUNC('day', bookings_source_src_28000.ds_partitioned) AS booking__ds_partitioned__day + , DATE_TRUNC('week', bookings_source_src_28000.ds_partitioned) AS booking__ds_partitioned__week + , DATE_TRUNC('month', bookings_source_src_28000.ds_partitioned) AS booking__ds_partitioned__month + , DATE_TRUNC('quarter', bookings_source_src_28000.ds_partitioned) AS booking__ds_partitioned__quarter + , DATE_TRUNC('year', bookings_source_src_28000.ds_partitioned) AS booking__ds_partitioned__year + , EXTRACT(year FROM bookings_source_src_28000.ds_partitioned) AS booking__ds_partitioned__extract_year + , EXTRACT(quarter FROM bookings_source_src_28000.ds_partitioned) AS booking__ds_partitioned__extract_quarter + , EXTRACT(month FROM bookings_source_src_28000.ds_partitioned) AS booking__ds_partitioned__extract_month + , EXTRACT(day FROM bookings_source_src_28000.ds_partitioned) AS booking__ds_partitioned__extract_day + , EXTRACT(DAYOFWEEK_ISO FROM bookings_source_src_28000.ds_partitioned) AS booking__ds_partitioned__extract_dow + , EXTRACT(doy FROM bookings_source_src_28000.ds_partitioned) AS booking__ds_partitioned__extract_doy + , DATE_TRUNC('day', bookings_source_src_28000.paid_at) AS booking__paid_at__day + , DATE_TRUNC('week', bookings_source_src_28000.paid_at) AS booking__paid_at__week + , DATE_TRUNC('month', bookings_source_src_28000.paid_at) AS booking__paid_at__month + , DATE_TRUNC('quarter', bookings_source_src_28000.paid_at) AS booking__paid_at__quarter + , DATE_TRUNC('year', bookings_source_src_28000.paid_at) AS booking__paid_at__year + , EXTRACT(year FROM bookings_source_src_28000.paid_at) AS booking__paid_at__extract_year + , EXTRACT(quarter FROM bookings_source_src_28000.paid_at) AS booking__paid_at__extract_quarter + , EXTRACT(month FROM bookings_source_src_28000.paid_at) AS booking__paid_at__extract_month + , EXTRACT(day FROM bookings_source_src_28000.paid_at) AS booking__paid_at__extract_day + , EXTRACT(DAYOFWEEK_ISO FROM bookings_source_src_28000.paid_at) AS booking__paid_at__extract_dow + , EXTRACT(doy FROM bookings_source_src_28000.paid_at) AS booking__paid_at__extract_doy + , bookings_source_src_28000.listing_id AS listing + , bookings_source_src_28000.guest_id AS guest + , bookings_source_src_28000.host_id AS host + , bookings_source_src_28000.listing_id AS booking__listing + , bookings_source_src_28000.guest_id AS booking__guest + , bookings_source_src_28000.host_id AS booking__host + FROM ***************************.fct_bookings bookings_source_src_28000 + ) subq_4 + ) subq_5 + ) subq_6 + LEFT OUTER JOIN ( + -- Pass Only Elements: ['guest', 'bookers'] + SELECT + subq_11.guest + , subq_11.bookers + FROM ( + -- Compute Metrics via Expressions + SELECT + subq_10.guest + , subq_10.bookers + FROM ( + -- Aggregate Measures + SELECT + subq_9.guest + , COUNT(DISTINCT subq_9.bookers) AS bookers + FROM ( + -- Pass Only Elements: ['bookers', 'guest'] + SELECT + subq_8.guest + , subq_8.bookers + FROM ( + -- Metric Time Dimension 'ds' + SELECT + subq_7.ds__day + , subq_7.ds__week + , subq_7.ds__month + , subq_7.ds__quarter + , subq_7.ds__year + , subq_7.ds__extract_year + , subq_7.ds__extract_quarter + , subq_7.ds__extract_month + , subq_7.ds__extract_day + , subq_7.ds__extract_dow + , subq_7.ds__extract_doy + , subq_7.ds_partitioned__day + , subq_7.ds_partitioned__week + , subq_7.ds_partitioned__month + , subq_7.ds_partitioned__quarter + , subq_7.ds_partitioned__year + , subq_7.ds_partitioned__extract_year + , subq_7.ds_partitioned__extract_quarter + , subq_7.ds_partitioned__extract_month + , subq_7.ds_partitioned__extract_day + , subq_7.ds_partitioned__extract_dow + , subq_7.ds_partitioned__extract_doy + , subq_7.paid_at__day + , subq_7.paid_at__week + , subq_7.paid_at__month + , subq_7.paid_at__quarter + , subq_7.paid_at__year + , subq_7.paid_at__extract_year + , subq_7.paid_at__extract_quarter + , subq_7.paid_at__extract_month + , subq_7.paid_at__extract_day + , subq_7.paid_at__extract_dow + , subq_7.paid_at__extract_doy + , subq_7.booking__ds__day + , subq_7.booking__ds__week + , subq_7.booking__ds__month + , subq_7.booking__ds__quarter + , subq_7.booking__ds__year + , subq_7.booking__ds__extract_year + , subq_7.booking__ds__extract_quarter + , subq_7.booking__ds__extract_month + , subq_7.booking__ds__extract_day + , subq_7.booking__ds__extract_dow + , subq_7.booking__ds__extract_doy + , subq_7.booking__ds_partitioned__day + , subq_7.booking__ds_partitioned__week + , subq_7.booking__ds_partitioned__month + , subq_7.booking__ds_partitioned__quarter + , subq_7.booking__ds_partitioned__year + , subq_7.booking__ds_partitioned__extract_year + , subq_7.booking__ds_partitioned__extract_quarter + , subq_7.booking__ds_partitioned__extract_month + , subq_7.booking__ds_partitioned__extract_day + , subq_7.booking__ds_partitioned__extract_dow + , subq_7.booking__ds_partitioned__extract_doy + , subq_7.booking__paid_at__day + , subq_7.booking__paid_at__week + , subq_7.booking__paid_at__month + , subq_7.booking__paid_at__quarter + , subq_7.booking__paid_at__year + , subq_7.booking__paid_at__extract_year + , subq_7.booking__paid_at__extract_quarter + , subq_7.booking__paid_at__extract_month + , subq_7.booking__paid_at__extract_day + , subq_7.booking__paid_at__extract_dow + , subq_7.booking__paid_at__extract_doy + , subq_7.ds__day AS metric_time__day + , subq_7.ds__week AS metric_time__week + , subq_7.ds__month AS metric_time__month + , subq_7.ds__quarter AS metric_time__quarter + , subq_7.ds__year AS metric_time__year + , subq_7.ds__extract_year AS metric_time__extract_year + , subq_7.ds__extract_quarter AS metric_time__extract_quarter + , subq_7.ds__extract_month AS metric_time__extract_month + , subq_7.ds__extract_day AS metric_time__extract_day + , subq_7.ds__extract_dow AS metric_time__extract_dow + , subq_7.ds__extract_doy AS metric_time__extract_doy + , subq_7.listing + , subq_7.guest + , subq_7.host + , subq_7.booking__listing + , subq_7.booking__guest + , subq_7.booking__host + , subq_7.is_instant + , subq_7.booking__is_instant + , subq_7.bookings + , subq_7.instant_bookings + , subq_7.booking_value + , subq_7.max_booking_value + , subq_7.min_booking_value + , subq_7.bookers + , subq_7.average_booking_value + , subq_7.referred_bookings + , subq_7.median_booking_value + , subq_7.booking_value_p99 + , subq_7.discrete_booking_value_p99 + , subq_7.approximate_continuous_booking_value_p99 + , subq_7.approximate_discrete_booking_value_p99 + FROM ( + -- Read Elements From Semantic Model 'bookings_source' + SELECT + 1 AS bookings + , CASE WHEN is_instant THEN 1 ELSE 0 END AS instant_bookings + , bookings_source_src_28000.booking_value + , bookings_source_src_28000.booking_value AS max_booking_value + , bookings_source_src_28000.booking_value AS min_booking_value + , bookings_source_src_28000.guest_id AS bookers + , bookings_source_src_28000.booking_value AS average_booking_value + , bookings_source_src_28000.booking_value AS booking_payments + , CASE WHEN referrer_id IS NOT NULL THEN 1 ELSE 0 END AS referred_bookings + , bookings_source_src_28000.booking_value AS median_booking_value + , bookings_source_src_28000.booking_value AS booking_value_p99 + , bookings_source_src_28000.booking_value AS discrete_booking_value_p99 + , bookings_source_src_28000.booking_value AS approximate_continuous_booking_value_p99 + , bookings_source_src_28000.booking_value AS approximate_discrete_booking_value_p99 + , bookings_source_src_28000.is_instant + , DATE_TRUNC('day', bookings_source_src_28000.ds) AS ds__day + , DATE_TRUNC('week', bookings_source_src_28000.ds) AS ds__week + , DATE_TRUNC('month', bookings_source_src_28000.ds) AS ds__month + , DATE_TRUNC('quarter', bookings_source_src_28000.ds) AS ds__quarter + , DATE_TRUNC('year', bookings_source_src_28000.ds) AS ds__year + , EXTRACT(year FROM bookings_source_src_28000.ds) AS ds__extract_year + , EXTRACT(quarter FROM bookings_source_src_28000.ds) AS ds__extract_quarter + , EXTRACT(month FROM bookings_source_src_28000.ds) AS ds__extract_month + , EXTRACT(day FROM bookings_source_src_28000.ds) AS ds__extract_day + , EXTRACT(DAYOFWEEK_ISO FROM bookings_source_src_28000.ds) AS ds__extract_dow + , EXTRACT(doy FROM bookings_source_src_28000.ds) AS ds__extract_doy + , DATE_TRUNC('day', bookings_source_src_28000.ds_partitioned) AS ds_partitioned__day + , DATE_TRUNC('week', bookings_source_src_28000.ds_partitioned) AS ds_partitioned__week + , DATE_TRUNC('month', bookings_source_src_28000.ds_partitioned) AS ds_partitioned__month + , DATE_TRUNC('quarter', bookings_source_src_28000.ds_partitioned) AS ds_partitioned__quarter + , DATE_TRUNC('year', bookings_source_src_28000.ds_partitioned) AS ds_partitioned__year + , EXTRACT(year FROM bookings_source_src_28000.ds_partitioned) AS ds_partitioned__extract_year + , EXTRACT(quarter FROM bookings_source_src_28000.ds_partitioned) AS ds_partitioned__extract_quarter + , EXTRACT(month FROM bookings_source_src_28000.ds_partitioned) AS ds_partitioned__extract_month + , EXTRACT(day FROM bookings_source_src_28000.ds_partitioned) AS ds_partitioned__extract_day + , EXTRACT(DAYOFWEEK_ISO FROM bookings_source_src_28000.ds_partitioned) AS ds_partitioned__extract_dow + , EXTRACT(doy FROM bookings_source_src_28000.ds_partitioned) AS ds_partitioned__extract_doy + , DATE_TRUNC('day', bookings_source_src_28000.paid_at) AS paid_at__day + , DATE_TRUNC('week', bookings_source_src_28000.paid_at) AS paid_at__week + , DATE_TRUNC('month', bookings_source_src_28000.paid_at) AS paid_at__month + , DATE_TRUNC('quarter', bookings_source_src_28000.paid_at) AS paid_at__quarter + , DATE_TRUNC('year', bookings_source_src_28000.paid_at) AS paid_at__year + , EXTRACT(year FROM bookings_source_src_28000.paid_at) AS paid_at__extract_year + , EXTRACT(quarter FROM bookings_source_src_28000.paid_at) AS paid_at__extract_quarter + , EXTRACT(month FROM bookings_source_src_28000.paid_at) AS paid_at__extract_month + , EXTRACT(day FROM bookings_source_src_28000.paid_at) AS paid_at__extract_day + , EXTRACT(DAYOFWEEK_ISO FROM bookings_source_src_28000.paid_at) AS paid_at__extract_dow + , EXTRACT(doy FROM bookings_source_src_28000.paid_at) AS paid_at__extract_doy + , bookings_source_src_28000.is_instant AS booking__is_instant + , DATE_TRUNC('day', bookings_source_src_28000.ds) AS booking__ds__day + , DATE_TRUNC('week', bookings_source_src_28000.ds) AS booking__ds__week + , DATE_TRUNC('month', bookings_source_src_28000.ds) AS booking__ds__month + , DATE_TRUNC('quarter', bookings_source_src_28000.ds) AS booking__ds__quarter + , DATE_TRUNC('year', bookings_source_src_28000.ds) AS booking__ds__year + , EXTRACT(year FROM bookings_source_src_28000.ds) AS booking__ds__extract_year + , EXTRACT(quarter FROM bookings_source_src_28000.ds) AS booking__ds__extract_quarter + , EXTRACT(month FROM bookings_source_src_28000.ds) AS booking__ds__extract_month + , EXTRACT(day FROM bookings_source_src_28000.ds) AS booking__ds__extract_day + , EXTRACT(DAYOFWEEK_ISO FROM bookings_source_src_28000.ds) AS booking__ds__extract_dow + , EXTRACT(doy FROM bookings_source_src_28000.ds) AS booking__ds__extract_doy + , DATE_TRUNC('day', bookings_source_src_28000.ds_partitioned) AS booking__ds_partitioned__day + , DATE_TRUNC('week', bookings_source_src_28000.ds_partitioned) AS booking__ds_partitioned__week + , DATE_TRUNC('month', bookings_source_src_28000.ds_partitioned) AS booking__ds_partitioned__month + , DATE_TRUNC('quarter', bookings_source_src_28000.ds_partitioned) AS booking__ds_partitioned__quarter + , DATE_TRUNC('year', bookings_source_src_28000.ds_partitioned) AS booking__ds_partitioned__year + , EXTRACT(year FROM bookings_source_src_28000.ds_partitioned) AS booking__ds_partitioned__extract_year + , EXTRACT(quarter FROM bookings_source_src_28000.ds_partitioned) AS booking__ds_partitioned__extract_quarter + , EXTRACT(month FROM bookings_source_src_28000.ds_partitioned) AS booking__ds_partitioned__extract_month + , EXTRACT(day FROM bookings_source_src_28000.ds_partitioned) AS booking__ds_partitioned__extract_day + , EXTRACT(DAYOFWEEK_ISO FROM bookings_source_src_28000.ds_partitioned) AS booking__ds_partitioned__extract_dow + , EXTRACT(doy FROM bookings_source_src_28000.ds_partitioned) AS booking__ds_partitioned__extract_doy + , DATE_TRUNC('day', bookings_source_src_28000.paid_at) AS booking__paid_at__day + , DATE_TRUNC('week', bookings_source_src_28000.paid_at) AS booking__paid_at__week + , DATE_TRUNC('month', bookings_source_src_28000.paid_at) AS booking__paid_at__month + , DATE_TRUNC('quarter', bookings_source_src_28000.paid_at) AS booking__paid_at__quarter + , DATE_TRUNC('year', bookings_source_src_28000.paid_at) AS booking__paid_at__year + , EXTRACT(year FROM bookings_source_src_28000.paid_at) AS booking__paid_at__extract_year + , EXTRACT(quarter FROM bookings_source_src_28000.paid_at) AS booking__paid_at__extract_quarter + , EXTRACT(month FROM bookings_source_src_28000.paid_at) AS booking__paid_at__extract_month + , EXTRACT(day FROM bookings_source_src_28000.paid_at) AS booking__paid_at__extract_day + , EXTRACT(DAYOFWEEK_ISO FROM bookings_source_src_28000.paid_at) AS booking__paid_at__extract_dow + , EXTRACT(doy FROM bookings_source_src_28000.paid_at) AS booking__paid_at__extract_doy + , bookings_source_src_28000.listing_id AS listing + , bookings_source_src_28000.guest_id AS guest + , bookings_source_src_28000.host_id AS host + , bookings_source_src_28000.listing_id AS booking__listing + , bookings_source_src_28000.guest_id AS booking__guest + , bookings_source_src_28000.host_id AS booking__host + FROM ***************************.fct_bookings bookings_source_src_28000 + ) subq_7 + ) subq_8 + ) subq_9 + GROUP BY + subq_9.guest + ) subq_10 + ) subq_11 + ) subq_12 + ON + subq_6.guest = subq_12.guest + ) subq_13 + ) subq_14 + WHERE guest__bookers > 1.00 + ) subq_15 + ) subq_16 +) subq_17 diff --git a/tests/snapshots/test_metric_filter_rendering.py/SqlQueryPlan/Databricks/test_metric_filtered_by_itself__plan0_optimized.sql b/tests/snapshots/test_metric_filter_rendering.py/SqlQueryPlan/Databricks/test_metric_filtered_by_itself__plan0_optimized.sql new file mode 100644 index 0000000000..eb7a693290 --- /dev/null +++ b/tests/snapshots/test_metric_filter_rendering.py/SqlQueryPlan/Databricks/test_metric_filtered_by_itself__plan0_optimized.sql @@ -0,0 +1,39 @@ +-- Constrain Output with WHERE +-- Pass Only Elements: ['bookers',] +-- Aggregate Measures +-- Compute Metrics via Expressions +SELECT + COUNT(DISTINCT bookers) AS bookers +FROM ( + -- Join Standard Outputs + -- Pass Only Elements: ['bookers', 'guest__bookers'] + SELECT + subq_26.bookers AS guest__bookers + , subq_20.bookers AS bookers + FROM ( + -- Read Elements From Semantic Model 'bookings_source' + -- Metric Time Dimension 'ds' + -- Pass Only Elements: ['bookers', 'guest'] + SELECT + guest_id AS guest + , guest_id AS bookers + FROM ***************************.fct_bookings bookings_source_src_28000 + ) subq_20 + LEFT OUTER JOIN ( + -- Read Elements From Semantic Model 'bookings_source' + -- Metric Time Dimension 'ds' + -- Pass Only Elements: ['bookers', 'guest'] + -- Aggregate Measures + -- Compute Metrics via Expressions + -- Pass Only Elements: ['guest', 'bookers'] + SELECT + guest_id AS guest + , COUNT(DISTINCT guest_id) AS bookers + FROM ***************************.fct_bookings bookings_source_src_28000 + GROUP BY + guest_id + ) subq_26 + ON + subq_20.guest = subq_26.guest +) subq_28 +WHERE guest__bookers > 1.00 diff --git a/tests/snapshots/test_metric_filter_rendering.py/SqlQueryPlan/Postgres/test_metric_filtered_by_itself__plan0.sql b/tests/snapshots/test_metric_filter_rendering.py/SqlQueryPlan/Postgres/test_metric_filtered_by_itself__plan0.sql new file mode 100644 index 0000000000..09749c68b5 --- /dev/null +++ b/tests/snapshots/test_metric_filter_rendering.py/SqlQueryPlan/Postgres/test_metric_filtered_by_itself__plan0.sql @@ -0,0 +1,457 @@ +-- Compute Metrics via Expressions +SELECT + subq_17.bookers +FROM ( + -- Aggregate Measures + SELECT + COUNT(DISTINCT subq_16.bookers) AS bookers + FROM ( + -- Pass Only Elements: ['bookers',] + SELECT + subq_15.bookers + FROM ( + -- Constrain Output with WHERE + SELECT + subq_14.guest__bookers + , subq_14.bookers + FROM ( + -- Pass Only Elements: ['bookers', 'guest__bookers'] + SELECT + subq_13.guest__bookers + , subq_13.bookers + FROM ( + -- Join Standard Outputs + SELECT + subq_6.guest AS guest + , subq_12.bookers AS guest__bookers + , subq_6.bookers AS bookers + FROM ( + -- Pass Only Elements: ['bookers', 'guest'] + SELECT + subq_5.guest + , subq_5.bookers + FROM ( + -- Metric Time Dimension 'ds' + SELECT + subq_4.ds__day + , subq_4.ds__week + , subq_4.ds__month + , subq_4.ds__quarter + , subq_4.ds__year + , subq_4.ds__extract_year + , subq_4.ds__extract_quarter + , subq_4.ds__extract_month + , subq_4.ds__extract_day + , subq_4.ds__extract_dow + , subq_4.ds__extract_doy + , subq_4.ds_partitioned__day + , subq_4.ds_partitioned__week + , subq_4.ds_partitioned__month + , subq_4.ds_partitioned__quarter + , subq_4.ds_partitioned__year + , subq_4.ds_partitioned__extract_year + , subq_4.ds_partitioned__extract_quarter + , subq_4.ds_partitioned__extract_month + , subq_4.ds_partitioned__extract_day + , subq_4.ds_partitioned__extract_dow + , subq_4.ds_partitioned__extract_doy + , subq_4.paid_at__day + , subq_4.paid_at__week + , subq_4.paid_at__month + , subq_4.paid_at__quarter + , subq_4.paid_at__year + , subq_4.paid_at__extract_year + , subq_4.paid_at__extract_quarter + , subq_4.paid_at__extract_month + , subq_4.paid_at__extract_day + , subq_4.paid_at__extract_dow + , subq_4.paid_at__extract_doy + , subq_4.booking__ds__day + , subq_4.booking__ds__week + , subq_4.booking__ds__month + , subq_4.booking__ds__quarter + , subq_4.booking__ds__year + , subq_4.booking__ds__extract_year + , subq_4.booking__ds__extract_quarter + , subq_4.booking__ds__extract_month + , subq_4.booking__ds__extract_day + , subq_4.booking__ds__extract_dow + , subq_4.booking__ds__extract_doy + , subq_4.booking__ds_partitioned__day + , subq_4.booking__ds_partitioned__week + , subq_4.booking__ds_partitioned__month + , subq_4.booking__ds_partitioned__quarter + , subq_4.booking__ds_partitioned__year + , subq_4.booking__ds_partitioned__extract_year + , subq_4.booking__ds_partitioned__extract_quarter + , subq_4.booking__ds_partitioned__extract_month + , subq_4.booking__ds_partitioned__extract_day + , subq_4.booking__ds_partitioned__extract_dow + , subq_4.booking__ds_partitioned__extract_doy + , subq_4.booking__paid_at__day + , subq_4.booking__paid_at__week + , subq_4.booking__paid_at__month + , subq_4.booking__paid_at__quarter + , subq_4.booking__paid_at__year + , subq_4.booking__paid_at__extract_year + , subq_4.booking__paid_at__extract_quarter + , subq_4.booking__paid_at__extract_month + , subq_4.booking__paid_at__extract_day + , subq_4.booking__paid_at__extract_dow + , subq_4.booking__paid_at__extract_doy + , subq_4.ds__day AS metric_time__day + , subq_4.ds__week AS metric_time__week + , subq_4.ds__month AS metric_time__month + , subq_4.ds__quarter AS metric_time__quarter + , subq_4.ds__year AS metric_time__year + , subq_4.ds__extract_year AS metric_time__extract_year + , subq_4.ds__extract_quarter AS metric_time__extract_quarter + , subq_4.ds__extract_month AS metric_time__extract_month + , subq_4.ds__extract_day AS metric_time__extract_day + , subq_4.ds__extract_dow AS metric_time__extract_dow + , subq_4.ds__extract_doy AS metric_time__extract_doy + , subq_4.listing + , subq_4.guest + , subq_4.host + , subq_4.booking__listing + , subq_4.booking__guest + , subq_4.booking__host + , subq_4.is_instant + , subq_4.booking__is_instant + , subq_4.bookings + , subq_4.instant_bookings + , subq_4.booking_value + , subq_4.max_booking_value + , subq_4.min_booking_value + , subq_4.bookers + , subq_4.average_booking_value + , subq_4.referred_bookings + , subq_4.median_booking_value + , subq_4.booking_value_p99 + , subq_4.discrete_booking_value_p99 + , subq_4.approximate_continuous_booking_value_p99 + , subq_4.approximate_discrete_booking_value_p99 + FROM ( + -- Read Elements From Semantic Model 'bookings_source' + SELECT + 1 AS bookings + , CASE WHEN is_instant THEN 1 ELSE 0 END AS instant_bookings + , bookings_source_src_28000.booking_value + , bookings_source_src_28000.booking_value AS max_booking_value + , bookings_source_src_28000.booking_value AS min_booking_value + , bookings_source_src_28000.guest_id AS bookers + , bookings_source_src_28000.booking_value AS average_booking_value + , bookings_source_src_28000.booking_value AS booking_payments + , CASE WHEN referrer_id IS NOT NULL THEN 1 ELSE 0 END AS referred_bookings + , bookings_source_src_28000.booking_value AS median_booking_value + , bookings_source_src_28000.booking_value AS booking_value_p99 + , bookings_source_src_28000.booking_value AS discrete_booking_value_p99 + , bookings_source_src_28000.booking_value AS approximate_continuous_booking_value_p99 + , bookings_source_src_28000.booking_value AS approximate_discrete_booking_value_p99 + , bookings_source_src_28000.is_instant + , DATE_TRUNC('day', bookings_source_src_28000.ds) AS ds__day + , DATE_TRUNC('week', bookings_source_src_28000.ds) AS ds__week + , DATE_TRUNC('month', bookings_source_src_28000.ds) AS ds__month + , DATE_TRUNC('quarter', bookings_source_src_28000.ds) AS ds__quarter + , DATE_TRUNC('year', bookings_source_src_28000.ds) AS ds__year + , EXTRACT(year FROM bookings_source_src_28000.ds) AS ds__extract_year + , EXTRACT(quarter FROM bookings_source_src_28000.ds) AS ds__extract_quarter + , EXTRACT(month FROM bookings_source_src_28000.ds) AS ds__extract_month + , EXTRACT(day FROM bookings_source_src_28000.ds) AS ds__extract_day + , EXTRACT(isodow FROM bookings_source_src_28000.ds) AS ds__extract_dow + , EXTRACT(doy FROM bookings_source_src_28000.ds) AS ds__extract_doy + , DATE_TRUNC('day', bookings_source_src_28000.ds_partitioned) AS ds_partitioned__day + , DATE_TRUNC('week', bookings_source_src_28000.ds_partitioned) AS ds_partitioned__week + , DATE_TRUNC('month', bookings_source_src_28000.ds_partitioned) AS ds_partitioned__month + , DATE_TRUNC('quarter', bookings_source_src_28000.ds_partitioned) AS ds_partitioned__quarter + , DATE_TRUNC('year', bookings_source_src_28000.ds_partitioned) AS ds_partitioned__year + , EXTRACT(year FROM bookings_source_src_28000.ds_partitioned) AS ds_partitioned__extract_year + , EXTRACT(quarter FROM bookings_source_src_28000.ds_partitioned) AS ds_partitioned__extract_quarter + , EXTRACT(month FROM bookings_source_src_28000.ds_partitioned) AS ds_partitioned__extract_month + , EXTRACT(day FROM bookings_source_src_28000.ds_partitioned) AS ds_partitioned__extract_day + , EXTRACT(isodow FROM bookings_source_src_28000.ds_partitioned) AS ds_partitioned__extract_dow + , EXTRACT(doy FROM bookings_source_src_28000.ds_partitioned) AS ds_partitioned__extract_doy + , DATE_TRUNC('day', bookings_source_src_28000.paid_at) AS paid_at__day + , DATE_TRUNC('week', bookings_source_src_28000.paid_at) AS paid_at__week + , DATE_TRUNC('month', bookings_source_src_28000.paid_at) AS paid_at__month + , DATE_TRUNC('quarter', bookings_source_src_28000.paid_at) AS paid_at__quarter + , DATE_TRUNC('year', bookings_source_src_28000.paid_at) AS paid_at__year + , EXTRACT(year FROM bookings_source_src_28000.paid_at) AS paid_at__extract_year + , EXTRACT(quarter FROM bookings_source_src_28000.paid_at) AS paid_at__extract_quarter + , EXTRACT(month FROM bookings_source_src_28000.paid_at) AS paid_at__extract_month + , EXTRACT(day FROM bookings_source_src_28000.paid_at) AS paid_at__extract_day + , EXTRACT(isodow FROM bookings_source_src_28000.paid_at) AS paid_at__extract_dow + , EXTRACT(doy FROM bookings_source_src_28000.paid_at) AS paid_at__extract_doy + , bookings_source_src_28000.is_instant AS booking__is_instant + , DATE_TRUNC('day', bookings_source_src_28000.ds) AS booking__ds__day + , DATE_TRUNC('week', bookings_source_src_28000.ds) AS booking__ds__week + , DATE_TRUNC('month', bookings_source_src_28000.ds) AS booking__ds__month + , DATE_TRUNC('quarter', bookings_source_src_28000.ds) AS booking__ds__quarter + , DATE_TRUNC('year', bookings_source_src_28000.ds) AS booking__ds__year + , EXTRACT(year FROM bookings_source_src_28000.ds) AS booking__ds__extract_year + , EXTRACT(quarter FROM bookings_source_src_28000.ds) AS booking__ds__extract_quarter + , EXTRACT(month FROM bookings_source_src_28000.ds) AS booking__ds__extract_month + , EXTRACT(day FROM bookings_source_src_28000.ds) AS booking__ds__extract_day + , EXTRACT(isodow FROM bookings_source_src_28000.ds) AS booking__ds__extract_dow + , EXTRACT(doy FROM bookings_source_src_28000.ds) AS booking__ds__extract_doy + , DATE_TRUNC('day', bookings_source_src_28000.ds_partitioned) AS booking__ds_partitioned__day + , DATE_TRUNC('week', bookings_source_src_28000.ds_partitioned) AS booking__ds_partitioned__week + , DATE_TRUNC('month', bookings_source_src_28000.ds_partitioned) AS booking__ds_partitioned__month + , DATE_TRUNC('quarter', bookings_source_src_28000.ds_partitioned) AS booking__ds_partitioned__quarter + , DATE_TRUNC('year', bookings_source_src_28000.ds_partitioned) AS booking__ds_partitioned__year + , EXTRACT(year FROM bookings_source_src_28000.ds_partitioned) AS booking__ds_partitioned__extract_year + , EXTRACT(quarter FROM bookings_source_src_28000.ds_partitioned) AS booking__ds_partitioned__extract_quarter + , EXTRACT(month FROM bookings_source_src_28000.ds_partitioned) AS booking__ds_partitioned__extract_month + , EXTRACT(day FROM bookings_source_src_28000.ds_partitioned) AS booking__ds_partitioned__extract_day + , EXTRACT(isodow FROM bookings_source_src_28000.ds_partitioned) AS booking__ds_partitioned__extract_dow + , EXTRACT(doy FROM bookings_source_src_28000.ds_partitioned) AS booking__ds_partitioned__extract_doy + , DATE_TRUNC('day', bookings_source_src_28000.paid_at) AS booking__paid_at__day + , DATE_TRUNC('week', bookings_source_src_28000.paid_at) AS booking__paid_at__week + , DATE_TRUNC('month', bookings_source_src_28000.paid_at) AS booking__paid_at__month + , DATE_TRUNC('quarter', bookings_source_src_28000.paid_at) AS booking__paid_at__quarter + , DATE_TRUNC('year', bookings_source_src_28000.paid_at) AS booking__paid_at__year + , EXTRACT(year FROM bookings_source_src_28000.paid_at) AS booking__paid_at__extract_year + , EXTRACT(quarter FROM bookings_source_src_28000.paid_at) AS booking__paid_at__extract_quarter + , EXTRACT(month FROM bookings_source_src_28000.paid_at) AS booking__paid_at__extract_month + , EXTRACT(day FROM bookings_source_src_28000.paid_at) AS booking__paid_at__extract_day + , EXTRACT(isodow FROM bookings_source_src_28000.paid_at) AS booking__paid_at__extract_dow + , EXTRACT(doy FROM bookings_source_src_28000.paid_at) AS booking__paid_at__extract_doy + , bookings_source_src_28000.listing_id AS listing + , bookings_source_src_28000.guest_id AS guest + , bookings_source_src_28000.host_id AS host + , bookings_source_src_28000.listing_id AS booking__listing + , bookings_source_src_28000.guest_id AS booking__guest + , bookings_source_src_28000.host_id AS booking__host + FROM ***************************.fct_bookings bookings_source_src_28000 + ) subq_4 + ) subq_5 + ) subq_6 + LEFT OUTER JOIN ( + -- Pass Only Elements: ['guest', 'bookers'] + SELECT + subq_11.guest + , subq_11.bookers + FROM ( + -- Compute Metrics via Expressions + SELECT + subq_10.guest + , subq_10.bookers + FROM ( + -- Aggregate Measures + SELECT + subq_9.guest + , COUNT(DISTINCT subq_9.bookers) AS bookers + FROM ( + -- Pass Only Elements: ['bookers', 'guest'] + SELECT + subq_8.guest + , subq_8.bookers + FROM ( + -- Metric Time Dimension 'ds' + SELECT + subq_7.ds__day + , subq_7.ds__week + , subq_7.ds__month + , subq_7.ds__quarter + , subq_7.ds__year + , subq_7.ds__extract_year + , subq_7.ds__extract_quarter + , subq_7.ds__extract_month + , subq_7.ds__extract_day + , subq_7.ds__extract_dow + , subq_7.ds__extract_doy + , subq_7.ds_partitioned__day + , subq_7.ds_partitioned__week + , subq_7.ds_partitioned__month + , subq_7.ds_partitioned__quarter + , subq_7.ds_partitioned__year + , subq_7.ds_partitioned__extract_year + , subq_7.ds_partitioned__extract_quarter + , subq_7.ds_partitioned__extract_month + , subq_7.ds_partitioned__extract_day + , subq_7.ds_partitioned__extract_dow + , subq_7.ds_partitioned__extract_doy + , subq_7.paid_at__day + , subq_7.paid_at__week + , subq_7.paid_at__month + , subq_7.paid_at__quarter + , subq_7.paid_at__year + , subq_7.paid_at__extract_year + , subq_7.paid_at__extract_quarter + , subq_7.paid_at__extract_month + , subq_7.paid_at__extract_day + , subq_7.paid_at__extract_dow + , subq_7.paid_at__extract_doy + , subq_7.booking__ds__day + , subq_7.booking__ds__week + , subq_7.booking__ds__month + , subq_7.booking__ds__quarter + , subq_7.booking__ds__year + , subq_7.booking__ds__extract_year + , subq_7.booking__ds__extract_quarter + , subq_7.booking__ds__extract_month + , subq_7.booking__ds__extract_day + , subq_7.booking__ds__extract_dow + , subq_7.booking__ds__extract_doy + , subq_7.booking__ds_partitioned__day + , subq_7.booking__ds_partitioned__week + , subq_7.booking__ds_partitioned__month + , subq_7.booking__ds_partitioned__quarter + , subq_7.booking__ds_partitioned__year + , subq_7.booking__ds_partitioned__extract_year + , subq_7.booking__ds_partitioned__extract_quarter + , subq_7.booking__ds_partitioned__extract_month + , subq_7.booking__ds_partitioned__extract_day + , subq_7.booking__ds_partitioned__extract_dow + , subq_7.booking__ds_partitioned__extract_doy + , subq_7.booking__paid_at__day + , subq_7.booking__paid_at__week + , subq_7.booking__paid_at__month + , subq_7.booking__paid_at__quarter + , subq_7.booking__paid_at__year + , subq_7.booking__paid_at__extract_year + , subq_7.booking__paid_at__extract_quarter + , subq_7.booking__paid_at__extract_month + , subq_7.booking__paid_at__extract_day + , subq_7.booking__paid_at__extract_dow + , subq_7.booking__paid_at__extract_doy + , subq_7.ds__day AS metric_time__day + , subq_7.ds__week AS metric_time__week + , subq_7.ds__month AS metric_time__month + , subq_7.ds__quarter AS metric_time__quarter + , subq_7.ds__year AS metric_time__year + , subq_7.ds__extract_year AS metric_time__extract_year + , subq_7.ds__extract_quarter AS metric_time__extract_quarter + , subq_7.ds__extract_month AS metric_time__extract_month + , subq_7.ds__extract_day AS metric_time__extract_day + , subq_7.ds__extract_dow AS metric_time__extract_dow + , subq_7.ds__extract_doy AS metric_time__extract_doy + , subq_7.listing + , subq_7.guest + , subq_7.host + , subq_7.booking__listing + , subq_7.booking__guest + , subq_7.booking__host + , subq_7.is_instant + , subq_7.booking__is_instant + , subq_7.bookings + , subq_7.instant_bookings + , subq_7.booking_value + , subq_7.max_booking_value + , subq_7.min_booking_value + , subq_7.bookers + , subq_7.average_booking_value + , subq_7.referred_bookings + , subq_7.median_booking_value + , subq_7.booking_value_p99 + , subq_7.discrete_booking_value_p99 + , subq_7.approximate_continuous_booking_value_p99 + , subq_7.approximate_discrete_booking_value_p99 + FROM ( + -- Read Elements From Semantic Model 'bookings_source' + SELECT + 1 AS bookings + , CASE WHEN is_instant THEN 1 ELSE 0 END AS instant_bookings + , bookings_source_src_28000.booking_value + , bookings_source_src_28000.booking_value AS max_booking_value + , bookings_source_src_28000.booking_value AS min_booking_value + , bookings_source_src_28000.guest_id AS bookers + , bookings_source_src_28000.booking_value AS average_booking_value + , bookings_source_src_28000.booking_value AS booking_payments + , CASE WHEN referrer_id IS NOT NULL THEN 1 ELSE 0 END AS referred_bookings + , bookings_source_src_28000.booking_value AS median_booking_value + , bookings_source_src_28000.booking_value AS booking_value_p99 + , bookings_source_src_28000.booking_value AS discrete_booking_value_p99 + , bookings_source_src_28000.booking_value AS approximate_continuous_booking_value_p99 + , bookings_source_src_28000.booking_value AS approximate_discrete_booking_value_p99 + , bookings_source_src_28000.is_instant + , DATE_TRUNC('day', bookings_source_src_28000.ds) AS ds__day + , DATE_TRUNC('week', bookings_source_src_28000.ds) AS ds__week + , DATE_TRUNC('month', bookings_source_src_28000.ds) AS ds__month + , DATE_TRUNC('quarter', bookings_source_src_28000.ds) AS ds__quarter + , DATE_TRUNC('year', bookings_source_src_28000.ds) AS ds__year + , EXTRACT(year FROM bookings_source_src_28000.ds) AS ds__extract_year + , EXTRACT(quarter FROM bookings_source_src_28000.ds) AS ds__extract_quarter + , EXTRACT(month FROM bookings_source_src_28000.ds) AS ds__extract_month + , EXTRACT(day FROM bookings_source_src_28000.ds) AS ds__extract_day + , EXTRACT(isodow FROM bookings_source_src_28000.ds) AS ds__extract_dow + , EXTRACT(doy FROM bookings_source_src_28000.ds) AS ds__extract_doy + , DATE_TRUNC('day', bookings_source_src_28000.ds_partitioned) AS ds_partitioned__day + , DATE_TRUNC('week', bookings_source_src_28000.ds_partitioned) AS ds_partitioned__week + , DATE_TRUNC('month', bookings_source_src_28000.ds_partitioned) AS ds_partitioned__month + , DATE_TRUNC('quarter', bookings_source_src_28000.ds_partitioned) AS ds_partitioned__quarter + , DATE_TRUNC('year', bookings_source_src_28000.ds_partitioned) AS ds_partitioned__year + , EXTRACT(year FROM bookings_source_src_28000.ds_partitioned) AS ds_partitioned__extract_year + , EXTRACT(quarter FROM bookings_source_src_28000.ds_partitioned) AS ds_partitioned__extract_quarter + , EXTRACT(month FROM bookings_source_src_28000.ds_partitioned) AS ds_partitioned__extract_month + , EXTRACT(day FROM bookings_source_src_28000.ds_partitioned) AS ds_partitioned__extract_day + , EXTRACT(isodow FROM bookings_source_src_28000.ds_partitioned) AS ds_partitioned__extract_dow + , EXTRACT(doy FROM bookings_source_src_28000.ds_partitioned) AS ds_partitioned__extract_doy + , DATE_TRUNC('day', bookings_source_src_28000.paid_at) AS paid_at__day + , DATE_TRUNC('week', bookings_source_src_28000.paid_at) AS paid_at__week + , DATE_TRUNC('month', bookings_source_src_28000.paid_at) AS paid_at__month + , DATE_TRUNC('quarter', bookings_source_src_28000.paid_at) AS paid_at__quarter + , DATE_TRUNC('year', bookings_source_src_28000.paid_at) AS paid_at__year + , EXTRACT(year FROM bookings_source_src_28000.paid_at) AS paid_at__extract_year + , EXTRACT(quarter FROM bookings_source_src_28000.paid_at) AS paid_at__extract_quarter + , EXTRACT(month FROM bookings_source_src_28000.paid_at) AS paid_at__extract_month + , EXTRACT(day FROM bookings_source_src_28000.paid_at) AS paid_at__extract_day + , EXTRACT(isodow FROM bookings_source_src_28000.paid_at) AS paid_at__extract_dow + , EXTRACT(doy FROM bookings_source_src_28000.paid_at) AS paid_at__extract_doy + , bookings_source_src_28000.is_instant AS booking__is_instant + , DATE_TRUNC('day', bookings_source_src_28000.ds) AS booking__ds__day + , DATE_TRUNC('week', bookings_source_src_28000.ds) AS booking__ds__week + , DATE_TRUNC('month', bookings_source_src_28000.ds) AS booking__ds__month + , DATE_TRUNC('quarter', bookings_source_src_28000.ds) AS booking__ds__quarter + , DATE_TRUNC('year', bookings_source_src_28000.ds) AS booking__ds__year + , EXTRACT(year FROM bookings_source_src_28000.ds) AS booking__ds__extract_year + , EXTRACT(quarter FROM bookings_source_src_28000.ds) AS booking__ds__extract_quarter + , EXTRACT(month FROM bookings_source_src_28000.ds) AS booking__ds__extract_month + , EXTRACT(day FROM bookings_source_src_28000.ds) AS booking__ds__extract_day + , EXTRACT(isodow FROM bookings_source_src_28000.ds) AS booking__ds__extract_dow + , EXTRACT(doy FROM bookings_source_src_28000.ds) AS booking__ds__extract_doy + , DATE_TRUNC('day', bookings_source_src_28000.ds_partitioned) AS booking__ds_partitioned__day + , DATE_TRUNC('week', bookings_source_src_28000.ds_partitioned) AS booking__ds_partitioned__week + , DATE_TRUNC('month', bookings_source_src_28000.ds_partitioned) AS booking__ds_partitioned__month + , DATE_TRUNC('quarter', bookings_source_src_28000.ds_partitioned) AS booking__ds_partitioned__quarter + , DATE_TRUNC('year', bookings_source_src_28000.ds_partitioned) AS booking__ds_partitioned__year + , EXTRACT(year FROM bookings_source_src_28000.ds_partitioned) AS booking__ds_partitioned__extract_year + , EXTRACT(quarter FROM bookings_source_src_28000.ds_partitioned) AS booking__ds_partitioned__extract_quarter + , EXTRACT(month FROM bookings_source_src_28000.ds_partitioned) AS booking__ds_partitioned__extract_month + , EXTRACT(day FROM bookings_source_src_28000.ds_partitioned) AS booking__ds_partitioned__extract_day + , EXTRACT(isodow FROM bookings_source_src_28000.ds_partitioned) AS booking__ds_partitioned__extract_dow + , EXTRACT(doy FROM bookings_source_src_28000.ds_partitioned) AS booking__ds_partitioned__extract_doy + , DATE_TRUNC('day', bookings_source_src_28000.paid_at) AS booking__paid_at__day + , DATE_TRUNC('week', bookings_source_src_28000.paid_at) AS booking__paid_at__week + , DATE_TRUNC('month', bookings_source_src_28000.paid_at) AS booking__paid_at__month + , DATE_TRUNC('quarter', bookings_source_src_28000.paid_at) AS booking__paid_at__quarter + , DATE_TRUNC('year', bookings_source_src_28000.paid_at) AS booking__paid_at__year + , EXTRACT(year FROM bookings_source_src_28000.paid_at) AS booking__paid_at__extract_year + , EXTRACT(quarter FROM bookings_source_src_28000.paid_at) AS booking__paid_at__extract_quarter + , EXTRACT(month FROM bookings_source_src_28000.paid_at) AS booking__paid_at__extract_month + , EXTRACT(day FROM bookings_source_src_28000.paid_at) AS booking__paid_at__extract_day + , EXTRACT(isodow FROM bookings_source_src_28000.paid_at) AS booking__paid_at__extract_dow + , EXTRACT(doy FROM bookings_source_src_28000.paid_at) AS booking__paid_at__extract_doy + , bookings_source_src_28000.listing_id AS listing + , bookings_source_src_28000.guest_id AS guest + , bookings_source_src_28000.host_id AS host + , bookings_source_src_28000.listing_id AS booking__listing + , bookings_source_src_28000.guest_id AS booking__guest + , bookings_source_src_28000.host_id AS booking__host + FROM ***************************.fct_bookings bookings_source_src_28000 + ) subq_7 + ) subq_8 + ) subq_9 + GROUP BY + subq_9.guest + ) subq_10 + ) subq_11 + ) subq_12 + ON + subq_6.guest = subq_12.guest + ) subq_13 + ) subq_14 + WHERE guest__bookers > 1.00 + ) subq_15 + ) subq_16 +) subq_17 diff --git a/tests/snapshots/test_metric_filter_rendering.py/SqlQueryPlan/Postgres/test_metric_filtered_by_itself__plan0_optimized.sql b/tests/snapshots/test_metric_filter_rendering.py/SqlQueryPlan/Postgres/test_metric_filtered_by_itself__plan0_optimized.sql new file mode 100644 index 0000000000..eb7a693290 --- /dev/null +++ b/tests/snapshots/test_metric_filter_rendering.py/SqlQueryPlan/Postgres/test_metric_filtered_by_itself__plan0_optimized.sql @@ -0,0 +1,39 @@ +-- Constrain Output with WHERE +-- Pass Only Elements: ['bookers',] +-- Aggregate Measures +-- Compute Metrics via Expressions +SELECT + COUNT(DISTINCT bookers) AS bookers +FROM ( + -- Join Standard Outputs + -- Pass Only Elements: ['bookers', 'guest__bookers'] + SELECT + subq_26.bookers AS guest__bookers + , subq_20.bookers AS bookers + FROM ( + -- Read Elements From Semantic Model 'bookings_source' + -- Metric Time Dimension 'ds' + -- Pass Only Elements: ['bookers', 'guest'] + SELECT + guest_id AS guest + , guest_id AS bookers + FROM ***************************.fct_bookings bookings_source_src_28000 + ) subq_20 + LEFT OUTER JOIN ( + -- Read Elements From Semantic Model 'bookings_source' + -- Metric Time Dimension 'ds' + -- Pass Only Elements: ['bookers', 'guest'] + -- Aggregate Measures + -- Compute Metrics via Expressions + -- Pass Only Elements: ['guest', 'bookers'] + SELECT + guest_id AS guest + , COUNT(DISTINCT guest_id) AS bookers + FROM ***************************.fct_bookings bookings_source_src_28000 + GROUP BY + guest_id + ) subq_26 + ON + subq_20.guest = subq_26.guest +) subq_28 +WHERE guest__bookers > 1.00 diff --git a/tests/snapshots/test_metric_filter_rendering.py/SqlQueryPlan/Redshift/test_metric_filtered_by_itself__plan0.sql b/tests/snapshots/test_metric_filter_rendering.py/SqlQueryPlan/Redshift/test_metric_filtered_by_itself__plan0.sql new file mode 100644 index 0000000000..ae71336a74 --- /dev/null +++ b/tests/snapshots/test_metric_filter_rendering.py/SqlQueryPlan/Redshift/test_metric_filtered_by_itself__plan0.sql @@ -0,0 +1,457 @@ +-- Compute Metrics via Expressions +SELECT + subq_17.bookers +FROM ( + -- Aggregate Measures + SELECT + COUNT(DISTINCT subq_16.bookers) AS bookers + FROM ( + -- Pass Only Elements: ['bookers',] + SELECT + subq_15.bookers + FROM ( + -- Constrain Output with WHERE + SELECT + subq_14.guest__bookers + , subq_14.bookers + FROM ( + -- Pass Only Elements: ['bookers', 'guest__bookers'] + SELECT + subq_13.guest__bookers + , subq_13.bookers + FROM ( + -- Join Standard Outputs + SELECT + subq_6.guest AS guest + , subq_12.bookers AS guest__bookers + , subq_6.bookers AS bookers + FROM ( + -- Pass Only Elements: ['bookers', 'guest'] + SELECT + subq_5.guest + , subq_5.bookers + FROM ( + -- Metric Time Dimension 'ds' + SELECT + subq_4.ds__day + , subq_4.ds__week + , subq_4.ds__month + , subq_4.ds__quarter + , subq_4.ds__year + , subq_4.ds__extract_year + , subq_4.ds__extract_quarter + , subq_4.ds__extract_month + , subq_4.ds__extract_day + , subq_4.ds__extract_dow + , subq_4.ds__extract_doy + , subq_4.ds_partitioned__day + , subq_4.ds_partitioned__week + , subq_4.ds_partitioned__month + , subq_4.ds_partitioned__quarter + , subq_4.ds_partitioned__year + , subq_4.ds_partitioned__extract_year + , subq_4.ds_partitioned__extract_quarter + , subq_4.ds_partitioned__extract_month + , subq_4.ds_partitioned__extract_day + , subq_4.ds_partitioned__extract_dow + , subq_4.ds_partitioned__extract_doy + , subq_4.paid_at__day + , subq_4.paid_at__week + , subq_4.paid_at__month + , subq_4.paid_at__quarter + , subq_4.paid_at__year + , subq_4.paid_at__extract_year + , subq_4.paid_at__extract_quarter + , subq_4.paid_at__extract_month + , subq_4.paid_at__extract_day + , subq_4.paid_at__extract_dow + , subq_4.paid_at__extract_doy + , subq_4.booking__ds__day + , subq_4.booking__ds__week + , subq_4.booking__ds__month + , subq_4.booking__ds__quarter + , subq_4.booking__ds__year + , subq_4.booking__ds__extract_year + , subq_4.booking__ds__extract_quarter + , subq_4.booking__ds__extract_month + , subq_4.booking__ds__extract_day + , subq_4.booking__ds__extract_dow + , subq_4.booking__ds__extract_doy + , subq_4.booking__ds_partitioned__day + , subq_4.booking__ds_partitioned__week + , subq_4.booking__ds_partitioned__month + , subq_4.booking__ds_partitioned__quarter + , subq_4.booking__ds_partitioned__year + , subq_4.booking__ds_partitioned__extract_year + , subq_4.booking__ds_partitioned__extract_quarter + , subq_4.booking__ds_partitioned__extract_month + , subq_4.booking__ds_partitioned__extract_day + , subq_4.booking__ds_partitioned__extract_dow + , subq_4.booking__ds_partitioned__extract_doy + , subq_4.booking__paid_at__day + , subq_4.booking__paid_at__week + , subq_4.booking__paid_at__month + , subq_4.booking__paid_at__quarter + , subq_4.booking__paid_at__year + , subq_4.booking__paid_at__extract_year + , subq_4.booking__paid_at__extract_quarter + , subq_4.booking__paid_at__extract_month + , subq_4.booking__paid_at__extract_day + , subq_4.booking__paid_at__extract_dow + , subq_4.booking__paid_at__extract_doy + , subq_4.ds__day AS metric_time__day + , subq_4.ds__week AS metric_time__week + , subq_4.ds__month AS metric_time__month + , subq_4.ds__quarter AS metric_time__quarter + , subq_4.ds__year AS metric_time__year + , subq_4.ds__extract_year AS metric_time__extract_year + , subq_4.ds__extract_quarter AS metric_time__extract_quarter + , subq_4.ds__extract_month AS metric_time__extract_month + , subq_4.ds__extract_day AS metric_time__extract_day + , subq_4.ds__extract_dow AS metric_time__extract_dow + , subq_4.ds__extract_doy AS metric_time__extract_doy + , subq_4.listing + , subq_4.guest + , subq_4.host + , subq_4.booking__listing + , subq_4.booking__guest + , subq_4.booking__host + , subq_4.is_instant + , subq_4.booking__is_instant + , subq_4.bookings + , subq_4.instant_bookings + , subq_4.booking_value + , subq_4.max_booking_value + , subq_4.min_booking_value + , subq_4.bookers + , subq_4.average_booking_value + , subq_4.referred_bookings + , subq_4.median_booking_value + , subq_4.booking_value_p99 + , subq_4.discrete_booking_value_p99 + , subq_4.approximate_continuous_booking_value_p99 + , subq_4.approximate_discrete_booking_value_p99 + FROM ( + -- Read Elements From Semantic Model 'bookings_source' + SELECT + 1 AS bookings + , CASE WHEN is_instant THEN 1 ELSE 0 END AS instant_bookings + , bookings_source_src_28000.booking_value + , bookings_source_src_28000.booking_value AS max_booking_value + , bookings_source_src_28000.booking_value AS min_booking_value + , bookings_source_src_28000.guest_id AS bookers + , bookings_source_src_28000.booking_value AS average_booking_value + , bookings_source_src_28000.booking_value AS booking_payments + , CASE WHEN referrer_id IS NOT NULL THEN 1 ELSE 0 END AS referred_bookings + , bookings_source_src_28000.booking_value AS median_booking_value + , bookings_source_src_28000.booking_value AS booking_value_p99 + , bookings_source_src_28000.booking_value AS discrete_booking_value_p99 + , bookings_source_src_28000.booking_value AS approximate_continuous_booking_value_p99 + , bookings_source_src_28000.booking_value AS approximate_discrete_booking_value_p99 + , bookings_source_src_28000.is_instant + , DATE_TRUNC('day', bookings_source_src_28000.ds) AS ds__day + , DATE_TRUNC('week', bookings_source_src_28000.ds) AS ds__week + , DATE_TRUNC('month', bookings_source_src_28000.ds) AS ds__month + , DATE_TRUNC('quarter', bookings_source_src_28000.ds) AS ds__quarter + , DATE_TRUNC('year', bookings_source_src_28000.ds) AS ds__year + , EXTRACT(year FROM bookings_source_src_28000.ds) AS ds__extract_year + , EXTRACT(quarter FROM bookings_source_src_28000.ds) AS ds__extract_quarter + , EXTRACT(month FROM bookings_source_src_28000.ds) AS ds__extract_month + , EXTRACT(day FROM bookings_source_src_28000.ds) AS ds__extract_day + , CASE WHEN EXTRACT(dow FROM bookings_source_src_28000.ds) = 0 THEN EXTRACT(dow FROM bookings_source_src_28000.ds) + 7 ELSE EXTRACT(dow FROM bookings_source_src_28000.ds) END AS ds__extract_dow + , EXTRACT(doy FROM bookings_source_src_28000.ds) AS ds__extract_doy + , DATE_TRUNC('day', bookings_source_src_28000.ds_partitioned) AS ds_partitioned__day + , DATE_TRUNC('week', bookings_source_src_28000.ds_partitioned) AS ds_partitioned__week + , DATE_TRUNC('month', bookings_source_src_28000.ds_partitioned) AS ds_partitioned__month + , DATE_TRUNC('quarter', bookings_source_src_28000.ds_partitioned) AS ds_partitioned__quarter + , DATE_TRUNC('year', bookings_source_src_28000.ds_partitioned) AS ds_partitioned__year + , EXTRACT(year FROM bookings_source_src_28000.ds_partitioned) AS ds_partitioned__extract_year + , EXTRACT(quarter FROM bookings_source_src_28000.ds_partitioned) AS ds_partitioned__extract_quarter + , EXTRACT(month FROM bookings_source_src_28000.ds_partitioned) AS ds_partitioned__extract_month + , EXTRACT(day FROM bookings_source_src_28000.ds_partitioned) AS ds_partitioned__extract_day + , CASE WHEN EXTRACT(dow FROM bookings_source_src_28000.ds_partitioned) = 0 THEN EXTRACT(dow FROM bookings_source_src_28000.ds_partitioned) + 7 ELSE EXTRACT(dow FROM bookings_source_src_28000.ds_partitioned) END AS ds_partitioned__extract_dow + , EXTRACT(doy FROM bookings_source_src_28000.ds_partitioned) AS ds_partitioned__extract_doy + , DATE_TRUNC('day', bookings_source_src_28000.paid_at) AS paid_at__day + , DATE_TRUNC('week', bookings_source_src_28000.paid_at) AS paid_at__week + , DATE_TRUNC('month', bookings_source_src_28000.paid_at) AS paid_at__month + , DATE_TRUNC('quarter', bookings_source_src_28000.paid_at) AS paid_at__quarter + , DATE_TRUNC('year', bookings_source_src_28000.paid_at) AS paid_at__year + , EXTRACT(year FROM bookings_source_src_28000.paid_at) AS paid_at__extract_year + , EXTRACT(quarter FROM bookings_source_src_28000.paid_at) AS paid_at__extract_quarter + , EXTRACT(month FROM bookings_source_src_28000.paid_at) AS paid_at__extract_month + , EXTRACT(day FROM bookings_source_src_28000.paid_at) AS paid_at__extract_day + , CASE WHEN EXTRACT(dow FROM bookings_source_src_28000.paid_at) = 0 THEN EXTRACT(dow FROM bookings_source_src_28000.paid_at) + 7 ELSE EXTRACT(dow FROM bookings_source_src_28000.paid_at) END AS paid_at__extract_dow + , EXTRACT(doy FROM bookings_source_src_28000.paid_at) AS paid_at__extract_doy + , bookings_source_src_28000.is_instant AS booking__is_instant + , DATE_TRUNC('day', bookings_source_src_28000.ds) AS booking__ds__day + , DATE_TRUNC('week', bookings_source_src_28000.ds) AS booking__ds__week + , DATE_TRUNC('month', bookings_source_src_28000.ds) AS booking__ds__month + , DATE_TRUNC('quarter', bookings_source_src_28000.ds) AS booking__ds__quarter + , DATE_TRUNC('year', bookings_source_src_28000.ds) AS booking__ds__year + , EXTRACT(year FROM bookings_source_src_28000.ds) AS booking__ds__extract_year + , EXTRACT(quarter FROM bookings_source_src_28000.ds) AS booking__ds__extract_quarter + , EXTRACT(month FROM bookings_source_src_28000.ds) AS booking__ds__extract_month + , EXTRACT(day FROM bookings_source_src_28000.ds) AS booking__ds__extract_day + , CASE WHEN EXTRACT(dow FROM bookings_source_src_28000.ds) = 0 THEN EXTRACT(dow FROM bookings_source_src_28000.ds) + 7 ELSE EXTRACT(dow FROM bookings_source_src_28000.ds) END AS booking__ds__extract_dow + , EXTRACT(doy FROM bookings_source_src_28000.ds) AS booking__ds__extract_doy + , DATE_TRUNC('day', bookings_source_src_28000.ds_partitioned) AS booking__ds_partitioned__day + , DATE_TRUNC('week', bookings_source_src_28000.ds_partitioned) AS booking__ds_partitioned__week + , DATE_TRUNC('month', bookings_source_src_28000.ds_partitioned) AS booking__ds_partitioned__month + , DATE_TRUNC('quarter', bookings_source_src_28000.ds_partitioned) AS booking__ds_partitioned__quarter + , DATE_TRUNC('year', bookings_source_src_28000.ds_partitioned) AS booking__ds_partitioned__year + , EXTRACT(year FROM bookings_source_src_28000.ds_partitioned) AS booking__ds_partitioned__extract_year + , EXTRACT(quarter FROM bookings_source_src_28000.ds_partitioned) AS booking__ds_partitioned__extract_quarter + , EXTRACT(month FROM bookings_source_src_28000.ds_partitioned) AS booking__ds_partitioned__extract_month + , EXTRACT(day FROM bookings_source_src_28000.ds_partitioned) AS booking__ds_partitioned__extract_day + , CASE WHEN EXTRACT(dow FROM bookings_source_src_28000.ds_partitioned) = 0 THEN EXTRACT(dow FROM bookings_source_src_28000.ds_partitioned) + 7 ELSE EXTRACT(dow FROM bookings_source_src_28000.ds_partitioned) END AS booking__ds_partitioned__extract_dow + , EXTRACT(doy FROM bookings_source_src_28000.ds_partitioned) AS booking__ds_partitioned__extract_doy + , DATE_TRUNC('day', bookings_source_src_28000.paid_at) AS booking__paid_at__day + , DATE_TRUNC('week', bookings_source_src_28000.paid_at) AS booking__paid_at__week + , DATE_TRUNC('month', bookings_source_src_28000.paid_at) AS booking__paid_at__month + , DATE_TRUNC('quarter', bookings_source_src_28000.paid_at) AS booking__paid_at__quarter + , DATE_TRUNC('year', bookings_source_src_28000.paid_at) AS booking__paid_at__year + , EXTRACT(year FROM bookings_source_src_28000.paid_at) AS booking__paid_at__extract_year + , EXTRACT(quarter FROM bookings_source_src_28000.paid_at) AS booking__paid_at__extract_quarter + , EXTRACT(month FROM bookings_source_src_28000.paid_at) AS booking__paid_at__extract_month + , EXTRACT(day FROM bookings_source_src_28000.paid_at) AS booking__paid_at__extract_day + , CASE WHEN EXTRACT(dow FROM bookings_source_src_28000.paid_at) = 0 THEN EXTRACT(dow FROM bookings_source_src_28000.paid_at) + 7 ELSE EXTRACT(dow FROM bookings_source_src_28000.paid_at) END AS booking__paid_at__extract_dow + , EXTRACT(doy FROM bookings_source_src_28000.paid_at) AS booking__paid_at__extract_doy + , bookings_source_src_28000.listing_id AS listing + , bookings_source_src_28000.guest_id AS guest + , bookings_source_src_28000.host_id AS host + , bookings_source_src_28000.listing_id AS booking__listing + , bookings_source_src_28000.guest_id AS booking__guest + , bookings_source_src_28000.host_id AS booking__host + FROM ***************************.fct_bookings bookings_source_src_28000 + ) subq_4 + ) subq_5 + ) subq_6 + LEFT OUTER JOIN ( + -- Pass Only Elements: ['guest', 'bookers'] + SELECT + subq_11.guest + , subq_11.bookers + FROM ( + -- Compute Metrics via Expressions + SELECT + subq_10.guest + , subq_10.bookers + FROM ( + -- Aggregate Measures + SELECT + subq_9.guest + , COUNT(DISTINCT subq_9.bookers) AS bookers + FROM ( + -- Pass Only Elements: ['bookers', 'guest'] + SELECT + subq_8.guest + , subq_8.bookers + FROM ( + -- Metric Time Dimension 'ds' + SELECT + subq_7.ds__day + , subq_7.ds__week + , subq_7.ds__month + , subq_7.ds__quarter + , subq_7.ds__year + , subq_7.ds__extract_year + , subq_7.ds__extract_quarter + , subq_7.ds__extract_month + , subq_7.ds__extract_day + , subq_7.ds__extract_dow + , subq_7.ds__extract_doy + , subq_7.ds_partitioned__day + , subq_7.ds_partitioned__week + , subq_7.ds_partitioned__month + , subq_7.ds_partitioned__quarter + , subq_7.ds_partitioned__year + , subq_7.ds_partitioned__extract_year + , subq_7.ds_partitioned__extract_quarter + , subq_7.ds_partitioned__extract_month + , subq_7.ds_partitioned__extract_day + , subq_7.ds_partitioned__extract_dow + , subq_7.ds_partitioned__extract_doy + , subq_7.paid_at__day + , subq_7.paid_at__week + , subq_7.paid_at__month + , subq_7.paid_at__quarter + , subq_7.paid_at__year + , subq_7.paid_at__extract_year + , subq_7.paid_at__extract_quarter + , subq_7.paid_at__extract_month + , subq_7.paid_at__extract_day + , subq_7.paid_at__extract_dow + , subq_7.paid_at__extract_doy + , subq_7.booking__ds__day + , subq_7.booking__ds__week + , subq_7.booking__ds__month + , subq_7.booking__ds__quarter + , subq_7.booking__ds__year + , subq_7.booking__ds__extract_year + , subq_7.booking__ds__extract_quarter + , subq_7.booking__ds__extract_month + , subq_7.booking__ds__extract_day + , subq_7.booking__ds__extract_dow + , subq_7.booking__ds__extract_doy + , subq_7.booking__ds_partitioned__day + , subq_7.booking__ds_partitioned__week + , subq_7.booking__ds_partitioned__month + , subq_7.booking__ds_partitioned__quarter + , subq_7.booking__ds_partitioned__year + , subq_7.booking__ds_partitioned__extract_year + , subq_7.booking__ds_partitioned__extract_quarter + , subq_7.booking__ds_partitioned__extract_month + , subq_7.booking__ds_partitioned__extract_day + , subq_7.booking__ds_partitioned__extract_dow + , subq_7.booking__ds_partitioned__extract_doy + , subq_7.booking__paid_at__day + , subq_7.booking__paid_at__week + , subq_7.booking__paid_at__month + , subq_7.booking__paid_at__quarter + , subq_7.booking__paid_at__year + , subq_7.booking__paid_at__extract_year + , subq_7.booking__paid_at__extract_quarter + , subq_7.booking__paid_at__extract_month + , subq_7.booking__paid_at__extract_day + , subq_7.booking__paid_at__extract_dow + , subq_7.booking__paid_at__extract_doy + , subq_7.ds__day AS metric_time__day + , subq_7.ds__week AS metric_time__week + , subq_7.ds__month AS metric_time__month + , subq_7.ds__quarter AS metric_time__quarter + , subq_7.ds__year AS metric_time__year + , subq_7.ds__extract_year AS metric_time__extract_year + , subq_7.ds__extract_quarter AS metric_time__extract_quarter + , subq_7.ds__extract_month AS metric_time__extract_month + , subq_7.ds__extract_day AS metric_time__extract_day + , subq_7.ds__extract_dow AS metric_time__extract_dow + , subq_7.ds__extract_doy AS metric_time__extract_doy + , subq_7.listing + , subq_7.guest + , subq_7.host + , subq_7.booking__listing + , subq_7.booking__guest + , subq_7.booking__host + , subq_7.is_instant + , subq_7.booking__is_instant + , subq_7.bookings + , subq_7.instant_bookings + , subq_7.booking_value + , subq_7.max_booking_value + , subq_7.min_booking_value + , subq_7.bookers + , subq_7.average_booking_value + , subq_7.referred_bookings + , subq_7.median_booking_value + , subq_7.booking_value_p99 + , subq_7.discrete_booking_value_p99 + , subq_7.approximate_continuous_booking_value_p99 + , subq_7.approximate_discrete_booking_value_p99 + FROM ( + -- Read Elements From Semantic Model 'bookings_source' + SELECT + 1 AS bookings + , CASE WHEN is_instant THEN 1 ELSE 0 END AS instant_bookings + , bookings_source_src_28000.booking_value + , bookings_source_src_28000.booking_value AS max_booking_value + , bookings_source_src_28000.booking_value AS min_booking_value + , bookings_source_src_28000.guest_id AS bookers + , bookings_source_src_28000.booking_value AS average_booking_value + , bookings_source_src_28000.booking_value AS booking_payments + , CASE WHEN referrer_id IS NOT NULL THEN 1 ELSE 0 END AS referred_bookings + , bookings_source_src_28000.booking_value AS median_booking_value + , bookings_source_src_28000.booking_value AS booking_value_p99 + , bookings_source_src_28000.booking_value AS discrete_booking_value_p99 + , bookings_source_src_28000.booking_value AS approximate_continuous_booking_value_p99 + , bookings_source_src_28000.booking_value AS approximate_discrete_booking_value_p99 + , bookings_source_src_28000.is_instant + , DATE_TRUNC('day', bookings_source_src_28000.ds) AS ds__day + , DATE_TRUNC('week', bookings_source_src_28000.ds) AS ds__week + , DATE_TRUNC('month', bookings_source_src_28000.ds) AS ds__month + , DATE_TRUNC('quarter', bookings_source_src_28000.ds) AS ds__quarter + , DATE_TRUNC('year', bookings_source_src_28000.ds) AS ds__year + , EXTRACT(year FROM bookings_source_src_28000.ds) AS ds__extract_year + , EXTRACT(quarter FROM bookings_source_src_28000.ds) AS ds__extract_quarter + , EXTRACT(month FROM bookings_source_src_28000.ds) AS ds__extract_month + , EXTRACT(day FROM bookings_source_src_28000.ds) AS ds__extract_day + , CASE WHEN EXTRACT(dow FROM bookings_source_src_28000.ds) = 0 THEN EXTRACT(dow FROM bookings_source_src_28000.ds) + 7 ELSE EXTRACT(dow FROM bookings_source_src_28000.ds) END AS ds__extract_dow + , EXTRACT(doy FROM bookings_source_src_28000.ds) AS ds__extract_doy + , DATE_TRUNC('day', bookings_source_src_28000.ds_partitioned) AS ds_partitioned__day + , DATE_TRUNC('week', bookings_source_src_28000.ds_partitioned) AS ds_partitioned__week + , DATE_TRUNC('month', bookings_source_src_28000.ds_partitioned) AS ds_partitioned__month + , DATE_TRUNC('quarter', bookings_source_src_28000.ds_partitioned) AS ds_partitioned__quarter + , DATE_TRUNC('year', bookings_source_src_28000.ds_partitioned) AS ds_partitioned__year + , EXTRACT(year FROM bookings_source_src_28000.ds_partitioned) AS ds_partitioned__extract_year + , EXTRACT(quarter FROM bookings_source_src_28000.ds_partitioned) AS ds_partitioned__extract_quarter + , EXTRACT(month FROM bookings_source_src_28000.ds_partitioned) AS ds_partitioned__extract_month + , EXTRACT(day FROM bookings_source_src_28000.ds_partitioned) AS ds_partitioned__extract_day + , CASE WHEN EXTRACT(dow FROM bookings_source_src_28000.ds_partitioned) = 0 THEN EXTRACT(dow FROM bookings_source_src_28000.ds_partitioned) + 7 ELSE EXTRACT(dow FROM bookings_source_src_28000.ds_partitioned) END AS ds_partitioned__extract_dow + , EXTRACT(doy FROM bookings_source_src_28000.ds_partitioned) AS ds_partitioned__extract_doy + , DATE_TRUNC('day', bookings_source_src_28000.paid_at) AS paid_at__day + , DATE_TRUNC('week', bookings_source_src_28000.paid_at) AS paid_at__week + , DATE_TRUNC('month', bookings_source_src_28000.paid_at) AS paid_at__month + , DATE_TRUNC('quarter', bookings_source_src_28000.paid_at) AS paid_at__quarter + , DATE_TRUNC('year', bookings_source_src_28000.paid_at) AS paid_at__year + , EXTRACT(year FROM bookings_source_src_28000.paid_at) AS paid_at__extract_year + , EXTRACT(quarter FROM bookings_source_src_28000.paid_at) AS paid_at__extract_quarter + , EXTRACT(month FROM bookings_source_src_28000.paid_at) AS paid_at__extract_month + , EXTRACT(day FROM bookings_source_src_28000.paid_at) AS paid_at__extract_day + , CASE WHEN EXTRACT(dow FROM bookings_source_src_28000.paid_at) = 0 THEN EXTRACT(dow FROM bookings_source_src_28000.paid_at) + 7 ELSE EXTRACT(dow FROM bookings_source_src_28000.paid_at) END AS paid_at__extract_dow + , EXTRACT(doy FROM bookings_source_src_28000.paid_at) AS paid_at__extract_doy + , bookings_source_src_28000.is_instant AS booking__is_instant + , DATE_TRUNC('day', bookings_source_src_28000.ds) AS booking__ds__day + , DATE_TRUNC('week', bookings_source_src_28000.ds) AS booking__ds__week + , DATE_TRUNC('month', bookings_source_src_28000.ds) AS booking__ds__month + , DATE_TRUNC('quarter', bookings_source_src_28000.ds) AS booking__ds__quarter + , DATE_TRUNC('year', bookings_source_src_28000.ds) AS booking__ds__year + , EXTRACT(year FROM bookings_source_src_28000.ds) AS booking__ds__extract_year + , EXTRACT(quarter FROM bookings_source_src_28000.ds) AS booking__ds__extract_quarter + , EXTRACT(month FROM bookings_source_src_28000.ds) AS booking__ds__extract_month + , EXTRACT(day FROM bookings_source_src_28000.ds) AS booking__ds__extract_day + , CASE WHEN EXTRACT(dow FROM bookings_source_src_28000.ds) = 0 THEN EXTRACT(dow FROM bookings_source_src_28000.ds) + 7 ELSE EXTRACT(dow FROM bookings_source_src_28000.ds) END AS booking__ds__extract_dow + , EXTRACT(doy FROM bookings_source_src_28000.ds) AS booking__ds__extract_doy + , DATE_TRUNC('day', bookings_source_src_28000.ds_partitioned) AS booking__ds_partitioned__day + , DATE_TRUNC('week', bookings_source_src_28000.ds_partitioned) AS booking__ds_partitioned__week + , DATE_TRUNC('month', bookings_source_src_28000.ds_partitioned) AS booking__ds_partitioned__month + , DATE_TRUNC('quarter', bookings_source_src_28000.ds_partitioned) AS booking__ds_partitioned__quarter + , DATE_TRUNC('year', bookings_source_src_28000.ds_partitioned) AS booking__ds_partitioned__year + , EXTRACT(year FROM bookings_source_src_28000.ds_partitioned) AS booking__ds_partitioned__extract_year + , EXTRACT(quarter FROM bookings_source_src_28000.ds_partitioned) AS booking__ds_partitioned__extract_quarter + , EXTRACT(month FROM bookings_source_src_28000.ds_partitioned) AS booking__ds_partitioned__extract_month + , EXTRACT(day FROM bookings_source_src_28000.ds_partitioned) AS booking__ds_partitioned__extract_day + , CASE WHEN EXTRACT(dow FROM bookings_source_src_28000.ds_partitioned) = 0 THEN EXTRACT(dow FROM bookings_source_src_28000.ds_partitioned) + 7 ELSE EXTRACT(dow FROM bookings_source_src_28000.ds_partitioned) END AS booking__ds_partitioned__extract_dow + , EXTRACT(doy FROM bookings_source_src_28000.ds_partitioned) AS booking__ds_partitioned__extract_doy + , DATE_TRUNC('day', bookings_source_src_28000.paid_at) AS booking__paid_at__day + , DATE_TRUNC('week', bookings_source_src_28000.paid_at) AS booking__paid_at__week + , DATE_TRUNC('month', bookings_source_src_28000.paid_at) AS booking__paid_at__month + , DATE_TRUNC('quarter', bookings_source_src_28000.paid_at) AS booking__paid_at__quarter + , DATE_TRUNC('year', bookings_source_src_28000.paid_at) AS booking__paid_at__year + , EXTRACT(year FROM bookings_source_src_28000.paid_at) AS booking__paid_at__extract_year + , EXTRACT(quarter FROM bookings_source_src_28000.paid_at) AS booking__paid_at__extract_quarter + , EXTRACT(month FROM bookings_source_src_28000.paid_at) AS booking__paid_at__extract_month + , EXTRACT(day FROM bookings_source_src_28000.paid_at) AS booking__paid_at__extract_day + , CASE WHEN EXTRACT(dow FROM bookings_source_src_28000.paid_at) = 0 THEN EXTRACT(dow FROM bookings_source_src_28000.paid_at) + 7 ELSE EXTRACT(dow FROM bookings_source_src_28000.paid_at) END AS booking__paid_at__extract_dow + , EXTRACT(doy FROM bookings_source_src_28000.paid_at) AS booking__paid_at__extract_doy + , bookings_source_src_28000.listing_id AS listing + , bookings_source_src_28000.guest_id AS guest + , bookings_source_src_28000.host_id AS host + , bookings_source_src_28000.listing_id AS booking__listing + , bookings_source_src_28000.guest_id AS booking__guest + , bookings_source_src_28000.host_id AS booking__host + FROM ***************************.fct_bookings bookings_source_src_28000 + ) subq_7 + ) subq_8 + ) subq_9 + GROUP BY + subq_9.guest + ) subq_10 + ) subq_11 + ) subq_12 + ON + subq_6.guest = subq_12.guest + ) subq_13 + ) subq_14 + WHERE guest__bookers > 1.00 + ) subq_15 + ) subq_16 +) subq_17 diff --git a/tests/snapshots/test_metric_filter_rendering.py/SqlQueryPlan/Redshift/test_metric_filtered_by_itself__plan0_optimized.sql b/tests/snapshots/test_metric_filter_rendering.py/SqlQueryPlan/Redshift/test_metric_filtered_by_itself__plan0_optimized.sql new file mode 100644 index 0000000000..eb7a693290 --- /dev/null +++ b/tests/snapshots/test_metric_filter_rendering.py/SqlQueryPlan/Redshift/test_metric_filtered_by_itself__plan0_optimized.sql @@ -0,0 +1,39 @@ +-- Constrain Output with WHERE +-- Pass Only Elements: ['bookers',] +-- Aggregate Measures +-- Compute Metrics via Expressions +SELECT + COUNT(DISTINCT bookers) AS bookers +FROM ( + -- Join Standard Outputs + -- Pass Only Elements: ['bookers', 'guest__bookers'] + SELECT + subq_26.bookers AS guest__bookers + , subq_20.bookers AS bookers + FROM ( + -- Read Elements From Semantic Model 'bookings_source' + -- Metric Time Dimension 'ds' + -- Pass Only Elements: ['bookers', 'guest'] + SELECT + guest_id AS guest + , guest_id AS bookers + FROM ***************************.fct_bookings bookings_source_src_28000 + ) subq_20 + LEFT OUTER JOIN ( + -- Read Elements From Semantic Model 'bookings_source' + -- Metric Time Dimension 'ds' + -- Pass Only Elements: ['bookers', 'guest'] + -- Aggregate Measures + -- Compute Metrics via Expressions + -- Pass Only Elements: ['guest', 'bookers'] + SELECT + guest_id AS guest + , COUNT(DISTINCT guest_id) AS bookers + FROM ***************************.fct_bookings bookings_source_src_28000 + GROUP BY + guest_id + ) subq_26 + ON + subq_20.guest = subq_26.guest +) subq_28 +WHERE guest__bookers > 1.00 diff --git a/tests/snapshots/test_metric_filter_rendering.py/SqlQueryPlan/Snowflake/test_metric_filtered_by_itself__plan0.sql b/tests/snapshots/test_metric_filter_rendering.py/SqlQueryPlan/Snowflake/test_metric_filtered_by_itself__plan0.sql new file mode 100644 index 0000000000..1bc92680bd --- /dev/null +++ b/tests/snapshots/test_metric_filter_rendering.py/SqlQueryPlan/Snowflake/test_metric_filtered_by_itself__plan0.sql @@ -0,0 +1,457 @@ +-- Compute Metrics via Expressions +SELECT + subq_17.bookers +FROM ( + -- Aggregate Measures + SELECT + COUNT(DISTINCT subq_16.bookers) AS bookers + FROM ( + -- Pass Only Elements: ['bookers',] + SELECT + subq_15.bookers + FROM ( + -- Constrain Output with WHERE + SELECT + subq_14.guest__bookers + , subq_14.bookers + FROM ( + -- Pass Only Elements: ['bookers', 'guest__bookers'] + SELECT + subq_13.guest__bookers + , subq_13.bookers + FROM ( + -- Join Standard Outputs + SELECT + subq_6.guest AS guest + , subq_12.bookers AS guest__bookers + , subq_6.bookers AS bookers + FROM ( + -- Pass Only Elements: ['bookers', 'guest'] + SELECT + subq_5.guest + , subq_5.bookers + FROM ( + -- Metric Time Dimension 'ds' + SELECT + subq_4.ds__day + , subq_4.ds__week + , subq_4.ds__month + , subq_4.ds__quarter + , subq_4.ds__year + , subq_4.ds__extract_year + , subq_4.ds__extract_quarter + , subq_4.ds__extract_month + , subq_4.ds__extract_day + , subq_4.ds__extract_dow + , subq_4.ds__extract_doy + , subq_4.ds_partitioned__day + , subq_4.ds_partitioned__week + , subq_4.ds_partitioned__month + , subq_4.ds_partitioned__quarter + , subq_4.ds_partitioned__year + , subq_4.ds_partitioned__extract_year + , subq_4.ds_partitioned__extract_quarter + , subq_4.ds_partitioned__extract_month + , subq_4.ds_partitioned__extract_day + , subq_4.ds_partitioned__extract_dow + , subq_4.ds_partitioned__extract_doy + , subq_4.paid_at__day + , subq_4.paid_at__week + , subq_4.paid_at__month + , subq_4.paid_at__quarter + , subq_4.paid_at__year + , subq_4.paid_at__extract_year + , subq_4.paid_at__extract_quarter + , subq_4.paid_at__extract_month + , subq_4.paid_at__extract_day + , subq_4.paid_at__extract_dow + , subq_4.paid_at__extract_doy + , subq_4.booking__ds__day + , subq_4.booking__ds__week + , subq_4.booking__ds__month + , subq_4.booking__ds__quarter + , subq_4.booking__ds__year + , subq_4.booking__ds__extract_year + , subq_4.booking__ds__extract_quarter + , subq_4.booking__ds__extract_month + , subq_4.booking__ds__extract_day + , subq_4.booking__ds__extract_dow + , subq_4.booking__ds__extract_doy + , subq_4.booking__ds_partitioned__day + , subq_4.booking__ds_partitioned__week + , subq_4.booking__ds_partitioned__month + , subq_4.booking__ds_partitioned__quarter + , subq_4.booking__ds_partitioned__year + , subq_4.booking__ds_partitioned__extract_year + , subq_4.booking__ds_partitioned__extract_quarter + , subq_4.booking__ds_partitioned__extract_month + , subq_4.booking__ds_partitioned__extract_day + , subq_4.booking__ds_partitioned__extract_dow + , subq_4.booking__ds_partitioned__extract_doy + , subq_4.booking__paid_at__day + , subq_4.booking__paid_at__week + , subq_4.booking__paid_at__month + , subq_4.booking__paid_at__quarter + , subq_4.booking__paid_at__year + , subq_4.booking__paid_at__extract_year + , subq_4.booking__paid_at__extract_quarter + , subq_4.booking__paid_at__extract_month + , subq_4.booking__paid_at__extract_day + , subq_4.booking__paid_at__extract_dow + , subq_4.booking__paid_at__extract_doy + , subq_4.ds__day AS metric_time__day + , subq_4.ds__week AS metric_time__week + , subq_4.ds__month AS metric_time__month + , subq_4.ds__quarter AS metric_time__quarter + , subq_4.ds__year AS metric_time__year + , subq_4.ds__extract_year AS metric_time__extract_year + , subq_4.ds__extract_quarter AS metric_time__extract_quarter + , subq_4.ds__extract_month AS metric_time__extract_month + , subq_4.ds__extract_day AS metric_time__extract_day + , subq_4.ds__extract_dow AS metric_time__extract_dow + , subq_4.ds__extract_doy AS metric_time__extract_doy + , subq_4.listing + , subq_4.guest + , subq_4.host + , subq_4.booking__listing + , subq_4.booking__guest + , subq_4.booking__host + , subq_4.is_instant + , subq_4.booking__is_instant + , subq_4.bookings + , subq_4.instant_bookings + , subq_4.booking_value + , subq_4.max_booking_value + , subq_4.min_booking_value + , subq_4.bookers + , subq_4.average_booking_value + , subq_4.referred_bookings + , subq_4.median_booking_value + , subq_4.booking_value_p99 + , subq_4.discrete_booking_value_p99 + , subq_4.approximate_continuous_booking_value_p99 + , subq_4.approximate_discrete_booking_value_p99 + FROM ( + -- Read Elements From Semantic Model 'bookings_source' + SELECT + 1 AS bookings + , CASE WHEN is_instant THEN 1 ELSE 0 END AS instant_bookings + , bookings_source_src_28000.booking_value + , bookings_source_src_28000.booking_value AS max_booking_value + , bookings_source_src_28000.booking_value AS min_booking_value + , bookings_source_src_28000.guest_id AS bookers + , bookings_source_src_28000.booking_value AS average_booking_value + , bookings_source_src_28000.booking_value AS booking_payments + , CASE WHEN referrer_id IS NOT NULL THEN 1 ELSE 0 END AS referred_bookings + , bookings_source_src_28000.booking_value AS median_booking_value + , bookings_source_src_28000.booking_value AS booking_value_p99 + , bookings_source_src_28000.booking_value AS discrete_booking_value_p99 + , bookings_source_src_28000.booking_value AS approximate_continuous_booking_value_p99 + , bookings_source_src_28000.booking_value AS approximate_discrete_booking_value_p99 + , bookings_source_src_28000.is_instant + , DATE_TRUNC('day', bookings_source_src_28000.ds) AS ds__day + , DATE_TRUNC('week', bookings_source_src_28000.ds) AS ds__week + , DATE_TRUNC('month', bookings_source_src_28000.ds) AS ds__month + , DATE_TRUNC('quarter', bookings_source_src_28000.ds) AS ds__quarter + , DATE_TRUNC('year', bookings_source_src_28000.ds) AS ds__year + , EXTRACT(year FROM bookings_source_src_28000.ds) AS ds__extract_year + , EXTRACT(quarter FROM bookings_source_src_28000.ds) AS ds__extract_quarter + , EXTRACT(month FROM bookings_source_src_28000.ds) AS ds__extract_month + , EXTRACT(day FROM bookings_source_src_28000.ds) AS ds__extract_day + , EXTRACT(dayofweekiso FROM bookings_source_src_28000.ds) AS ds__extract_dow + , EXTRACT(doy FROM bookings_source_src_28000.ds) AS ds__extract_doy + , DATE_TRUNC('day', bookings_source_src_28000.ds_partitioned) AS ds_partitioned__day + , DATE_TRUNC('week', bookings_source_src_28000.ds_partitioned) AS ds_partitioned__week + , DATE_TRUNC('month', bookings_source_src_28000.ds_partitioned) AS ds_partitioned__month + , DATE_TRUNC('quarter', bookings_source_src_28000.ds_partitioned) AS ds_partitioned__quarter + , DATE_TRUNC('year', bookings_source_src_28000.ds_partitioned) AS ds_partitioned__year + , EXTRACT(year FROM bookings_source_src_28000.ds_partitioned) AS ds_partitioned__extract_year + , EXTRACT(quarter FROM bookings_source_src_28000.ds_partitioned) AS ds_partitioned__extract_quarter + , EXTRACT(month FROM bookings_source_src_28000.ds_partitioned) AS ds_partitioned__extract_month + , EXTRACT(day FROM bookings_source_src_28000.ds_partitioned) AS ds_partitioned__extract_day + , EXTRACT(dayofweekiso FROM bookings_source_src_28000.ds_partitioned) AS ds_partitioned__extract_dow + , EXTRACT(doy FROM bookings_source_src_28000.ds_partitioned) AS ds_partitioned__extract_doy + , DATE_TRUNC('day', bookings_source_src_28000.paid_at) AS paid_at__day + , DATE_TRUNC('week', bookings_source_src_28000.paid_at) AS paid_at__week + , DATE_TRUNC('month', bookings_source_src_28000.paid_at) AS paid_at__month + , DATE_TRUNC('quarter', bookings_source_src_28000.paid_at) AS paid_at__quarter + , DATE_TRUNC('year', bookings_source_src_28000.paid_at) AS paid_at__year + , EXTRACT(year FROM bookings_source_src_28000.paid_at) AS paid_at__extract_year + , EXTRACT(quarter FROM bookings_source_src_28000.paid_at) AS paid_at__extract_quarter + , EXTRACT(month FROM bookings_source_src_28000.paid_at) AS paid_at__extract_month + , EXTRACT(day FROM bookings_source_src_28000.paid_at) AS paid_at__extract_day + , EXTRACT(dayofweekiso FROM bookings_source_src_28000.paid_at) AS paid_at__extract_dow + , EXTRACT(doy FROM bookings_source_src_28000.paid_at) AS paid_at__extract_doy + , bookings_source_src_28000.is_instant AS booking__is_instant + , DATE_TRUNC('day', bookings_source_src_28000.ds) AS booking__ds__day + , DATE_TRUNC('week', bookings_source_src_28000.ds) AS booking__ds__week + , DATE_TRUNC('month', bookings_source_src_28000.ds) AS booking__ds__month + , DATE_TRUNC('quarter', bookings_source_src_28000.ds) AS booking__ds__quarter + , DATE_TRUNC('year', bookings_source_src_28000.ds) AS booking__ds__year + , EXTRACT(year FROM bookings_source_src_28000.ds) AS booking__ds__extract_year + , EXTRACT(quarter FROM bookings_source_src_28000.ds) AS booking__ds__extract_quarter + , EXTRACT(month FROM bookings_source_src_28000.ds) AS booking__ds__extract_month + , EXTRACT(day FROM bookings_source_src_28000.ds) AS booking__ds__extract_day + , EXTRACT(dayofweekiso FROM bookings_source_src_28000.ds) AS booking__ds__extract_dow + , EXTRACT(doy FROM bookings_source_src_28000.ds) AS booking__ds__extract_doy + , DATE_TRUNC('day', bookings_source_src_28000.ds_partitioned) AS booking__ds_partitioned__day + , DATE_TRUNC('week', bookings_source_src_28000.ds_partitioned) AS booking__ds_partitioned__week + , DATE_TRUNC('month', bookings_source_src_28000.ds_partitioned) AS booking__ds_partitioned__month + , DATE_TRUNC('quarter', bookings_source_src_28000.ds_partitioned) AS booking__ds_partitioned__quarter + , DATE_TRUNC('year', bookings_source_src_28000.ds_partitioned) AS booking__ds_partitioned__year + , EXTRACT(year FROM bookings_source_src_28000.ds_partitioned) AS booking__ds_partitioned__extract_year + , EXTRACT(quarter FROM bookings_source_src_28000.ds_partitioned) AS booking__ds_partitioned__extract_quarter + , EXTRACT(month FROM bookings_source_src_28000.ds_partitioned) AS booking__ds_partitioned__extract_month + , EXTRACT(day FROM bookings_source_src_28000.ds_partitioned) AS booking__ds_partitioned__extract_day + , EXTRACT(dayofweekiso FROM bookings_source_src_28000.ds_partitioned) AS booking__ds_partitioned__extract_dow + , EXTRACT(doy FROM bookings_source_src_28000.ds_partitioned) AS booking__ds_partitioned__extract_doy + , DATE_TRUNC('day', bookings_source_src_28000.paid_at) AS booking__paid_at__day + , DATE_TRUNC('week', bookings_source_src_28000.paid_at) AS booking__paid_at__week + , DATE_TRUNC('month', bookings_source_src_28000.paid_at) AS booking__paid_at__month + , DATE_TRUNC('quarter', bookings_source_src_28000.paid_at) AS booking__paid_at__quarter + , DATE_TRUNC('year', bookings_source_src_28000.paid_at) AS booking__paid_at__year + , EXTRACT(year FROM bookings_source_src_28000.paid_at) AS booking__paid_at__extract_year + , EXTRACT(quarter FROM bookings_source_src_28000.paid_at) AS booking__paid_at__extract_quarter + , EXTRACT(month FROM bookings_source_src_28000.paid_at) AS booking__paid_at__extract_month + , EXTRACT(day FROM bookings_source_src_28000.paid_at) AS booking__paid_at__extract_day + , EXTRACT(dayofweekiso FROM bookings_source_src_28000.paid_at) AS booking__paid_at__extract_dow + , EXTRACT(doy FROM bookings_source_src_28000.paid_at) AS booking__paid_at__extract_doy + , bookings_source_src_28000.listing_id AS listing + , bookings_source_src_28000.guest_id AS guest + , bookings_source_src_28000.host_id AS host + , bookings_source_src_28000.listing_id AS booking__listing + , bookings_source_src_28000.guest_id AS booking__guest + , bookings_source_src_28000.host_id AS booking__host + FROM ***************************.fct_bookings bookings_source_src_28000 + ) subq_4 + ) subq_5 + ) subq_6 + LEFT OUTER JOIN ( + -- Pass Only Elements: ['guest', 'bookers'] + SELECT + subq_11.guest + , subq_11.bookers + FROM ( + -- Compute Metrics via Expressions + SELECT + subq_10.guest + , subq_10.bookers + FROM ( + -- Aggregate Measures + SELECT + subq_9.guest + , COUNT(DISTINCT subq_9.bookers) AS bookers + FROM ( + -- Pass Only Elements: ['bookers', 'guest'] + SELECT + subq_8.guest + , subq_8.bookers + FROM ( + -- Metric Time Dimension 'ds' + SELECT + subq_7.ds__day + , subq_7.ds__week + , subq_7.ds__month + , subq_7.ds__quarter + , subq_7.ds__year + , subq_7.ds__extract_year + , subq_7.ds__extract_quarter + , subq_7.ds__extract_month + , subq_7.ds__extract_day + , subq_7.ds__extract_dow + , subq_7.ds__extract_doy + , subq_7.ds_partitioned__day + , subq_7.ds_partitioned__week + , subq_7.ds_partitioned__month + , subq_7.ds_partitioned__quarter + , subq_7.ds_partitioned__year + , subq_7.ds_partitioned__extract_year + , subq_7.ds_partitioned__extract_quarter + , subq_7.ds_partitioned__extract_month + , subq_7.ds_partitioned__extract_day + , subq_7.ds_partitioned__extract_dow + , subq_7.ds_partitioned__extract_doy + , subq_7.paid_at__day + , subq_7.paid_at__week + , subq_7.paid_at__month + , subq_7.paid_at__quarter + , subq_7.paid_at__year + , subq_7.paid_at__extract_year + , subq_7.paid_at__extract_quarter + , subq_7.paid_at__extract_month + , subq_7.paid_at__extract_day + , subq_7.paid_at__extract_dow + , subq_7.paid_at__extract_doy + , subq_7.booking__ds__day + , subq_7.booking__ds__week + , subq_7.booking__ds__month + , subq_7.booking__ds__quarter + , subq_7.booking__ds__year + , subq_7.booking__ds__extract_year + , subq_7.booking__ds__extract_quarter + , subq_7.booking__ds__extract_month + , subq_7.booking__ds__extract_day + , subq_7.booking__ds__extract_dow + , subq_7.booking__ds__extract_doy + , subq_7.booking__ds_partitioned__day + , subq_7.booking__ds_partitioned__week + , subq_7.booking__ds_partitioned__month + , subq_7.booking__ds_partitioned__quarter + , subq_7.booking__ds_partitioned__year + , subq_7.booking__ds_partitioned__extract_year + , subq_7.booking__ds_partitioned__extract_quarter + , subq_7.booking__ds_partitioned__extract_month + , subq_7.booking__ds_partitioned__extract_day + , subq_7.booking__ds_partitioned__extract_dow + , subq_7.booking__ds_partitioned__extract_doy + , subq_7.booking__paid_at__day + , subq_7.booking__paid_at__week + , subq_7.booking__paid_at__month + , subq_7.booking__paid_at__quarter + , subq_7.booking__paid_at__year + , subq_7.booking__paid_at__extract_year + , subq_7.booking__paid_at__extract_quarter + , subq_7.booking__paid_at__extract_month + , subq_7.booking__paid_at__extract_day + , subq_7.booking__paid_at__extract_dow + , subq_7.booking__paid_at__extract_doy + , subq_7.ds__day AS metric_time__day + , subq_7.ds__week AS metric_time__week + , subq_7.ds__month AS metric_time__month + , subq_7.ds__quarter AS metric_time__quarter + , subq_7.ds__year AS metric_time__year + , subq_7.ds__extract_year AS metric_time__extract_year + , subq_7.ds__extract_quarter AS metric_time__extract_quarter + , subq_7.ds__extract_month AS metric_time__extract_month + , subq_7.ds__extract_day AS metric_time__extract_day + , subq_7.ds__extract_dow AS metric_time__extract_dow + , subq_7.ds__extract_doy AS metric_time__extract_doy + , subq_7.listing + , subq_7.guest + , subq_7.host + , subq_7.booking__listing + , subq_7.booking__guest + , subq_7.booking__host + , subq_7.is_instant + , subq_7.booking__is_instant + , subq_7.bookings + , subq_7.instant_bookings + , subq_7.booking_value + , subq_7.max_booking_value + , subq_7.min_booking_value + , subq_7.bookers + , subq_7.average_booking_value + , subq_7.referred_bookings + , subq_7.median_booking_value + , subq_7.booking_value_p99 + , subq_7.discrete_booking_value_p99 + , subq_7.approximate_continuous_booking_value_p99 + , subq_7.approximate_discrete_booking_value_p99 + FROM ( + -- Read Elements From Semantic Model 'bookings_source' + SELECT + 1 AS bookings + , CASE WHEN is_instant THEN 1 ELSE 0 END AS instant_bookings + , bookings_source_src_28000.booking_value + , bookings_source_src_28000.booking_value AS max_booking_value + , bookings_source_src_28000.booking_value AS min_booking_value + , bookings_source_src_28000.guest_id AS bookers + , bookings_source_src_28000.booking_value AS average_booking_value + , bookings_source_src_28000.booking_value AS booking_payments + , CASE WHEN referrer_id IS NOT NULL THEN 1 ELSE 0 END AS referred_bookings + , bookings_source_src_28000.booking_value AS median_booking_value + , bookings_source_src_28000.booking_value AS booking_value_p99 + , bookings_source_src_28000.booking_value AS discrete_booking_value_p99 + , bookings_source_src_28000.booking_value AS approximate_continuous_booking_value_p99 + , bookings_source_src_28000.booking_value AS approximate_discrete_booking_value_p99 + , bookings_source_src_28000.is_instant + , DATE_TRUNC('day', bookings_source_src_28000.ds) AS ds__day + , DATE_TRUNC('week', bookings_source_src_28000.ds) AS ds__week + , DATE_TRUNC('month', bookings_source_src_28000.ds) AS ds__month + , DATE_TRUNC('quarter', bookings_source_src_28000.ds) AS ds__quarter + , DATE_TRUNC('year', bookings_source_src_28000.ds) AS ds__year + , EXTRACT(year FROM bookings_source_src_28000.ds) AS ds__extract_year + , EXTRACT(quarter FROM bookings_source_src_28000.ds) AS ds__extract_quarter + , EXTRACT(month FROM bookings_source_src_28000.ds) AS ds__extract_month + , EXTRACT(day FROM bookings_source_src_28000.ds) AS ds__extract_day + , EXTRACT(dayofweekiso FROM bookings_source_src_28000.ds) AS ds__extract_dow + , EXTRACT(doy FROM bookings_source_src_28000.ds) AS ds__extract_doy + , DATE_TRUNC('day', bookings_source_src_28000.ds_partitioned) AS ds_partitioned__day + , DATE_TRUNC('week', bookings_source_src_28000.ds_partitioned) AS ds_partitioned__week + , DATE_TRUNC('month', bookings_source_src_28000.ds_partitioned) AS ds_partitioned__month + , DATE_TRUNC('quarter', bookings_source_src_28000.ds_partitioned) AS ds_partitioned__quarter + , DATE_TRUNC('year', bookings_source_src_28000.ds_partitioned) AS ds_partitioned__year + , EXTRACT(year FROM bookings_source_src_28000.ds_partitioned) AS ds_partitioned__extract_year + , EXTRACT(quarter FROM bookings_source_src_28000.ds_partitioned) AS ds_partitioned__extract_quarter + , EXTRACT(month FROM bookings_source_src_28000.ds_partitioned) AS ds_partitioned__extract_month + , EXTRACT(day FROM bookings_source_src_28000.ds_partitioned) AS ds_partitioned__extract_day + , EXTRACT(dayofweekiso FROM bookings_source_src_28000.ds_partitioned) AS ds_partitioned__extract_dow + , EXTRACT(doy FROM bookings_source_src_28000.ds_partitioned) AS ds_partitioned__extract_doy + , DATE_TRUNC('day', bookings_source_src_28000.paid_at) AS paid_at__day + , DATE_TRUNC('week', bookings_source_src_28000.paid_at) AS paid_at__week + , DATE_TRUNC('month', bookings_source_src_28000.paid_at) AS paid_at__month + , DATE_TRUNC('quarter', bookings_source_src_28000.paid_at) AS paid_at__quarter + , DATE_TRUNC('year', bookings_source_src_28000.paid_at) AS paid_at__year + , EXTRACT(year FROM bookings_source_src_28000.paid_at) AS paid_at__extract_year + , EXTRACT(quarter FROM bookings_source_src_28000.paid_at) AS paid_at__extract_quarter + , EXTRACT(month FROM bookings_source_src_28000.paid_at) AS paid_at__extract_month + , EXTRACT(day FROM bookings_source_src_28000.paid_at) AS paid_at__extract_day + , EXTRACT(dayofweekiso FROM bookings_source_src_28000.paid_at) AS paid_at__extract_dow + , EXTRACT(doy FROM bookings_source_src_28000.paid_at) AS paid_at__extract_doy + , bookings_source_src_28000.is_instant AS booking__is_instant + , DATE_TRUNC('day', bookings_source_src_28000.ds) AS booking__ds__day + , DATE_TRUNC('week', bookings_source_src_28000.ds) AS booking__ds__week + , DATE_TRUNC('month', bookings_source_src_28000.ds) AS booking__ds__month + , DATE_TRUNC('quarter', bookings_source_src_28000.ds) AS booking__ds__quarter + , DATE_TRUNC('year', bookings_source_src_28000.ds) AS booking__ds__year + , EXTRACT(year FROM bookings_source_src_28000.ds) AS booking__ds__extract_year + , EXTRACT(quarter FROM bookings_source_src_28000.ds) AS booking__ds__extract_quarter + , EXTRACT(month FROM bookings_source_src_28000.ds) AS booking__ds__extract_month + , EXTRACT(day FROM bookings_source_src_28000.ds) AS booking__ds__extract_day + , EXTRACT(dayofweekiso FROM bookings_source_src_28000.ds) AS booking__ds__extract_dow + , EXTRACT(doy FROM bookings_source_src_28000.ds) AS booking__ds__extract_doy + , DATE_TRUNC('day', bookings_source_src_28000.ds_partitioned) AS booking__ds_partitioned__day + , DATE_TRUNC('week', bookings_source_src_28000.ds_partitioned) AS booking__ds_partitioned__week + , DATE_TRUNC('month', bookings_source_src_28000.ds_partitioned) AS booking__ds_partitioned__month + , DATE_TRUNC('quarter', bookings_source_src_28000.ds_partitioned) AS booking__ds_partitioned__quarter + , DATE_TRUNC('year', bookings_source_src_28000.ds_partitioned) AS booking__ds_partitioned__year + , EXTRACT(year FROM bookings_source_src_28000.ds_partitioned) AS booking__ds_partitioned__extract_year + , EXTRACT(quarter FROM bookings_source_src_28000.ds_partitioned) AS booking__ds_partitioned__extract_quarter + , EXTRACT(month FROM bookings_source_src_28000.ds_partitioned) AS booking__ds_partitioned__extract_month + , EXTRACT(day FROM bookings_source_src_28000.ds_partitioned) AS booking__ds_partitioned__extract_day + , EXTRACT(dayofweekiso FROM bookings_source_src_28000.ds_partitioned) AS booking__ds_partitioned__extract_dow + , EXTRACT(doy FROM bookings_source_src_28000.ds_partitioned) AS booking__ds_partitioned__extract_doy + , DATE_TRUNC('day', bookings_source_src_28000.paid_at) AS booking__paid_at__day + , DATE_TRUNC('week', bookings_source_src_28000.paid_at) AS booking__paid_at__week + , DATE_TRUNC('month', bookings_source_src_28000.paid_at) AS booking__paid_at__month + , DATE_TRUNC('quarter', bookings_source_src_28000.paid_at) AS booking__paid_at__quarter + , DATE_TRUNC('year', bookings_source_src_28000.paid_at) AS booking__paid_at__year + , EXTRACT(year FROM bookings_source_src_28000.paid_at) AS booking__paid_at__extract_year + , EXTRACT(quarter FROM bookings_source_src_28000.paid_at) AS booking__paid_at__extract_quarter + , EXTRACT(month FROM bookings_source_src_28000.paid_at) AS booking__paid_at__extract_month + , EXTRACT(day FROM bookings_source_src_28000.paid_at) AS booking__paid_at__extract_day + , EXTRACT(dayofweekiso FROM bookings_source_src_28000.paid_at) AS booking__paid_at__extract_dow + , EXTRACT(doy FROM bookings_source_src_28000.paid_at) AS booking__paid_at__extract_doy + , bookings_source_src_28000.listing_id AS listing + , bookings_source_src_28000.guest_id AS guest + , bookings_source_src_28000.host_id AS host + , bookings_source_src_28000.listing_id AS booking__listing + , bookings_source_src_28000.guest_id AS booking__guest + , bookings_source_src_28000.host_id AS booking__host + FROM ***************************.fct_bookings bookings_source_src_28000 + ) subq_7 + ) subq_8 + ) subq_9 + GROUP BY + subq_9.guest + ) subq_10 + ) subq_11 + ) subq_12 + ON + subq_6.guest = subq_12.guest + ) subq_13 + ) subq_14 + WHERE guest__bookers > 1.00 + ) subq_15 + ) subq_16 +) subq_17 diff --git a/tests/snapshots/test_metric_filter_rendering.py/SqlQueryPlan/Snowflake/test_metric_filtered_by_itself__plan0_optimized.sql b/tests/snapshots/test_metric_filter_rendering.py/SqlQueryPlan/Snowflake/test_metric_filtered_by_itself__plan0_optimized.sql new file mode 100644 index 0000000000..eb7a693290 --- /dev/null +++ b/tests/snapshots/test_metric_filter_rendering.py/SqlQueryPlan/Snowflake/test_metric_filtered_by_itself__plan0_optimized.sql @@ -0,0 +1,39 @@ +-- Constrain Output with WHERE +-- Pass Only Elements: ['bookers',] +-- Aggregate Measures +-- Compute Metrics via Expressions +SELECT + COUNT(DISTINCT bookers) AS bookers +FROM ( + -- Join Standard Outputs + -- Pass Only Elements: ['bookers', 'guest__bookers'] + SELECT + subq_26.bookers AS guest__bookers + , subq_20.bookers AS bookers + FROM ( + -- Read Elements From Semantic Model 'bookings_source' + -- Metric Time Dimension 'ds' + -- Pass Only Elements: ['bookers', 'guest'] + SELECT + guest_id AS guest + , guest_id AS bookers + FROM ***************************.fct_bookings bookings_source_src_28000 + ) subq_20 + LEFT OUTER JOIN ( + -- Read Elements From Semantic Model 'bookings_source' + -- Metric Time Dimension 'ds' + -- Pass Only Elements: ['bookers', 'guest'] + -- Aggregate Measures + -- Compute Metrics via Expressions + -- Pass Only Elements: ['guest', 'bookers'] + SELECT + guest_id AS guest + , COUNT(DISTINCT guest_id) AS bookers + FROM ***************************.fct_bookings bookings_source_src_28000 + GROUP BY + guest_id + ) subq_26 + ON + subq_20.guest = subq_26.guest +) subq_28 +WHERE guest__bookers > 1.00 diff --git a/tests/snapshots/test_metric_filter_rendering.py/SqlQueryPlan/Trino/test_metric_filtered_by_itself__plan0.sql b/tests/snapshots/test_metric_filter_rendering.py/SqlQueryPlan/Trino/test_metric_filtered_by_itself__plan0.sql new file mode 100644 index 0000000000..5c48f6bfd7 --- /dev/null +++ b/tests/snapshots/test_metric_filter_rendering.py/SqlQueryPlan/Trino/test_metric_filtered_by_itself__plan0.sql @@ -0,0 +1,457 @@ +-- Compute Metrics via Expressions +SELECT + subq_17.bookers +FROM ( + -- Aggregate Measures + SELECT + COUNT(DISTINCT subq_16.bookers) AS bookers + FROM ( + -- Pass Only Elements: ['bookers',] + SELECT + subq_15.bookers + FROM ( + -- Constrain Output with WHERE + SELECT + subq_14.guest__bookers + , subq_14.bookers + FROM ( + -- Pass Only Elements: ['bookers', 'guest__bookers'] + SELECT + subq_13.guest__bookers + , subq_13.bookers + FROM ( + -- Join Standard Outputs + SELECT + subq_6.guest AS guest + , subq_12.bookers AS guest__bookers + , subq_6.bookers AS bookers + FROM ( + -- Pass Only Elements: ['bookers', 'guest'] + SELECT + subq_5.guest + , subq_5.bookers + FROM ( + -- Metric Time Dimension 'ds' + SELECT + subq_4.ds__day + , subq_4.ds__week + , subq_4.ds__month + , subq_4.ds__quarter + , subq_4.ds__year + , subq_4.ds__extract_year + , subq_4.ds__extract_quarter + , subq_4.ds__extract_month + , subq_4.ds__extract_day + , subq_4.ds__extract_dow + , subq_4.ds__extract_doy + , subq_4.ds_partitioned__day + , subq_4.ds_partitioned__week + , subq_4.ds_partitioned__month + , subq_4.ds_partitioned__quarter + , subq_4.ds_partitioned__year + , subq_4.ds_partitioned__extract_year + , subq_4.ds_partitioned__extract_quarter + , subq_4.ds_partitioned__extract_month + , subq_4.ds_partitioned__extract_day + , subq_4.ds_partitioned__extract_dow + , subq_4.ds_partitioned__extract_doy + , subq_4.paid_at__day + , subq_4.paid_at__week + , subq_4.paid_at__month + , subq_4.paid_at__quarter + , subq_4.paid_at__year + , subq_4.paid_at__extract_year + , subq_4.paid_at__extract_quarter + , subq_4.paid_at__extract_month + , subq_4.paid_at__extract_day + , subq_4.paid_at__extract_dow + , subq_4.paid_at__extract_doy + , subq_4.booking__ds__day + , subq_4.booking__ds__week + , subq_4.booking__ds__month + , subq_4.booking__ds__quarter + , subq_4.booking__ds__year + , subq_4.booking__ds__extract_year + , subq_4.booking__ds__extract_quarter + , subq_4.booking__ds__extract_month + , subq_4.booking__ds__extract_day + , subq_4.booking__ds__extract_dow + , subq_4.booking__ds__extract_doy + , subq_4.booking__ds_partitioned__day + , subq_4.booking__ds_partitioned__week + , subq_4.booking__ds_partitioned__month + , subq_4.booking__ds_partitioned__quarter + , subq_4.booking__ds_partitioned__year + , subq_4.booking__ds_partitioned__extract_year + , subq_4.booking__ds_partitioned__extract_quarter + , subq_4.booking__ds_partitioned__extract_month + , subq_4.booking__ds_partitioned__extract_day + , subq_4.booking__ds_partitioned__extract_dow + , subq_4.booking__ds_partitioned__extract_doy + , subq_4.booking__paid_at__day + , subq_4.booking__paid_at__week + , subq_4.booking__paid_at__month + , subq_4.booking__paid_at__quarter + , subq_4.booking__paid_at__year + , subq_4.booking__paid_at__extract_year + , subq_4.booking__paid_at__extract_quarter + , subq_4.booking__paid_at__extract_month + , subq_4.booking__paid_at__extract_day + , subq_4.booking__paid_at__extract_dow + , subq_4.booking__paid_at__extract_doy + , subq_4.ds__day AS metric_time__day + , subq_4.ds__week AS metric_time__week + , subq_4.ds__month AS metric_time__month + , subq_4.ds__quarter AS metric_time__quarter + , subq_4.ds__year AS metric_time__year + , subq_4.ds__extract_year AS metric_time__extract_year + , subq_4.ds__extract_quarter AS metric_time__extract_quarter + , subq_4.ds__extract_month AS metric_time__extract_month + , subq_4.ds__extract_day AS metric_time__extract_day + , subq_4.ds__extract_dow AS metric_time__extract_dow + , subq_4.ds__extract_doy AS metric_time__extract_doy + , subq_4.listing + , subq_4.guest + , subq_4.host + , subq_4.booking__listing + , subq_4.booking__guest + , subq_4.booking__host + , subq_4.is_instant + , subq_4.booking__is_instant + , subq_4.bookings + , subq_4.instant_bookings + , subq_4.booking_value + , subq_4.max_booking_value + , subq_4.min_booking_value + , subq_4.bookers + , subq_4.average_booking_value + , subq_4.referred_bookings + , subq_4.median_booking_value + , subq_4.booking_value_p99 + , subq_4.discrete_booking_value_p99 + , subq_4.approximate_continuous_booking_value_p99 + , subq_4.approximate_discrete_booking_value_p99 + FROM ( + -- Read Elements From Semantic Model 'bookings_source' + SELECT + 1 AS bookings + , CASE WHEN is_instant THEN 1 ELSE 0 END AS instant_bookings + , bookings_source_src_28000.booking_value + , bookings_source_src_28000.booking_value AS max_booking_value + , bookings_source_src_28000.booking_value AS min_booking_value + , bookings_source_src_28000.guest_id AS bookers + , bookings_source_src_28000.booking_value AS average_booking_value + , bookings_source_src_28000.booking_value AS booking_payments + , CASE WHEN referrer_id IS NOT NULL THEN 1 ELSE 0 END AS referred_bookings + , bookings_source_src_28000.booking_value AS median_booking_value + , bookings_source_src_28000.booking_value AS booking_value_p99 + , bookings_source_src_28000.booking_value AS discrete_booking_value_p99 + , bookings_source_src_28000.booking_value AS approximate_continuous_booking_value_p99 + , bookings_source_src_28000.booking_value AS approximate_discrete_booking_value_p99 + , bookings_source_src_28000.is_instant + , DATE_TRUNC('day', bookings_source_src_28000.ds) AS ds__day + , DATE_TRUNC('week', bookings_source_src_28000.ds) AS ds__week + , DATE_TRUNC('month', bookings_source_src_28000.ds) AS ds__month + , DATE_TRUNC('quarter', bookings_source_src_28000.ds) AS ds__quarter + , DATE_TRUNC('year', bookings_source_src_28000.ds) AS ds__year + , EXTRACT(year FROM bookings_source_src_28000.ds) AS ds__extract_year + , EXTRACT(quarter FROM bookings_source_src_28000.ds) AS ds__extract_quarter + , EXTRACT(month FROM bookings_source_src_28000.ds) AS ds__extract_month + , EXTRACT(day FROM bookings_source_src_28000.ds) AS ds__extract_day + , EXTRACT(DAY_OF_WEEK FROM bookings_source_src_28000.ds) AS ds__extract_dow + , EXTRACT(doy FROM bookings_source_src_28000.ds) AS ds__extract_doy + , DATE_TRUNC('day', bookings_source_src_28000.ds_partitioned) AS ds_partitioned__day + , DATE_TRUNC('week', bookings_source_src_28000.ds_partitioned) AS ds_partitioned__week + , DATE_TRUNC('month', bookings_source_src_28000.ds_partitioned) AS ds_partitioned__month + , DATE_TRUNC('quarter', bookings_source_src_28000.ds_partitioned) AS ds_partitioned__quarter + , DATE_TRUNC('year', bookings_source_src_28000.ds_partitioned) AS ds_partitioned__year + , EXTRACT(year FROM bookings_source_src_28000.ds_partitioned) AS ds_partitioned__extract_year + , EXTRACT(quarter FROM bookings_source_src_28000.ds_partitioned) AS ds_partitioned__extract_quarter + , EXTRACT(month FROM bookings_source_src_28000.ds_partitioned) AS ds_partitioned__extract_month + , EXTRACT(day FROM bookings_source_src_28000.ds_partitioned) AS ds_partitioned__extract_day + , EXTRACT(DAY_OF_WEEK FROM bookings_source_src_28000.ds_partitioned) AS ds_partitioned__extract_dow + , EXTRACT(doy FROM bookings_source_src_28000.ds_partitioned) AS ds_partitioned__extract_doy + , DATE_TRUNC('day', bookings_source_src_28000.paid_at) AS paid_at__day + , DATE_TRUNC('week', bookings_source_src_28000.paid_at) AS paid_at__week + , DATE_TRUNC('month', bookings_source_src_28000.paid_at) AS paid_at__month + , DATE_TRUNC('quarter', bookings_source_src_28000.paid_at) AS paid_at__quarter + , DATE_TRUNC('year', bookings_source_src_28000.paid_at) AS paid_at__year + , EXTRACT(year FROM bookings_source_src_28000.paid_at) AS paid_at__extract_year + , EXTRACT(quarter FROM bookings_source_src_28000.paid_at) AS paid_at__extract_quarter + , EXTRACT(month FROM bookings_source_src_28000.paid_at) AS paid_at__extract_month + , EXTRACT(day FROM bookings_source_src_28000.paid_at) AS paid_at__extract_day + , EXTRACT(DAY_OF_WEEK FROM bookings_source_src_28000.paid_at) AS paid_at__extract_dow + , EXTRACT(doy FROM bookings_source_src_28000.paid_at) AS paid_at__extract_doy + , bookings_source_src_28000.is_instant AS booking__is_instant + , DATE_TRUNC('day', bookings_source_src_28000.ds) AS booking__ds__day + , DATE_TRUNC('week', bookings_source_src_28000.ds) AS booking__ds__week + , DATE_TRUNC('month', bookings_source_src_28000.ds) AS booking__ds__month + , DATE_TRUNC('quarter', bookings_source_src_28000.ds) AS booking__ds__quarter + , DATE_TRUNC('year', bookings_source_src_28000.ds) AS booking__ds__year + , EXTRACT(year FROM bookings_source_src_28000.ds) AS booking__ds__extract_year + , EXTRACT(quarter FROM bookings_source_src_28000.ds) AS booking__ds__extract_quarter + , EXTRACT(month FROM bookings_source_src_28000.ds) AS booking__ds__extract_month + , EXTRACT(day FROM bookings_source_src_28000.ds) AS booking__ds__extract_day + , EXTRACT(DAY_OF_WEEK FROM bookings_source_src_28000.ds) AS booking__ds__extract_dow + , EXTRACT(doy FROM bookings_source_src_28000.ds) AS booking__ds__extract_doy + , DATE_TRUNC('day', bookings_source_src_28000.ds_partitioned) AS booking__ds_partitioned__day + , DATE_TRUNC('week', bookings_source_src_28000.ds_partitioned) AS booking__ds_partitioned__week + , DATE_TRUNC('month', bookings_source_src_28000.ds_partitioned) AS booking__ds_partitioned__month + , DATE_TRUNC('quarter', bookings_source_src_28000.ds_partitioned) AS booking__ds_partitioned__quarter + , DATE_TRUNC('year', bookings_source_src_28000.ds_partitioned) AS booking__ds_partitioned__year + , EXTRACT(year FROM bookings_source_src_28000.ds_partitioned) AS booking__ds_partitioned__extract_year + , EXTRACT(quarter FROM bookings_source_src_28000.ds_partitioned) AS booking__ds_partitioned__extract_quarter + , EXTRACT(month FROM bookings_source_src_28000.ds_partitioned) AS booking__ds_partitioned__extract_month + , EXTRACT(day FROM bookings_source_src_28000.ds_partitioned) AS booking__ds_partitioned__extract_day + , EXTRACT(DAY_OF_WEEK FROM bookings_source_src_28000.ds_partitioned) AS booking__ds_partitioned__extract_dow + , EXTRACT(doy FROM bookings_source_src_28000.ds_partitioned) AS booking__ds_partitioned__extract_doy + , DATE_TRUNC('day', bookings_source_src_28000.paid_at) AS booking__paid_at__day + , DATE_TRUNC('week', bookings_source_src_28000.paid_at) AS booking__paid_at__week + , DATE_TRUNC('month', bookings_source_src_28000.paid_at) AS booking__paid_at__month + , DATE_TRUNC('quarter', bookings_source_src_28000.paid_at) AS booking__paid_at__quarter + , DATE_TRUNC('year', bookings_source_src_28000.paid_at) AS booking__paid_at__year + , EXTRACT(year FROM bookings_source_src_28000.paid_at) AS booking__paid_at__extract_year + , EXTRACT(quarter FROM bookings_source_src_28000.paid_at) AS booking__paid_at__extract_quarter + , EXTRACT(month FROM bookings_source_src_28000.paid_at) AS booking__paid_at__extract_month + , EXTRACT(day FROM bookings_source_src_28000.paid_at) AS booking__paid_at__extract_day + , EXTRACT(DAY_OF_WEEK FROM bookings_source_src_28000.paid_at) AS booking__paid_at__extract_dow + , EXTRACT(doy FROM bookings_source_src_28000.paid_at) AS booking__paid_at__extract_doy + , bookings_source_src_28000.listing_id AS listing + , bookings_source_src_28000.guest_id AS guest + , bookings_source_src_28000.host_id AS host + , bookings_source_src_28000.listing_id AS booking__listing + , bookings_source_src_28000.guest_id AS booking__guest + , bookings_source_src_28000.host_id AS booking__host + FROM ***************************.fct_bookings bookings_source_src_28000 + ) subq_4 + ) subq_5 + ) subq_6 + LEFT OUTER JOIN ( + -- Pass Only Elements: ['guest', 'bookers'] + SELECT + subq_11.guest + , subq_11.bookers + FROM ( + -- Compute Metrics via Expressions + SELECT + subq_10.guest + , subq_10.bookers + FROM ( + -- Aggregate Measures + SELECT + subq_9.guest + , COUNT(DISTINCT subq_9.bookers) AS bookers + FROM ( + -- Pass Only Elements: ['bookers', 'guest'] + SELECT + subq_8.guest + , subq_8.bookers + FROM ( + -- Metric Time Dimension 'ds' + SELECT + subq_7.ds__day + , subq_7.ds__week + , subq_7.ds__month + , subq_7.ds__quarter + , subq_7.ds__year + , subq_7.ds__extract_year + , subq_7.ds__extract_quarter + , subq_7.ds__extract_month + , subq_7.ds__extract_day + , subq_7.ds__extract_dow + , subq_7.ds__extract_doy + , subq_7.ds_partitioned__day + , subq_7.ds_partitioned__week + , subq_7.ds_partitioned__month + , subq_7.ds_partitioned__quarter + , subq_7.ds_partitioned__year + , subq_7.ds_partitioned__extract_year + , subq_7.ds_partitioned__extract_quarter + , subq_7.ds_partitioned__extract_month + , subq_7.ds_partitioned__extract_day + , subq_7.ds_partitioned__extract_dow + , subq_7.ds_partitioned__extract_doy + , subq_7.paid_at__day + , subq_7.paid_at__week + , subq_7.paid_at__month + , subq_7.paid_at__quarter + , subq_7.paid_at__year + , subq_7.paid_at__extract_year + , subq_7.paid_at__extract_quarter + , subq_7.paid_at__extract_month + , subq_7.paid_at__extract_day + , subq_7.paid_at__extract_dow + , subq_7.paid_at__extract_doy + , subq_7.booking__ds__day + , subq_7.booking__ds__week + , subq_7.booking__ds__month + , subq_7.booking__ds__quarter + , subq_7.booking__ds__year + , subq_7.booking__ds__extract_year + , subq_7.booking__ds__extract_quarter + , subq_7.booking__ds__extract_month + , subq_7.booking__ds__extract_day + , subq_7.booking__ds__extract_dow + , subq_7.booking__ds__extract_doy + , subq_7.booking__ds_partitioned__day + , subq_7.booking__ds_partitioned__week + , subq_7.booking__ds_partitioned__month + , subq_7.booking__ds_partitioned__quarter + , subq_7.booking__ds_partitioned__year + , subq_7.booking__ds_partitioned__extract_year + , subq_7.booking__ds_partitioned__extract_quarter + , subq_7.booking__ds_partitioned__extract_month + , subq_7.booking__ds_partitioned__extract_day + , subq_7.booking__ds_partitioned__extract_dow + , subq_7.booking__ds_partitioned__extract_doy + , subq_7.booking__paid_at__day + , subq_7.booking__paid_at__week + , subq_7.booking__paid_at__month + , subq_7.booking__paid_at__quarter + , subq_7.booking__paid_at__year + , subq_7.booking__paid_at__extract_year + , subq_7.booking__paid_at__extract_quarter + , subq_7.booking__paid_at__extract_month + , subq_7.booking__paid_at__extract_day + , subq_7.booking__paid_at__extract_dow + , subq_7.booking__paid_at__extract_doy + , subq_7.ds__day AS metric_time__day + , subq_7.ds__week AS metric_time__week + , subq_7.ds__month AS metric_time__month + , subq_7.ds__quarter AS metric_time__quarter + , subq_7.ds__year AS metric_time__year + , subq_7.ds__extract_year AS metric_time__extract_year + , subq_7.ds__extract_quarter AS metric_time__extract_quarter + , subq_7.ds__extract_month AS metric_time__extract_month + , subq_7.ds__extract_day AS metric_time__extract_day + , subq_7.ds__extract_dow AS metric_time__extract_dow + , subq_7.ds__extract_doy AS metric_time__extract_doy + , subq_7.listing + , subq_7.guest + , subq_7.host + , subq_7.booking__listing + , subq_7.booking__guest + , subq_7.booking__host + , subq_7.is_instant + , subq_7.booking__is_instant + , subq_7.bookings + , subq_7.instant_bookings + , subq_7.booking_value + , subq_7.max_booking_value + , subq_7.min_booking_value + , subq_7.bookers + , subq_7.average_booking_value + , subq_7.referred_bookings + , subq_7.median_booking_value + , subq_7.booking_value_p99 + , subq_7.discrete_booking_value_p99 + , subq_7.approximate_continuous_booking_value_p99 + , subq_7.approximate_discrete_booking_value_p99 + FROM ( + -- Read Elements From Semantic Model 'bookings_source' + SELECT + 1 AS bookings + , CASE WHEN is_instant THEN 1 ELSE 0 END AS instant_bookings + , bookings_source_src_28000.booking_value + , bookings_source_src_28000.booking_value AS max_booking_value + , bookings_source_src_28000.booking_value AS min_booking_value + , bookings_source_src_28000.guest_id AS bookers + , bookings_source_src_28000.booking_value AS average_booking_value + , bookings_source_src_28000.booking_value AS booking_payments + , CASE WHEN referrer_id IS NOT NULL THEN 1 ELSE 0 END AS referred_bookings + , bookings_source_src_28000.booking_value AS median_booking_value + , bookings_source_src_28000.booking_value AS booking_value_p99 + , bookings_source_src_28000.booking_value AS discrete_booking_value_p99 + , bookings_source_src_28000.booking_value AS approximate_continuous_booking_value_p99 + , bookings_source_src_28000.booking_value AS approximate_discrete_booking_value_p99 + , bookings_source_src_28000.is_instant + , DATE_TRUNC('day', bookings_source_src_28000.ds) AS ds__day + , DATE_TRUNC('week', bookings_source_src_28000.ds) AS ds__week + , DATE_TRUNC('month', bookings_source_src_28000.ds) AS ds__month + , DATE_TRUNC('quarter', bookings_source_src_28000.ds) AS ds__quarter + , DATE_TRUNC('year', bookings_source_src_28000.ds) AS ds__year + , EXTRACT(year FROM bookings_source_src_28000.ds) AS ds__extract_year + , EXTRACT(quarter FROM bookings_source_src_28000.ds) AS ds__extract_quarter + , EXTRACT(month FROM bookings_source_src_28000.ds) AS ds__extract_month + , EXTRACT(day FROM bookings_source_src_28000.ds) AS ds__extract_day + , EXTRACT(DAY_OF_WEEK FROM bookings_source_src_28000.ds) AS ds__extract_dow + , EXTRACT(doy FROM bookings_source_src_28000.ds) AS ds__extract_doy + , DATE_TRUNC('day', bookings_source_src_28000.ds_partitioned) AS ds_partitioned__day + , DATE_TRUNC('week', bookings_source_src_28000.ds_partitioned) AS ds_partitioned__week + , DATE_TRUNC('month', bookings_source_src_28000.ds_partitioned) AS ds_partitioned__month + , DATE_TRUNC('quarter', bookings_source_src_28000.ds_partitioned) AS ds_partitioned__quarter + , DATE_TRUNC('year', bookings_source_src_28000.ds_partitioned) AS ds_partitioned__year + , EXTRACT(year FROM bookings_source_src_28000.ds_partitioned) AS ds_partitioned__extract_year + , EXTRACT(quarter FROM bookings_source_src_28000.ds_partitioned) AS ds_partitioned__extract_quarter + , EXTRACT(month FROM bookings_source_src_28000.ds_partitioned) AS ds_partitioned__extract_month + , EXTRACT(day FROM bookings_source_src_28000.ds_partitioned) AS ds_partitioned__extract_day + , EXTRACT(DAY_OF_WEEK FROM bookings_source_src_28000.ds_partitioned) AS ds_partitioned__extract_dow + , EXTRACT(doy FROM bookings_source_src_28000.ds_partitioned) AS ds_partitioned__extract_doy + , DATE_TRUNC('day', bookings_source_src_28000.paid_at) AS paid_at__day + , DATE_TRUNC('week', bookings_source_src_28000.paid_at) AS paid_at__week + , DATE_TRUNC('month', bookings_source_src_28000.paid_at) AS paid_at__month + , DATE_TRUNC('quarter', bookings_source_src_28000.paid_at) AS paid_at__quarter + , DATE_TRUNC('year', bookings_source_src_28000.paid_at) AS paid_at__year + , EXTRACT(year FROM bookings_source_src_28000.paid_at) AS paid_at__extract_year + , EXTRACT(quarter FROM bookings_source_src_28000.paid_at) AS paid_at__extract_quarter + , EXTRACT(month FROM bookings_source_src_28000.paid_at) AS paid_at__extract_month + , EXTRACT(day FROM bookings_source_src_28000.paid_at) AS paid_at__extract_day + , EXTRACT(DAY_OF_WEEK FROM bookings_source_src_28000.paid_at) AS paid_at__extract_dow + , EXTRACT(doy FROM bookings_source_src_28000.paid_at) AS paid_at__extract_doy + , bookings_source_src_28000.is_instant AS booking__is_instant + , DATE_TRUNC('day', bookings_source_src_28000.ds) AS booking__ds__day + , DATE_TRUNC('week', bookings_source_src_28000.ds) AS booking__ds__week + , DATE_TRUNC('month', bookings_source_src_28000.ds) AS booking__ds__month + , DATE_TRUNC('quarter', bookings_source_src_28000.ds) AS booking__ds__quarter + , DATE_TRUNC('year', bookings_source_src_28000.ds) AS booking__ds__year + , EXTRACT(year FROM bookings_source_src_28000.ds) AS booking__ds__extract_year + , EXTRACT(quarter FROM bookings_source_src_28000.ds) AS booking__ds__extract_quarter + , EXTRACT(month FROM bookings_source_src_28000.ds) AS booking__ds__extract_month + , EXTRACT(day FROM bookings_source_src_28000.ds) AS booking__ds__extract_day + , EXTRACT(DAY_OF_WEEK FROM bookings_source_src_28000.ds) AS booking__ds__extract_dow + , EXTRACT(doy FROM bookings_source_src_28000.ds) AS booking__ds__extract_doy + , DATE_TRUNC('day', bookings_source_src_28000.ds_partitioned) AS booking__ds_partitioned__day + , DATE_TRUNC('week', bookings_source_src_28000.ds_partitioned) AS booking__ds_partitioned__week + , DATE_TRUNC('month', bookings_source_src_28000.ds_partitioned) AS booking__ds_partitioned__month + , DATE_TRUNC('quarter', bookings_source_src_28000.ds_partitioned) AS booking__ds_partitioned__quarter + , DATE_TRUNC('year', bookings_source_src_28000.ds_partitioned) AS booking__ds_partitioned__year + , EXTRACT(year FROM bookings_source_src_28000.ds_partitioned) AS booking__ds_partitioned__extract_year + , EXTRACT(quarter FROM bookings_source_src_28000.ds_partitioned) AS booking__ds_partitioned__extract_quarter + , EXTRACT(month FROM bookings_source_src_28000.ds_partitioned) AS booking__ds_partitioned__extract_month + , EXTRACT(day FROM bookings_source_src_28000.ds_partitioned) AS booking__ds_partitioned__extract_day + , EXTRACT(DAY_OF_WEEK FROM bookings_source_src_28000.ds_partitioned) AS booking__ds_partitioned__extract_dow + , EXTRACT(doy FROM bookings_source_src_28000.ds_partitioned) AS booking__ds_partitioned__extract_doy + , DATE_TRUNC('day', bookings_source_src_28000.paid_at) AS booking__paid_at__day + , DATE_TRUNC('week', bookings_source_src_28000.paid_at) AS booking__paid_at__week + , DATE_TRUNC('month', bookings_source_src_28000.paid_at) AS booking__paid_at__month + , DATE_TRUNC('quarter', bookings_source_src_28000.paid_at) AS booking__paid_at__quarter + , DATE_TRUNC('year', bookings_source_src_28000.paid_at) AS booking__paid_at__year + , EXTRACT(year FROM bookings_source_src_28000.paid_at) AS booking__paid_at__extract_year + , EXTRACT(quarter FROM bookings_source_src_28000.paid_at) AS booking__paid_at__extract_quarter + , EXTRACT(month FROM bookings_source_src_28000.paid_at) AS booking__paid_at__extract_month + , EXTRACT(day FROM bookings_source_src_28000.paid_at) AS booking__paid_at__extract_day + , EXTRACT(DAY_OF_WEEK FROM bookings_source_src_28000.paid_at) AS booking__paid_at__extract_dow + , EXTRACT(doy FROM bookings_source_src_28000.paid_at) AS booking__paid_at__extract_doy + , bookings_source_src_28000.listing_id AS listing + , bookings_source_src_28000.guest_id AS guest + , bookings_source_src_28000.host_id AS host + , bookings_source_src_28000.listing_id AS booking__listing + , bookings_source_src_28000.guest_id AS booking__guest + , bookings_source_src_28000.host_id AS booking__host + FROM ***************************.fct_bookings bookings_source_src_28000 + ) subq_7 + ) subq_8 + ) subq_9 + GROUP BY + subq_9.guest + ) subq_10 + ) subq_11 + ) subq_12 + ON + subq_6.guest = subq_12.guest + ) subq_13 + ) subq_14 + WHERE guest__bookers > 1.00 + ) subq_15 + ) subq_16 +) subq_17 diff --git a/tests/snapshots/test_metric_filter_rendering.py/SqlQueryPlan/Trino/test_metric_filtered_by_itself__plan0_optimized.sql b/tests/snapshots/test_metric_filter_rendering.py/SqlQueryPlan/Trino/test_metric_filtered_by_itself__plan0_optimized.sql new file mode 100644 index 0000000000..eb7a693290 --- /dev/null +++ b/tests/snapshots/test_metric_filter_rendering.py/SqlQueryPlan/Trino/test_metric_filtered_by_itself__plan0_optimized.sql @@ -0,0 +1,39 @@ +-- Constrain Output with WHERE +-- Pass Only Elements: ['bookers',] +-- Aggregate Measures +-- Compute Metrics via Expressions +SELECT + COUNT(DISTINCT bookers) AS bookers +FROM ( + -- Join Standard Outputs + -- Pass Only Elements: ['bookers', 'guest__bookers'] + SELECT + subq_26.bookers AS guest__bookers + , subq_20.bookers AS bookers + FROM ( + -- Read Elements From Semantic Model 'bookings_source' + -- Metric Time Dimension 'ds' + -- Pass Only Elements: ['bookers', 'guest'] + SELECT + guest_id AS guest + , guest_id AS bookers + FROM ***************************.fct_bookings bookings_source_src_28000 + ) subq_20 + LEFT OUTER JOIN ( + -- Read Elements From Semantic Model 'bookings_source' + -- Metric Time Dimension 'ds' + -- Pass Only Elements: ['bookers', 'guest'] + -- Aggregate Measures + -- Compute Metrics via Expressions + -- Pass Only Elements: ['guest', 'bookers'] + SELECT + guest_id AS guest + , COUNT(DISTINCT guest_id) AS bookers + FROM ***************************.fct_bookings bookings_source_src_28000 + GROUP BY + guest_id + ) subq_26 + ON + subq_20.guest = subq_26.guest +) subq_28 +WHERE guest__bookers > 1.00 From ac75be25043819a0d1a69a86ba45067c2377d44c Mon Sep 17 00:00:00 2001 From: Courtney Holcomb Date: Thu, 25 Apr 2024 15:07:41 -0700 Subject: [PATCH 22/37] Add metrics where missed in spec set logic --- metricflow/plan_conversion/node_processor.py | 5 ++++- metricflow/specs/spec_set_transforms.py | 2 ++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/metricflow/plan_conversion/node_processor.py b/metricflow/plan_conversion/node_processor.py index d3bdcd5afe..89dbaa14b4 100644 --- a/metricflow/plan_conversion/node_processor.py +++ b/metricflow/plan_conversion/node_processor.py @@ -223,7 +223,10 @@ def _get_candidates_nodes_for_multi_hop( filtered_joinable_node = FilterElementsNode( parent_node=second_node_that_could_be_joined, include_specs=InstanceSpecSet.from_specs( - specs.dimension_specs + specs.entity_specs + specs.time_dimension_specs + specs.dimension_specs + + specs.entity_specs + + specs.time_dimension_specs + + specs.group_by_metric_specs ), ) diff --git a/metricflow/specs/spec_set_transforms.py b/metricflow/specs/spec_set_transforms.py index fffebd0a45..f2241daa28 100644 --- a/metricflow/specs/spec_set_transforms.py +++ b/metricflow/specs/spec_set_transforms.py @@ -15,4 +15,6 @@ def transform(self, spec_set: InstanceSpecSet) -> Set[str]: # noqa: D102 .union({x.element_name for x in spec_set.dimension_specs}) .union({x.element_name for x in spec_set.time_dimension_specs}) .union({x.element_name for x in spec_set.entity_specs}) + .union({x.element_name for x in spec_set.metric_specs}) + .union({x.element_name for x in spec_set.group_by_metric_specs}) ) From 1c1d28af118098f90fbf43d61aa503844eb290ac Mon Sep 17 00:00:00 2001 From: Courtney Holcomb Date: Tue, 23 Apr 2024 12:43:15 -0700 Subject: [PATCH 23/37] Use query parser to build group by metric source node Needed to resolve the appropriate join path for multi-hop joins. Moved source node-building logic to query parser class to avoid cirular import errors. This change also required adding the query parser as a dependency for the dataflow plan builder. --- .../dataflow/builder/dataflow_plan_builder.py | 6 +++++- metricflow/engine/metricflow_engine.py | 9 +++++---- metricflow/query/query_parser.py | 11 +++++++++++ metricflow/specs/specs.py | 18 ++++++++++-------- tests/fixtures/manifest_fixtures.py | 1 + 5 files changed, 32 insertions(+), 13 deletions(-) diff --git a/metricflow/dataflow/builder/dataflow_plan_builder.py b/metricflow/dataflow/builder/dataflow_plan_builder.py index d825701242..3ce778c13f 100644 --- a/metricflow/dataflow/builder/dataflow_plan_builder.py +++ b/metricflow/dataflow/builder/dataflow_plan_builder.py @@ -63,6 +63,7 @@ from metricflow.plan_conversion.node_processor import PreJoinNodeProcessor from metricflow.query.group_by_item.filter_spec_resolution.filter_location import WhereFilterLocation from metricflow.query.group_by_item.filter_spec_resolution.filter_spec_lookup import FilterSpecResolutionLookUp +from metricflow.query.query_parser import MetricFlowQueryParser from metricflow.specs.column_assoc import ColumnAssociationResolver from metricflow.specs.specs import ( ConstantPropertySpec, @@ -123,6 +124,7 @@ def __init__( # noqa: D107 semantic_manifest_lookup: SemanticManifestLookup, node_output_resolver: DataflowPlanNodeOutputDataSetResolver, column_association_resolver: ColumnAssociationResolver, + query_parser: MetricFlowQueryParser, ) -> None: self._semantic_model_lookup = semantic_manifest_lookup.semantic_model_lookup self._metric_lookup = semantic_manifest_lookup.metric_lookup @@ -130,6 +132,7 @@ def __init__( # noqa: D107 self._source_node_set = source_node_set self._column_association_resolver = column_association_resolver self._node_data_set_resolver = node_output_resolver + self._query_parser = query_parser def build_plan( self, @@ -825,7 +828,8 @@ def _find_dataflow_recipe( # MetricGroupBy source nodes could be extremely large (and potentially slow). candidate_nodes_for_right_side_of_join += [ self._build_query_output_node( - query_spec=group_by_metric_spec.query_spec_for_source_node, for_group_by_source_node=True + query_spec=self._query_parser.build_query_spec_for_group_by_metric_source_node(group_by_metric_spec), + for_group_by_source_node=True, ) for group_by_metric_spec in linkable_spec_set.group_by_metric_specs ] diff --git a/metricflow/engine/metricflow_engine.py b/metricflow/engine/metricflow_engine.py index 5bf4160a9d..4f3d6d72a1 100644 --- a/metricflow/engine/metricflow_engine.py +++ b/metricflow/engine/metricflow_engine.py @@ -382,11 +382,16 @@ def __init__( ) node_output_resolver.cache_output_data_sets(source_node_set.all_nodes) + self._query_parser = query_parser or MetricFlowQueryParser( + semantic_manifest_lookup=self._semantic_manifest_lookup, + ) + self._dataflow_plan_builder = DataflowPlanBuilder( source_node_set=source_node_set, semantic_manifest_lookup=self._semantic_manifest_lookup, column_association_resolver=self._column_association_resolver, node_output_resolver=node_output_resolver, + query_parser=self._query_parser, ) self._to_sql_query_plan_converter = DataflowToSqlQueryPlanConverter( column_association_resolver=self._column_association_resolver, @@ -399,10 +404,6 @@ def __init__( ) self._executor = SequentialPlanExecutor() - self._query_parser = query_parser or MetricFlowQueryParser( - semantic_manifest_lookup=self._semantic_manifest_lookup, - ) - @log_call(module_name=__name__, telemetry_reporter=_telemetry_reporter) def query(self, mf_request: MetricFlowQueryRequest) -> MetricFlowQueryResult: # noqa: D102 logger.info(f"Starting query request:\n{indent(mf_pformat(mf_request))}") diff --git a/metricflow/query/query_parser.py b/metricflow/query/query_parser.py index 75dcd34ee2..7bbf104f25 100644 --- a/metricflow/query/query_parser.py +++ b/metricflow/query/query_parser.py @@ -54,7 +54,9 @@ from metricflow.specs.patterns.base_time_grain import BaseTimeGrainPattern from metricflow.specs.patterns.metric_time_pattern import MetricTimePattern from metricflow.specs.patterns.none_date_part import NoneDatePartPattern +from metricflow.specs.query_param_implementations import DimensionOrEntityParameter, MetricParameter from metricflow.specs.specs import ( + GroupByMetricSpec, InstanceSpec, InstanceSpecSet, MetricFlowQuerySpec, @@ -511,3 +513,12 @@ def _parse_and_validate_query( return query_spec.with_time_range_constraint(time_constraint) return query_spec + + def build_query_spec_for_group_by_metric_source_node( + self, group_by_metric_spec: GroupByMetricSpec + ) -> MetricFlowQuerySpec: + """Query spec that can be used to build a source node for this spec in the DFP.""" + return self.parse_and_validate_query( + metrics=(MetricParameter(group_by_metric_spec.reference.element_name),), + group_by=(DimensionOrEntityParameter(group_by_metric_spec.entity_spec.qualified_name),), + ) diff --git a/metricflow/specs/specs.py b/metricflow/specs/specs.py index 41ee7e6f38..ca4728642d 100644 --- a/metricflow/specs/specs.py +++ b/metricflow/specs/specs.py @@ -253,6 +253,11 @@ def without_first_entity_link(self) -> GroupByMetricSpec: # noqa: D102 def without_entity_links(self) -> GroupByMetricSpec: # noqa: D102 return GroupByMetricSpec(element_name=self.element_name, entity_links=()) + @property + def last_entity_link(self) -> EntityReference: # noqa: D102 + assert len(self.entity_links) > 0, f"Spec does not have any entity links: {self}" + return self.entity_links[-1] + @staticmethod def from_name(name: str) -> GroupByMetricSpec: # noqa: D102 structured_name = StructuredLinkableSpecName.from_name(name) @@ -261,6 +266,11 @@ def from_name(name: str) -> GroupByMetricSpec: # noqa: D102 element_name=structured_name.element_name, ) + @property + def entity_spec(self) -> EntitySpec: + """Entity that the metric will be grouped by on aggregation.""" + return EntitySpec(element_name=self.last_entity_link.element_name, entity_links=self.entity_links[:-1]) + def __eq__(self, other: Any) -> bool: # type: ignore[misc] # noqa: D105 if not isinstance(other, GroupByMetricSpec): return False @@ -281,14 +291,6 @@ def as_spec_set(self) -> InstanceSpecSet: def accept(self, visitor: InstanceSpecVisitor[VisitorOutputT]) -> VisitorOutputT: # noqa: D102 return visitor.visit_group_by_metric_spec(self) - @property - def query_spec_for_source_node(self) -> MetricFlowQuerySpec: - """Query spec that can be used to build a source node for this spec in the DFP.""" - return MetricFlowQuerySpec( - metric_specs=(MetricSpec(element_name=self.element_name),), - entity_specs=tuple(EntitySpec.from_name(entity_link.element_name) for entity_link in self.entity_links), - ) - @dataclass(frozen=True) class LinklessEntitySpec(EntitySpec, SerializableDataclass): diff --git a/tests/fixtures/manifest_fixtures.py b/tests/fixtures/manifest_fixtures.py index 5e9285803d..802ac1dad1 100644 --- a/tests/fixtures/manifest_fixtures.py +++ b/tests/fixtures/manifest_fixtures.py @@ -163,6 +163,7 @@ def dataflow_plan_builder(self) -> DataflowPlanBuilder: semantic_manifest_lookup=self.semantic_manifest_lookup, node_output_resolver=self._node_output_resolver.copy(), column_association_resolver=self.column_association_resolver, + query_parser=self.query_parser, ) @staticmethod From 5f765062fd62a0ea8b481fbf8b27f0a9f0d58092 Mon Sep 17 00:00:00 2001 From: Courtney Holcomb Date: Tue, 23 Apr 2024 12:49:18 -0700 Subject: [PATCH 24/37] Parse entity links in Metric.group_by param --- metricflow/specs/patterns/typed_patterns.py | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/metricflow/specs/patterns/typed_patterns.py b/metricflow/specs/patterns/typed_patterns.py index e59dd1d6f6..236ada1b21 100644 --- a/metricflow/specs/patterns/typed_patterns.py +++ b/metricflow/specs/patterns/typed_patterns.py @@ -12,6 +12,7 @@ from dbt_semantic_interfaces.references import EntityReference from typing_extensions import override +from metricflow.naming.linkable_spec_name import StructuredLinkableSpecName from metricflow.specs.patterns.entity_link_pattern import ( EntityLinkPattern, EntityLinkPatternParameterSet, @@ -129,6 +130,19 @@ def match(self, candidate_specs: Sequence[InstanceSpec]) -> Sequence[LinkableIns def from_call_parameter_set( # noqa: D102 metric_call_parameter_set: MetricCallParameterSet, ) -> GroupByMetricPattern: + # This looks hacky because the typing for the interface does not match the implementation, but that's temporary! + # This will get a lot less hacky once we enable multiple entities and dimensions in the group by. + if len(metric_call_parameter_set.group_by) != 1: + raise RuntimeError( + "Currently only one group by item is allowed for Metric filters. " + "This should have been caught by validations." + ) + group_by = metric_call_parameter_set.group_by[0] + structured_name = StructuredLinkableSpecName.from_name(group_by.element_name) + entity_links = tuple( + EntityReference(entity_name) + for entity_name in (structured_name.entity_link_names + (structured_name.element_name,)) + ) return GroupByMetricPattern( parameter_set=EntityLinkPatternParameterSet.from_parameters( fields_to_compare=( @@ -136,9 +150,6 @@ def from_call_parameter_set( # noqa: D102 ParameterSetField.ENTITY_LINKS, ), element_name=metric_call_parameter_set.metric_reference.element_name, - entity_links=tuple( - EntityReference(element_name=group_by_ref.element_name) - for group_by_ref in metric_call_parameter_set.group_by - ), + entity_links=entity_links, ) ) From b9d8f15bb519c1e946d38a75da6fe7f65e8f8764 Mon Sep 17 00:00:00 2001 From: Courtney Holcomb Date: Wed, 24 Apr 2024 14:54:56 -0700 Subject: [PATCH 25/37] Update LinkableMetrics & related classes to track metric_to_entity_join_path LinkableMetrics are extra complicated because they involve multiple join paths: 1) the join path needed to join the metric subquery to the outer query, and 2) the join path used in the subquery to join the metric to the group by entity. So far we have only been tracking join path 1. This commit adds tracking for join path 2. --- .../model/semantics/linkable_spec_resolver.py | 57 ++++++++++++++----- 1 file changed, 42 insertions(+), 15 deletions(-) diff --git a/metricflow/model/semantics/linkable_spec_resolver.py b/metricflow/model/semantics/linkable_spec_resolver.py index cac65fd2e5..fbe2513915 100644 --- a/metricflow/model/semantics/linkable_spec_resolver.py +++ b/metricflow/model/semantics/linkable_spec_resolver.py @@ -105,7 +105,7 @@ class LinkableMetric: """Describes how a metric can be realized by joining based on entity links.""" properties: FrozenSet[LinkableElementProperty] - join_path: MetricSubqueryJoinPath + join_path: SemanticModelToMetricSubqueryJoinPath def __post_init__(self) -> None: """Ensure expected LinkableElementProperties have been set. @@ -130,6 +130,16 @@ def reference(self) -> MetricReference: # noqa: D102 def join_by_semantic_model(self) -> Optional[SemanticModelReference]: # noqa: D102 return self.join_path.last_semantic_model_reference + @property + def metric_to_entity_join_path(self) -> Optional[SemanticModelJoinPath]: + """Join path used in metric subquery to join entity to metric, if needed.""" + return self.join_path.metric_subquery_join_path_element.metric_to_entity_join_path + + @property + def metric_subquery_entity_links(self) -> Tuple[EntityReference, ...]: + """Entity links used to join the metric to the entity it's grouped by in the metric subquery.""" + return self.metric_to_entity_join_path.entity_links if self.metric_to_entity_join_path else () + @dataclass(frozen=True) class LinkableElementSet: @@ -344,10 +354,11 @@ def as_spec_set(self) -> LinkableSpecSet: # noqa: D102 ), group_by_metric_specs=tuple( GroupByMetricSpec( - element_name=path_key.element_name, - entity_links=path_key.entity_links, + element_name=linkable_metric.element_name, + entity_links=linkable_metric.join_path.entity_links, ) - for path_key in self.path_key_to_linkable_metrics + for linkable_metrics in self.path_key_to_linkable_metrics.values() + for linkable_metric in linkable_metrics ), ) @@ -383,17 +394,26 @@ class SemanticModelJoinPathElement: @dataclass(frozen=True) class MetricSubqueryJoinPathElement: - """Describes joining a metric subquery by the given entity.""" + """Describes joining from a semantic model to a metric subquery. + + Args: + metric_reference: The metric that's aggregated in the subquery. + join_on_entity: The entity that the metric is grouped by in the subquery. This will be updated in V2 to allow a list + of entitites & dimensions. + metric_to_entity_join_path: Describes the join path used in the subquery to join the metric to the `join_on_entity`. + Can be none if all required elements are defined in the same semantic model. + """ metric_reference: MetricReference join_on_entity: EntityReference + metric_to_entity_join_path: Optional[SemanticModelJoinPath] = None @dataclass(frozen=True) -class MetricSubqueryJoinPath: - """Describes how to join to a metric subquery. +class SemanticModelToMetricSubqueryJoinPath: + """Describes how to join from a semantic model to a metric subquery. - Starts with semantic model join path, if exists. Always ends with metric subquery join path. + Starts with semantic model join path, if needed. Always ends with metric subquery join path. """ metric_subquery_join_path_element: MetricSubqueryJoinPathElement @@ -544,7 +564,9 @@ def __init__( self._entity_to_semantic_model[entity.reference.element_name].append(semantic_model) self._metric_to_linkable_element_sets: Dict[str, List[LinkableElementSet]] = {} - self._joinable_metrics_for_entities: Dict[EntityReference, Set[MetricReference]] = defaultdict(set) + self._joinable_metrics_for_entities: Dict[EntityReference, Set[MetricSubqueryJoinPathElement]] = defaultdict( + set + ) start_time = time.time() for metric in self._semantic_manifest.metrics: @@ -591,7 +613,14 @@ def __init__( linkable_element_set_for_metric = self.get_linkable_elements_for_metrics([metric_reference]) for linkable_entities in linkable_element_set_for_metric.path_key_to_linkable_entities.values(): for linkable_entity in linkable_entities: - self._joinable_metrics_for_entities[linkable_entity.reference].add(metric_reference) + metric_subquery_join_path_element = MetricSubqueryJoinPathElement( + metric_reference=metric_reference, + join_on_entity=linkable_entity.reference, + metric_to_entity_join_path=SemanticModelJoinPath(linkable_entity.join_path), + ) + self._joinable_metrics_for_entities[linkable_entity.reference].add( + metric_subquery_join_path_element + ) # If no metrics are specified, the query interface supports querying distinct values for dimensions, entities, # and group by metrics. @@ -641,13 +670,11 @@ def _get_joinable_metrics_for_semantic_model( for entity_reference in [entity.reference for entity in semantic_model.entities]: if using_join_path and entity_reference in using_join_path.entity_links: continue - for metric_reference in self._joinable_metrics_for_entities[entity_reference]: + for metric_subquery_join_path_element in self._joinable_metrics_for_entities[entity_reference]: linkable_metric = LinkableMetric( properties=properties, - join_path=MetricSubqueryJoinPath( - metric_subquery_join_path_element=MetricSubqueryJoinPathElement( - metric_reference=metric_reference, join_on_entity=entity_reference - ), + join_path=SemanticModelToMetricSubqueryJoinPath( + metric_subquery_join_path_element=metric_subquery_join_path_element, semantic_model_join_path=using_join_path, ), ) From 29e1ab12bc8961dfe6e3d5e207c3a55662564c8f Mon Sep 17 00:00:00 2001 From: Courtney Holcomb Date: Thu, 25 Apr 2024 15:23:08 -0700 Subject: [PATCH 26/37] Add metric_subquery_entity_links to GroupByMetricSpec Needed when building source node for group by metric. --- .../model/semantics/linkable_spec_resolver.py | 1 + metricflow/plan_conversion/dataflow_to_sql.py | 6 +++- .../plan_conversion/instance_converters.py | 1 + metricflow/query/query_parser.py | 2 +- metricflow/specs/specs.py | 35 +++++++++++++++---- tests/model/test_where_filter_spec.py | 4 ++- tests/naming/conftest.py | 6 +++- .../test_object_builder_naming_scheme.py | 7 +++- .../patterns/test_entity_link_pattern.py | 7 +++- tests/specs/patterns/test_typed_patterns.py | 2 ++ tests/test_specs.py | 3 ++ 11 files changed, 62 insertions(+), 12 deletions(-) diff --git a/metricflow/model/semantics/linkable_spec_resolver.py b/metricflow/model/semantics/linkable_spec_resolver.py index fbe2513915..3a5f6e9655 100644 --- a/metricflow/model/semantics/linkable_spec_resolver.py +++ b/metricflow/model/semantics/linkable_spec_resolver.py @@ -356,6 +356,7 @@ def as_spec_set(self) -> LinkableSpecSet: # noqa: D102 GroupByMetricSpec( element_name=linkable_metric.element_name, entity_links=linkable_metric.join_path.entity_links, + metric_subquery_entity_links=linkable_metric.metric_subquery_entity_links, ) for linkable_metrics in self.path_key_to_linkable_metrics.values() for linkable_metric in linkable_metrics diff --git a/metricflow/plan_conversion/dataflow_to_sql.py b/metricflow/plan_conversion/dataflow_to_sql.py index 05ff5212e4..fb4d065180 100644 --- a/metricflow/plan_conversion/dataflow_to_sql.py +++ b/metricflow/plan_conversion/dataflow_to_sql.py @@ -727,7 +727,11 @@ def visit_compute_metrics_node(self, node: ComputeMetricsNode) -> SqlDataSet: GroupByMetricInstance( associated_columns=(output_column_association,), defined_from=MetricModelReference(metric_name=metric_spec.element_name), - spec=GroupByMetricSpec(element_name=metric_spec.element_name, entity_links=()), + spec=GroupByMetricSpec( + element_name=metric_spec.element_name, + entity_links=(), + metric_subquery_entity_links=(), # TODO + ), ) ) diff --git a/metricflow/plan_conversion/instance_converters.py b/metricflow/plan_conversion/instance_converters.py index c60fba87be..e7c4b60a4f 100644 --- a/metricflow/plan_conversion/instance_converters.py +++ b/metricflow/plan_conversion/instance_converters.py @@ -462,6 +462,7 @@ def transform(self, instance_set: InstanceSet) -> InstanceSet: # noqa: D102 transformed_group_by_metric_spec_from_right = GroupByMetricSpec( element_name=group_by_metric_instance.spec.element_name, entity_links=self._join_on_entity.as_linkless_prefix + group_by_metric_instance.spec.entity_links, + metric_subquery_entity_links=group_by_metric_instance.spec.metric_subquery_entity_links, ) group_by_metric_instances_with_additional_link.append( GroupByMetricInstance( diff --git a/metricflow/query/query_parser.py b/metricflow/query/query_parser.py index 7bbf104f25..9f2f997a78 100644 --- a/metricflow/query/query_parser.py +++ b/metricflow/query/query_parser.py @@ -520,5 +520,5 @@ def build_query_spec_for_group_by_metric_source_node( """Query spec that can be used to build a source node for this spec in the DFP.""" return self.parse_and_validate_query( metrics=(MetricParameter(group_by_metric_spec.reference.element_name),), - group_by=(DimensionOrEntityParameter(group_by_metric_spec.entity_spec.qualified_name),), + group_by=(DimensionOrEntityParameter(group_by_metric_spec.metric_subquery_entity_spec.qualified_name),), ) diff --git a/metricflow/specs/specs.py b/metricflow/specs/specs.py index ca4728642d..8e86a247be 100644 --- a/metricflow/specs/specs.py +++ b/metricflow/specs/specs.py @@ -242,16 +242,35 @@ def accept(self, visitor: InstanceSpecVisitor[VisitorOutputT]) -> VisitorOutputT @dataclass(frozen=True) class GroupByMetricSpec(LinkableInstanceSpec, SerializableDataclass): - """Metric used in group by or where filter.""" + """Metric used in group by or where filter. + + Args: + element_name: Name of the metric being joined. + entity_links: Sequence of entities joined to join the metric subquery to the outer query. Last entity is the one + joining the subquery to the outer query. + metric_subquery_entity_links: Sequence of entities used in the metric subquery to join the metric to the entity. + Does not include the top-level entity (to avoid duplicating the last element of `entity_links`). + + """ + + metric_subquery_entity_links: Tuple[EntityReference, ...] @property def without_first_entity_link(self) -> GroupByMetricSpec: # noqa: D102 assert len(self.entity_links) > 0, f"Spec does not have any entity links: {self}" - return GroupByMetricSpec(element_name=self.element_name, entity_links=self.entity_links[1:]) + return GroupByMetricSpec( + element_name=self.element_name, + entity_links=self.entity_links[1:], + metric_subquery_entity_links=self.metric_subquery_entity_links, + ) @property def without_entity_links(self) -> GroupByMetricSpec: # noqa: D102 - return GroupByMetricSpec(element_name=self.element_name, entity_links=()) + return GroupByMetricSpec( + element_name=self.element_name, + entity_links=(), + metric_subquery_entity_links=self.metric_subquery_entity_links, + ) @property def last_entity_link(self) -> EntityReference: # noqa: D102 @@ -264,12 +283,16 @@ def from_name(name: str) -> GroupByMetricSpec: # noqa: D102 return GroupByMetricSpec( entity_links=tuple(EntityReference(idl) for idl in structured_name.entity_link_names), element_name=structured_name.element_name, + metric_subquery_entity_links=(), ) @property - def entity_spec(self) -> EntitySpec: - """Entity that the metric will be grouped by on aggregation.""" - return EntitySpec(element_name=self.last_entity_link.element_name, entity_links=self.entity_links[:-1]) + def metric_subquery_entity_spec(self) -> EntitySpec: + """Spec for the entity that the metric will be grouped by it the metric subquery.""" + return EntitySpec( + element_name=self.last_entity_link.element_name, + entity_links=self.metric_subquery_entity_links, + ) def __eq__(self, other: Any) -> bool: # type: ignore[misc] # noqa: D105 if not isinstance(other, GroupByMetricSpec): diff --git a/tests/model/test_where_filter_spec.py b/tests/model/test_where_filter_spec.py index a4df031e72..f7f1d41a0f 100644 --- a/tests/model/test_where_filter_spec.py +++ b/tests/model/test_where_filter_spec.py @@ -370,7 +370,9 @@ def test_metric_in_filter( # noqa: D103 ) -> None: where_filter = PydanticWhereFilter(where_sql_template="{{ Metric('bookings', group_by=['listing']) }} > 2") - group_by_metric_spec = GroupByMetricSpec(element_name="bookings", entity_links=(EntityReference("listing"),)) + group_by_metric_spec = GroupByMetricSpec( + element_name="bookings", entity_links=(EntityReference("listing"),), metric_subquery_entity_links=() + ) where_filter_spec = WhereSpecFactory( column_association_resolver=column_association_resolver, spec_resolution_lookup=create_spec_lookup( diff --git a/tests/naming/conftest.py b/tests/naming/conftest.py index 5bd2701b22..07f8fb07d1 100644 --- a/tests/naming/conftest.py +++ b/tests/naming/conftest.py @@ -50,5 +50,9 @@ def specs() -> Sequence[LinkableInstanceSpec]: # noqa: D103 entity_links=(EntityReference(element_name="booking"), EntityReference(element_name="listing")), ), # GroupByMetrics - GroupByMetricSpec(element_name="bookings", entity_links=(EntityReference(element_name="listing"),)), + GroupByMetricSpec( + element_name="bookings", + entity_links=(EntityReference(element_name="listing"),), + metric_subquery_entity_links=(), + ), ) diff --git a/tests/naming/test_object_builder_naming_scheme.py b/tests/naming/test_object_builder_naming_scheme.py index 2bebc6c5b5..e003503b3d 100644 --- a/tests/naming/test_object_builder_naming_scheme.py +++ b/tests/naming/test_object_builder_naming_scheme.py @@ -52,6 +52,7 @@ def test_input_str(object_builder_naming_scheme: ObjectBuilderNamingScheme) -> N GroupByMetricSpec( element_name="bookings", entity_links=(EntityReference(element_name="listing"),), + metric_subquery_entity_links=(), ) ) == "Metric('bookings', group_by=['listing'])" @@ -121,5 +122,9 @@ def test_spec_pattern( # noqa: D103 assert tuple( object_builder_naming_scheme.spec_pattern("Metric('bookings', group_by=['listing'])").match(specs) ) == ( - GroupByMetricSpec(element_name="bookings", entity_links=(EntityReference(element_name="listing"),)), + GroupByMetricSpec( + element_name="bookings", + entity_links=(EntityReference(element_name="listing"),), + metric_subquery_entity_links=(), + ), ) diff --git a/tests/specs/patterns/test_entity_link_pattern.py b/tests/specs/patterns/test_entity_link_pattern.py index aea60bc2c0..73e5fc2562 100644 --- a/tests/specs/patterns/test_entity_link_pattern.py +++ b/tests/specs/patterns/test_entity_link_pattern.py @@ -56,6 +56,7 @@ def specs() -> Sequence[LinkableInstanceSpec]: # noqa: D103 GroupByMetricSpec( element_name="bookings", entity_links=(EntityReference(element_name="listing"),), + metric_subquery_entity_links=(), ), ) @@ -127,7 +128,11 @@ def test_group_by_metric_match(specs: Sequence[LinkableInstanceSpec]) -> None: ) assert tuple(pattern.match(specs)) == ( - GroupByMetricSpec(element_name="bookings", entity_links=(EntityReference(element_name="listing"),)), + GroupByMetricSpec( + element_name="bookings", + entity_links=(EntityReference(element_name="listing"),), + metric_subquery_entity_links=(), + ), ) diff --git a/tests/specs/patterns/test_typed_patterns.py b/tests/specs/patterns/test_typed_patterns.py index 754a06d660..d0625cd741 100644 --- a/tests/specs/patterns/test_typed_patterns.py +++ b/tests/specs/patterns/test_typed_patterns.py @@ -60,6 +60,7 @@ def specs() -> Sequence[LinkableInstanceSpec]: # noqa: D103 GroupByMetricSpec( element_name="bookings", entity_links=(EntityReference(element_name="listing"),), + metric_subquery_entity_links=(), ), ) @@ -157,5 +158,6 @@ def test_group_by_metric_pattern(specs: Sequence[LinkableInstanceSpec]) -> None: GroupByMetricSpec( element_name="bookings", entity_links=(EntityReference("listing"),), + metric_subquery_entity_links=(), ), ) diff --git a/tests/test_specs.py b/tests/test_specs.py index da922e61c9..27c3a26be6 100644 --- a/tests/test_specs.py +++ b/tests/test_specs.py @@ -145,6 +145,7 @@ def spec_set() -> InstanceSpecSet: # noqa: D103 GroupByMetricSpec( element_name="bookings", entity_links=(EntityReference(element_name="listing_id"),), + metric_subquery_entity_links=(), ), ), ) @@ -165,6 +166,7 @@ def test_spec_set_linkable_specs(spec_set: InstanceSpecSet) -> None: # noqa: D1 GroupByMetricSpec( element_name="bookings", entity_links=(EntityReference(element_name="listing_id"),), + metric_subquery_entity_links=(), ), } @@ -188,6 +190,7 @@ def test_spec_set_all_specs(spec_set: InstanceSpecSet) -> None: # noqa: D103 GroupByMetricSpec( element_name="bookings", entity_links=(EntityReference(element_name="listing_id"),), + metric_subquery_entity_links=(), ), } From 9bc8ebbc326c17163fc9020fce7c58ca44c35460 Mon Sep 17 00:00:00 2001 From: Courtney Holcomb Date: Thu, 25 Apr 2024 15:26:59 -0700 Subject: [PATCH 27/37] Update DFP join logic to account for group by metric source nodes --- metricflow/dataflow/builder/node_evaluator.py | 5 --- metricflow/dataset/sql_dataset.py | 44 +++++++++++-------- .../semantic_model_join_evaluator.py | 37 ++++++++++++---- metricflow/plan_conversion/dataflow_to_sql.py | 36 ++++++++------- metricflow/plan_conversion/node_processor.py | 6 +-- 5 files changed, 75 insertions(+), 53 deletions(-) diff --git a/metricflow/dataflow/builder/node_evaluator.py b/metricflow/dataflow/builder/node_evaluator.py index 995d7fca29..431b8a8072 100644 --- a/metricflow/dataflow/builder/node_evaluator.py +++ b/metricflow/dataflow/builder/node_evaluator.py @@ -219,11 +219,6 @@ def _find_joinable_candidate_nodes_that_can_satisfy_linkable_specs( # then produce the linkable spec. See comments further below for more details. for entity_spec_in_right_node in entity_specs_in_right_node: - # If an entity has links, what that means and whether it can be used is unclear at the moment, - # so skip it. - if len(entity_spec_in_right_node.entity_links) > 0: - continue - entity_instance_in_right_node = None for instance in data_set_in_right_node.instance_set.entity_instances: if instance.spec == entity_spec_in_right_node: diff --git a/metricflow/dataset/sql_dataset.py b/metricflow/dataset/sql_dataset.py index c59b1c48f4..01bf5246f5 100644 --- a/metricflow/dataset/sql_dataset.py +++ b/metricflow/dataset/sql_dataset.py @@ -1,15 +1,13 @@ from __future__ import annotations -from typing import Optional, Sequence +from typing import List, Optional, Sequence from dbt_semantic_interfaces.references import SemanticModelReference from typing_extensions import override from metricflow.assert_one_arg import assert_exactly_one_arg_set from metricflow.dataset.dataset import DataSet -from metricflow.instances import ( - InstanceSet, -) +from metricflow.instances import EntityInstance, InstanceSet from metricflow.specs.column_assoc import ColumnAssociation from metricflow.specs.specs import DimensionSpec, EntitySpec, TimeDimensionSpec from metricflow.sql.sql_plan import ( @@ -60,25 +58,33 @@ def column_associations_for_entity( entity_spec: EntitySpec, ) -> Sequence[ColumnAssociation]: """Given the name of the entity, return the set of columns associated with it in the data set.""" - matching_instances = 0 - column_associations_to_return = None + matching_instances_with_same_entity_links: List[EntityInstance] = [] + matching_instances_with_different_entity_links: List[EntityInstance] = [] for linkable_instance in self.instance_set.entity_instances: - if ( - entity_spec.element_name == linkable_instance.spec.element_name - and entity_spec.entity_links == linkable_instance.spec.entity_links - ): - column_associations_to_return = linkable_instance.associated_columns - matching_instances += 1 - - if matching_instances > 1: + if entity_spec.element_name == linkable_instance.spec.element_name: + if entity_spec.entity_links == linkable_instance.spec.entity_links: + matching_instances_with_same_entity_links.append(linkable_instance) + else: + matching_instances_with_different_entity_links.append(linkable_instance) + + # Prioritize instances with matching entity links, but use mismatched links if matching links not found. + # Semantic model source data sets might have multiple instances of the same entity, in which case we want the one without + # links. But group by metric source data sets might only have an instance of the entity with links, and we can join to that. + matching_instances = matching_instances_with_same_entity_links or matching_instances_with_different_entity_links + + if len(matching_instances) != 1: raise RuntimeError( - f"More than one instance with spec {entity_spec} in " f"instance set: {self.instance_set}" + f"Expected exactly one matching instance for {entity_spec} in instance set, but found: {matching_instances}" + ) + matching_instance = matching_instances[0] + if not matching_instance.associated_columns: + print("entity links to compare:", entity_spec.entity_links, linkable_instance.spec.entity_links) + raise RuntimeError( + f"No associated columns for entity instance {matching_instance} in data set." + "This indicates internal misconfiguration." ) - if not column_associations_to_return: - raise RuntimeError(f"No instances with spec {entity_spec} in instance set: {self.instance_set}") - - return column_associations_to_return + return matching_instance.associated_columns def column_association_for_dimension( self, diff --git a/metricflow/model/semantics/semantic_model_join_evaluator.py b/metricflow/model/semantics/semantic_model_join_evaluator.py index ed8c3f7205..7438ac1318 100644 --- a/metricflow/model/semantics/semantic_model_join_evaluator.py +++ b/metricflow/model/semantics/semantic_model_join_evaluator.py @@ -243,15 +243,34 @@ def is_valid_instance_set_join( left_instance_set: InstanceSet, right_instance_set: InstanceSet, on_entity_reference: EntityReference, + right_node_is_subquery: bool = False, ) -> bool: """Return true if the instance sets can be joined using the given entity.""" - return self.is_valid_semantic_model_join( - left_semantic_model_reference=SemanticModelJoinEvaluator._semantic_model_of_entity_in_instance_set( - instance_set=left_instance_set, entity_reference=on_entity_reference - ), - right_semantic_model_reference=SemanticModelJoinEvaluator._semantic_model_of_entity_in_instance_set( - instance_set=right_instance_set, - entity_reference=on_entity_reference, - ), - on_entity_reference=on_entity_reference, + left_semantic_model_reference = SemanticModelJoinEvaluator._semantic_model_of_entity_in_instance_set( + instance_set=left_instance_set, entity_reference=on_entity_reference ) + if right_node_is_subquery: + left_entity = self._semantic_model_lookup.get_entity_in_semantic_model( + SemanticModelElementReference.create_from_references(left_semantic_model_reference, on_entity_reference) + ) + if not left_entity: + return False + possible_right_entities = [ + entity_instance + for entity_instance in right_instance_set.entity_instances + if entity_instance.spec.reference == on_entity_reference + ] + if len(possible_right_entities) != 1: + return False + + # No fan-out check needed since right subquery is aggregated to the entity level, ensuring uniqueness. + return True + else: + return self.is_valid_semantic_model_join( + left_semantic_model_reference=left_semantic_model_reference, + right_semantic_model_reference=SemanticModelJoinEvaluator._semantic_model_of_entity_in_instance_set( + instance_set=right_instance_set, + entity_reference=on_entity_reference, + ), + on_entity_reference=on_entity_reference, + ) diff --git a/metricflow/plan_conversion/dataflow_to_sql.py b/metricflow/plan_conversion/dataflow_to_sql.py index fb4d065180..0294e75926 100644 --- a/metricflow/plan_conversion/dataflow_to_sql.py +++ b/metricflow/plan_conversion/dataflow_to_sql.py @@ -67,6 +67,7 @@ CreateSqlColumnReferencesForInstances, FilterElements, FilterLinkableInstancesWithLeadingLink, + InstanceSetTransform, RemoveMeasures, RemoveMetrics, UpdateMeasureFillNullsWith, @@ -608,8 +609,7 @@ def visit_compute_metrics_node(self, node: ComputeMetricsNode) -> SqlDataSet: # Add select columns that would compute the metrics to the select columns. metric_select_columns = [] - metric_instances = [] - group_by_metric_instances = [] + metric_instances: List[MetricInstance] = [] for metric_spec in node.metric_specs: metric = self._metric_lookup.get_metric(metric_spec.reference) @@ -723,23 +723,25 @@ def visit_compute_metrics_node(self, node: ComputeMetricsNode) -> SqlDataSet: spec=metric_spec, ) ) - group_by_metric_instances.append( - GroupByMetricInstance( - associated_columns=(output_column_association,), - defined_from=MetricModelReference(metric_name=metric_spec.element_name), - spec=GroupByMetricSpec( - element_name=metric_spec.element_name, - entity_links=(), - metric_subquery_entity_links=(), # TODO - ), - ) + + transform_func: InstanceSetTransform = AddMetrics(metric_instances) + if node.for_group_by_source_node: + assert ( + len(metric_instances) == 1 and len(output_instance_set.entity_instances) == 1 + ), "Group by metrics currently only support exactly one metric grouped by exactly one entity." + metric_instance = metric_instances[0] + entity_instance = output_instance_set.entity_instances[0] + group_by_metric_instance = GroupByMetricInstance( + associated_columns=metric_instance.associated_columns, + defined_from=metric_instance.defined_from, + spec=GroupByMetricSpec( + element_name=metric_spec.element_name, + entity_links=(), # check this + metric_subquery_entity_links=entity_instance.spec.entity_links, + ), ) + transform_func = AddGroupByMetrics([group_by_metric_instance]) - transform_func = ( - AddGroupByMetrics(group_by_metric_instances) - if node.for_group_by_source_node - else AddMetrics(metric_instances) - ) output_instance_set = output_instance_set.transform(transform_func) combined_select_column_set = non_metric_select_column_set.merge( diff --git a/metricflow/plan_conversion/node_processor.py b/metricflow/plan_conversion/node_processor.py index 89dbaa14b4..80310511a7 100644 --- a/metricflow/plan_conversion/node_processor.py +++ b/metricflow/plan_conversion/node_processor.py @@ -11,6 +11,7 @@ from metricflow.dataflow.dataflow_plan import ( BaseOutput, ) +from metricflow.dataflow.nodes.compute_metrics import ComputeMetricsNode from metricflow.dataflow.nodes.constrain_time import ConstrainTimeRangeNode from metricflow.dataflow.nodes.filter_elements import FilterElementsNode from metricflow.dataflow.nodes.join_to_base import JoinDescription, JoinToBaseOutputNode @@ -130,9 +131,6 @@ def _node_contains_entity( if entity_spec_in_first_node.reference != entity_reference: continue - if len(entity_spec_in_first_node.entity_links) > 0: - continue - assert ( len(entity_instance_in_first_node.defined_from) == 1 ), "Multiple items in defined_from not yet supported" @@ -215,6 +213,8 @@ def _get_candidates_nodes_for_multi_hop( left_instance_set=data_set_of_first_node_that_could_be_joined.instance_set, right_instance_set=data_set_of_second_node_that_can_be_joined.instance_set, on_entity_reference=entity_reference_to_join_first_and_second_nodes, + # TODO: make this check more substantial in V2 + right_node_is_subquery=isinstance(second_node_that_could_be_joined, ComputeMetricsNode), ): continue From a0bee882fa69bea21518f0c817a071da61867ee1 Mon Sep 17 00:00:00 2001 From: Courtney Holcomb Date: Thu, 25 Apr 2024 15:36:59 -0700 Subject: [PATCH 28/37] Remove metrics that must be queried with metric_time from linkable metric options --- .../model/semantics/linkable_spec_resolver.py | 32 +- ...linkable_element_set_as_spec_set__set0.txt | 62 -- ...le_element_set_from_join_path__result0.txt | 229 +++-- ..._set_from_join_path_multi_hop__result0.txt | 229 +++-- ...linkable_elements_for_measure__result0.txt | 800 ++++++++---------- 5 files changed, 612 insertions(+), 740 deletions(-) diff --git a/metricflow/model/semantics/linkable_spec_resolver.py b/metricflow/model/semantics/linkable_spec_resolver.py index 3a5f6e9655..f3fedf0f81 100644 --- a/metricflow/model/semantics/linkable_spec_resolver.py +++ b/metricflow/model/semantics/linkable_spec_resolver.py @@ -8,6 +8,7 @@ from dbt_semantic_interfaces.enum_extension import assert_values_exhausted from dbt_semantic_interfaces.protocols.dimension import Dimension, DimensionType +from dbt_semantic_interfaces.protocols.metric import Metric from dbt_semantic_interfaces.protocols.semantic_manifest import SemanticManifest from dbt_semantic_interfaces.protocols.semantic_model import SemanticModel from dbt_semantic_interfaces.references import ( @@ -565,12 +566,14 @@ def __init__( self._entity_to_semantic_model[entity.reference.element_name].append(semantic_model) self._metric_to_linkable_element_sets: Dict[str, List[LinkableElementSet]] = {} + self._metric_references_to_metrics: Dict[MetricReference, Metric] = {} self._joinable_metrics_for_entities: Dict[EntityReference, Set[MetricSubqueryJoinPathElement]] = defaultdict( set ) start_time = time.time() for metric in self._semantic_manifest.metrics: + self._metric_references_to_metrics[MetricReference(metric.name)] = metric linkable_sets_for_measure = [] for measure in metric.measure_references: # Cumulative metrics currently can't be queried by other time granularities. @@ -608,8 +611,13 @@ def __init__( self._metric_to_linkable_element_sets[metric.name] = linkable_sets_for_measure - # This loop must happen after the one above so that _metric_to_linkable_element_sets is populated. + # Populate storage dicts with linkable metrics. This loop must happen after the one above so that + # _metric_to_linkable_element_sets is populated with entities and dimensions. for metric in self._semantic_manifest.metrics: + # Cumulative metrics and time offset metrics require grouping by metric_time, which is not yet available for + # linkable metrics. So skip those. + if self._metric_requires_metric_time(metric): + continue metric_reference = MetricReference(metric.name) linkable_element_set_for_metric = self.get_linkable_elements_for_metrics([metric_reference]) for linkable_entities in linkable_element_set_for_metric.path_key_to_linkable_entities.values(): @@ -622,6 +630,7 @@ def __init__( self._joinable_metrics_for_entities[linkable_entity.reference].add( metric_subquery_join_path_element ) + # TODO: update _metric_to_linkable_element_sets to have linkable metrics # If no metrics are specified, the query interface supports querying distinct values for dimensions, entities, # and group by metrics. @@ -639,6 +648,27 @@ def __init__( logger.info(f"Building valid group-by-item indexes took: {time.time() - start_time:.2f}s") + def _metric_requires_metric_time(self, metric: Metric) -> bool: + """Checks if the metric can only be queried with metric_time. Also checks input metrics. + + True if the metric uses cumulative time component or a time offset. + """ + metrics_to_check = [metric] + while metrics_to_check: + metric_to_check = metrics_to_check.pop() + if metric_to_check.type_params.window is not None or metric_to_check.type_params.grain_to_date is not None: + return True + for input_metric in metric_to_check.input_metrics: + if input_metric.offset_window is not None or input_metric.offset_to_grain is not None: + return True + metric_for_input_metric = self._metric_references_to_metrics.get(MetricReference(input_metric.name)) + assert ( + metric_for_input_metric + ), f"Did not find input metric {input_metric.name} in registered metrics. This indicates internal misconfiguration." + metrics_to_check.append(metric_for_input_metric) + + return False + def _get_semantic_model_for_measure(self, measure_reference: MeasureReference) -> SemanticModel: semantic_models_where_measure_was_found = [] for semantic_model in self._semantic_models: diff --git a/tests/snapshots/test_linkable_spec_resolver.py/list/test_linkable_element_set_as_spec_set__set0.txt b/tests/snapshots/test_linkable_spec_resolver.py/list/test_linkable_element_set_as_spec_set__set0.txt index 17b183e31e..50853aecf0 100644 --- a/tests/snapshots/test_linkable_spec_resolver.py/list/test_linkable_element_set_as_spec_set__set0.txt +++ b/tests/snapshots/test_linkable_spec_resolver.py/list/test_linkable_element_set_as_spec_set__set0.txt @@ -7,9 +7,7 @@ 'listing__average_instant_booking_value', 'listing__bookers', 'listing__booking_fees', - 'listing__booking_fees_last_week_per_booker_this_week', 'listing__booking_fees_per_booker', - 'listing__booking_fees_since_start_of_month', 'listing__booking_payments', 'listing__booking_value', 'listing__booking_value_for_non_null_listing_id', @@ -18,18 +16,9 @@ 'listing__booking_value_sub_instant', 'listing__booking_value_sub_instant_add_10', 'listing__bookings', - 'listing__bookings_5_day_lag', - 'listing__bookings_at_start_of_month', 'listing__bookings_fill_nulls_with_0', 'listing__bookings_fill_nulls_with_0_without_time_spine', - 'listing__bookings_growth_2_weeks', - 'listing__bookings_growth_2_weeks_fill_nulls_with_0', - 'listing__bookings_growth_2_weeks_fill_nulls_with_0_for_non_offset', - 'listing__bookings_growth_since_start_of_month', 'listing__bookings_join_to_time_spine', - 'listing__bookings_month_start_compared_to_1_month_prior', - 'listing__bookings_offset_once', - 'listing__bookings_offset_twice', 'listing__bookings_per_booker', 'listing__bookings_per_dollar', 'listing__bookings_per_listing', @@ -81,9 +70,6 @@ 'listing__ds__quarter', 'listing__ds__week', 'listing__ds__year', - 'listing__every_2_days_bookers_2_days_ago', - 'listing__every_two_days_bookers', - 'listing__every_two_days_bookers_fill_nulls_with_0', 'listing__instant_booking_fraction_of_max_value', 'listing__instant_booking_value', 'listing__instant_booking_value_ratio', @@ -103,9 +89,7 @@ 'listing__lux_listing__average_instant_booking_value', 'listing__lux_listing__bookers', 'listing__lux_listing__booking_fees', - 'listing__lux_listing__booking_fees_last_week_per_booker_this_week', 'listing__lux_listing__booking_fees_per_booker', - 'listing__lux_listing__booking_fees_since_start_of_month', 'listing__lux_listing__booking_payments', 'listing__lux_listing__booking_value', 'listing__lux_listing__booking_value_for_non_null_listing_id', @@ -114,18 +98,9 @@ 'listing__lux_listing__booking_value_sub_instant', 'listing__lux_listing__booking_value_sub_instant_add_10', 'listing__lux_listing__bookings', - 'listing__lux_listing__bookings_5_day_lag', - 'listing__lux_listing__bookings_at_start_of_month', 'listing__lux_listing__bookings_fill_nulls_with_0', 'listing__lux_listing__bookings_fill_nulls_with_0_without_time_spine', - 'listing__lux_listing__bookings_growth_2_weeks', - 'listing__lux_listing__bookings_growth_2_weeks_fill_nulls_with_0', - 'listing__lux_listing__bookings_growth_2_weeks_fill_nulls_with_0_for_non_offset', - 'listing__lux_listing__bookings_growth_since_start_of_month', 'listing__lux_listing__bookings_join_to_time_spine', - 'listing__lux_listing__bookings_month_start_compared_to_1_month_prior', - 'listing__lux_listing__bookings_offset_once', - 'listing__lux_listing__bookings_offset_twice', 'listing__lux_listing__bookings_per_booker', 'listing__lux_listing__bookings_per_dollar', 'listing__lux_listing__bookings_per_listing', @@ -135,9 +110,6 @@ 'listing__lux_listing__derived_bookings_1', 'listing__lux_listing__discrete_booking_value_p99', 'listing__lux_listing__double_counted_delayed_bookings', - 'listing__lux_listing__every_2_days_bookers_2_days_ago', - 'listing__lux_listing__every_two_days_bookers', - 'listing__lux_listing__every_two_days_bookers_fill_nulls_with_0', 'listing__lux_listing__instant_booking_fraction_of_max_value', 'listing__lux_listing__instant_booking_value', 'listing__lux_listing__instant_booking_value_ratio', @@ -199,9 +171,7 @@ 'user__average_instant_booking_value', 'user__bookers', 'user__booking_fees', - 'user__booking_fees_last_week_per_booker_this_week', 'user__booking_fees_per_booker', - 'user__booking_fees_since_start_of_month', 'user__booking_payments', 'user__booking_value', 'user__booking_value_for_non_null_listing_id', @@ -210,18 +180,9 @@ 'user__booking_value_sub_instant', 'user__booking_value_sub_instant_add_10', 'user__bookings', - 'user__bookings_5_day_lag', - 'user__bookings_at_start_of_month', 'user__bookings_fill_nulls_with_0', 'user__bookings_fill_nulls_with_0_without_time_spine', - 'user__bookings_growth_2_weeks', - 'user__bookings_growth_2_weeks_fill_nulls_with_0', - 'user__bookings_growth_2_weeks_fill_nulls_with_0_for_non_offset', - 'user__bookings_growth_since_start_of_month', 'user__bookings_join_to_time_spine', - 'user__bookings_month_start_compared_to_1_month_prior', - 'user__bookings_offset_once', - 'user__bookings_offset_twice', 'user__bookings_per_booker', 'user__bookings_per_dollar', 'user__bookings_per_listing', @@ -235,9 +196,7 @@ 'user__company__average_instant_booking_value', 'user__company__bookers', 'user__company__booking_fees', - 'user__company__booking_fees_last_week_per_booker_this_week', 'user__company__booking_fees_per_booker', - 'user__company__booking_fees_since_start_of_month', 'user__company__booking_payments', 'user__company__booking_value', 'user__company__booking_value_for_non_null_listing_id', @@ -246,18 +205,9 @@ 'user__company__booking_value_sub_instant', 'user__company__booking_value_sub_instant_add_10', 'user__company__bookings', - 'user__company__bookings_5_day_lag', - 'user__company__bookings_at_start_of_month', 'user__company__bookings_fill_nulls_with_0', 'user__company__bookings_fill_nulls_with_0_without_time_spine', - 'user__company__bookings_growth_2_weeks', - 'user__company__bookings_growth_2_weeks_fill_nulls_with_0', - 'user__company__bookings_growth_2_weeks_fill_nulls_with_0_for_non_offset', - 'user__company__bookings_growth_since_start_of_month', 'user__company__bookings_join_to_time_spine', - 'user__company__bookings_month_start_compared_to_1_month_prior', - 'user__company__bookings_offset_once', - 'user__company__bookings_offset_twice', 'user__company__bookings_per_booker', 'user__company__bookings_per_dollar', 'user__company__bookings_per_view', @@ -266,9 +216,6 @@ 'user__company__derived_bookings_1', 'user__company__discrete_booking_value_p99', 'user__company__double_counted_delayed_bookings', - 'user__company__every_2_days_bookers_2_days_ago', - 'user__company__every_two_days_bookers', - 'user__company__every_two_days_bookers_fill_nulls_with_0', 'user__company__identity_verifications', 'user__company__instant_booking_fraction_of_max_value', 'user__company__instant_booking_value', @@ -290,11 +237,8 @@ 'user__company__regional_starting_balance_ratios', 'user__company__revenue', 'user__company__revenue_all_time', - 'user__company__revenue_mtd', 'user__company__smallest_listing', 'user__company__total_account_balance_first_day', - 'user__company__trailing_2_months_revenue', - 'user__company__trailing_2_months_revenue_sub_10', 'user__company__twice_bookings_fill_nulls_with_0_without_time_spine', 'user__company__views', 'user__company__views_times_booking_value', @@ -389,9 +333,6 @@ 'user__ds_partitioned__quarter', 'user__ds_partitioned__week', 'user__ds_partitioned__year', - 'user__every_2_days_bookers_2_days_ago', - 'user__every_two_days_bookers', - 'user__every_two_days_bookers_fill_nulls_with_0', 'user__home_state', 'user__home_state_latest', 'user__identity_verifications', @@ -415,11 +356,8 @@ 'user__regional_starting_balance_ratios', 'user__revenue', 'user__revenue_all_time', - 'user__revenue_mtd', 'user__smallest_listing', 'user__total_account_balance_first_day', - 'user__trailing_2_months_revenue', - 'user__trailing_2_months_revenue_sub_10', 'user__twice_bookings_fill_nulls_with_0_without_time_spine', 'user__views', 'user__views_times_booking_value', diff --git a/tests/snapshots/test_linkable_spec_resolver.py/str/test_create_linkable_element_set_from_join_path__result0.txt b/tests/snapshots/test_linkable_spec_resolver.py/str/test_create_linkable_element_set_from_join_path__result0.txt index 56e7aaf2e6..9dc5906340 100644 --- a/tests/snapshots/test_linkable_spec_resolver.py/str/test_create_linkable_element_set_from_join_path__result0.txt +++ b/tests/snapshots/test_linkable_spec_resolver.py/str/test_create_linkable_element_set_from_join_path__result0.txt @@ -1,123 +1,106 @@ -Semantic Model Entity Links Name Time Granularity Date Part Properties ----------------- ------------------- -------------------------------------------------------- ------------------ ----------- -------------------------------------- -listings_latest ('listing',) capacity_latest ['JOINED'] -listings_latest ('listing',) country_latest ['JOINED'] -listings_latest ('listing',) created_at DAY ['JOINED'] -listings_latest ('listing',) created_at DAY DAY ['JOINED'] -listings_latest ('listing',) created_at DAY DOW ['JOINED'] -listings_latest ('listing',) created_at DAY DOY ['JOINED'] -listings_latest ('listing',) created_at DAY MONTH ['JOINED'] -listings_latest ('listing',) created_at DAY QUARTER ['JOINED'] -listings_latest ('listing',) created_at DAY YEAR ['JOINED'] -listings_latest ('listing',) created_at MONTH ['DERIVED_TIME_GRANULARITY', 'JOINED'] -listings_latest ('listing',) created_at MONTH MONTH ['DERIVED_TIME_GRANULARITY', 'JOINED'] -listings_latest ('listing',) created_at MONTH QUARTER ['DERIVED_TIME_GRANULARITY', 'JOINED'] -listings_latest ('listing',) created_at MONTH YEAR ['DERIVED_TIME_GRANULARITY', 'JOINED'] -listings_latest ('listing',) created_at QUARTER ['DERIVED_TIME_GRANULARITY', 'JOINED'] -listings_latest ('listing',) created_at QUARTER QUARTER ['DERIVED_TIME_GRANULARITY', 'JOINED'] -listings_latest ('listing',) created_at QUARTER YEAR ['DERIVED_TIME_GRANULARITY', 'JOINED'] -listings_latest ('listing',) created_at WEEK ['DERIVED_TIME_GRANULARITY', 'JOINED'] -listings_latest ('listing',) created_at WEEK MONTH ['DERIVED_TIME_GRANULARITY', 'JOINED'] -listings_latest ('listing',) created_at WEEK QUARTER ['DERIVED_TIME_GRANULARITY', 'JOINED'] -listings_latest ('listing',) created_at WEEK YEAR ['DERIVED_TIME_GRANULARITY', 'JOINED'] -listings_latest ('listing',) created_at YEAR ['DERIVED_TIME_GRANULARITY', 'JOINED'] -listings_latest ('listing',) created_at YEAR YEAR ['DERIVED_TIME_GRANULARITY', 'JOINED'] -listings_latest ('listing',) ds DAY ['JOINED'] -listings_latest ('listing',) ds DAY DAY ['JOINED'] -listings_latest ('listing',) ds DAY DOW ['JOINED'] -listings_latest ('listing',) ds DAY DOY ['JOINED'] -listings_latest ('listing',) ds DAY MONTH ['JOINED'] -listings_latest ('listing',) ds DAY QUARTER ['JOINED'] -listings_latest ('listing',) ds DAY YEAR ['JOINED'] -listings_latest ('listing',) ds MONTH ['DERIVED_TIME_GRANULARITY', 'JOINED'] -listings_latest ('listing',) ds MONTH MONTH ['DERIVED_TIME_GRANULARITY', 'JOINED'] -listings_latest ('listing',) ds MONTH QUARTER ['DERIVED_TIME_GRANULARITY', 'JOINED'] -listings_latest ('listing',) ds MONTH YEAR ['DERIVED_TIME_GRANULARITY', 'JOINED'] -listings_latest ('listing',) ds QUARTER ['DERIVED_TIME_GRANULARITY', 'JOINED'] -listings_latest ('listing',) ds QUARTER QUARTER ['DERIVED_TIME_GRANULARITY', 'JOINED'] -listings_latest ('listing',) ds QUARTER YEAR ['DERIVED_TIME_GRANULARITY', 'JOINED'] -listings_latest ('listing',) ds WEEK ['DERIVED_TIME_GRANULARITY', 'JOINED'] -listings_latest ('listing',) ds WEEK MONTH ['DERIVED_TIME_GRANULARITY', 'JOINED'] -listings_latest ('listing',) ds WEEK QUARTER ['DERIVED_TIME_GRANULARITY', 'JOINED'] -listings_latest ('listing',) ds WEEK YEAR ['DERIVED_TIME_GRANULARITY', 'JOINED'] -listings_latest ('listing',) ds YEAR ['DERIVED_TIME_GRANULARITY', 'JOINED'] -listings_latest ('listing',) ds YEAR YEAR ['DERIVED_TIME_GRANULARITY', 'JOINED'] -listings_latest ('listing',) is_lux_latest ['JOINED'] -listings_latest ('listing',) user ['ENTITY', 'JOINED'] -listings_latest ('listing', 'user') active_listings ['JOINED', 'METRIC', 'MULTI_HOP'] -listings_latest ('listing', 'user') approximate_continuous_booking_value_p99 ['JOINED', 'METRIC', 'MULTI_HOP'] -listings_latest ('listing', 'user') approximate_discrete_booking_value_p99 ['JOINED', 'METRIC', 'MULTI_HOP'] -listings_latest ('listing', 'user') average_booking_value ['JOINED', 'METRIC', 'MULTI_HOP'] -listings_latest ('listing', 'user') average_instant_booking_value ['JOINED', 'METRIC', 'MULTI_HOP'] -listings_latest ('listing', 'user') bookers ['JOINED', 'METRIC', 'MULTI_HOP'] -listings_latest ('listing', 'user') booking_fees ['JOINED', 'METRIC', 'MULTI_HOP'] -listings_latest ('listing', 'user') booking_fees_last_week_per_booker_this_week ['JOINED', 'METRIC', 'MULTI_HOP'] -listings_latest ('listing', 'user') booking_fees_per_booker ['JOINED', 'METRIC', 'MULTI_HOP'] -listings_latest ('listing', 'user') booking_fees_since_start_of_month ['JOINED', 'METRIC', 'MULTI_HOP'] -listings_latest ('listing', 'user') booking_payments ['JOINED', 'METRIC', 'MULTI_HOP'] -listings_latest ('listing', 'user') booking_value ['JOINED', 'METRIC', 'MULTI_HOP'] -listings_latest ('listing', 'user') booking_value_for_non_null_listing_id ['JOINED', 'METRIC', 'MULTI_HOP'] -listings_latest ('listing', 'user') booking_value_p99 ['JOINED', 'METRIC', 'MULTI_HOP'] -listings_latest ('listing', 'user') booking_value_per_view ['JOINED', 'METRIC', 'MULTI_HOP'] -listings_latest ('listing', 'user') booking_value_sub_instant ['JOINED', 'METRIC', 'MULTI_HOP'] -listings_latest ('listing', 'user') booking_value_sub_instant_add_10 ['JOINED', 'METRIC', 'MULTI_HOP'] -listings_latest ('listing', 'user') bookings ['JOINED', 'METRIC', 'MULTI_HOP'] -listings_latest ('listing', 'user') bookings_5_day_lag ['JOINED', 'METRIC', 'MULTI_HOP'] -listings_latest ('listing', 'user') bookings_at_start_of_month ['JOINED', 'METRIC', 'MULTI_HOP'] -listings_latest ('listing', 'user') bookings_fill_nulls_with_0 ['JOINED', 'METRIC', 'MULTI_HOP'] -listings_latest ('listing', 'user') bookings_fill_nulls_with_0_without_time_spine ['JOINED', 'METRIC', 'MULTI_HOP'] -listings_latest ('listing', 'user') bookings_growth_2_weeks ['JOINED', 'METRIC', 'MULTI_HOP'] -listings_latest ('listing', 'user') bookings_growth_2_weeks_fill_nulls_with_0 ['JOINED', 'METRIC', 'MULTI_HOP'] -listings_latest ('listing', 'user') bookings_growth_2_weeks_fill_nulls_with_0_for_non_offset ['JOINED', 'METRIC', 'MULTI_HOP'] -listings_latest ('listing', 'user') bookings_growth_since_start_of_month ['JOINED', 'METRIC', 'MULTI_HOP'] -listings_latest ('listing', 'user') bookings_join_to_time_spine ['JOINED', 'METRIC', 'MULTI_HOP'] -listings_latest ('listing', 'user') bookings_month_start_compared_to_1_month_prior ['JOINED', 'METRIC', 'MULTI_HOP'] -listings_latest ('listing', 'user') bookings_offset_once ['JOINED', 'METRIC', 'MULTI_HOP'] -listings_latest ('listing', 'user') bookings_offset_twice ['JOINED', 'METRIC', 'MULTI_HOP'] -listings_latest ('listing', 'user') bookings_per_booker ['JOINED', 'METRIC', 'MULTI_HOP'] -listings_latest ('listing', 'user') bookings_per_dollar ['JOINED', 'METRIC', 'MULTI_HOP'] -listings_latest ('listing', 'user') bookings_per_listing ['JOINED', 'METRIC', 'MULTI_HOP'] -listings_latest ('listing', 'user') bookings_per_lux_listing_derived ['JOINED', 'METRIC', 'MULTI_HOP'] -listings_latest ('listing', 'user') bookings_per_view ['JOINED', 'METRIC', 'MULTI_HOP'] -listings_latest ('listing', 'user') current_account_balance_by_user ['JOINED', 'METRIC', 'MULTI_HOP'] -listings_latest ('listing', 'user') derived_bookings_0 ['JOINED', 'METRIC', 'MULTI_HOP'] -listings_latest ('listing', 'user') derived_bookings_1 ['JOINED', 'METRIC', 'MULTI_HOP'] -listings_latest ('listing', 'user') discrete_booking_value_p99 ['JOINED', 'METRIC', 'MULTI_HOP'] -listings_latest ('listing', 'user') double_counted_delayed_bookings ['JOINED', 'METRIC', 'MULTI_HOP'] -listings_latest ('listing', 'user') every_2_days_bookers_2_days_ago ['JOINED', 'METRIC', 'MULTI_HOP'] -listings_latest ('listing', 'user') every_two_days_bookers ['JOINED', 'METRIC', 'MULTI_HOP'] -listings_latest ('listing', 'user') every_two_days_bookers_fill_nulls_with_0 ['JOINED', 'METRIC', 'MULTI_HOP'] -listings_latest ('listing', 'user') identity_verifications ['JOINED', 'METRIC', 'MULTI_HOP'] -listings_latest ('listing', 'user') instant_booking_fraction_of_max_value ['JOINED', 'METRIC', 'MULTI_HOP'] -listings_latest ('listing', 'user') instant_booking_value ['JOINED', 'METRIC', 'MULTI_HOP'] -listings_latest ('listing', 'user') instant_booking_value_ratio ['JOINED', 'METRIC', 'MULTI_HOP'] -listings_latest ('listing', 'user') instant_bookings ['JOINED', 'METRIC', 'MULTI_HOP'] -listings_latest ('listing', 'user') instant_lux_booking_value_rate ['JOINED', 'METRIC', 'MULTI_HOP'] -listings_latest ('listing', 'user') instant_plus_non_referred_bookings_pct ['JOINED', 'METRIC', 'MULTI_HOP'] -listings_latest ('listing', 'user') largest_listing ['JOINED', 'METRIC', 'MULTI_HOP'] -listings_latest ('listing', 'user') listings ['JOINED', 'METRIC', 'MULTI_HOP'] -listings_latest ('listing', 'user') lux_booking_fraction_of_max_value ['JOINED', 'METRIC', 'MULTI_HOP'] -listings_latest ('listing', 'user') lux_booking_value_rate_expr ['JOINED', 'METRIC', 'MULTI_HOP'] -listings_latest ('listing', 'user') lux_listings ['JOINED', 'METRIC', 'MULTI_HOP'] -listings_latest ('listing', 'user') max_booking_value ['JOINED', 'METRIC', 'MULTI_HOP'] -listings_latest ('listing', 'user') median_booking_value ['JOINED', 'METRIC', 'MULTI_HOP'] -listings_latest ('listing', 'user') min_booking_value ['JOINED', 'METRIC', 'MULTI_HOP'] -listings_latest ('listing', 'user') nested_fill_nulls_without_time_spine ['JOINED', 'METRIC', 'MULTI_HOP'] -listings_latest ('listing', 'user') non_referred_bookings_pct ['JOINED', 'METRIC', 'MULTI_HOP'] -listings_latest ('listing', 'user') referred_bookings ['JOINED', 'METRIC', 'MULTI_HOP'] -listings_latest ('listing', 'user') regional_starting_balance_ratios ['JOINED', 'METRIC', 'MULTI_HOP'] -listings_latest ('listing', 'user') revenue ['JOINED', 'METRIC', 'MULTI_HOP'] -listings_latest ('listing', 'user') revenue_all_time ['JOINED', 'METRIC', 'MULTI_HOP'] -listings_latest ('listing', 'user') revenue_mtd ['JOINED', 'METRIC', 'MULTI_HOP'] -listings_latest ('listing', 'user') smallest_listing ['JOINED', 'METRIC', 'MULTI_HOP'] -listings_latest ('listing', 'user') total_account_balance_first_day ['JOINED', 'METRIC', 'MULTI_HOP'] -listings_latest ('listing', 'user') trailing_2_months_revenue ['JOINED', 'METRIC', 'MULTI_HOP'] -listings_latest ('listing', 'user') trailing_2_months_revenue_sub_10 ['JOINED', 'METRIC', 'MULTI_HOP'] -listings_latest ('listing', 'user') twice_bookings_fill_nulls_with_0_without_time_spine ['JOINED', 'METRIC', 'MULTI_HOP'] -listings_latest ('listing', 'user') views ['JOINED', 'METRIC', 'MULTI_HOP'] -listings_latest ('listing', 'user') views_times_booking_value ['JOINED', 'METRIC', 'MULTI_HOP'] -listings_latest ('listing', 'user') visit_buy_conversion_rate ['JOINED', 'METRIC', 'MULTI_HOP'] -listings_latest ('listing', 'user') visit_buy_conversion_rate_7days ['JOINED', 'METRIC', 'MULTI_HOP'] -listings_latest ('listing', 'user') visit_buy_conversion_rate_7days_fill_nulls_with_0 ['JOINED', 'METRIC', 'MULTI_HOP'] -listings_latest ('listing', 'user') visit_buy_conversion_rate_by_session ['JOINED', 'METRIC', 'MULTI_HOP'] -listings_latest ('listing', 'user') visit_buy_conversions ['JOINED', 'METRIC', 'MULTI_HOP'] +Semantic Model Entity Links Name Time Granularity Date Part Properties +---------------- ------------------- --------------------------------------------------- ------------------ ----------- -------------------------------------- +listings_latest ('listing',) capacity_latest ['JOINED'] +listings_latest ('listing',) country_latest ['JOINED'] +listings_latest ('listing',) created_at DAY ['JOINED'] +listings_latest ('listing',) created_at DAY DAY ['JOINED'] +listings_latest ('listing',) created_at DAY DOW ['JOINED'] +listings_latest ('listing',) created_at DAY DOY ['JOINED'] +listings_latest ('listing',) created_at DAY MONTH ['JOINED'] +listings_latest ('listing',) created_at DAY QUARTER ['JOINED'] +listings_latest ('listing',) created_at DAY YEAR ['JOINED'] +listings_latest ('listing',) created_at MONTH ['DERIVED_TIME_GRANULARITY', 'JOINED'] +listings_latest ('listing',) created_at MONTH MONTH ['DERIVED_TIME_GRANULARITY', 'JOINED'] +listings_latest ('listing',) created_at MONTH QUARTER ['DERIVED_TIME_GRANULARITY', 'JOINED'] +listings_latest ('listing',) created_at MONTH YEAR ['DERIVED_TIME_GRANULARITY', 'JOINED'] +listings_latest ('listing',) created_at QUARTER ['DERIVED_TIME_GRANULARITY', 'JOINED'] +listings_latest ('listing',) created_at QUARTER QUARTER ['DERIVED_TIME_GRANULARITY', 'JOINED'] +listings_latest ('listing',) created_at QUARTER YEAR ['DERIVED_TIME_GRANULARITY', 'JOINED'] +listings_latest ('listing',) created_at WEEK ['DERIVED_TIME_GRANULARITY', 'JOINED'] +listings_latest ('listing',) created_at WEEK MONTH ['DERIVED_TIME_GRANULARITY', 'JOINED'] +listings_latest ('listing',) created_at WEEK QUARTER ['DERIVED_TIME_GRANULARITY', 'JOINED'] +listings_latest ('listing',) created_at WEEK YEAR ['DERIVED_TIME_GRANULARITY', 'JOINED'] +listings_latest ('listing',) created_at YEAR ['DERIVED_TIME_GRANULARITY', 'JOINED'] +listings_latest ('listing',) created_at YEAR YEAR ['DERIVED_TIME_GRANULARITY', 'JOINED'] +listings_latest ('listing',) ds DAY ['JOINED'] +listings_latest ('listing',) ds DAY DAY ['JOINED'] +listings_latest ('listing',) ds DAY DOW ['JOINED'] +listings_latest ('listing',) ds DAY DOY ['JOINED'] +listings_latest ('listing',) ds DAY MONTH ['JOINED'] +listings_latest ('listing',) ds DAY QUARTER ['JOINED'] +listings_latest ('listing',) ds DAY YEAR ['JOINED'] +listings_latest ('listing',) ds MONTH ['DERIVED_TIME_GRANULARITY', 'JOINED'] +listings_latest ('listing',) ds MONTH MONTH ['DERIVED_TIME_GRANULARITY', 'JOINED'] +listings_latest ('listing',) ds MONTH QUARTER ['DERIVED_TIME_GRANULARITY', 'JOINED'] +listings_latest ('listing',) ds MONTH YEAR ['DERIVED_TIME_GRANULARITY', 'JOINED'] +listings_latest ('listing',) ds QUARTER ['DERIVED_TIME_GRANULARITY', 'JOINED'] +listings_latest ('listing',) ds QUARTER QUARTER ['DERIVED_TIME_GRANULARITY', 'JOINED'] +listings_latest ('listing',) ds QUARTER YEAR ['DERIVED_TIME_GRANULARITY', 'JOINED'] +listings_latest ('listing',) ds WEEK ['DERIVED_TIME_GRANULARITY', 'JOINED'] +listings_latest ('listing',) ds WEEK MONTH ['DERIVED_TIME_GRANULARITY', 'JOINED'] +listings_latest ('listing',) ds WEEK QUARTER ['DERIVED_TIME_GRANULARITY', 'JOINED'] +listings_latest ('listing',) ds WEEK YEAR ['DERIVED_TIME_GRANULARITY', 'JOINED'] +listings_latest ('listing',) ds YEAR ['DERIVED_TIME_GRANULARITY', 'JOINED'] +listings_latest ('listing',) ds YEAR YEAR ['DERIVED_TIME_GRANULARITY', 'JOINED'] +listings_latest ('listing',) is_lux_latest ['JOINED'] +listings_latest ('listing',) user ['ENTITY', 'JOINED'] +listings_latest ('listing', 'user') active_listings ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('listing', 'user') approximate_continuous_booking_value_p99 ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('listing', 'user') approximate_discrete_booking_value_p99 ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('listing', 'user') average_booking_value ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('listing', 'user') average_instant_booking_value ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('listing', 'user') bookers ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('listing', 'user') booking_fees ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('listing', 'user') booking_fees_per_booker ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('listing', 'user') booking_payments ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('listing', 'user') booking_value ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('listing', 'user') booking_value_for_non_null_listing_id ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('listing', 'user') booking_value_p99 ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('listing', 'user') booking_value_per_view ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('listing', 'user') booking_value_sub_instant ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('listing', 'user') booking_value_sub_instant_add_10 ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('listing', 'user') bookings ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('listing', 'user') bookings_fill_nulls_with_0 ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('listing', 'user') bookings_fill_nulls_with_0_without_time_spine ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('listing', 'user') bookings_join_to_time_spine ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('listing', 'user') bookings_per_booker ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('listing', 'user') bookings_per_dollar ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('listing', 'user') bookings_per_listing ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('listing', 'user') bookings_per_lux_listing_derived ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('listing', 'user') bookings_per_view ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('listing', 'user') current_account_balance_by_user ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('listing', 'user') derived_bookings_0 ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('listing', 'user') derived_bookings_1 ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('listing', 'user') discrete_booking_value_p99 ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('listing', 'user') double_counted_delayed_bookings ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('listing', 'user') identity_verifications ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('listing', 'user') instant_booking_fraction_of_max_value ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('listing', 'user') instant_booking_value ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('listing', 'user') instant_booking_value_ratio ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('listing', 'user') instant_bookings ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('listing', 'user') instant_lux_booking_value_rate ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('listing', 'user') instant_plus_non_referred_bookings_pct ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('listing', 'user') largest_listing ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('listing', 'user') listings ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('listing', 'user') lux_booking_fraction_of_max_value ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('listing', 'user') lux_booking_value_rate_expr ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('listing', 'user') lux_listings ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('listing', 'user') max_booking_value ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('listing', 'user') median_booking_value ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('listing', 'user') min_booking_value ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('listing', 'user') nested_fill_nulls_without_time_spine ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('listing', 'user') non_referred_bookings_pct ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('listing', 'user') referred_bookings ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('listing', 'user') regional_starting_balance_ratios ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('listing', 'user') revenue ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('listing', 'user') revenue_all_time ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('listing', 'user') smallest_listing ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('listing', 'user') total_account_balance_first_day ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('listing', 'user') twice_bookings_fill_nulls_with_0_without_time_spine ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('listing', 'user') views ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('listing', 'user') views_times_booking_value ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('listing', 'user') visit_buy_conversion_rate ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('listing', 'user') visit_buy_conversion_rate_7days ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('listing', 'user') visit_buy_conversion_rate_7days_fill_nulls_with_0 ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('listing', 'user') visit_buy_conversion_rate_by_session ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('listing', 'user') visit_buy_conversions ['JOINED', 'METRIC', 'MULTI_HOP'] diff --git a/tests/snapshots/test_linkable_spec_resolver.py/str/test_create_linkable_element_set_from_join_path_multi_hop__result0.txt b/tests/snapshots/test_linkable_spec_resolver.py/str/test_create_linkable_element_set_from_join_path_multi_hop__result0.txt index d45d38ec9c..281437a0a5 100644 --- a/tests/snapshots/test_linkable_spec_resolver.py/str/test_create_linkable_element_set_from_join_path_multi_hop__result0.txt +++ b/tests/snapshots/test_linkable_spec_resolver.py/str/test_create_linkable_element_set_from_join_path_multi_hop__result0.txt @@ -1,123 +1,106 @@ -Semantic Model Entity Links Name Time Granularity Date Part Properties ----------------- ---------------------------- -------------------------------------------------------- ------------------ ----------- --------------------------------------------------- -listings_latest ('guest', 'listing') capacity_latest ['JOINED', 'MULTI_HOP'] -listings_latest ('guest', 'listing') country_latest ['JOINED', 'MULTI_HOP'] -listings_latest ('guest', 'listing') created_at DAY ['JOINED', 'MULTI_HOP'] -listings_latest ('guest', 'listing') created_at DAY DAY ['JOINED', 'MULTI_HOP'] -listings_latest ('guest', 'listing') created_at DAY DOW ['JOINED', 'MULTI_HOP'] -listings_latest ('guest', 'listing') created_at DAY DOY ['JOINED', 'MULTI_HOP'] -listings_latest ('guest', 'listing') created_at DAY MONTH ['JOINED', 'MULTI_HOP'] -listings_latest ('guest', 'listing') created_at DAY QUARTER ['JOINED', 'MULTI_HOP'] -listings_latest ('guest', 'listing') created_at DAY YEAR ['JOINED', 'MULTI_HOP'] -listings_latest ('guest', 'listing') created_at MONTH ['DERIVED_TIME_GRANULARITY', 'JOINED', 'MULTI_HOP'] -listings_latest ('guest', 'listing') created_at MONTH MONTH ['DERIVED_TIME_GRANULARITY', 'JOINED', 'MULTI_HOP'] -listings_latest ('guest', 'listing') created_at MONTH QUARTER ['DERIVED_TIME_GRANULARITY', 'JOINED', 'MULTI_HOP'] -listings_latest ('guest', 'listing') created_at MONTH YEAR ['DERIVED_TIME_GRANULARITY', 'JOINED', 'MULTI_HOP'] -listings_latest ('guest', 'listing') created_at QUARTER ['DERIVED_TIME_GRANULARITY', 'JOINED', 'MULTI_HOP'] -listings_latest ('guest', 'listing') created_at QUARTER QUARTER ['DERIVED_TIME_GRANULARITY', 'JOINED', 'MULTI_HOP'] -listings_latest ('guest', 'listing') created_at QUARTER YEAR ['DERIVED_TIME_GRANULARITY', 'JOINED', 'MULTI_HOP'] -listings_latest ('guest', 'listing') created_at WEEK ['DERIVED_TIME_GRANULARITY', 'JOINED', 'MULTI_HOP'] -listings_latest ('guest', 'listing') created_at WEEK MONTH ['DERIVED_TIME_GRANULARITY', 'JOINED', 'MULTI_HOP'] -listings_latest ('guest', 'listing') created_at WEEK QUARTER ['DERIVED_TIME_GRANULARITY', 'JOINED', 'MULTI_HOP'] -listings_latest ('guest', 'listing') created_at WEEK YEAR ['DERIVED_TIME_GRANULARITY', 'JOINED', 'MULTI_HOP'] -listings_latest ('guest', 'listing') created_at YEAR ['DERIVED_TIME_GRANULARITY', 'JOINED', 'MULTI_HOP'] -listings_latest ('guest', 'listing') created_at YEAR YEAR ['DERIVED_TIME_GRANULARITY', 'JOINED', 'MULTI_HOP'] -listings_latest ('guest', 'listing') ds DAY ['JOINED', 'MULTI_HOP'] -listings_latest ('guest', 'listing') ds DAY DAY ['JOINED', 'MULTI_HOP'] -listings_latest ('guest', 'listing') ds DAY DOW ['JOINED', 'MULTI_HOP'] -listings_latest ('guest', 'listing') ds DAY DOY ['JOINED', 'MULTI_HOP'] -listings_latest ('guest', 'listing') ds DAY MONTH ['JOINED', 'MULTI_HOP'] -listings_latest ('guest', 'listing') ds DAY QUARTER ['JOINED', 'MULTI_HOP'] -listings_latest ('guest', 'listing') ds DAY YEAR ['JOINED', 'MULTI_HOP'] -listings_latest ('guest', 'listing') ds MONTH ['DERIVED_TIME_GRANULARITY', 'JOINED', 'MULTI_HOP'] -listings_latest ('guest', 'listing') ds MONTH MONTH ['DERIVED_TIME_GRANULARITY', 'JOINED', 'MULTI_HOP'] -listings_latest ('guest', 'listing') ds MONTH QUARTER ['DERIVED_TIME_GRANULARITY', 'JOINED', 'MULTI_HOP'] -listings_latest ('guest', 'listing') ds MONTH YEAR ['DERIVED_TIME_GRANULARITY', 'JOINED', 'MULTI_HOP'] -listings_latest ('guest', 'listing') ds QUARTER ['DERIVED_TIME_GRANULARITY', 'JOINED', 'MULTI_HOP'] -listings_latest ('guest', 'listing') ds QUARTER QUARTER ['DERIVED_TIME_GRANULARITY', 'JOINED', 'MULTI_HOP'] -listings_latest ('guest', 'listing') ds QUARTER YEAR ['DERIVED_TIME_GRANULARITY', 'JOINED', 'MULTI_HOP'] -listings_latest ('guest', 'listing') ds WEEK ['DERIVED_TIME_GRANULARITY', 'JOINED', 'MULTI_HOP'] -listings_latest ('guest', 'listing') ds WEEK MONTH ['DERIVED_TIME_GRANULARITY', 'JOINED', 'MULTI_HOP'] -listings_latest ('guest', 'listing') ds WEEK QUARTER ['DERIVED_TIME_GRANULARITY', 'JOINED', 'MULTI_HOP'] -listings_latest ('guest', 'listing') ds WEEK YEAR ['DERIVED_TIME_GRANULARITY', 'JOINED', 'MULTI_HOP'] -listings_latest ('guest', 'listing') ds YEAR ['DERIVED_TIME_GRANULARITY', 'JOINED', 'MULTI_HOP'] -listings_latest ('guest', 'listing') ds YEAR YEAR ['DERIVED_TIME_GRANULARITY', 'JOINED', 'MULTI_HOP'] -listings_latest ('guest', 'listing') is_lux_latest ['JOINED', 'MULTI_HOP'] -listings_latest ('guest', 'listing') user ['ENTITY', 'JOINED', 'MULTI_HOP'] -listings_latest ('guest', 'listing', 'user') active_listings ['JOINED', 'METRIC', 'MULTI_HOP'] -listings_latest ('guest', 'listing', 'user') approximate_continuous_booking_value_p99 ['JOINED', 'METRIC', 'MULTI_HOP'] -listings_latest ('guest', 'listing', 'user') approximate_discrete_booking_value_p99 ['JOINED', 'METRIC', 'MULTI_HOP'] -listings_latest ('guest', 'listing', 'user') average_booking_value ['JOINED', 'METRIC', 'MULTI_HOP'] -listings_latest ('guest', 'listing', 'user') average_instant_booking_value ['JOINED', 'METRIC', 'MULTI_HOP'] -listings_latest ('guest', 'listing', 'user') bookers ['JOINED', 'METRIC', 'MULTI_HOP'] -listings_latest ('guest', 'listing', 'user') booking_fees ['JOINED', 'METRIC', 'MULTI_HOP'] -listings_latest ('guest', 'listing', 'user') booking_fees_last_week_per_booker_this_week ['JOINED', 'METRIC', 'MULTI_HOP'] -listings_latest ('guest', 'listing', 'user') booking_fees_per_booker ['JOINED', 'METRIC', 'MULTI_HOP'] -listings_latest ('guest', 'listing', 'user') booking_fees_since_start_of_month ['JOINED', 'METRIC', 'MULTI_HOP'] -listings_latest ('guest', 'listing', 'user') booking_payments ['JOINED', 'METRIC', 'MULTI_HOP'] -listings_latest ('guest', 'listing', 'user') booking_value ['JOINED', 'METRIC', 'MULTI_HOP'] -listings_latest ('guest', 'listing', 'user') booking_value_for_non_null_listing_id ['JOINED', 'METRIC', 'MULTI_HOP'] -listings_latest ('guest', 'listing', 'user') booking_value_p99 ['JOINED', 'METRIC', 'MULTI_HOP'] -listings_latest ('guest', 'listing', 'user') booking_value_per_view ['JOINED', 'METRIC', 'MULTI_HOP'] -listings_latest ('guest', 'listing', 'user') booking_value_sub_instant ['JOINED', 'METRIC', 'MULTI_HOP'] -listings_latest ('guest', 'listing', 'user') booking_value_sub_instant_add_10 ['JOINED', 'METRIC', 'MULTI_HOP'] -listings_latest ('guest', 'listing', 'user') bookings ['JOINED', 'METRIC', 'MULTI_HOP'] -listings_latest ('guest', 'listing', 'user') bookings_5_day_lag ['JOINED', 'METRIC', 'MULTI_HOP'] -listings_latest ('guest', 'listing', 'user') bookings_at_start_of_month ['JOINED', 'METRIC', 'MULTI_HOP'] -listings_latest ('guest', 'listing', 'user') bookings_fill_nulls_with_0 ['JOINED', 'METRIC', 'MULTI_HOP'] -listings_latest ('guest', 'listing', 'user') bookings_fill_nulls_with_0_without_time_spine ['JOINED', 'METRIC', 'MULTI_HOP'] -listings_latest ('guest', 'listing', 'user') bookings_growth_2_weeks ['JOINED', 'METRIC', 'MULTI_HOP'] -listings_latest ('guest', 'listing', 'user') bookings_growth_2_weeks_fill_nulls_with_0 ['JOINED', 'METRIC', 'MULTI_HOP'] -listings_latest ('guest', 'listing', 'user') bookings_growth_2_weeks_fill_nulls_with_0_for_non_offset ['JOINED', 'METRIC', 'MULTI_HOP'] -listings_latest ('guest', 'listing', 'user') bookings_growth_since_start_of_month ['JOINED', 'METRIC', 'MULTI_HOP'] -listings_latest ('guest', 'listing', 'user') bookings_join_to_time_spine ['JOINED', 'METRIC', 'MULTI_HOP'] -listings_latest ('guest', 'listing', 'user') bookings_month_start_compared_to_1_month_prior ['JOINED', 'METRIC', 'MULTI_HOP'] -listings_latest ('guest', 'listing', 'user') bookings_offset_once ['JOINED', 'METRIC', 'MULTI_HOP'] -listings_latest ('guest', 'listing', 'user') bookings_offset_twice ['JOINED', 'METRIC', 'MULTI_HOP'] -listings_latest ('guest', 'listing', 'user') bookings_per_booker ['JOINED', 'METRIC', 'MULTI_HOP'] -listings_latest ('guest', 'listing', 'user') bookings_per_dollar ['JOINED', 'METRIC', 'MULTI_HOP'] -listings_latest ('guest', 'listing', 'user') bookings_per_listing ['JOINED', 'METRIC', 'MULTI_HOP'] -listings_latest ('guest', 'listing', 'user') bookings_per_lux_listing_derived ['JOINED', 'METRIC', 'MULTI_HOP'] -listings_latest ('guest', 'listing', 'user') bookings_per_view ['JOINED', 'METRIC', 'MULTI_HOP'] -listings_latest ('guest', 'listing', 'user') current_account_balance_by_user ['JOINED', 'METRIC', 'MULTI_HOP'] -listings_latest ('guest', 'listing', 'user') derived_bookings_0 ['JOINED', 'METRIC', 'MULTI_HOP'] -listings_latest ('guest', 'listing', 'user') derived_bookings_1 ['JOINED', 'METRIC', 'MULTI_HOP'] -listings_latest ('guest', 'listing', 'user') discrete_booking_value_p99 ['JOINED', 'METRIC', 'MULTI_HOP'] -listings_latest ('guest', 'listing', 'user') double_counted_delayed_bookings ['JOINED', 'METRIC', 'MULTI_HOP'] -listings_latest ('guest', 'listing', 'user') every_2_days_bookers_2_days_ago ['JOINED', 'METRIC', 'MULTI_HOP'] -listings_latest ('guest', 'listing', 'user') every_two_days_bookers ['JOINED', 'METRIC', 'MULTI_HOP'] -listings_latest ('guest', 'listing', 'user') every_two_days_bookers_fill_nulls_with_0 ['JOINED', 'METRIC', 'MULTI_HOP'] -listings_latest ('guest', 'listing', 'user') identity_verifications ['JOINED', 'METRIC', 'MULTI_HOP'] -listings_latest ('guest', 'listing', 'user') instant_booking_fraction_of_max_value ['JOINED', 'METRIC', 'MULTI_HOP'] -listings_latest ('guest', 'listing', 'user') instant_booking_value ['JOINED', 'METRIC', 'MULTI_HOP'] -listings_latest ('guest', 'listing', 'user') instant_booking_value_ratio ['JOINED', 'METRIC', 'MULTI_HOP'] -listings_latest ('guest', 'listing', 'user') instant_bookings ['JOINED', 'METRIC', 'MULTI_HOP'] -listings_latest ('guest', 'listing', 'user') instant_lux_booking_value_rate ['JOINED', 'METRIC', 'MULTI_HOP'] -listings_latest ('guest', 'listing', 'user') instant_plus_non_referred_bookings_pct ['JOINED', 'METRIC', 'MULTI_HOP'] -listings_latest ('guest', 'listing', 'user') largest_listing ['JOINED', 'METRIC', 'MULTI_HOP'] -listings_latest ('guest', 'listing', 'user') listings ['JOINED', 'METRIC', 'MULTI_HOP'] -listings_latest ('guest', 'listing', 'user') lux_booking_fraction_of_max_value ['JOINED', 'METRIC', 'MULTI_HOP'] -listings_latest ('guest', 'listing', 'user') lux_booking_value_rate_expr ['JOINED', 'METRIC', 'MULTI_HOP'] -listings_latest ('guest', 'listing', 'user') lux_listings ['JOINED', 'METRIC', 'MULTI_HOP'] -listings_latest ('guest', 'listing', 'user') max_booking_value ['JOINED', 'METRIC', 'MULTI_HOP'] -listings_latest ('guest', 'listing', 'user') median_booking_value ['JOINED', 'METRIC', 'MULTI_HOP'] -listings_latest ('guest', 'listing', 'user') min_booking_value ['JOINED', 'METRIC', 'MULTI_HOP'] -listings_latest ('guest', 'listing', 'user') nested_fill_nulls_without_time_spine ['JOINED', 'METRIC', 'MULTI_HOP'] -listings_latest ('guest', 'listing', 'user') non_referred_bookings_pct ['JOINED', 'METRIC', 'MULTI_HOP'] -listings_latest ('guest', 'listing', 'user') referred_bookings ['JOINED', 'METRIC', 'MULTI_HOP'] -listings_latest ('guest', 'listing', 'user') regional_starting_balance_ratios ['JOINED', 'METRIC', 'MULTI_HOP'] -listings_latest ('guest', 'listing', 'user') revenue ['JOINED', 'METRIC', 'MULTI_HOP'] -listings_latest ('guest', 'listing', 'user') revenue_all_time ['JOINED', 'METRIC', 'MULTI_HOP'] -listings_latest ('guest', 'listing', 'user') revenue_mtd ['JOINED', 'METRIC', 'MULTI_HOP'] -listings_latest ('guest', 'listing', 'user') smallest_listing ['JOINED', 'METRIC', 'MULTI_HOP'] -listings_latest ('guest', 'listing', 'user') total_account_balance_first_day ['JOINED', 'METRIC', 'MULTI_HOP'] -listings_latest ('guest', 'listing', 'user') trailing_2_months_revenue ['JOINED', 'METRIC', 'MULTI_HOP'] -listings_latest ('guest', 'listing', 'user') trailing_2_months_revenue_sub_10 ['JOINED', 'METRIC', 'MULTI_HOP'] -listings_latest ('guest', 'listing', 'user') twice_bookings_fill_nulls_with_0_without_time_spine ['JOINED', 'METRIC', 'MULTI_HOP'] -listings_latest ('guest', 'listing', 'user') views ['JOINED', 'METRIC', 'MULTI_HOP'] -listings_latest ('guest', 'listing', 'user') views_times_booking_value ['JOINED', 'METRIC', 'MULTI_HOP'] -listings_latest ('guest', 'listing', 'user') visit_buy_conversion_rate ['JOINED', 'METRIC', 'MULTI_HOP'] -listings_latest ('guest', 'listing', 'user') visit_buy_conversion_rate_7days ['JOINED', 'METRIC', 'MULTI_HOP'] -listings_latest ('guest', 'listing', 'user') visit_buy_conversion_rate_7days_fill_nulls_with_0 ['JOINED', 'METRIC', 'MULTI_HOP'] -listings_latest ('guest', 'listing', 'user') visit_buy_conversion_rate_by_session ['JOINED', 'METRIC', 'MULTI_HOP'] -listings_latest ('guest', 'listing', 'user') visit_buy_conversions ['JOINED', 'METRIC', 'MULTI_HOP'] +Semantic Model Entity Links Name Time Granularity Date Part Properties +---------------- ---------------------------- --------------------------------------------------- ------------------ ----------- --------------------------------------------------- +listings_latest ('guest', 'listing') capacity_latest ['JOINED', 'MULTI_HOP'] +listings_latest ('guest', 'listing') country_latest ['JOINED', 'MULTI_HOP'] +listings_latest ('guest', 'listing') created_at DAY ['JOINED', 'MULTI_HOP'] +listings_latest ('guest', 'listing') created_at DAY DAY ['JOINED', 'MULTI_HOP'] +listings_latest ('guest', 'listing') created_at DAY DOW ['JOINED', 'MULTI_HOP'] +listings_latest ('guest', 'listing') created_at DAY DOY ['JOINED', 'MULTI_HOP'] +listings_latest ('guest', 'listing') created_at DAY MONTH ['JOINED', 'MULTI_HOP'] +listings_latest ('guest', 'listing') created_at DAY QUARTER ['JOINED', 'MULTI_HOP'] +listings_latest ('guest', 'listing') created_at DAY YEAR ['JOINED', 'MULTI_HOP'] +listings_latest ('guest', 'listing') created_at MONTH ['DERIVED_TIME_GRANULARITY', 'JOINED', 'MULTI_HOP'] +listings_latest ('guest', 'listing') created_at MONTH MONTH ['DERIVED_TIME_GRANULARITY', 'JOINED', 'MULTI_HOP'] +listings_latest ('guest', 'listing') created_at MONTH QUARTER ['DERIVED_TIME_GRANULARITY', 'JOINED', 'MULTI_HOP'] +listings_latest ('guest', 'listing') created_at MONTH YEAR ['DERIVED_TIME_GRANULARITY', 'JOINED', 'MULTI_HOP'] +listings_latest ('guest', 'listing') created_at QUARTER ['DERIVED_TIME_GRANULARITY', 'JOINED', 'MULTI_HOP'] +listings_latest ('guest', 'listing') created_at QUARTER QUARTER ['DERIVED_TIME_GRANULARITY', 'JOINED', 'MULTI_HOP'] +listings_latest ('guest', 'listing') created_at QUARTER YEAR ['DERIVED_TIME_GRANULARITY', 'JOINED', 'MULTI_HOP'] +listings_latest ('guest', 'listing') created_at WEEK ['DERIVED_TIME_GRANULARITY', 'JOINED', 'MULTI_HOP'] +listings_latest ('guest', 'listing') created_at WEEK MONTH ['DERIVED_TIME_GRANULARITY', 'JOINED', 'MULTI_HOP'] +listings_latest ('guest', 'listing') created_at WEEK QUARTER ['DERIVED_TIME_GRANULARITY', 'JOINED', 'MULTI_HOP'] +listings_latest ('guest', 'listing') created_at WEEK YEAR ['DERIVED_TIME_GRANULARITY', 'JOINED', 'MULTI_HOP'] +listings_latest ('guest', 'listing') created_at YEAR ['DERIVED_TIME_GRANULARITY', 'JOINED', 'MULTI_HOP'] +listings_latest ('guest', 'listing') created_at YEAR YEAR ['DERIVED_TIME_GRANULARITY', 'JOINED', 'MULTI_HOP'] +listings_latest ('guest', 'listing') ds DAY ['JOINED', 'MULTI_HOP'] +listings_latest ('guest', 'listing') ds DAY DAY ['JOINED', 'MULTI_HOP'] +listings_latest ('guest', 'listing') ds DAY DOW ['JOINED', 'MULTI_HOP'] +listings_latest ('guest', 'listing') ds DAY DOY ['JOINED', 'MULTI_HOP'] +listings_latest ('guest', 'listing') ds DAY MONTH ['JOINED', 'MULTI_HOP'] +listings_latest ('guest', 'listing') ds DAY QUARTER ['JOINED', 'MULTI_HOP'] +listings_latest ('guest', 'listing') ds DAY YEAR ['JOINED', 'MULTI_HOP'] +listings_latest ('guest', 'listing') ds MONTH ['DERIVED_TIME_GRANULARITY', 'JOINED', 'MULTI_HOP'] +listings_latest ('guest', 'listing') ds MONTH MONTH ['DERIVED_TIME_GRANULARITY', 'JOINED', 'MULTI_HOP'] +listings_latest ('guest', 'listing') ds MONTH QUARTER ['DERIVED_TIME_GRANULARITY', 'JOINED', 'MULTI_HOP'] +listings_latest ('guest', 'listing') ds MONTH YEAR ['DERIVED_TIME_GRANULARITY', 'JOINED', 'MULTI_HOP'] +listings_latest ('guest', 'listing') ds QUARTER ['DERIVED_TIME_GRANULARITY', 'JOINED', 'MULTI_HOP'] +listings_latest ('guest', 'listing') ds QUARTER QUARTER ['DERIVED_TIME_GRANULARITY', 'JOINED', 'MULTI_HOP'] +listings_latest ('guest', 'listing') ds QUARTER YEAR ['DERIVED_TIME_GRANULARITY', 'JOINED', 'MULTI_HOP'] +listings_latest ('guest', 'listing') ds WEEK ['DERIVED_TIME_GRANULARITY', 'JOINED', 'MULTI_HOP'] +listings_latest ('guest', 'listing') ds WEEK MONTH ['DERIVED_TIME_GRANULARITY', 'JOINED', 'MULTI_HOP'] +listings_latest ('guest', 'listing') ds WEEK QUARTER ['DERIVED_TIME_GRANULARITY', 'JOINED', 'MULTI_HOP'] +listings_latest ('guest', 'listing') ds WEEK YEAR ['DERIVED_TIME_GRANULARITY', 'JOINED', 'MULTI_HOP'] +listings_latest ('guest', 'listing') ds YEAR ['DERIVED_TIME_GRANULARITY', 'JOINED', 'MULTI_HOP'] +listings_latest ('guest', 'listing') ds YEAR YEAR ['DERIVED_TIME_GRANULARITY', 'JOINED', 'MULTI_HOP'] +listings_latest ('guest', 'listing') is_lux_latest ['JOINED', 'MULTI_HOP'] +listings_latest ('guest', 'listing') user ['ENTITY', 'JOINED', 'MULTI_HOP'] +listings_latest ('guest', 'listing', 'user') active_listings ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('guest', 'listing', 'user') approximate_continuous_booking_value_p99 ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('guest', 'listing', 'user') approximate_discrete_booking_value_p99 ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('guest', 'listing', 'user') average_booking_value ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('guest', 'listing', 'user') average_instant_booking_value ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('guest', 'listing', 'user') bookers ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('guest', 'listing', 'user') booking_fees ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('guest', 'listing', 'user') booking_fees_per_booker ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('guest', 'listing', 'user') booking_payments ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('guest', 'listing', 'user') booking_value ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('guest', 'listing', 'user') booking_value_for_non_null_listing_id ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('guest', 'listing', 'user') booking_value_p99 ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('guest', 'listing', 'user') booking_value_per_view ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('guest', 'listing', 'user') booking_value_sub_instant ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('guest', 'listing', 'user') booking_value_sub_instant_add_10 ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('guest', 'listing', 'user') bookings ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('guest', 'listing', 'user') bookings_fill_nulls_with_0 ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('guest', 'listing', 'user') bookings_fill_nulls_with_0_without_time_spine ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('guest', 'listing', 'user') bookings_join_to_time_spine ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('guest', 'listing', 'user') bookings_per_booker ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('guest', 'listing', 'user') bookings_per_dollar ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('guest', 'listing', 'user') bookings_per_listing ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('guest', 'listing', 'user') bookings_per_lux_listing_derived ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('guest', 'listing', 'user') bookings_per_view ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('guest', 'listing', 'user') current_account_balance_by_user ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('guest', 'listing', 'user') derived_bookings_0 ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('guest', 'listing', 'user') derived_bookings_1 ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('guest', 'listing', 'user') discrete_booking_value_p99 ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('guest', 'listing', 'user') double_counted_delayed_bookings ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('guest', 'listing', 'user') identity_verifications ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('guest', 'listing', 'user') instant_booking_fraction_of_max_value ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('guest', 'listing', 'user') instant_booking_value ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('guest', 'listing', 'user') instant_booking_value_ratio ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('guest', 'listing', 'user') instant_bookings ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('guest', 'listing', 'user') instant_lux_booking_value_rate ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('guest', 'listing', 'user') instant_plus_non_referred_bookings_pct ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('guest', 'listing', 'user') largest_listing ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('guest', 'listing', 'user') listings ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('guest', 'listing', 'user') lux_booking_fraction_of_max_value ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('guest', 'listing', 'user') lux_booking_value_rate_expr ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('guest', 'listing', 'user') lux_listings ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('guest', 'listing', 'user') max_booking_value ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('guest', 'listing', 'user') median_booking_value ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('guest', 'listing', 'user') min_booking_value ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('guest', 'listing', 'user') nested_fill_nulls_without_time_spine ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('guest', 'listing', 'user') non_referred_bookings_pct ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('guest', 'listing', 'user') referred_bookings ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('guest', 'listing', 'user') regional_starting_balance_ratios ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('guest', 'listing', 'user') revenue ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('guest', 'listing', 'user') revenue_all_time ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('guest', 'listing', 'user') smallest_listing ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('guest', 'listing', 'user') total_account_balance_first_day ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('guest', 'listing', 'user') twice_bookings_fill_nulls_with_0_without_time_spine ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('guest', 'listing', 'user') views ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('guest', 'listing', 'user') views_times_booking_value ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('guest', 'listing', 'user') visit_buy_conversion_rate ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('guest', 'listing', 'user') visit_buy_conversion_rate_7days ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('guest', 'listing', 'user') visit_buy_conversion_rate_7days_fill_nulls_with_0 ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('guest', 'listing', 'user') visit_buy_conversion_rate_by_session ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('guest', 'listing', 'user') visit_buy_conversions ['JOINED', 'METRIC', 'MULTI_HOP'] diff --git a/tests/snapshots/test_semantic_model_container.py/str/test_linkable_elements_for_measure__result0.txt b/tests/snapshots/test_semantic_model_container.py/str/test_linkable_elements_for_measure__result0.txt index 9c91598cd6..f3ac302c66 100644 --- a/tests/snapshots/test_semantic_model_container.py/str/test_linkable_elements_for_measure__result0.txt +++ b/tests/snapshots/test_semantic_model_container.py/str/test_linkable_elements_for_measure__result0.txt @@ -1,431 +1,369 @@ -Semantic Model Entity Links Name Time Granularity Date Part Properties -------------------- -------------------------- -------------------------------------------------------- ------------------ ----------- ------------------------------------------- - ('listing',) active_listings ['JOINED', 'METRIC'] - ('listing',) approximate_continuous_booking_value_p99 ['JOINED', 'METRIC'] - ('listing',) approximate_discrete_booking_value_p99 ['JOINED', 'METRIC'] - ('listing',) average_booking_value ['JOINED', 'METRIC'] - ('listing',) average_instant_booking_value ['JOINED', 'METRIC'] - ('listing',) bookers ['JOINED', 'METRIC'] - ('listing',) booking_fees ['JOINED', 'METRIC'] - ('listing',) booking_fees_last_week_per_booker_this_week ['JOINED', 'METRIC'] - ('listing',) booking_fees_per_booker ['JOINED', 'METRIC'] - ('listing',) booking_fees_since_start_of_month ['JOINED', 'METRIC'] - ('listing',) booking_payments ['JOINED', 'METRIC'] - ('listing',) booking_value ['JOINED', 'METRIC'] - ('listing',) booking_value_for_non_null_listing_id ['JOINED', 'METRIC'] - ('listing',) booking_value_p99 ['JOINED', 'METRIC'] - ('listing',) booking_value_per_view ['JOINED', 'METRIC'] - ('listing',) booking_value_sub_instant ['JOINED', 'METRIC'] - ('listing',) booking_value_sub_instant_add_10 ['JOINED', 'METRIC'] - ('listing',) bookings ['JOINED', 'METRIC'] - ('listing',) bookings_5_day_lag ['JOINED', 'METRIC'] - ('listing',) bookings_at_start_of_month ['JOINED', 'METRIC'] - ('listing',) bookings_fill_nulls_with_0 ['JOINED', 'METRIC'] - ('listing',) bookings_fill_nulls_with_0_without_time_spine ['JOINED', 'METRIC'] - ('listing',) bookings_growth_2_weeks ['JOINED', 'METRIC'] - ('listing',) bookings_growth_2_weeks_fill_nulls_with_0 ['JOINED', 'METRIC'] - ('listing',) bookings_growth_2_weeks_fill_nulls_with_0_for_non_offset ['JOINED', 'METRIC'] - ('listing',) bookings_growth_since_start_of_month ['JOINED', 'METRIC'] - ('listing',) bookings_join_to_time_spine ['JOINED', 'METRIC'] - ('listing',) bookings_month_start_compared_to_1_month_prior ['JOINED', 'METRIC'] - ('listing',) bookings_offset_once ['JOINED', 'METRIC'] - ('listing',) bookings_offset_twice ['JOINED', 'METRIC'] - ('listing',) bookings_per_booker ['JOINED', 'METRIC'] - ('listing',) bookings_per_dollar ['JOINED', 'METRIC'] - ('listing',) bookings_per_listing ['JOINED', 'METRIC'] - ('listing',) bookings_per_lux_listing_derived ['JOINED', 'METRIC'] - ('listing',) bookings_per_view ['JOINED', 'METRIC'] - ('listing',) derived_bookings_0 ['JOINED', 'METRIC'] - ('listing',) derived_bookings_1 ['JOINED', 'METRIC'] - ('listing',) discrete_booking_value_p99 ['JOINED', 'METRIC'] - ('listing',) double_counted_delayed_bookings ['JOINED', 'METRIC'] - ('listing',) every_2_days_bookers_2_days_ago ['JOINED', 'METRIC'] - ('listing',) every_two_days_bookers ['JOINED', 'METRIC'] - ('listing',) every_two_days_bookers_fill_nulls_with_0 ['JOINED', 'METRIC'] - ('listing',) instant_booking_fraction_of_max_value ['JOINED', 'METRIC'] - ('listing',) instant_booking_value ['JOINED', 'METRIC'] - ('listing',) instant_booking_value_ratio ['JOINED', 'METRIC'] - ('listing',) instant_bookings ['JOINED', 'METRIC'] - ('listing',) instant_lux_booking_value_rate ['JOINED', 'METRIC'] - ('listing',) instant_plus_non_referred_bookings_pct ['JOINED', 'METRIC'] - ('listing',) largest_listing ['JOINED', 'METRIC'] - ('listing',) listings ['JOINED', 'METRIC'] - ('listing',) lux_booking_fraction_of_max_value ['JOINED', 'METRIC'] - ('listing',) lux_booking_value_rate_expr ['JOINED', 'METRIC'] - ('listing',) lux_listings ['JOINED', 'METRIC'] - ('listing',) max_booking_value ['JOINED', 'METRIC'] - ('listing',) median_booking_value ['JOINED', 'METRIC'] - ('listing',) min_booking_value ['JOINED', 'METRIC'] - ('listing',) nested_fill_nulls_without_time_spine ['JOINED', 'METRIC'] - ('listing',) non_referred_bookings_pct ['JOINED', 'METRIC'] - ('listing',) referred_bookings ['JOINED', 'METRIC'] - ('listing',) smallest_listing ['JOINED', 'METRIC'] - ('listing',) twice_bookings_fill_nulls_with_0_without_time_spine ['JOINED', 'METRIC'] - ('listing',) views ['JOINED', 'METRIC'] - ('listing',) views_times_booking_value ['JOINED', 'METRIC'] - ('user',) active_listings ['JOINED', 'METRIC'] - ('user',) approximate_continuous_booking_value_p99 ['JOINED', 'METRIC'] - ('user',) approximate_discrete_booking_value_p99 ['JOINED', 'METRIC'] - ('user',) average_booking_value ['JOINED', 'METRIC'] - ('user',) average_instant_booking_value ['JOINED', 'METRIC'] - ('user',) bookers ['JOINED', 'METRIC'] - ('user',) booking_fees ['JOINED', 'METRIC'] - ('user',) booking_fees_last_week_per_booker_this_week ['JOINED', 'METRIC'] - ('user',) booking_fees_per_booker ['JOINED', 'METRIC'] - ('user',) booking_fees_since_start_of_month ['JOINED', 'METRIC'] - ('user',) booking_payments ['JOINED', 'METRIC'] - ('user',) booking_value ['JOINED', 'METRIC'] - ('user',) booking_value_for_non_null_listing_id ['JOINED', 'METRIC'] - ('user',) booking_value_p99 ['JOINED', 'METRIC'] - ('user',) booking_value_per_view ['JOINED', 'METRIC'] - ('user',) booking_value_sub_instant ['JOINED', 'METRIC'] - ('user',) booking_value_sub_instant_add_10 ['JOINED', 'METRIC'] - ('user',) bookings ['JOINED', 'METRIC'] - ('user',) bookings_5_day_lag ['JOINED', 'METRIC'] - ('user',) bookings_at_start_of_month ['JOINED', 'METRIC'] - ('user',) bookings_fill_nulls_with_0 ['JOINED', 'METRIC'] - ('user',) bookings_fill_nulls_with_0_without_time_spine ['JOINED', 'METRIC'] - ('user',) bookings_growth_2_weeks ['JOINED', 'METRIC'] - ('user',) bookings_growth_2_weeks_fill_nulls_with_0 ['JOINED', 'METRIC'] - ('user',) bookings_growth_2_weeks_fill_nulls_with_0_for_non_offset ['JOINED', 'METRIC'] - ('user',) bookings_growth_since_start_of_month ['JOINED', 'METRIC'] - ('user',) bookings_join_to_time_spine ['JOINED', 'METRIC'] - ('user',) bookings_month_start_compared_to_1_month_prior ['JOINED', 'METRIC'] - ('user',) bookings_offset_once ['JOINED', 'METRIC'] - ('user',) bookings_offset_twice ['JOINED', 'METRIC'] - ('user',) bookings_per_booker ['JOINED', 'METRIC'] - ('user',) bookings_per_dollar ['JOINED', 'METRIC'] - ('user',) bookings_per_listing ['JOINED', 'METRIC'] - ('user',) bookings_per_lux_listing_derived ['JOINED', 'METRIC'] - ('user',) bookings_per_view ['JOINED', 'METRIC'] - ('user',) current_account_balance_by_user ['JOINED', 'METRIC'] - ('user',) derived_bookings_0 ['JOINED', 'METRIC'] - ('user',) derived_bookings_1 ['JOINED', 'METRIC'] - ('user',) discrete_booking_value_p99 ['JOINED', 'METRIC'] - ('user',) double_counted_delayed_bookings ['JOINED', 'METRIC'] - ('user',) every_2_days_bookers_2_days_ago ['JOINED', 'METRIC'] - ('user',) every_two_days_bookers ['JOINED', 'METRIC'] - ('user',) every_two_days_bookers_fill_nulls_with_0 ['JOINED', 'METRIC'] - ('user',) identity_verifications ['JOINED', 'METRIC'] - ('user',) instant_booking_fraction_of_max_value ['JOINED', 'METRIC'] - ('user',) instant_booking_value ['JOINED', 'METRIC'] - ('user',) instant_booking_value_ratio ['JOINED', 'METRIC'] - ('user',) instant_bookings ['JOINED', 'METRIC'] - ('user',) instant_lux_booking_value_rate ['JOINED', 'METRIC'] - ('user',) instant_plus_non_referred_bookings_pct ['JOINED', 'METRIC'] - ('user',) largest_listing ['JOINED', 'METRIC'] - ('user',) listings ['JOINED', 'METRIC'] - ('user',) lux_booking_fraction_of_max_value ['JOINED', 'METRIC'] - ('user',) lux_booking_value_rate_expr ['JOINED', 'METRIC'] - ('user',) lux_listings ['JOINED', 'METRIC'] - ('user',) max_booking_value ['JOINED', 'METRIC'] - ('user',) median_booking_value ['JOINED', 'METRIC'] - ('user',) min_booking_value ['JOINED', 'METRIC'] - ('user',) nested_fill_nulls_without_time_spine ['JOINED', 'METRIC'] - ('user',) non_referred_bookings_pct ['JOINED', 'METRIC'] - ('user',) referred_bookings ['JOINED', 'METRIC'] - ('user',) regional_starting_balance_ratios ['JOINED', 'METRIC'] - ('user',) revenue ['JOINED', 'METRIC'] - ('user',) revenue_all_time ['JOINED', 'METRIC'] - ('user',) revenue_mtd ['JOINED', 'METRIC'] - ('user',) smallest_listing ['JOINED', 'METRIC'] - ('user',) total_account_balance_first_day ['JOINED', 'METRIC'] - ('user',) trailing_2_months_revenue ['JOINED', 'METRIC'] - ('user',) trailing_2_months_revenue_sub_10 ['JOINED', 'METRIC'] - ('user',) twice_bookings_fill_nulls_with_0_without_time_spine ['JOINED', 'METRIC'] - ('user',) views ['JOINED', 'METRIC'] - ('user',) views_times_booking_value ['JOINED', 'METRIC'] - ('user',) visit_buy_conversion_rate ['JOINED', 'METRIC'] - ('user',) visit_buy_conversion_rate_7days ['JOINED', 'METRIC'] - ('user',) visit_buy_conversion_rate_7days_fill_nulls_with_0 ['JOINED', 'METRIC'] - ('user',) visit_buy_conversion_rate_by_session ['JOINED', 'METRIC'] - ('user',) visit_buy_conversions ['JOINED', 'METRIC'] -companies ('user',) company ['ENTITY', 'JOINED'] -companies ('user',) company_name ['JOINED'] -companies ('user', 'company') active_listings ['JOINED', 'METRIC', 'MULTI_HOP'] -companies ('user', 'company') approximate_continuous_booking_value_p99 ['JOINED', 'METRIC', 'MULTI_HOP'] -companies ('user', 'company') approximate_discrete_booking_value_p99 ['JOINED', 'METRIC', 'MULTI_HOP'] -companies ('user', 'company') average_booking_value ['JOINED', 'METRIC', 'MULTI_HOP'] -companies ('user', 'company') average_instant_booking_value ['JOINED', 'METRIC', 'MULTI_HOP'] -companies ('user', 'company') bookers ['JOINED', 'METRIC', 'MULTI_HOP'] -companies ('user', 'company') booking_fees ['JOINED', 'METRIC', 'MULTI_HOP'] -companies ('user', 'company') booking_fees_last_week_per_booker_this_week ['JOINED', 'METRIC', 'MULTI_HOP'] -companies ('user', 'company') booking_fees_per_booker ['JOINED', 'METRIC', 'MULTI_HOP'] -companies ('user', 'company') booking_fees_since_start_of_month ['JOINED', 'METRIC', 'MULTI_HOP'] -companies ('user', 'company') booking_payments ['JOINED', 'METRIC', 'MULTI_HOP'] -companies ('user', 'company') booking_value ['JOINED', 'METRIC', 'MULTI_HOP'] -companies ('user', 'company') booking_value_for_non_null_listing_id ['JOINED', 'METRIC', 'MULTI_HOP'] -companies ('user', 'company') booking_value_p99 ['JOINED', 'METRIC', 'MULTI_HOP'] -companies ('user', 'company') booking_value_per_view ['JOINED', 'METRIC', 'MULTI_HOP'] -companies ('user', 'company') booking_value_sub_instant ['JOINED', 'METRIC', 'MULTI_HOP'] -companies ('user', 'company') booking_value_sub_instant_add_10 ['JOINED', 'METRIC', 'MULTI_HOP'] -companies ('user', 'company') bookings ['JOINED', 'METRIC', 'MULTI_HOP'] -companies ('user', 'company') bookings_5_day_lag ['JOINED', 'METRIC', 'MULTI_HOP'] -companies ('user', 'company') bookings_at_start_of_month ['JOINED', 'METRIC', 'MULTI_HOP'] -companies ('user', 'company') bookings_fill_nulls_with_0 ['JOINED', 'METRIC', 'MULTI_HOP'] -companies ('user', 'company') bookings_fill_nulls_with_0_without_time_spine ['JOINED', 'METRIC', 'MULTI_HOP'] -companies ('user', 'company') bookings_growth_2_weeks ['JOINED', 'METRIC', 'MULTI_HOP'] -companies ('user', 'company') bookings_growth_2_weeks_fill_nulls_with_0 ['JOINED', 'METRIC', 'MULTI_HOP'] -companies ('user', 'company') bookings_growth_2_weeks_fill_nulls_with_0_for_non_offset ['JOINED', 'METRIC', 'MULTI_HOP'] -companies ('user', 'company') bookings_growth_since_start_of_month ['JOINED', 'METRIC', 'MULTI_HOP'] -companies ('user', 'company') bookings_join_to_time_spine ['JOINED', 'METRIC', 'MULTI_HOP'] -companies ('user', 'company') bookings_month_start_compared_to_1_month_prior ['JOINED', 'METRIC', 'MULTI_HOP'] -companies ('user', 'company') bookings_offset_once ['JOINED', 'METRIC', 'MULTI_HOP'] -companies ('user', 'company') bookings_offset_twice ['JOINED', 'METRIC', 'MULTI_HOP'] -companies ('user', 'company') bookings_per_booker ['JOINED', 'METRIC', 'MULTI_HOP'] -companies ('user', 'company') bookings_per_dollar ['JOINED', 'METRIC', 'MULTI_HOP'] -companies ('user', 'company') bookings_per_view ['JOINED', 'METRIC', 'MULTI_HOP'] -companies ('user', 'company') current_account_balance_by_user ['JOINED', 'METRIC', 'MULTI_HOP'] -companies ('user', 'company') derived_bookings_0 ['JOINED', 'METRIC', 'MULTI_HOP'] -companies ('user', 'company') derived_bookings_1 ['JOINED', 'METRIC', 'MULTI_HOP'] -companies ('user', 'company') discrete_booking_value_p99 ['JOINED', 'METRIC', 'MULTI_HOP'] -companies ('user', 'company') double_counted_delayed_bookings ['JOINED', 'METRIC', 'MULTI_HOP'] -companies ('user', 'company') every_2_days_bookers_2_days_ago ['JOINED', 'METRIC', 'MULTI_HOP'] -companies ('user', 'company') every_two_days_bookers ['JOINED', 'METRIC', 'MULTI_HOP'] -companies ('user', 'company') every_two_days_bookers_fill_nulls_with_0 ['JOINED', 'METRIC', 'MULTI_HOP'] -companies ('user', 'company') identity_verifications ['JOINED', 'METRIC', 'MULTI_HOP'] -companies ('user', 'company') instant_booking_fraction_of_max_value ['JOINED', 'METRIC', 'MULTI_HOP'] -companies ('user', 'company') instant_booking_value ['JOINED', 'METRIC', 'MULTI_HOP'] -companies ('user', 'company') instant_booking_value_ratio ['JOINED', 'METRIC', 'MULTI_HOP'] -companies ('user', 'company') instant_bookings ['JOINED', 'METRIC', 'MULTI_HOP'] -companies ('user', 'company') instant_lux_booking_value_rate ['JOINED', 'METRIC', 'MULTI_HOP'] -companies ('user', 'company') instant_plus_non_referred_bookings_pct ['JOINED', 'METRIC', 'MULTI_HOP'] -companies ('user', 'company') largest_listing ['JOINED', 'METRIC', 'MULTI_HOP'] -companies ('user', 'company') listings ['JOINED', 'METRIC', 'MULTI_HOP'] -companies ('user', 'company') lux_booking_fraction_of_max_value ['JOINED', 'METRIC', 'MULTI_HOP'] -companies ('user', 'company') lux_booking_value_rate_expr ['JOINED', 'METRIC', 'MULTI_HOP'] -companies ('user', 'company') lux_listings ['JOINED', 'METRIC', 'MULTI_HOP'] -companies ('user', 'company') max_booking_value ['JOINED', 'METRIC', 'MULTI_HOP'] -companies ('user', 'company') median_booking_value ['JOINED', 'METRIC', 'MULTI_HOP'] -companies ('user', 'company') min_booking_value ['JOINED', 'METRIC', 'MULTI_HOP'] -companies ('user', 'company') nested_fill_nulls_without_time_spine ['JOINED', 'METRIC', 'MULTI_HOP'] -companies ('user', 'company') non_referred_bookings_pct ['JOINED', 'METRIC', 'MULTI_HOP'] -companies ('user', 'company') referred_bookings ['JOINED', 'METRIC', 'MULTI_HOP'] -companies ('user', 'company') regional_starting_balance_ratios ['JOINED', 'METRIC', 'MULTI_HOP'] -companies ('user', 'company') revenue ['JOINED', 'METRIC', 'MULTI_HOP'] -companies ('user', 'company') revenue_all_time ['JOINED', 'METRIC', 'MULTI_HOP'] -companies ('user', 'company') revenue_mtd ['JOINED', 'METRIC', 'MULTI_HOP'] -companies ('user', 'company') smallest_listing ['JOINED', 'METRIC', 'MULTI_HOP'] -companies ('user', 'company') total_account_balance_first_day ['JOINED', 'METRIC', 'MULTI_HOP'] -companies ('user', 'company') trailing_2_months_revenue ['JOINED', 'METRIC', 'MULTI_HOP'] -companies ('user', 'company') trailing_2_months_revenue_sub_10 ['JOINED', 'METRIC', 'MULTI_HOP'] -companies ('user', 'company') twice_bookings_fill_nulls_with_0_without_time_spine ['JOINED', 'METRIC', 'MULTI_HOP'] -companies ('user', 'company') views ['JOINED', 'METRIC', 'MULTI_HOP'] -companies ('user', 'company') views_times_booking_value ['JOINED', 'METRIC', 'MULTI_HOP'] -companies ('user', 'company') visit_buy_conversion_rate ['JOINED', 'METRIC', 'MULTI_HOP'] -companies ('user', 'company') visit_buy_conversion_rate_7days ['JOINED', 'METRIC', 'MULTI_HOP'] -companies ('user', 'company') visit_buy_conversion_rate_7days_fill_nulls_with_0 ['JOINED', 'METRIC', 'MULTI_HOP'] -companies ('user', 'company') visit_buy_conversion_rate_by_session ['JOINED', 'METRIC', 'MULTI_HOP'] -companies ('user', 'company') visit_buy_conversions ['JOINED', 'METRIC', 'MULTI_HOP'] -listings_latest () listing ['ENTITY', 'LOCAL'] -listings_latest () metric_time DAY ['METRIC_TIME'] -listings_latest () metric_time DAY DAY ['DERIVED_TIME_GRANULARITY', 'METRIC_TIME'] -listings_latest () metric_time DAY DOW ['DERIVED_TIME_GRANULARITY', 'METRIC_TIME'] -listings_latest () metric_time DAY DOY ['DERIVED_TIME_GRANULARITY', 'METRIC_TIME'] -listings_latest () metric_time DAY MONTH ['DERIVED_TIME_GRANULARITY', 'METRIC_TIME'] -listings_latest () metric_time DAY QUARTER ['DERIVED_TIME_GRANULARITY', 'METRIC_TIME'] -listings_latest () metric_time DAY YEAR ['DERIVED_TIME_GRANULARITY', 'METRIC_TIME'] -listings_latest () metric_time MONTH ['DERIVED_TIME_GRANULARITY', 'METRIC_TIME'] -listings_latest () metric_time MONTH MONTH ['DERIVED_TIME_GRANULARITY', 'METRIC_TIME'] -listings_latest () metric_time MONTH QUARTER ['DERIVED_TIME_GRANULARITY', 'METRIC_TIME'] -listings_latest () metric_time MONTH YEAR ['DERIVED_TIME_GRANULARITY', 'METRIC_TIME'] -listings_latest () metric_time QUARTER ['DERIVED_TIME_GRANULARITY', 'METRIC_TIME'] -listings_latest () metric_time QUARTER QUARTER ['DERIVED_TIME_GRANULARITY', 'METRIC_TIME'] -listings_latest () metric_time QUARTER YEAR ['DERIVED_TIME_GRANULARITY', 'METRIC_TIME'] -listings_latest () metric_time WEEK ['DERIVED_TIME_GRANULARITY', 'METRIC_TIME'] -listings_latest () metric_time WEEK MONTH ['DERIVED_TIME_GRANULARITY', 'METRIC_TIME'] -listings_latest () metric_time WEEK QUARTER ['DERIVED_TIME_GRANULARITY', 'METRIC_TIME'] -listings_latest () metric_time WEEK YEAR ['DERIVED_TIME_GRANULARITY', 'METRIC_TIME'] -listings_latest () metric_time YEAR ['DERIVED_TIME_GRANULARITY', 'METRIC_TIME'] -listings_latest () metric_time YEAR YEAR ['DERIVED_TIME_GRANULARITY', 'METRIC_TIME'] -listings_latest () user ['ENTITY', 'LOCAL'] -listings_latest ('listing',) capacity_latest ['LOCAL'] -listings_latest ('listing',) country_latest ['LOCAL'] -listings_latest ('listing',) created_at DAY ['LOCAL'] -listings_latest ('listing',) created_at DAY DAY ['LOCAL'] -listings_latest ('listing',) created_at DAY DOW ['LOCAL'] -listings_latest ('listing',) created_at DAY DOY ['LOCAL'] -listings_latest ('listing',) created_at DAY MONTH ['LOCAL'] -listings_latest ('listing',) created_at DAY QUARTER ['LOCAL'] -listings_latest ('listing',) created_at DAY YEAR ['LOCAL'] -listings_latest ('listing',) created_at MONTH ['DERIVED_TIME_GRANULARITY', 'LOCAL'] -listings_latest ('listing',) created_at MONTH MONTH ['DERIVED_TIME_GRANULARITY', 'LOCAL'] -listings_latest ('listing',) created_at MONTH QUARTER ['DERIVED_TIME_GRANULARITY', 'LOCAL'] -listings_latest ('listing',) created_at MONTH YEAR ['DERIVED_TIME_GRANULARITY', 'LOCAL'] -listings_latest ('listing',) created_at QUARTER ['DERIVED_TIME_GRANULARITY', 'LOCAL'] -listings_latest ('listing',) created_at QUARTER QUARTER ['DERIVED_TIME_GRANULARITY', 'LOCAL'] -listings_latest ('listing',) created_at QUARTER YEAR ['DERIVED_TIME_GRANULARITY', 'LOCAL'] -listings_latest ('listing',) created_at WEEK ['DERIVED_TIME_GRANULARITY', 'LOCAL'] -listings_latest ('listing',) created_at WEEK MONTH ['DERIVED_TIME_GRANULARITY', 'LOCAL'] -listings_latest ('listing',) created_at WEEK QUARTER ['DERIVED_TIME_GRANULARITY', 'LOCAL'] -listings_latest ('listing',) created_at WEEK YEAR ['DERIVED_TIME_GRANULARITY', 'LOCAL'] -listings_latest ('listing',) created_at YEAR ['DERIVED_TIME_GRANULARITY', 'LOCAL'] -listings_latest ('listing',) created_at YEAR YEAR ['DERIVED_TIME_GRANULARITY', 'LOCAL'] -listings_latest ('listing',) ds DAY ['LOCAL'] -listings_latest ('listing',) ds DAY DAY ['LOCAL'] -listings_latest ('listing',) ds DAY DOW ['LOCAL'] -listings_latest ('listing',) ds DAY DOY ['LOCAL'] -listings_latest ('listing',) ds DAY MONTH ['LOCAL'] -listings_latest ('listing',) ds DAY QUARTER ['LOCAL'] -listings_latest ('listing',) ds DAY YEAR ['LOCAL'] -listings_latest ('listing',) ds MONTH ['DERIVED_TIME_GRANULARITY', 'LOCAL'] -listings_latest ('listing',) ds MONTH MONTH ['DERIVED_TIME_GRANULARITY', 'LOCAL'] -listings_latest ('listing',) ds MONTH QUARTER ['DERIVED_TIME_GRANULARITY', 'LOCAL'] -listings_latest ('listing',) ds MONTH YEAR ['DERIVED_TIME_GRANULARITY', 'LOCAL'] -listings_latest ('listing',) ds QUARTER ['DERIVED_TIME_GRANULARITY', 'LOCAL'] -listings_latest ('listing',) ds QUARTER QUARTER ['DERIVED_TIME_GRANULARITY', 'LOCAL'] -listings_latest ('listing',) ds QUARTER YEAR ['DERIVED_TIME_GRANULARITY', 'LOCAL'] -listings_latest ('listing',) ds WEEK ['DERIVED_TIME_GRANULARITY', 'LOCAL'] -listings_latest ('listing',) ds WEEK MONTH ['DERIVED_TIME_GRANULARITY', 'LOCAL'] -listings_latest ('listing',) ds WEEK QUARTER ['DERIVED_TIME_GRANULARITY', 'LOCAL'] -listings_latest ('listing',) ds WEEK YEAR ['DERIVED_TIME_GRANULARITY', 'LOCAL'] -listings_latest ('listing',) ds YEAR ['DERIVED_TIME_GRANULARITY', 'LOCAL'] -listings_latest ('listing',) ds YEAR YEAR ['DERIVED_TIME_GRANULARITY', 'LOCAL'] -listings_latest ('listing',) is_lux_latest ['LOCAL'] -listings_latest ('listing',) user ['ENTITY', 'LOCAL'] -lux_listing_mapping ('listing',) lux_listing ['ENTITY', 'JOINED'] -lux_listing_mapping ('listing', 'lux_listing') active_listings ['JOINED', 'METRIC', 'MULTI_HOP'] -lux_listing_mapping ('listing', 'lux_listing') approximate_continuous_booking_value_p99 ['JOINED', 'METRIC', 'MULTI_HOP'] -lux_listing_mapping ('listing', 'lux_listing') approximate_discrete_booking_value_p99 ['JOINED', 'METRIC', 'MULTI_HOP'] -lux_listing_mapping ('listing', 'lux_listing') average_booking_value ['JOINED', 'METRIC', 'MULTI_HOP'] -lux_listing_mapping ('listing', 'lux_listing') average_instant_booking_value ['JOINED', 'METRIC', 'MULTI_HOP'] -lux_listing_mapping ('listing', 'lux_listing') bookers ['JOINED', 'METRIC', 'MULTI_HOP'] -lux_listing_mapping ('listing', 'lux_listing') booking_fees ['JOINED', 'METRIC', 'MULTI_HOP'] -lux_listing_mapping ('listing', 'lux_listing') booking_fees_last_week_per_booker_this_week ['JOINED', 'METRIC', 'MULTI_HOP'] -lux_listing_mapping ('listing', 'lux_listing') booking_fees_per_booker ['JOINED', 'METRIC', 'MULTI_HOP'] -lux_listing_mapping ('listing', 'lux_listing') booking_fees_since_start_of_month ['JOINED', 'METRIC', 'MULTI_HOP'] -lux_listing_mapping ('listing', 'lux_listing') booking_payments ['JOINED', 'METRIC', 'MULTI_HOP'] -lux_listing_mapping ('listing', 'lux_listing') booking_value ['JOINED', 'METRIC', 'MULTI_HOP'] -lux_listing_mapping ('listing', 'lux_listing') booking_value_for_non_null_listing_id ['JOINED', 'METRIC', 'MULTI_HOP'] -lux_listing_mapping ('listing', 'lux_listing') booking_value_p99 ['JOINED', 'METRIC', 'MULTI_HOP'] -lux_listing_mapping ('listing', 'lux_listing') booking_value_per_view ['JOINED', 'METRIC', 'MULTI_HOP'] -lux_listing_mapping ('listing', 'lux_listing') booking_value_sub_instant ['JOINED', 'METRIC', 'MULTI_HOP'] -lux_listing_mapping ('listing', 'lux_listing') booking_value_sub_instant_add_10 ['JOINED', 'METRIC', 'MULTI_HOP'] -lux_listing_mapping ('listing', 'lux_listing') bookings ['JOINED', 'METRIC', 'MULTI_HOP'] -lux_listing_mapping ('listing', 'lux_listing') bookings_5_day_lag ['JOINED', 'METRIC', 'MULTI_HOP'] -lux_listing_mapping ('listing', 'lux_listing') bookings_at_start_of_month ['JOINED', 'METRIC', 'MULTI_HOP'] -lux_listing_mapping ('listing', 'lux_listing') bookings_fill_nulls_with_0 ['JOINED', 'METRIC', 'MULTI_HOP'] -lux_listing_mapping ('listing', 'lux_listing') bookings_fill_nulls_with_0_without_time_spine ['JOINED', 'METRIC', 'MULTI_HOP'] -lux_listing_mapping ('listing', 'lux_listing') bookings_growth_2_weeks ['JOINED', 'METRIC', 'MULTI_HOP'] -lux_listing_mapping ('listing', 'lux_listing') bookings_growth_2_weeks_fill_nulls_with_0 ['JOINED', 'METRIC', 'MULTI_HOP'] -lux_listing_mapping ('listing', 'lux_listing') bookings_growth_2_weeks_fill_nulls_with_0_for_non_offset ['JOINED', 'METRIC', 'MULTI_HOP'] -lux_listing_mapping ('listing', 'lux_listing') bookings_growth_since_start_of_month ['JOINED', 'METRIC', 'MULTI_HOP'] -lux_listing_mapping ('listing', 'lux_listing') bookings_join_to_time_spine ['JOINED', 'METRIC', 'MULTI_HOP'] -lux_listing_mapping ('listing', 'lux_listing') bookings_month_start_compared_to_1_month_prior ['JOINED', 'METRIC', 'MULTI_HOP'] -lux_listing_mapping ('listing', 'lux_listing') bookings_offset_once ['JOINED', 'METRIC', 'MULTI_HOP'] -lux_listing_mapping ('listing', 'lux_listing') bookings_offset_twice ['JOINED', 'METRIC', 'MULTI_HOP'] -lux_listing_mapping ('listing', 'lux_listing') bookings_per_booker ['JOINED', 'METRIC', 'MULTI_HOP'] -lux_listing_mapping ('listing', 'lux_listing') bookings_per_dollar ['JOINED', 'METRIC', 'MULTI_HOP'] -lux_listing_mapping ('listing', 'lux_listing') bookings_per_listing ['JOINED', 'METRIC', 'MULTI_HOP'] -lux_listing_mapping ('listing', 'lux_listing') bookings_per_lux_listing_derived ['JOINED', 'METRIC', 'MULTI_HOP'] -lux_listing_mapping ('listing', 'lux_listing') bookings_per_view ['JOINED', 'METRIC', 'MULTI_HOP'] -lux_listing_mapping ('listing', 'lux_listing') derived_bookings_0 ['JOINED', 'METRIC', 'MULTI_HOP'] -lux_listing_mapping ('listing', 'lux_listing') derived_bookings_1 ['JOINED', 'METRIC', 'MULTI_HOP'] -lux_listing_mapping ('listing', 'lux_listing') discrete_booking_value_p99 ['JOINED', 'METRIC', 'MULTI_HOP'] -lux_listing_mapping ('listing', 'lux_listing') double_counted_delayed_bookings ['JOINED', 'METRIC', 'MULTI_HOP'] -lux_listing_mapping ('listing', 'lux_listing') every_2_days_bookers_2_days_ago ['JOINED', 'METRIC', 'MULTI_HOP'] -lux_listing_mapping ('listing', 'lux_listing') every_two_days_bookers ['JOINED', 'METRIC', 'MULTI_HOP'] -lux_listing_mapping ('listing', 'lux_listing') every_two_days_bookers_fill_nulls_with_0 ['JOINED', 'METRIC', 'MULTI_HOP'] -lux_listing_mapping ('listing', 'lux_listing') instant_booking_fraction_of_max_value ['JOINED', 'METRIC', 'MULTI_HOP'] -lux_listing_mapping ('listing', 'lux_listing') instant_booking_value ['JOINED', 'METRIC', 'MULTI_HOP'] -lux_listing_mapping ('listing', 'lux_listing') instant_booking_value_ratio ['JOINED', 'METRIC', 'MULTI_HOP'] -lux_listing_mapping ('listing', 'lux_listing') instant_bookings ['JOINED', 'METRIC', 'MULTI_HOP'] -lux_listing_mapping ('listing', 'lux_listing') instant_lux_booking_value_rate ['JOINED', 'METRIC', 'MULTI_HOP'] -lux_listing_mapping ('listing', 'lux_listing') instant_plus_non_referred_bookings_pct ['JOINED', 'METRIC', 'MULTI_HOP'] -lux_listing_mapping ('listing', 'lux_listing') largest_listing ['JOINED', 'METRIC', 'MULTI_HOP'] -lux_listing_mapping ('listing', 'lux_listing') listings ['JOINED', 'METRIC', 'MULTI_HOP'] -lux_listing_mapping ('listing', 'lux_listing') lux_booking_fraction_of_max_value ['JOINED', 'METRIC', 'MULTI_HOP'] -lux_listing_mapping ('listing', 'lux_listing') lux_booking_value_rate_expr ['JOINED', 'METRIC', 'MULTI_HOP'] -lux_listing_mapping ('listing', 'lux_listing') lux_listings ['JOINED', 'METRIC', 'MULTI_HOP'] -lux_listing_mapping ('listing', 'lux_listing') max_booking_value ['JOINED', 'METRIC', 'MULTI_HOP'] -lux_listing_mapping ('listing', 'lux_listing') median_booking_value ['JOINED', 'METRIC', 'MULTI_HOP'] -lux_listing_mapping ('listing', 'lux_listing') min_booking_value ['JOINED', 'METRIC', 'MULTI_HOP'] -lux_listing_mapping ('listing', 'lux_listing') nested_fill_nulls_without_time_spine ['JOINED', 'METRIC', 'MULTI_HOP'] -lux_listing_mapping ('listing', 'lux_listing') non_referred_bookings_pct ['JOINED', 'METRIC', 'MULTI_HOP'] -lux_listing_mapping ('listing', 'lux_listing') referred_bookings ['JOINED', 'METRIC', 'MULTI_HOP'] -lux_listing_mapping ('listing', 'lux_listing') smallest_listing ['JOINED', 'METRIC', 'MULTI_HOP'] -lux_listing_mapping ('listing', 'lux_listing') twice_bookings_fill_nulls_with_0_without_time_spine ['JOINED', 'METRIC', 'MULTI_HOP'] -lux_listing_mapping ('listing', 'lux_listing') views ['JOINED', 'METRIC', 'MULTI_HOP'] -lux_listing_mapping ('listing', 'lux_listing') views_times_booking_value ['JOINED', 'METRIC', 'MULTI_HOP'] -users_ds_source ('user',) created_at DAY ['JOINED'] -users_ds_source ('user',) created_at DAY DAY ['JOINED'] -users_ds_source ('user',) created_at DAY DOW ['JOINED'] -users_ds_source ('user',) created_at DAY DOY ['JOINED'] -users_ds_source ('user',) created_at DAY MONTH ['JOINED'] -users_ds_source ('user',) created_at DAY QUARTER ['JOINED'] -users_ds_source ('user',) created_at DAY YEAR ['JOINED'] -users_ds_source ('user',) created_at MONTH ['DERIVED_TIME_GRANULARITY', 'JOINED'] -users_ds_source ('user',) created_at MONTH MONTH ['DERIVED_TIME_GRANULARITY', 'JOINED'] -users_ds_source ('user',) created_at MONTH QUARTER ['DERIVED_TIME_GRANULARITY', 'JOINED'] -users_ds_source ('user',) created_at MONTH YEAR ['DERIVED_TIME_GRANULARITY', 'JOINED'] -users_ds_source ('user',) created_at QUARTER ['DERIVED_TIME_GRANULARITY', 'JOINED'] -users_ds_source ('user',) created_at QUARTER QUARTER ['DERIVED_TIME_GRANULARITY', 'JOINED'] -users_ds_source ('user',) created_at QUARTER YEAR ['DERIVED_TIME_GRANULARITY', 'JOINED'] -users_ds_source ('user',) created_at WEEK ['DERIVED_TIME_GRANULARITY', 'JOINED'] -users_ds_source ('user',) created_at WEEK MONTH ['DERIVED_TIME_GRANULARITY', 'JOINED'] -users_ds_source ('user',) created_at WEEK QUARTER ['DERIVED_TIME_GRANULARITY', 'JOINED'] -users_ds_source ('user',) created_at WEEK YEAR ['DERIVED_TIME_GRANULARITY', 'JOINED'] -users_ds_source ('user',) created_at YEAR ['DERIVED_TIME_GRANULARITY', 'JOINED'] -users_ds_source ('user',) created_at YEAR YEAR ['DERIVED_TIME_GRANULARITY', 'JOINED'] -users_ds_source ('user',) ds DAY ['JOINED'] -users_ds_source ('user',) ds DAY DAY ['JOINED'] -users_ds_source ('user',) ds DAY DOW ['JOINED'] -users_ds_source ('user',) ds DAY DOY ['JOINED'] -users_ds_source ('user',) ds DAY MONTH ['JOINED'] -users_ds_source ('user',) ds DAY QUARTER ['JOINED'] -users_ds_source ('user',) ds DAY YEAR ['JOINED'] -users_ds_source ('user',) ds MONTH ['DERIVED_TIME_GRANULARITY', 'JOINED'] -users_ds_source ('user',) ds MONTH MONTH ['DERIVED_TIME_GRANULARITY', 'JOINED'] -users_ds_source ('user',) ds MONTH QUARTER ['DERIVED_TIME_GRANULARITY', 'JOINED'] -users_ds_source ('user',) ds MONTH YEAR ['DERIVED_TIME_GRANULARITY', 'JOINED'] -users_ds_source ('user',) ds QUARTER ['DERIVED_TIME_GRANULARITY', 'JOINED'] -users_ds_source ('user',) ds QUARTER QUARTER ['DERIVED_TIME_GRANULARITY', 'JOINED'] -users_ds_source ('user',) ds QUARTER YEAR ['DERIVED_TIME_GRANULARITY', 'JOINED'] -users_ds_source ('user',) ds WEEK ['DERIVED_TIME_GRANULARITY', 'JOINED'] -users_ds_source ('user',) ds WEEK MONTH ['DERIVED_TIME_GRANULARITY', 'JOINED'] -users_ds_source ('user',) ds WEEK QUARTER ['DERIVED_TIME_GRANULARITY', 'JOINED'] -users_ds_source ('user',) ds WEEK YEAR ['DERIVED_TIME_GRANULARITY', 'JOINED'] -users_ds_source ('user',) ds YEAR ['DERIVED_TIME_GRANULARITY', 'JOINED'] -users_ds_source ('user',) ds YEAR YEAR ['DERIVED_TIME_GRANULARITY', 'JOINED'] -users_ds_source ('user',) ds_partitioned DAY ['JOINED'] -users_ds_source ('user',) ds_partitioned DAY DAY ['JOINED'] -users_ds_source ('user',) ds_partitioned DAY DOW ['JOINED'] -users_ds_source ('user',) ds_partitioned DAY DOY ['JOINED'] -users_ds_source ('user',) ds_partitioned DAY MONTH ['JOINED'] -users_ds_source ('user',) ds_partitioned DAY QUARTER ['JOINED'] -users_ds_source ('user',) ds_partitioned DAY YEAR ['JOINED'] -users_ds_source ('user',) ds_partitioned MONTH ['DERIVED_TIME_GRANULARITY', 'JOINED'] -users_ds_source ('user',) ds_partitioned MONTH MONTH ['DERIVED_TIME_GRANULARITY', 'JOINED'] -users_ds_source ('user',) ds_partitioned MONTH QUARTER ['DERIVED_TIME_GRANULARITY', 'JOINED'] -users_ds_source ('user',) ds_partitioned MONTH YEAR ['DERIVED_TIME_GRANULARITY', 'JOINED'] -users_ds_source ('user',) ds_partitioned QUARTER ['DERIVED_TIME_GRANULARITY', 'JOINED'] -users_ds_source ('user',) ds_partitioned QUARTER QUARTER ['DERIVED_TIME_GRANULARITY', 'JOINED'] -users_ds_source ('user',) ds_partitioned QUARTER YEAR ['DERIVED_TIME_GRANULARITY', 'JOINED'] -users_ds_source ('user',) ds_partitioned WEEK ['DERIVED_TIME_GRANULARITY', 'JOINED'] -users_ds_source ('user',) ds_partitioned WEEK MONTH ['DERIVED_TIME_GRANULARITY', 'JOINED'] -users_ds_source ('user',) ds_partitioned WEEK QUARTER ['DERIVED_TIME_GRANULARITY', 'JOINED'] -users_ds_source ('user',) ds_partitioned WEEK YEAR ['DERIVED_TIME_GRANULARITY', 'JOINED'] -users_ds_source ('user',) ds_partitioned YEAR ['DERIVED_TIME_GRANULARITY', 'JOINED'] -users_ds_source ('user',) ds_partitioned YEAR YEAR ['DERIVED_TIME_GRANULARITY', 'JOINED'] -users_ds_source ('user',) home_state ['JOINED'] -users_latest ('user',) ds_latest DAY ['JOINED'] -users_latest ('user',) ds_latest DAY DAY ['JOINED'] -users_latest ('user',) ds_latest DAY DOW ['JOINED'] -users_latest ('user',) ds_latest DAY DOY ['JOINED'] -users_latest ('user',) ds_latest DAY MONTH ['JOINED'] -users_latest ('user',) ds_latest DAY QUARTER ['JOINED'] -users_latest ('user',) ds_latest DAY YEAR ['JOINED'] -users_latest ('user',) ds_latest MONTH ['DERIVED_TIME_GRANULARITY', 'JOINED'] -users_latest ('user',) ds_latest MONTH MONTH ['DERIVED_TIME_GRANULARITY', 'JOINED'] -users_latest ('user',) ds_latest MONTH QUARTER ['DERIVED_TIME_GRANULARITY', 'JOINED'] -users_latest ('user',) ds_latest MONTH YEAR ['DERIVED_TIME_GRANULARITY', 'JOINED'] -users_latest ('user',) ds_latest QUARTER ['DERIVED_TIME_GRANULARITY', 'JOINED'] -users_latest ('user',) ds_latest QUARTER QUARTER ['DERIVED_TIME_GRANULARITY', 'JOINED'] -users_latest ('user',) ds_latest QUARTER YEAR ['DERIVED_TIME_GRANULARITY', 'JOINED'] -users_latest ('user',) ds_latest WEEK ['DERIVED_TIME_GRANULARITY', 'JOINED'] -users_latest ('user',) ds_latest WEEK MONTH ['DERIVED_TIME_GRANULARITY', 'JOINED'] -users_latest ('user',) ds_latest WEEK QUARTER ['DERIVED_TIME_GRANULARITY', 'JOINED'] -users_latest ('user',) ds_latest WEEK YEAR ['DERIVED_TIME_GRANULARITY', 'JOINED'] -users_latest ('user',) ds_latest YEAR ['DERIVED_TIME_GRANULARITY', 'JOINED'] -users_latest ('user',) ds_latest YEAR YEAR ['DERIVED_TIME_GRANULARITY', 'JOINED'] -users_latest ('user',) home_state_latest ['JOINED'] +Semantic Model Entity Links Name Time Granularity Date Part Properties +------------------- -------------------------- --------------------------------------------------- ------------------ ----------- ------------------------------------------- + ('listing',) active_listings ['JOINED', 'METRIC'] + ('listing',) approximate_continuous_booking_value_p99 ['JOINED', 'METRIC'] + ('listing',) approximate_discrete_booking_value_p99 ['JOINED', 'METRIC'] + ('listing',) average_booking_value ['JOINED', 'METRIC'] + ('listing',) average_instant_booking_value ['JOINED', 'METRIC'] + ('listing',) bookers ['JOINED', 'METRIC'] + ('listing',) booking_fees ['JOINED', 'METRIC'] + ('listing',) booking_fees_per_booker ['JOINED', 'METRIC'] + ('listing',) booking_payments ['JOINED', 'METRIC'] + ('listing',) booking_value ['JOINED', 'METRIC'] + ('listing',) booking_value_for_non_null_listing_id ['JOINED', 'METRIC'] + ('listing',) booking_value_p99 ['JOINED', 'METRIC'] + ('listing',) booking_value_per_view ['JOINED', 'METRIC'] + ('listing',) booking_value_sub_instant ['JOINED', 'METRIC'] + ('listing',) booking_value_sub_instant_add_10 ['JOINED', 'METRIC'] + ('listing',) bookings ['JOINED', 'METRIC'] + ('listing',) bookings_fill_nulls_with_0 ['JOINED', 'METRIC'] + ('listing',) bookings_fill_nulls_with_0_without_time_spine ['JOINED', 'METRIC'] + ('listing',) bookings_join_to_time_spine ['JOINED', 'METRIC'] + ('listing',) bookings_per_booker ['JOINED', 'METRIC'] + ('listing',) bookings_per_dollar ['JOINED', 'METRIC'] + ('listing',) bookings_per_listing ['JOINED', 'METRIC'] + ('listing',) bookings_per_lux_listing_derived ['JOINED', 'METRIC'] + ('listing',) bookings_per_view ['JOINED', 'METRIC'] + ('listing',) derived_bookings_0 ['JOINED', 'METRIC'] + ('listing',) derived_bookings_1 ['JOINED', 'METRIC'] + ('listing',) discrete_booking_value_p99 ['JOINED', 'METRIC'] + ('listing',) double_counted_delayed_bookings ['JOINED', 'METRIC'] + ('listing',) instant_booking_fraction_of_max_value ['JOINED', 'METRIC'] + ('listing',) instant_booking_value ['JOINED', 'METRIC'] + ('listing',) instant_booking_value_ratio ['JOINED', 'METRIC'] + ('listing',) instant_bookings ['JOINED', 'METRIC'] + ('listing',) instant_lux_booking_value_rate ['JOINED', 'METRIC'] + ('listing',) instant_plus_non_referred_bookings_pct ['JOINED', 'METRIC'] + ('listing',) largest_listing ['JOINED', 'METRIC'] + ('listing',) listings ['JOINED', 'METRIC'] + ('listing',) lux_booking_fraction_of_max_value ['JOINED', 'METRIC'] + ('listing',) lux_booking_value_rate_expr ['JOINED', 'METRIC'] + ('listing',) lux_listings ['JOINED', 'METRIC'] + ('listing',) max_booking_value ['JOINED', 'METRIC'] + ('listing',) median_booking_value ['JOINED', 'METRIC'] + ('listing',) min_booking_value ['JOINED', 'METRIC'] + ('listing',) nested_fill_nulls_without_time_spine ['JOINED', 'METRIC'] + ('listing',) non_referred_bookings_pct ['JOINED', 'METRIC'] + ('listing',) referred_bookings ['JOINED', 'METRIC'] + ('listing',) smallest_listing ['JOINED', 'METRIC'] + ('listing',) twice_bookings_fill_nulls_with_0_without_time_spine ['JOINED', 'METRIC'] + ('listing',) views ['JOINED', 'METRIC'] + ('listing',) views_times_booking_value ['JOINED', 'METRIC'] + ('user',) active_listings ['JOINED', 'METRIC'] + ('user',) approximate_continuous_booking_value_p99 ['JOINED', 'METRIC'] + ('user',) approximate_discrete_booking_value_p99 ['JOINED', 'METRIC'] + ('user',) average_booking_value ['JOINED', 'METRIC'] + ('user',) average_instant_booking_value ['JOINED', 'METRIC'] + ('user',) bookers ['JOINED', 'METRIC'] + ('user',) booking_fees ['JOINED', 'METRIC'] + ('user',) booking_fees_per_booker ['JOINED', 'METRIC'] + ('user',) booking_payments ['JOINED', 'METRIC'] + ('user',) booking_value ['JOINED', 'METRIC'] + ('user',) booking_value_for_non_null_listing_id ['JOINED', 'METRIC'] + ('user',) booking_value_p99 ['JOINED', 'METRIC'] + ('user',) booking_value_per_view ['JOINED', 'METRIC'] + ('user',) booking_value_sub_instant ['JOINED', 'METRIC'] + ('user',) booking_value_sub_instant_add_10 ['JOINED', 'METRIC'] + ('user',) bookings ['JOINED', 'METRIC'] + ('user',) bookings_fill_nulls_with_0 ['JOINED', 'METRIC'] + ('user',) bookings_fill_nulls_with_0_without_time_spine ['JOINED', 'METRIC'] + ('user',) bookings_join_to_time_spine ['JOINED', 'METRIC'] + ('user',) bookings_per_booker ['JOINED', 'METRIC'] + ('user',) bookings_per_dollar ['JOINED', 'METRIC'] + ('user',) bookings_per_listing ['JOINED', 'METRIC'] + ('user',) bookings_per_lux_listing_derived ['JOINED', 'METRIC'] + ('user',) bookings_per_view ['JOINED', 'METRIC'] + ('user',) current_account_balance_by_user ['JOINED', 'METRIC'] + ('user',) derived_bookings_0 ['JOINED', 'METRIC'] + ('user',) derived_bookings_1 ['JOINED', 'METRIC'] + ('user',) discrete_booking_value_p99 ['JOINED', 'METRIC'] + ('user',) double_counted_delayed_bookings ['JOINED', 'METRIC'] + ('user',) identity_verifications ['JOINED', 'METRIC'] + ('user',) instant_booking_fraction_of_max_value ['JOINED', 'METRIC'] + ('user',) instant_booking_value ['JOINED', 'METRIC'] + ('user',) instant_booking_value_ratio ['JOINED', 'METRIC'] + ('user',) instant_bookings ['JOINED', 'METRIC'] + ('user',) instant_lux_booking_value_rate ['JOINED', 'METRIC'] + ('user',) instant_plus_non_referred_bookings_pct ['JOINED', 'METRIC'] + ('user',) largest_listing ['JOINED', 'METRIC'] + ('user',) listings ['JOINED', 'METRIC'] + ('user',) lux_booking_fraction_of_max_value ['JOINED', 'METRIC'] + ('user',) lux_booking_value_rate_expr ['JOINED', 'METRIC'] + ('user',) lux_listings ['JOINED', 'METRIC'] + ('user',) max_booking_value ['JOINED', 'METRIC'] + ('user',) median_booking_value ['JOINED', 'METRIC'] + ('user',) min_booking_value ['JOINED', 'METRIC'] + ('user',) nested_fill_nulls_without_time_spine ['JOINED', 'METRIC'] + ('user',) non_referred_bookings_pct ['JOINED', 'METRIC'] + ('user',) referred_bookings ['JOINED', 'METRIC'] + ('user',) regional_starting_balance_ratios ['JOINED', 'METRIC'] + ('user',) revenue ['JOINED', 'METRIC'] + ('user',) revenue_all_time ['JOINED', 'METRIC'] + ('user',) smallest_listing ['JOINED', 'METRIC'] + ('user',) total_account_balance_first_day ['JOINED', 'METRIC'] + ('user',) twice_bookings_fill_nulls_with_0_without_time_spine ['JOINED', 'METRIC'] + ('user',) views ['JOINED', 'METRIC'] + ('user',) views_times_booking_value ['JOINED', 'METRIC'] + ('user',) visit_buy_conversion_rate ['JOINED', 'METRIC'] + ('user',) visit_buy_conversion_rate_7days ['JOINED', 'METRIC'] + ('user',) visit_buy_conversion_rate_7days_fill_nulls_with_0 ['JOINED', 'METRIC'] + ('user',) visit_buy_conversion_rate_by_session ['JOINED', 'METRIC'] + ('user',) visit_buy_conversions ['JOINED', 'METRIC'] +companies ('user',) company ['ENTITY', 'JOINED'] +companies ('user',) company_name ['JOINED'] +companies ('user', 'company') active_listings ['JOINED', 'METRIC', 'MULTI_HOP'] +companies ('user', 'company') approximate_continuous_booking_value_p99 ['JOINED', 'METRIC', 'MULTI_HOP'] +companies ('user', 'company') approximate_discrete_booking_value_p99 ['JOINED', 'METRIC', 'MULTI_HOP'] +companies ('user', 'company') average_booking_value ['JOINED', 'METRIC', 'MULTI_HOP'] +companies ('user', 'company') average_instant_booking_value ['JOINED', 'METRIC', 'MULTI_HOP'] +companies ('user', 'company') bookers ['JOINED', 'METRIC', 'MULTI_HOP'] +companies ('user', 'company') booking_fees ['JOINED', 'METRIC', 'MULTI_HOP'] +companies ('user', 'company') booking_fees_per_booker ['JOINED', 'METRIC', 'MULTI_HOP'] +companies ('user', 'company') booking_payments ['JOINED', 'METRIC', 'MULTI_HOP'] +companies ('user', 'company') booking_value ['JOINED', 'METRIC', 'MULTI_HOP'] +companies ('user', 'company') booking_value_for_non_null_listing_id ['JOINED', 'METRIC', 'MULTI_HOP'] +companies ('user', 'company') booking_value_p99 ['JOINED', 'METRIC', 'MULTI_HOP'] +companies ('user', 'company') booking_value_per_view ['JOINED', 'METRIC', 'MULTI_HOP'] +companies ('user', 'company') booking_value_sub_instant ['JOINED', 'METRIC', 'MULTI_HOP'] +companies ('user', 'company') booking_value_sub_instant_add_10 ['JOINED', 'METRIC', 'MULTI_HOP'] +companies ('user', 'company') bookings ['JOINED', 'METRIC', 'MULTI_HOP'] +companies ('user', 'company') bookings_fill_nulls_with_0 ['JOINED', 'METRIC', 'MULTI_HOP'] +companies ('user', 'company') bookings_fill_nulls_with_0_without_time_spine ['JOINED', 'METRIC', 'MULTI_HOP'] +companies ('user', 'company') bookings_join_to_time_spine ['JOINED', 'METRIC', 'MULTI_HOP'] +companies ('user', 'company') bookings_per_booker ['JOINED', 'METRIC', 'MULTI_HOP'] +companies ('user', 'company') bookings_per_dollar ['JOINED', 'METRIC', 'MULTI_HOP'] +companies ('user', 'company') bookings_per_view ['JOINED', 'METRIC', 'MULTI_HOP'] +companies ('user', 'company') current_account_balance_by_user ['JOINED', 'METRIC', 'MULTI_HOP'] +companies ('user', 'company') derived_bookings_0 ['JOINED', 'METRIC', 'MULTI_HOP'] +companies ('user', 'company') derived_bookings_1 ['JOINED', 'METRIC', 'MULTI_HOP'] +companies ('user', 'company') discrete_booking_value_p99 ['JOINED', 'METRIC', 'MULTI_HOP'] +companies ('user', 'company') double_counted_delayed_bookings ['JOINED', 'METRIC', 'MULTI_HOP'] +companies ('user', 'company') identity_verifications ['JOINED', 'METRIC', 'MULTI_HOP'] +companies ('user', 'company') instant_booking_fraction_of_max_value ['JOINED', 'METRIC', 'MULTI_HOP'] +companies ('user', 'company') instant_booking_value ['JOINED', 'METRIC', 'MULTI_HOP'] +companies ('user', 'company') instant_booking_value_ratio ['JOINED', 'METRIC', 'MULTI_HOP'] +companies ('user', 'company') instant_bookings ['JOINED', 'METRIC', 'MULTI_HOP'] +companies ('user', 'company') instant_lux_booking_value_rate ['JOINED', 'METRIC', 'MULTI_HOP'] +companies ('user', 'company') instant_plus_non_referred_bookings_pct ['JOINED', 'METRIC', 'MULTI_HOP'] +companies ('user', 'company') largest_listing ['JOINED', 'METRIC', 'MULTI_HOP'] +companies ('user', 'company') listings ['JOINED', 'METRIC', 'MULTI_HOP'] +companies ('user', 'company') lux_booking_fraction_of_max_value ['JOINED', 'METRIC', 'MULTI_HOP'] +companies ('user', 'company') lux_booking_value_rate_expr ['JOINED', 'METRIC', 'MULTI_HOP'] +companies ('user', 'company') lux_listings ['JOINED', 'METRIC', 'MULTI_HOP'] +companies ('user', 'company') max_booking_value ['JOINED', 'METRIC', 'MULTI_HOP'] +companies ('user', 'company') median_booking_value ['JOINED', 'METRIC', 'MULTI_HOP'] +companies ('user', 'company') min_booking_value ['JOINED', 'METRIC', 'MULTI_HOP'] +companies ('user', 'company') nested_fill_nulls_without_time_spine ['JOINED', 'METRIC', 'MULTI_HOP'] +companies ('user', 'company') non_referred_bookings_pct ['JOINED', 'METRIC', 'MULTI_HOP'] +companies ('user', 'company') referred_bookings ['JOINED', 'METRIC', 'MULTI_HOP'] +companies ('user', 'company') regional_starting_balance_ratios ['JOINED', 'METRIC', 'MULTI_HOP'] +companies ('user', 'company') revenue ['JOINED', 'METRIC', 'MULTI_HOP'] +companies ('user', 'company') revenue_all_time ['JOINED', 'METRIC', 'MULTI_HOP'] +companies ('user', 'company') smallest_listing ['JOINED', 'METRIC', 'MULTI_HOP'] +companies ('user', 'company') total_account_balance_first_day ['JOINED', 'METRIC', 'MULTI_HOP'] +companies ('user', 'company') twice_bookings_fill_nulls_with_0_without_time_spine ['JOINED', 'METRIC', 'MULTI_HOP'] +companies ('user', 'company') views ['JOINED', 'METRIC', 'MULTI_HOP'] +companies ('user', 'company') views_times_booking_value ['JOINED', 'METRIC', 'MULTI_HOP'] +companies ('user', 'company') visit_buy_conversion_rate ['JOINED', 'METRIC', 'MULTI_HOP'] +companies ('user', 'company') visit_buy_conversion_rate_7days ['JOINED', 'METRIC', 'MULTI_HOP'] +companies ('user', 'company') visit_buy_conversion_rate_7days_fill_nulls_with_0 ['JOINED', 'METRIC', 'MULTI_HOP'] +companies ('user', 'company') visit_buy_conversion_rate_by_session ['JOINED', 'METRIC', 'MULTI_HOP'] +companies ('user', 'company') visit_buy_conversions ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest () listing ['ENTITY', 'LOCAL'] +listings_latest () metric_time DAY ['METRIC_TIME'] +listings_latest () metric_time DAY DAY ['DERIVED_TIME_GRANULARITY', 'METRIC_TIME'] +listings_latest () metric_time DAY DOW ['DERIVED_TIME_GRANULARITY', 'METRIC_TIME'] +listings_latest () metric_time DAY DOY ['DERIVED_TIME_GRANULARITY', 'METRIC_TIME'] +listings_latest () metric_time DAY MONTH ['DERIVED_TIME_GRANULARITY', 'METRIC_TIME'] +listings_latest () metric_time DAY QUARTER ['DERIVED_TIME_GRANULARITY', 'METRIC_TIME'] +listings_latest () metric_time DAY YEAR ['DERIVED_TIME_GRANULARITY', 'METRIC_TIME'] +listings_latest () metric_time MONTH ['DERIVED_TIME_GRANULARITY', 'METRIC_TIME'] +listings_latest () metric_time MONTH MONTH ['DERIVED_TIME_GRANULARITY', 'METRIC_TIME'] +listings_latest () metric_time MONTH QUARTER ['DERIVED_TIME_GRANULARITY', 'METRIC_TIME'] +listings_latest () metric_time MONTH YEAR ['DERIVED_TIME_GRANULARITY', 'METRIC_TIME'] +listings_latest () metric_time QUARTER ['DERIVED_TIME_GRANULARITY', 'METRIC_TIME'] +listings_latest () metric_time QUARTER QUARTER ['DERIVED_TIME_GRANULARITY', 'METRIC_TIME'] +listings_latest () metric_time QUARTER YEAR ['DERIVED_TIME_GRANULARITY', 'METRIC_TIME'] +listings_latest () metric_time WEEK ['DERIVED_TIME_GRANULARITY', 'METRIC_TIME'] +listings_latest () metric_time WEEK MONTH ['DERIVED_TIME_GRANULARITY', 'METRIC_TIME'] +listings_latest () metric_time WEEK QUARTER ['DERIVED_TIME_GRANULARITY', 'METRIC_TIME'] +listings_latest () metric_time WEEK YEAR ['DERIVED_TIME_GRANULARITY', 'METRIC_TIME'] +listings_latest () metric_time YEAR ['DERIVED_TIME_GRANULARITY', 'METRIC_TIME'] +listings_latest () metric_time YEAR YEAR ['DERIVED_TIME_GRANULARITY', 'METRIC_TIME'] +listings_latest () user ['ENTITY', 'LOCAL'] +listings_latest ('listing',) capacity_latest ['LOCAL'] +listings_latest ('listing',) country_latest ['LOCAL'] +listings_latest ('listing',) created_at DAY ['LOCAL'] +listings_latest ('listing',) created_at DAY DAY ['LOCAL'] +listings_latest ('listing',) created_at DAY DOW ['LOCAL'] +listings_latest ('listing',) created_at DAY DOY ['LOCAL'] +listings_latest ('listing',) created_at DAY MONTH ['LOCAL'] +listings_latest ('listing',) created_at DAY QUARTER ['LOCAL'] +listings_latest ('listing',) created_at DAY YEAR ['LOCAL'] +listings_latest ('listing',) created_at MONTH ['DERIVED_TIME_GRANULARITY', 'LOCAL'] +listings_latest ('listing',) created_at MONTH MONTH ['DERIVED_TIME_GRANULARITY', 'LOCAL'] +listings_latest ('listing',) created_at MONTH QUARTER ['DERIVED_TIME_GRANULARITY', 'LOCAL'] +listings_latest ('listing',) created_at MONTH YEAR ['DERIVED_TIME_GRANULARITY', 'LOCAL'] +listings_latest ('listing',) created_at QUARTER ['DERIVED_TIME_GRANULARITY', 'LOCAL'] +listings_latest ('listing',) created_at QUARTER QUARTER ['DERIVED_TIME_GRANULARITY', 'LOCAL'] +listings_latest ('listing',) created_at QUARTER YEAR ['DERIVED_TIME_GRANULARITY', 'LOCAL'] +listings_latest ('listing',) created_at WEEK ['DERIVED_TIME_GRANULARITY', 'LOCAL'] +listings_latest ('listing',) created_at WEEK MONTH ['DERIVED_TIME_GRANULARITY', 'LOCAL'] +listings_latest ('listing',) created_at WEEK QUARTER ['DERIVED_TIME_GRANULARITY', 'LOCAL'] +listings_latest ('listing',) created_at WEEK YEAR ['DERIVED_TIME_GRANULARITY', 'LOCAL'] +listings_latest ('listing',) created_at YEAR ['DERIVED_TIME_GRANULARITY', 'LOCAL'] +listings_latest ('listing',) created_at YEAR YEAR ['DERIVED_TIME_GRANULARITY', 'LOCAL'] +listings_latest ('listing',) ds DAY ['LOCAL'] +listings_latest ('listing',) ds DAY DAY ['LOCAL'] +listings_latest ('listing',) ds DAY DOW ['LOCAL'] +listings_latest ('listing',) ds DAY DOY ['LOCAL'] +listings_latest ('listing',) ds DAY MONTH ['LOCAL'] +listings_latest ('listing',) ds DAY QUARTER ['LOCAL'] +listings_latest ('listing',) ds DAY YEAR ['LOCAL'] +listings_latest ('listing',) ds MONTH ['DERIVED_TIME_GRANULARITY', 'LOCAL'] +listings_latest ('listing',) ds MONTH MONTH ['DERIVED_TIME_GRANULARITY', 'LOCAL'] +listings_latest ('listing',) ds MONTH QUARTER ['DERIVED_TIME_GRANULARITY', 'LOCAL'] +listings_latest ('listing',) ds MONTH YEAR ['DERIVED_TIME_GRANULARITY', 'LOCAL'] +listings_latest ('listing',) ds QUARTER ['DERIVED_TIME_GRANULARITY', 'LOCAL'] +listings_latest ('listing',) ds QUARTER QUARTER ['DERIVED_TIME_GRANULARITY', 'LOCAL'] +listings_latest ('listing',) ds QUARTER YEAR ['DERIVED_TIME_GRANULARITY', 'LOCAL'] +listings_latest ('listing',) ds WEEK ['DERIVED_TIME_GRANULARITY', 'LOCAL'] +listings_latest ('listing',) ds WEEK MONTH ['DERIVED_TIME_GRANULARITY', 'LOCAL'] +listings_latest ('listing',) ds WEEK QUARTER ['DERIVED_TIME_GRANULARITY', 'LOCAL'] +listings_latest ('listing',) ds WEEK YEAR ['DERIVED_TIME_GRANULARITY', 'LOCAL'] +listings_latest ('listing',) ds YEAR ['DERIVED_TIME_GRANULARITY', 'LOCAL'] +listings_latest ('listing',) ds YEAR YEAR ['DERIVED_TIME_GRANULARITY', 'LOCAL'] +listings_latest ('listing',) is_lux_latest ['LOCAL'] +listings_latest ('listing',) user ['ENTITY', 'LOCAL'] +lux_listing_mapping ('listing',) lux_listing ['ENTITY', 'JOINED'] +lux_listing_mapping ('listing', 'lux_listing') active_listings ['JOINED', 'METRIC', 'MULTI_HOP'] +lux_listing_mapping ('listing', 'lux_listing') approximate_continuous_booking_value_p99 ['JOINED', 'METRIC', 'MULTI_HOP'] +lux_listing_mapping ('listing', 'lux_listing') approximate_discrete_booking_value_p99 ['JOINED', 'METRIC', 'MULTI_HOP'] +lux_listing_mapping ('listing', 'lux_listing') average_booking_value ['JOINED', 'METRIC', 'MULTI_HOP'] +lux_listing_mapping ('listing', 'lux_listing') average_instant_booking_value ['JOINED', 'METRIC', 'MULTI_HOP'] +lux_listing_mapping ('listing', 'lux_listing') bookers ['JOINED', 'METRIC', 'MULTI_HOP'] +lux_listing_mapping ('listing', 'lux_listing') booking_fees ['JOINED', 'METRIC', 'MULTI_HOP'] +lux_listing_mapping ('listing', 'lux_listing') booking_fees_per_booker ['JOINED', 'METRIC', 'MULTI_HOP'] +lux_listing_mapping ('listing', 'lux_listing') booking_payments ['JOINED', 'METRIC', 'MULTI_HOP'] +lux_listing_mapping ('listing', 'lux_listing') booking_value ['JOINED', 'METRIC', 'MULTI_HOP'] +lux_listing_mapping ('listing', 'lux_listing') booking_value_for_non_null_listing_id ['JOINED', 'METRIC', 'MULTI_HOP'] +lux_listing_mapping ('listing', 'lux_listing') booking_value_p99 ['JOINED', 'METRIC', 'MULTI_HOP'] +lux_listing_mapping ('listing', 'lux_listing') booking_value_per_view ['JOINED', 'METRIC', 'MULTI_HOP'] +lux_listing_mapping ('listing', 'lux_listing') booking_value_sub_instant ['JOINED', 'METRIC', 'MULTI_HOP'] +lux_listing_mapping ('listing', 'lux_listing') booking_value_sub_instant_add_10 ['JOINED', 'METRIC', 'MULTI_HOP'] +lux_listing_mapping ('listing', 'lux_listing') bookings ['JOINED', 'METRIC', 'MULTI_HOP'] +lux_listing_mapping ('listing', 'lux_listing') bookings_fill_nulls_with_0 ['JOINED', 'METRIC', 'MULTI_HOP'] +lux_listing_mapping ('listing', 'lux_listing') bookings_fill_nulls_with_0_without_time_spine ['JOINED', 'METRIC', 'MULTI_HOP'] +lux_listing_mapping ('listing', 'lux_listing') bookings_join_to_time_spine ['JOINED', 'METRIC', 'MULTI_HOP'] +lux_listing_mapping ('listing', 'lux_listing') bookings_per_booker ['JOINED', 'METRIC', 'MULTI_HOP'] +lux_listing_mapping ('listing', 'lux_listing') bookings_per_dollar ['JOINED', 'METRIC', 'MULTI_HOP'] +lux_listing_mapping ('listing', 'lux_listing') bookings_per_listing ['JOINED', 'METRIC', 'MULTI_HOP'] +lux_listing_mapping ('listing', 'lux_listing') bookings_per_lux_listing_derived ['JOINED', 'METRIC', 'MULTI_HOP'] +lux_listing_mapping ('listing', 'lux_listing') bookings_per_view ['JOINED', 'METRIC', 'MULTI_HOP'] +lux_listing_mapping ('listing', 'lux_listing') derived_bookings_0 ['JOINED', 'METRIC', 'MULTI_HOP'] +lux_listing_mapping ('listing', 'lux_listing') derived_bookings_1 ['JOINED', 'METRIC', 'MULTI_HOP'] +lux_listing_mapping ('listing', 'lux_listing') discrete_booking_value_p99 ['JOINED', 'METRIC', 'MULTI_HOP'] +lux_listing_mapping ('listing', 'lux_listing') double_counted_delayed_bookings ['JOINED', 'METRIC', 'MULTI_HOP'] +lux_listing_mapping ('listing', 'lux_listing') instant_booking_fraction_of_max_value ['JOINED', 'METRIC', 'MULTI_HOP'] +lux_listing_mapping ('listing', 'lux_listing') instant_booking_value ['JOINED', 'METRIC', 'MULTI_HOP'] +lux_listing_mapping ('listing', 'lux_listing') instant_booking_value_ratio ['JOINED', 'METRIC', 'MULTI_HOP'] +lux_listing_mapping ('listing', 'lux_listing') instant_bookings ['JOINED', 'METRIC', 'MULTI_HOP'] +lux_listing_mapping ('listing', 'lux_listing') instant_lux_booking_value_rate ['JOINED', 'METRIC', 'MULTI_HOP'] +lux_listing_mapping ('listing', 'lux_listing') instant_plus_non_referred_bookings_pct ['JOINED', 'METRIC', 'MULTI_HOP'] +lux_listing_mapping ('listing', 'lux_listing') largest_listing ['JOINED', 'METRIC', 'MULTI_HOP'] +lux_listing_mapping ('listing', 'lux_listing') listings ['JOINED', 'METRIC', 'MULTI_HOP'] +lux_listing_mapping ('listing', 'lux_listing') lux_booking_fraction_of_max_value ['JOINED', 'METRIC', 'MULTI_HOP'] +lux_listing_mapping ('listing', 'lux_listing') lux_booking_value_rate_expr ['JOINED', 'METRIC', 'MULTI_HOP'] +lux_listing_mapping ('listing', 'lux_listing') lux_listings ['JOINED', 'METRIC', 'MULTI_HOP'] +lux_listing_mapping ('listing', 'lux_listing') max_booking_value ['JOINED', 'METRIC', 'MULTI_HOP'] +lux_listing_mapping ('listing', 'lux_listing') median_booking_value ['JOINED', 'METRIC', 'MULTI_HOP'] +lux_listing_mapping ('listing', 'lux_listing') min_booking_value ['JOINED', 'METRIC', 'MULTI_HOP'] +lux_listing_mapping ('listing', 'lux_listing') nested_fill_nulls_without_time_spine ['JOINED', 'METRIC', 'MULTI_HOP'] +lux_listing_mapping ('listing', 'lux_listing') non_referred_bookings_pct ['JOINED', 'METRIC', 'MULTI_HOP'] +lux_listing_mapping ('listing', 'lux_listing') referred_bookings ['JOINED', 'METRIC', 'MULTI_HOP'] +lux_listing_mapping ('listing', 'lux_listing') smallest_listing ['JOINED', 'METRIC', 'MULTI_HOP'] +lux_listing_mapping ('listing', 'lux_listing') twice_bookings_fill_nulls_with_0_without_time_spine ['JOINED', 'METRIC', 'MULTI_HOP'] +lux_listing_mapping ('listing', 'lux_listing') views ['JOINED', 'METRIC', 'MULTI_HOP'] +lux_listing_mapping ('listing', 'lux_listing') views_times_booking_value ['JOINED', 'METRIC', 'MULTI_HOP'] +users_ds_source ('user',) created_at DAY ['JOINED'] +users_ds_source ('user',) created_at DAY DAY ['JOINED'] +users_ds_source ('user',) created_at DAY DOW ['JOINED'] +users_ds_source ('user',) created_at DAY DOY ['JOINED'] +users_ds_source ('user',) created_at DAY MONTH ['JOINED'] +users_ds_source ('user',) created_at DAY QUARTER ['JOINED'] +users_ds_source ('user',) created_at DAY YEAR ['JOINED'] +users_ds_source ('user',) created_at MONTH ['DERIVED_TIME_GRANULARITY', 'JOINED'] +users_ds_source ('user',) created_at MONTH MONTH ['DERIVED_TIME_GRANULARITY', 'JOINED'] +users_ds_source ('user',) created_at MONTH QUARTER ['DERIVED_TIME_GRANULARITY', 'JOINED'] +users_ds_source ('user',) created_at MONTH YEAR ['DERIVED_TIME_GRANULARITY', 'JOINED'] +users_ds_source ('user',) created_at QUARTER ['DERIVED_TIME_GRANULARITY', 'JOINED'] +users_ds_source ('user',) created_at QUARTER QUARTER ['DERIVED_TIME_GRANULARITY', 'JOINED'] +users_ds_source ('user',) created_at QUARTER YEAR ['DERIVED_TIME_GRANULARITY', 'JOINED'] +users_ds_source ('user',) created_at WEEK ['DERIVED_TIME_GRANULARITY', 'JOINED'] +users_ds_source ('user',) created_at WEEK MONTH ['DERIVED_TIME_GRANULARITY', 'JOINED'] +users_ds_source ('user',) created_at WEEK QUARTER ['DERIVED_TIME_GRANULARITY', 'JOINED'] +users_ds_source ('user',) created_at WEEK YEAR ['DERIVED_TIME_GRANULARITY', 'JOINED'] +users_ds_source ('user',) created_at YEAR ['DERIVED_TIME_GRANULARITY', 'JOINED'] +users_ds_source ('user',) created_at YEAR YEAR ['DERIVED_TIME_GRANULARITY', 'JOINED'] +users_ds_source ('user',) ds DAY ['JOINED'] +users_ds_source ('user',) ds DAY DAY ['JOINED'] +users_ds_source ('user',) ds DAY DOW ['JOINED'] +users_ds_source ('user',) ds DAY DOY ['JOINED'] +users_ds_source ('user',) ds DAY MONTH ['JOINED'] +users_ds_source ('user',) ds DAY QUARTER ['JOINED'] +users_ds_source ('user',) ds DAY YEAR ['JOINED'] +users_ds_source ('user',) ds MONTH ['DERIVED_TIME_GRANULARITY', 'JOINED'] +users_ds_source ('user',) ds MONTH MONTH ['DERIVED_TIME_GRANULARITY', 'JOINED'] +users_ds_source ('user',) ds MONTH QUARTER ['DERIVED_TIME_GRANULARITY', 'JOINED'] +users_ds_source ('user',) ds MONTH YEAR ['DERIVED_TIME_GRANULARITY', 'JOINED'] +users_ds_source ('user',) ds QUARTER ['DERIVED_TIME_GRANULARITY', 'JOINED'] +users_ds_source ('user',) ds QUARTER QUARTER ['DERIVED_TIME_GRANULARITY', 'JOINED'] +users_ds_source ('user',) ds QUARTER YEAR ['DERIVED_TIME_GRANULARITY', 'JOINED'] +users_ds_source ('user',) ds WEEK ['DERIVED_TIME_GRANULARITY', 'JOINED'] +users_ds_source ('user',) ds WEEK MONTH ['DERIVED_TIME_GRANULARITY', 'JOINED'] +users_ds_source ('user',) ds WEEK QUARTER ['DERIVED_TIME_GRANULARITY', 'JOINED'] +users_ds_source ('user',) ds WEEK YEAR ['DERIVED_TIME_GRANULARITY', 'JOINED'] +users_ds_source ('user',) ds YEAR ['DERIVED_TIME_GRANULARITY', 'JOINED'] +users_ds_source ('user',) ds YEAR YEAR ['DERIVED_TIME_GRANULARITY', 'JOINED'] +users_ds_source ('user',) ds_partitioned DAY ['JOINED'] +users_ds_source ('user',) ds_partitioned DAY DAY ['JOINED'] +users_ds_source ('user',) ds_partitioned DAY DOW ['JOINED'] +users_ds_source ('user',) ds_partitioned DAY DOY ['JOINED'] +users_ds_source ('user',) ds_partitioned DAY MONTH ['JOINED'] +users_ds_source ('user',) ds_partitioned DAY QUARTER ['JOINED'] +users_ds_source ('user',) ds_partitioned DAY YEAR ['JOINED'] +users_ds_source ('user',) ds_partitioned MONTH ['DERIVED_TIME_GRANULARITY', 'JOINED'] +users_ds_source ('user',) ds_partitioned MONTH MONTH ['DERIVED_TIME_GRANULARITY', 'JOINED'] +users_ds_source ('user',) ds_partitioned MONTH QUARTER ['DERIVED_TIME_GRANULARITY', 'JOINED'] +users_ds_source ('user',) ds_partitioned MONTH YEAR ['DERIVED_TIME_GRANULARITY', 'JOINED'] +users_ds_source ('user',) ds_partitioned QUARTER ['DERIVED_TIME_GRANULARITY', 'JOINED'] +users_ds_source ('user',) ds_partitioned QUARTER QUARTER ['DERIVED_TIME_GRANULARITY', 'JOINED'] +users_ds_source ('user',) ds_partitioned QUARTER YEAR ['DERIVED_TIME_GRANULARITY', 'JOINED'] +users_ds_source ('user',) ds_partitioned WEEK ['DERIVED_TIME_GRANULARITY', 'JOINED'] +users_ds_source ('user',) ds_partitioned WEEK MONTH ['DERIVED_TIME_GRANULARITY', 'JOINED'] +users_ds_source ('user',) ds_partitioned WEEK QUARTER ['DERIVED_TIME_GRANULARITY', 'JOINED'] +users_ds_source ('user',) ds_partitioned WEEK YEAR ['DERIVED_TIME_GRANULARITY', 'JOINED'] +users_ds_source ('user',) ds_partitioned YEAR ['DERIVED_TIME_GRANULARITY', 'JOINED'] +users_ds_source ('user',) ds_partitioned YEAR YEAR ['DERIVED_TIME_GRANULARITY', 'JOINED'] +users_ds_source ('user',) home_state ['JOINED'] +users_latest ('user',) ds_latest DAY ['JOINED'] +users_latest ('user',) ds_latest DAY DAY ['JOINED'] +users_latest ('user',) ds_latest DAY DOW ['JOINED'] +users_latest ('user',) ds_latest DAY DOY ['JOINED'] +users_latest ('user',) ds_latest DAY MONTH ['JOINED'] +users_latest ('user',) ds_latest DAY QUARTER ['JOINED'] +users_latest ('user',) ds_latest DAY YEAR ['JOINED'] +users_latest ('user',) ds_latest MONTH ['DERIVED_TIME_GRANULARITY', 'JOINED'] +users_latest ('user',) ds_latest MONTH MONTH ['DERIVED_TIME_GRANULARITY', 'JOINED'] +users_latest ('user',) ds_latest MONTH QUARTER ['DERIVED_TIME_GRANULARITY', 'JOINED'] +users_latest ('user',) ds_latest MONTH YEAR ['DERIVED_TIME_GRANULARITY', 'JOINED'] +users_latest ('user',) ds_latest QUARTER ['DERIVED_TIME_GRANULARITY', 'JOINED'] +users_latest ('user',) ds_latest QUARTER QUARTER ['DERIVED_TIME_GRANULARITY', 'JOINED'] +users_latest ('user',) ds_latest QUARTER YEAR ['DERIVED_TIME_GRANULARITY', 'JOINED'] +users_latest ('user',) ds_latest WEEK ['DERIVED_TIME_GRANULARITY', 'JOINED'] +users_latest ('user',) ds_latest WEEK MONTH ['DERIVED_TIME_GRANULARITY', 'JOINED'] +users_latest ('user',) ds_latest WEEK QUARTER ['DERIVED_TIME_GRANULARITY', 'JOINED'] +users_latest ('user',) ds_latest WEEK YEAR ['DERIVED_TIME_GRANULARITY', 'JOINED'] +users_latest ('user',) ds_latest YEAR ['DERIVED_TIME_GRANULARITY', 'JOINED'] +users_latest ('user',) ds_latest YEAR YEAR ['DERIVED_TIME_GRANULARITY', 'JOINED'] +users_latest ('user',) home_state_latest ['JOINED'] From 0a400a5ae37660063cbfb0b178555990d37bbcf0 Mon Sep 17 00:00:00 2001 From: Courtney Holcomb Date: Thu, 25 Apr 2024 09:29:57 -0700 Subject: [PATCH 29/37] Update AddGroupByMetrics to be singular AddGroupByMetric - should only ever accept one group by metric --- metricflow/plan_conversion/dataflow_to_sql.py | 4 ++-- metricflow/plan_conversion/instance_converters.py | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/metricflow/plan_conversion/dataflow_to_sql.py b/metricflow/plan_conversion/dataflow_to_sql.py index 0294e75926..05895e7a81 100644 --- a/metricflow/plan_conversion/dataflow_to_sql.py +++ b/metricflow/plan_conversion/dataflow_to_sql.py @@ -53,7 +53,7 @@ from metricflow.model.semantic_manifest_lookup import SemanticManifestLookup from metricflow.plan_conversion.convert_to_sql_plan import ConvertToSqlPlanResult from metricflow.plan_conversion.instance_converters import ( - AddGroupByMetrics, + AddGroupByMetric, AddLinkToLinkableElements, AddMetadata, AddMetrics, @@ -740,7 +740,7 @@ def visit_compute_metrics_node(self, node: ComputeMetricsNode) -> SqlDataSet: metric_subquery_entity_links=entity_instance.spec.entity_links, ), ) - transform_func = AddGroupByMetrics([group_by_metric_instance]) + transform_func = AddGroupByMetric(group_by_metric_instance) output_instance_set = output_instance_set.transform(transform_func) diff --git a/metricflow/plan_conversion/instance_converters.py b/metricflow/plan_conversion/instance_converters.py index e7c4b60a4f..66180b4064 100644 --- a/metricflow/plan_conversion/instance_converters.py +++ b/metricflow/plan_conversion/instance_converters.py @@ -745,11 +745,11 @@ def transform(self, instance_set: InstanceSet) -> InstanceSet: # noqa: D102 ) -class AddGroupByMetrics(InstanceSetTransform[InstanceSet]): +class AddGroupByMetric(InstanceSetTransform[InstanceSet]): """Adds the given metric instances to the instance set.""" - def __init__(self, group_by_metric_instances: List[GroupByMetricInstance]) -> None: # noqa: D107 - self._group_by_metric_instances = group_by_metric_instances + def __init__(self, group_by_metric_instance: GroupByMetricInstance) -> None: # noqa: D107 + self._group_by_metric_instance = group_by_metric_instance def transform(self, instance_set: InstanceSet) -> InstanceSet: # noqa: D102 return InstanceSet( @@ -757,7 +757,7 @@ def transform(self, instance_set: InstanceSet) -> InstanceSet: # noqa: D102 dimension_instances=instance_set.dimension_instances, time_dimension_instances=instance_set.time_dimension_instances, entity_instances=instance_set.entity_instances, - group_by_metric_instances=instance_set.group_by_metric_instances + tuple(self._group_by_metric_instances), + group_by_metric_instances=instance_set.group_by_metric_instances + (self._group_by_metric_instance,), metric_instances=instance_set.metric_instances, metadata_instances=instance_set.metadata_instances, ) From d5fd394e800d869144c08663323b0411ba2610bf Mon Sep 17 00:00:00 2001 From: Courtney Holcomb Date: Thu, 25 Apr 2024 17:27:34 -0700 Subject: [PATCH 30/37] Include last entity link in metric subquery entity path Originally I left out this last entity link because it was duplicated in the outer query entity links. Turns out this is needed when there are no entity links left in the outer query, because otherwise we won't know what entity the metric is being grouped by. --- .../model/semantics/linkable_spec_resolver.py | 7 +- metricflow/plan_conversion/dataflow_to_sql.py | 4 +- metricflow/specs/specs.py | 26 +-- tests/model/test_where_filter_spec.py | 4 +- tests/naming/conftest.py | 2 +- .../test_object_builder_naming_scheme.py | 4 +- ...t_metric_in_metric_where_filter__dfp_0.xml | 19 +- ...st_metric_in_query_where_filter__dfp_0.xml | 19 +- ...linkable_element_set_as_spec_set__set0.txt | 170 +++++++++--------- ...values_query_with_metric_filter__plan0.sql | 2 +- ...ry_with_metric_filter__plan0_optimized.sql | 2 +- ...emantic_model_as_queried_metric__plan0.sql | 2 +- ...del_as_queried_metric__plan0_optimized.sql | 2 +- .../test_metric_filtered_by_itself__plan0.sql | 2 +- ...ic_filtered_by_itself__plan0_optimized.sql | 2 +- ...ric_with_metric_in_where_filter__plan0.sql | 2 +- ...etric_in_where_filter__plan0_optimized.sql | 2 +- ...mulative_metric_in_where_filter__plan0.sql | 2 +- ...etric_in_where_filter__plan0_optimized.sql | 2 +- ..._derived_metric_in_where_filter__plan0.sql | 2 +- ...etric_in_where_filter__plan0_optimized.sql | 2 +- ...with_multiple_metrics_in_filter__plan0.sql | 4 +- ...ple_metrics_in_filter__plan0_optimized.sql | 4 +- ...th_ratio_metric_in_where_filter__plan0.sql | 2 +- ...h_simple_metric_in_where_filter__plan0.sql | 2 +- ...etric_in_where_filter__plan0_optimized.sql | 2 +- .../patterns/test_entity_link_pattern.py | 4 +- tests/specs/patterns/test_typed_patterns.py | 4 +- tests/test_specs.py | 6 +- 29 files changed, 162 insertions(+), 145 deletions(-) diff --git a/metricflow/model/semantics/linkable_spec_resolver.py b/metricflow/model/semantics/linkable_spec_resolver.py index f3fedf0f81..26f36af5a0 100644 --- a/metricflow/model/semantics/linkable_spec_resolver.py +++ b/metricflow/model/semantics/linkable_spec_resolver.py @@ -139,7 +139,7 @@ def metric_to_entity_join_path(self) -> Optional[SemanticModelJoinPath]: @property def metric_subquery_entity_links(self) -> Tuple[EntityReference, ...]: """Entity links used to join the metric to the entity it's grouped by in the metric subquery.""" - return self.metric_to_entity_join_path.entity_links if self.metric_to_entity_join_path else () + return self.join_path.metric_subquery_join_path_element.entity_links @dataclass(frozen=True) @@ -410,6 +410,11 @@ class MetricSubqueryJoinPathElement: join_on_entity: EntityReference metric_to_entity_join_path: Optional[SemanticModelJoinPath] = None + @property + def entity_links(self) -> Tuple[EntityReference, ...]: # noqa: D102 + join_links = self.metric_to_entity_join_path.entity_links if self.metric_to_entity_join_path else () + return join_links + (self.join_on_entity,) + @dataclass(frozen=True) class SemanticModelToMetricSubqueryJoinPath: diff --git a/metricflow/plan_conversion/dataflow_to_sql.py b/metricflow/plan_conversion/dataflow_to_sql.py index 05895e7a81..e2160630cb 100644 --- a/metricflow/plan_conversion/dataflow_to_sql.py +++ b/metricflow/plan_conversion/dataflow_to_sql.py @@ -736,8 +736,8 @@ def visit_compute_metrics_node(self, node: ComputeMetricsNode) -> SqlDataSet: defined_from=metric_instance.defined_from, spec=GroupByMetricSpec( element_name=metric_spec.element_name, - entity_links=(), # check this - metric_subquery_entity_links=entity_instance.spec.entity_links, + entity_links=(), + metric_subquery_entity_links=entity_instance.spec.entity_links + (entity_instance.spec.reference,), ), ) transform_func = AddGroupByMetric(group_by_metric_instance) diff --git a/metricflow/specs/specs.py b/metricflow/specs/specs.py index 8e86a247be..e51b525da2 100644 --- a/metricflow/specs/specs.py +++ b/metricflow/specs/specs.py @@ -249,12 +249,18 @@ class GroupByMetricSpec(LinkableInstanceSpec, SerializableDataclass): entity_links: Sequence of entities joined to join the metric subquery to the outer query. Last entity is the one joining the subquery to the outer query. metric_subquery_entity_links: Sequence of entities used in the metric subquery to join the metric to the entity. - Does not include the top-level entity (to avoid duplicating the last element of `entity_links`). - """ metric_subquery_entity_links: Tuple[EntityReference, ...] + def __post_init__(self) -> None: + """The inner query and outer query entity paths must end with the same entity (that's what they join on). + + If no entity links, it's because we're already in the final joined node (no links left). + """ + if self.entity_links: + assert self.metric_subquery_entity_links[-1] == self.entity_links[-1] + @property def without_first_entity_link(self) -> GroupByMetricSpec: # noqa: D102 assert len(self.entity_links) > 0, f"Spec does not have any entity links: {self}" @@ -277,21 +283,15 @@ def last_entity_link(self) -> EntityReference: # noqa: D102 assert len(self.entity_links) > 0, f"Spec does not have any entity links: {self}" return self.entity_links[-1] - @staticmethod - def from_name(name: str) -> GroupByMetricSpec: # noqa: D102 - structured_name = StructuredLinkableSpecName.from_name(name) - return GroupByMetricSpec( - entity_links=tuple(EntityReference(idl) for idl in structured_name.entity_link_names), - element_name=structured_name.element_name, - metric_subquery_entity_links=(), - ) - @property def metric_subquery_entity_spec(self) -> EntitySpec: """Spec for the entity that the metric will be grouped by it the metric subquery.""" + assert ( + len(self.metric_subquery_entity_links) > 0 + ), "GroupByMetricSpec must have at least one metric_subquery_entity_link." return EntitySpec( - element_name=self.last_entity_link.element_name, - entity_links=self.metric_subquery_entity_links, + element_name=self.metric_subquery_entity_links[-1].element_name, + entity_links=self.metric_subquery_entity_links[:-1], ) def __eq__(self, other: Any) -> bool: # type: ignore[misc] # noqa: D105 diff --git a/tests/model/test_where_filter_spec.py b/tests/model/test_where_filter_spec.py index f7f1d41a0f..b48afacb81 100644 --- a/tests/model/test_where_filter_spec.py +++ b/tests/model/test_where_filter_spec.py @@ -371,7 +371,9 @@ def test_metric_in_filter( # noqa: D103 where_filter = PydanticWhereFilter(where_sql_template="{{ Metric('bookings', group_by=['listing']) }} > 2") group_by_metric_spec = GroupByMetricSpec( - element_name="bookings", entity_links=(EntityReference("listing"),), metric_subquery_entity_links=() + element_name="bookings", + entity_links=(EntityReference("listing"),), + metric_subquery_entity_links=(EntityReference(element_name="listing"),), ) where_filter_spec = WhereSpecFactory( column_association_resolver=column_association_resolver, diff --git a/tests/naming/conftest.py b/tests/naming/conftest.py index 07f8fb07d1..9d28e000cc 100644 --- a/tests/naming/conftest.py +++ b/tests/naming/conftest.py @@ -53,6 +53,6 @@ def specs() -> Sequence[LinkableInstanceSpec]: # noqa: D103 GroupByMetricSpec( element_name="bookings", entity_links=(EntityReference(element_name="listing"),), - metric_subquery_entity_links=(), + metric_subquery_entity_links=(EntityReference(element_name="listing"),), ), ) diff --git a/tests/naming/test_object_builder_naming_scheme.py b/tests/naming/test_object_builder_naming_scheme.py index e003503b3d..0e906c8848 100644 --- a/tests/naming/test_object_builder_naming_scheme.py +++ b/tests/naming/test_object_builder_naming_scheme.py @@ -52,7 +52,7 @@ def test_input_str(object_builder_naming_scheme: ObjectBuilderNamingScheme) -> N GroupByMetricSpec( element_name="bookings", entity_links=(EntityReference(element_name="listing"),), - metric_subquery_entity_links=(), + metric_subquery_entity_links=(EntityReference(element_name="listing"),), ) ) == "Metric('bookings', group_by=['listing'])" @@ -125,6 +125,6 @@ def test_spec_pattern( # noqa: D103 GroupByMetricSpec( element_name="bookings", entity_links=(EntityReference(element_name="listing"),), - metric_subquery_entity_links=(), + metric_subquery_entity_links=(EntityReference(element_name="listing"),), ), ) diff --git a/tests/snapshots/test_dataflow_plan_builder.py/DataflowPlan/test_metric_in_metric_where_filter__dfp_0.xml b/tests/snapshots/test_dataflow_plan_builder.py/DataflowPlan/test_metric_in_metric_where_filter__dfp_0.xml index 1f539c3a57..6fa76e63ee 100644 --- a/tests/snapshots/test_dataflow_plan_builder.py/DataflowPlan/test_metric_in_metric_where_filter__dfp_0.xml +++ b/tests/snapshots/test_dataflow_plan_builder.py/DataflowPlan/test_metric_in_metric_where_filter__dfp_0.xml @@ -23,11 +23,12 @@ - - - - - + + + + + + @@ -56,10 +57,14 @@ - + - + + + + + diff --git a/tests/snapshots/test_dataflow_plan_builder.py/DataflowPlan/test_metric_in_query_where_filter__dfp_0.xml b/tests/snapshots/test_dataflow_plan_builder.py/DataflowPlan/test_metric_in_query_where_filter__dfp_0.xml index f0a5328a55..37fcaf497c 100644 --- a/tests/snapshots/test_dataflow_plan_builder.py/DataflowPlan/test_metric_in_query_where_filter__dfp_0.xml +++ b/tests/snapshots/test_dataflow_plan_builder.py/DataflowPlan/test_metric_in_query_where_filter__dfp_0.xml @@ -32,11 +32,12 @@ - - - - - + + + + + + @@ -65,10 +66,14 @@ - + - + + + + + diff --git a/tests/snapshots/test_linkable_spec_resolver.py/list/test_linkable_element_set_as_spec_set__set0.txt b/tests/snapshots/test_linkable_spec_resolver.py/list/test_linkable_element_set_as_spec_set__set0.txt index 50853aecf0..b01f907f15 100644 --- a/tests/snapshots/test_linkable_spec_resolver.py/list/test_linkable_element_set_as_spec_set__set0.txt +++ b/tests/snapshots/test_linkable_spec_resolver.py/list/test_linkable_element_set_as_spec_set__set0.txt @@ -165,83 +165,61 @@ 'metric_time__year', 'user', 'user__active_listings', - 'user__approximate_continuous_booking_value_p99', - 'user__approximate_discrete_booking_value_p99', - 'user__average_booking_value', - 'user__average_instant_booking_value', - 'user__bookers', - 'user__booking_fees', - 'user__booking_fees_per_booker', - 'user__booking_payments', - 'user__booking_value', - 'user__booking_value_for_non_null_listing_id', - 'user__booking_value_p99', - 'user__booking_value_per_view', - 'user__booking_value_sub_instant', - 'user__booking_value_sub_instant_add_10', - 'user__bookings', - 'user__bookings_fill_nulls_with_0', - 'user__bookings_fill_nulls_with_0_without_time_spine', - 'user__bookings_join_to_time_spine', - 'user__bookings_per_booker', - 'user__bookings_per_dollar', 'user__bookings_per_listing', - 'user__bookings_per_lux_listing_derived', - 'user__bookings_per_view', 'user__company', 'user__company__active_listings', - 'user__company__approximate_continuous_booking_value_p99', - 'user__company__approximate_discrete_booking_value_p99', - 'user__company__average_booking_value', - 'user__company__average_instant_booking_value', - 'user__company__bookers', - 'user__company__booking_fees', - 'user__company__booking_fees_per_booker', - 'user__company__booking_payments', - 'user__company__booking_value', - 'user__company__booking_value_for_non_null_listing_id', - 'user__company__booking_value_p99', - 'user__company__booking_value_per_view', - 'user__company__booking_value_sub_instant', - 'user__company__booking_value_sub_instant_add_10', - 'user__company__bookings', - 'user__company__bookings_fill_nulls_with_0', - 'user__company__bookings_fill_nulls_with_0_without_time_spine', - 'user__company__bookings_join_to_time_spine', - 'user__company__bookings_per_booker', - 'user__company__bookings_per_dollar', - 'user__company__bookings_per_view', 'user__company__current_account_balance_by_user', - 'user__company__derived_bookings_0', - 'user__company__derived_bookings_1', - 'user__company__discrete_booking_value_p99', - 'user__company__double_counted_delayed_bookings', 'user__company__identity_verifications', - 'user__company__instant_booking_fraction_of_max_value', - 'user__company__instant_booking_value', - 'user__company__instant_booking_value_ratio', - 'user__company__instant_bookings', - 'user__company__instant_lux_booking_value_rate', - 'user__company__instant_plus_non_referred_bookings_pct', 'user__company__largest_listing', + 'user__company__listing__user__company__approximate_continuous_booking_value_p99', + 'user__company__listing__user__company__approximate_discrete_booking_value_p99', + 'user__company__listing__user__company__average_booking_value', + 'user__company__listing__user__company__average_instant_booking_value', + 'user__company__listing__user__company__bookers', + 'user__company__listing__user__company__booking_fees', + 'user__company__listing__user__company__booking_fees_per_booker', + 'user__company__listing__user__company__booking_payments', + 'user__company__listing__user__company__booking_value', + 'user__company__listing__user__company__booking_value_for_non_null_listing_id', + 'user__company__listing__user__company__booking_value_p99', + 'user__company__listing__user__company__booking_value_per_view', + 'user__company__listing__user__company__booking_value_sub_instant', + 'user__company__listing__user__company__booking_value_sub_instant_add_10', + 'user__company__listing__user__company__bookings', + 'user__company__listing__user__company__bookings_fill_nulls_with_0', + 'user__company__listing__user__company__bookings_fill_nulls_with_0_without_time_spine', + 'user__company__listing__user__company__bookings_join_to_time_spine', + 'user__company__listing__user__company__bookings_per_booker', + 'user__company__listing__user__company__bookings_per_dollar', + 'user__company__listing__user__company__bookings_per_view', + 'user__company__listing__user__company__derived_bookings_0', + 'user__company__listing__user__company__derived_bookings_1', + 'user__company__listing__user__company__discrete_booking_value_p99', + 'user__company__listing__user__company__double_counted_delayed_bookings', + 'user__company__listing__user__company__instant_booking_fraction_of_max_value', + 'user__company__listing__user__company__instant_booking_value', + 'user__company__listing__user__company__instant_booking_value_ratio', + 'user__company__listing__user__company__instant_bookings', + 'user__company__listing__user__company__instant_lux_booking_value_rate', + 'user__company__listing__user__company__instant_plus_non_referred_bookings_pct', + 'user__company__listing__user__company__lux_booking_fraction_of_max_value', + 'user__company__listing__user__company__lux_booking_value_rate_expr', + 'user__company__listing__user__company__max_booking_value', + 'user__company__listing__user__company__median_booking_value', + 'user__company__listing__user__company__min_booking_value', + 'user__company__listing__user__company__nested_fill_nulls_without_time_spine', + 'user__company__listing__user__company__non_referred_bookings_pct', + 'user__company__listing__user__company__referred_bookings', + 'user__company__listing__user__company__twice_bookings_fill_nulls_with_0_without_time_spine', + 'user__company__listing__user__company__views', + 'user__company__listing__user__company__views_times_booking_value', 'user__company__listings', - 'user__company__lux_booking_fraction_of_max_value', - 'user__company__lux_booking_value_rate_expr', 'user__company__lux_listings', - 'user__company__max_booking_value', - 'user__company__median_booking_value', - 'user__company__min_booking_value', - 'user__company__nested_fill_nulls_without_time_spine', - 'user__company__non_referred_bookings_pct', - 'user__company__referred_bookings', 'user__company__regional_starting_balance_ratios', 'user__company__revenue', 'user__company__revenue_all_time', 'user__company__smallest_listing', 'user__company__total_account_balance_first_day', - 'user__company__twice_bookings_fill_nulls_with_0_without_time_spine', - 'user__company__views', - 'user__company__views_times_booking_value', 'user__company__visit_buy_conversion_rate', 'user__company__visit_buy_conversion_rate_7days', 'user__company__visit_buy_conversion_rate_7days_fill_nulls_with_0', @@ -269,10 +247,6 @@ 'user__created_at__week', 'user__created_at__year', 'user__current_account_balance_by_user', - 'user__derived_bookings_0', - 'user__derived_bookings_1', - 'user__discrete_booking_value_p99', - 'user__double_counted_delayed_bookings', 'user__ds__day', 'user__ds__extract_day', 'user__ds__extract_dow', @@ -336,31 +310,57 @@ 'user__home_state', 'user__home_state_latest', 'user__identity_verifications', - 'user__instant_booking_fraction_of_max_value', - 'user__instant_booking_value', - 'user__instant_booking_value_ratio', - 'user__instant_bookings', - 'user__instant_lux_booking_value_rate', - 'user__instant_plus_non_referred_bookings_pct', 'user__largest_listing', + 'user__listing__user__approximate_continuous_booking_value_p99', + 'user__listing__user__approximate_discrete_booking_value_p99', + 'user__listing__user__average_booking_value', + 'user__listing__user__average_instant_booking_value', + 'user__listing__user__bookers', + 'user__listing__user__booking_fees', + 'user__listing__user__booking_fees_per_booker', + 'user__listing__user__booking_payments', + 'user__listing__user__booking_value', + 'user__listing__user__booking_value_for_non_null_listing_id', + 'user__listing__user__booking_value_p99', + 'user__listing__user__booking_value_per_view', + 'user__listing__user__booking_value_sub_instant', + 'user__listing__user__booking_value_sub_instant_add_10', + 'user__listing__user__bookings', + 'user__listing__user__bookings_fill_nulls_with_0', + 'user__listing__user__bookings_fill_nulls_with_0_without_time_spine', + 'user__listing__user__bookings_join_to_time_spine', + 'user__listing__user__bookings_per_booker', + 'user__listing__user__bookings_per_dollar', + 'user__listing__user__bookings_per_lux_listing_derived', + 'user__listing__user__bookings_per_view', + 'user__listing__user__derived_bookings_0', + 'user__listing__user__derived_bookings_1', + 'user__listing__user__discrete_booking_value_p99', + 'user__listing__user__double_counted_delayed_bookings', + 'user__listing__user__instant_booking_fraction_of_max_value', + 'user__listing__user__instant_booking_value', + 'user__listing__user__instant_booking_value_ratio', + 'user__listing__user__instant_bookings', + 'user__listing__user__instant_lux_booking_value_rate', + 'user__listing__user__instant_plus_non_referred_bookings_pct', + 'user__listing__user__lux_booking_fraction_of_max_value', + 'user__listing__user__lux_booking_value_rate_expr', + 'user__listing__user__max_booking_value', + 'user__listing__user__median_booking_value', + 'user__listing__user__min_booking_value', + 'user__listing__user__nested_fill_nulls_without_time_spine', + 'user__listing__user__non_referred_bookings_pct', + 'user__listing__user__referred_bookings', + 'user__listing__user__twice_bookings_fill_nulls_with_0_without_time_spine', + 'user__listing__user__views', + 'user__listing__user__views_times_booking_value', 'user__listings', - 'user__lux_booking_fraction_of_max_value', - 'user__lux_booking_value_rate_expr', 'user__lux_listings', - 'user__max_booking_value', - 'user__median_booking_value', - 'user__min_booking_value', - 'user__nested_fill_nulls_without_time_spine', - 'user__non_referred_bookings_pct', - 'user__referred_bookings', 'user__regional_starting_balance_ratios', 'user__revenue', 'user__revenue_all_time', 'user__smallest_listing', 'user__total_account_balance_first_day', - 'user__twice_bookings_fill_nulls_with_0_without_time_spine', - 'user__views', - 'user__views_times_booking_value', 'user__visit_buy_conversion_rate', 'user__visit_buy_conversion_rate_7days', 'user__visit_buy_conversion_rate_7days_fill_nulls_with_0', diff --git a/tests/snapshots/test_metric_filter_rendering.py/SqlQueryPlan/DuckDB/test_distinct_values_query_with_metric_filter__plan0.sql b/tests/snapshots/test_metric_filter_rendering.py/SqlQueryPlan/DuckDB/test_distinct_values_query_with_metric_filter__plan0.sql index e899374cbf..af2d1974cd 100644 --- a/tests/snapshots/test_metric_filter_rendering.py/SqlQueryPlan/DuckDB/test_distinct_values_query_with_metric_filter__plan0.sql +++ b/tests/snapshots/test_metric_filter_rendering.py/SqlQueryPlan/DuckDB/test_distinct_values_query_with_metric_filter__plan0.sql @@ -24,7 +24,7 @@ FROM ( FROM ***************************.dim_lux_listing_id_mapping lux_listing_mapping_src_28000 ) subq_4 FULL OUTER JOIN ( - -- Pass Only Elements: ['listing', 'bookings'] + -- Pass Only Elements: ['listing', 'listing__bookings'] SELECT subq_9.listing , subq_9.bookings diff --git a/tests/snapshots/test_metric_filter_rendering.py/SqlQueryPlan/DuckDB/test_distinct_values_query_with_metric_filter__plan0_optimized.sql b/tests/snapshots/test_metric_filter_rendering.py/SqlQueryPlan/DuckDB/test_distinct_values_query_with_metric_filter__plan0_optimized.sql index ceb44d1602..28223e439b 100644 --- a/tests/snapshots/test_metric_filter_rendering.py/SqlQueryPlan/DuckDB/test_distinct_values_query_with_metric_filter__plan0_optimized.sql +++ b/tests/snapshots/test_metric_filter_rendering.py/SqlQueryPlan/DuckDB/test_distinct_values_query_with_metric_filter__plan0_optimized.sql @@ -11,7 +11,7 @@ FROM ( FULL OUTER JOIN ( -- Aggregate Measures -- Compute Metrics via Expressions - -- Pass Only Elements: ['listing', 'bookings'] + -- Pass Only Elements: ['listing', 'listing__bookings'] SELECT listing , SUM(bookings) AS bookings diff --git a/tests/snapshots/test_metric_filter_rendering.py/SqlQueryPlan/DuckDB/test_filter_by_metric_in_same_semantic_model_as_queried_metric__plan0.sql b/tests/snapshots/test_metric_filter_rendering.py/SqlQueryPlan/DuckDB/test_filter_by_metric_in_same_semantic_model_as_queried_metric__plan0.sql index 65a3c59db6..2b315eab94 100644 --- a/tests/snapshots/test_metric_filter_rendering.py/SqlQueryPlan/DuckDB/test_filter_by_metric_in_same_semantic_model_as_queried_metric__plan0.sql +++ b/tests/snapshots/test_metric_filter_rendering.py/SqlQueryPlan/DuckDB/test_filter_by_metric_in_same_semantic_model_as_queried_metric__plan0.sql @@ -227,7 +227,7 @@ FROM ( ) subq_5 ) subq_6 LEFT OUTER JOIN ( - -- Pass Only Elements: ['guest', 'booking_value'] + -- Pass Only Elements: ['guest', 'guest__booking_value'] SELECT subq_11.guest , subq_11.booking_value diff --git a/tests/snapshots/test_metric_filter_rendering.py/SqlQueryPlan/DuckDB/test_filter_by_metric_in_same_semantic_model_as_queried_metric__plan0_optimized.sql b/tests/snapshots/test_metric_filter_rendering.py/SqlQueryPlan/DuckDB/test_filter_by_metric_in_same_semantic_model_as_queried_metric__plan0_optimized.sql index d7ee2ded1b..53c4da07c1 100644 --- a/tests/snapshots/test_metric_filter_rendering.py/SqlQueryPlan/DuckDB/test_filter_by_metric_in_same_semantic_model_as_queried_metric__plan0_optimized.sql +++ b/tests/snapshots/test_metric_filter_rendering.py/SqlQueryPlan/DuckDB/test_filter_by_metric_in_same_semantic_model_as_queried_metric__plan0_optimized.sql @@ -25,7 +25,7 @@ FROM ( -- Pass Only Elements: ['booking_value', 'guest'] -- Aggregate Measures -- Compute Metrics via Expressions - -- Pass Only Elements: ['guest', 'booking_value'] + -- Pass Only Elements: ['guest', 'guest__booking_value'] SELECT guest_id AS guest , SUM(booking_value) AS booking_value diff --git a/tests/snapshots/test_metric_filter_rendering.py/SqlQueryPlan/DuckDB/test_metric_filtered_by_itself__plan0.sql b/tests/snapshots/test_metric_filter_rendering.py/SqlQueryPlan/DuckDB/test_metric_filtered_by_itself__plan0.sql index 09749c68b5..503523e9cd 100644 --- a/tests/snapshots/test_metric_filter_rendering.py/SqlQueryPlan/DuckDB/test_metric_filtered_by_itself__plan0.sql +++ b/tests/snapshots/test_metric_filter_rendering.py/SqlQueryPlan/DuckDB/test_metric_filtered_by_itself__plan0.sql @@ -227,7 +227,7 @@ FROM ( ) subq_5 ) subq_6 LEFT OUTER JOIN ( - -- Pass Only Elements: ['guest', 'bookers'] + -- Pass Only Elements: ['guest', 'guest__bookers'] SELECT subq_11.guest , subq_11.bookers diff --git a/tests/snapshots/test_metric_filter_rendering.py/SqlQueryPlan/DuckDB/test_metric_filtered_by_itself__plan0_optimized.sql b/tests/snapshots/test_metric_filter_rendering.py/SqlQueryPlan/DuckDB/test_metric_filtered_by_itself__plan0_optimized.sql index eb7a693290..07a356a39c 100644 --- a/tests/snapshots/test_metric_filter_rendering.py/SqlQueryPlan/DuckDB/test_metric_filtered_by_itself__plan0_optimized.sql +++ b/tests/snapshots/test_metric_filter_rendering.py/SqlQueryPlan/DuckDB/test_metric_filtered_by_itself__plan0_optimized.sql @@ -25,7 +25,7 @@ FROM ( -- Pass Only Elements: ['bookers', 'guest'] -- Aggregate Measures -- Compute Metrics via Expressions - -- Pass Only Elements: ['guest', 'bookers'] + -- Pass Only Elements: ['guest', 'guest__bookers'] SELECT guest_id AS guest , COUNT(DISTINCT guest_id) AS bookers diff --git a/tests/snapshots/test_metric_filter_rendering.py/SqlQueryPlan/DuckDB/test_metric_with_metric_in_where_filter__plan0.sql b/tests/snapshots/test_metric_filter_rendering.py/SqlQueryPlan/DuckDB/test_metric_with_metric_in_where_filter__plan0.sql index 62adc84823..575a247d37 100644 --- a/tests/snapshots/test_metric_filter_rendering.py/SqlQueryPlan/DuckDB/test_metric_with_metric_in_where_filter__plan0.sql +++ b/tests/snapshots/test_metric_filter_rendering.py/SqlQueryPlan/DuckDB/test_metric_with_metric_in_where_filter__plan0.sql @@ -171,7 +171,7 @@ FROM ( ) subq_5 ) subq_6 LEFT OUTER JOIN ( - -- Pass Only Elements: ['listing', 'bookings'] + -- Pass Only Elements: ['listing', 'listing__bookings'] SELECT subq_11.listing , subq_11.bookings diff --git a/tests/snapshots/test_metric_filter_rendering.py/SqlQueryPlan/DuckDB/test_metric_with_metric_in_where_filter__plan0_optimized.sql b/tests/snapshots/test_metric_filter_rendering.py/SqlQueryPlan/DuckDB/test_metric_with_metric_in_where_filter__plan0_optimized.sql index 903c2101af..1ad72fa0ef 100644 --- a/tests/snapshots/test_metric_filter_rendering.py/SqlQueryPlan/DuckDB/test_metric_with_metric_in_where_filter__plan0_optimized.sql +++ b/tests/snapshots/test_metric_filter_rendering.py/SqlQueryPlan/DuckDB/test_metric_with_metric_in_where_filter__plan0_optimized.sql @@ -25,7 +25,7 @@ FROM ( LEFT OUTER JOIN ( -- Aggregate Measures -- Compute Metrics via Expressions - -- Pass Only Elements: ['listing', 'bookings'] + -- Pass Only Elements: ['listing', 'listing__bookings'] SELECT listing , SUM(bookings) AS bookings diff --git a/tests/snapshots/test_metric_filter_rendering.py/SqlQueryPlan/DuckDB/test_query_with_cumulative_metric_in_where_filter__plan0.sql b/tests/snapshots/test_metric_filter_rendering.py/SqlQueryPlan/DuckDB/test_query_with_cumulative_metric_in_where_filter__plan0.sql index 6b74b95a17..3a031bcabc 100644 --- a/tests/snapshots/test_metric_filter_rendering.py/SqlQueryPlan/DuckDB/test_query_with_cumulative_metric_in_where_filter__plan0.sql +++ b/tests/snapshots/test_metric_filter_rendering.py/SqlQueryPlan/DuckDB/test_query_with_cumulative_metric_in_where_filter__plan0.sql @@ -164,7 +164,7 @@ FROM ( ) subq_5 ) subq_6 LEFT OUTER JOIN ( - -- Pass Only Elements: ['user', 'revenue_all_time'] + -- Pass Only Elements: ['user', 'user__revenue_all_time'] SELECT subq_11.user , subq_11.revenue_all_time diff --git a/tests/snapshots/test_metric_filter_rendering.py/SqlQueryPlan/DuckDB/test_query_with_cumulative_metric_in_where_filter__plan0_optimized.sql b/tests/snapshots/test_metric_filter_rendering.py/SqlQueryPlan/DuckDB/test_query_with_cumulative_metric_in_where_filter__plan0_optimized.sql index a792c0fd8c..ca59324e35 100644 --- a/tests/snapshots/test_metric_filter_rendering.py/SqlQueryPlan/DuckDB/test_query_with_cumulative_metric_in_where_filter__plan0_optimized.sql +++ b/tests/snapshots/test_metric_filter_rendering.py/SqlQueryPlan/DuckDB/test_query_with_cumulative_metric_in_where_filter__plan0_optimized.sql @@ -25,7 +25,7 @@ FROM ( -- Pass Only Elements: ['txn_revenue', 'user'] -- Aggregate Measures -- Compute Metrics via Expressions - -- Pass Only Elements: ['user', 'revenue_all_time'] + -- Pass Only Elements: ['user', 'user__revenue_all_time'] SELECT user_id AS user , SUM(revenue) AS revenue_all_time diff --git a/tests/snapshots/test_metric_filter_rendering.py/SqlQueryPlan/DuckDB/test_query_with_derived_metric_in_where_filter__plan0.sql b/tests/snapshots/test_metric_filter_rendering.py/SqlQueryPlan/DuckDB/test_query_with_derived_metric_in_where_filter__plan0.sql index 77c1a58da0..c0386038eb 100644 --- a/tests/snapshots/test_metric_filter_rendering.py/SqlQueryPlan/DuckDB/test_query_with_derived_metric_in_where_filter__plan0.sql +++ b/tests/snapshots/test_metric_filter_rendering.py/SqlQueryPlan/DuckDB/test_query_with_derived_metric_in_where_filter__plan0.sql @@ -164,7 +164,7 @@ FROM ( ) subq_12 ) subq_13 LEFT OUTER JOIN ( - -- Pass Only Elements: ['listing', 'views_times_booking_value'] + -- Pass Only Elements: ['listing', 'listing__views_times_booking_value'] SELECT subq_25.listing , subq_25.views_times_booking_value diff --git a/tests/snapshots/test_metric_filter_rendering.py/SqlQueryPlan/DuckDB/test_query_with_derived_metric_in_where_filter__plan0_optimized.sql b/tests/snapshots/test_metric_filter_rendering.py/SqlQueryPlan/DuckDB/test_query_with_derived_metric_in_where_filter__plan0_optimized.sql index 26cfeb4e15..d91def71f1 100644 --- a/tests/snapshots/test_metric_filter_rendering.py/SqlQueryPlan/DuckDB/test_query_with_derived_metric_in_where_filter__plan0_optimized.sql +++ b/tests/snapshots/test_metric_filter_rendering.py/SqlQueryPlan/DuckDB/test_query_with_derived_metric_in_where_filter__plan0_optimized.sql @@ -21,7 +21,7 @@ FROM ( ) subq_34 LEFT OUTER JOIN ( -- Compute Metrics via Expressions - -- Pass Only Elements: ['listing', 'views_times_booking_value'] + -- Pass Only Elements: ['listing', 'listing__views_times_booking_value'] SELECT listing , booking_value * views AS views_times_booking_value diff --git a/tests/snapshots/test_metric_filter_rendering.py/SqlQueryPlan/DuckDB/test_query_with_multiple_metrics_in_filter__plan0.sql b/tests/snapshots/test_metric_filter_rendering.py/SqlQueryPlan/DuckDB/test_query_with_multiple_metrics_in_filter__plan0.sql index 7216cec41a..c8ea694bf4 100644 --- a/tests/snapshots/test_metric_filter_rendering.py/SqlQueryPlan/DuckDB/test_query_with_multiple_metrics_in_filter__plan0.sql +++ b/tests/snapshots/test_metric_filter_rendering.py/SqlQueryPlan/DuckDB/test_query_with_multiple_metrics_in_filter__plan0.sql @@ -167,7 +167,7 @@ FROM ( ) subq_9 ) subq_10 LEFT OUTER JOIN ( - -- Pass Only Elements: ['listing', 'bookings'] + -- Pass Only Elements: ['listing', 'listing__bookings'] SELECT subq_15.listing , subq_15.bookings @@ -390,7 +390,7 @@ FROM ( ON subq_10.listing = subq_16.listing LEFT OUTER JOIN ( - -- Pass Only Elements: ['listing', 'bookers'] + -- Pass Only Elements: ['listing', 'listing__bookers'] SELECT subq_21.listing , subq_21.bookers diff --git a/tests/snapshots/test_metric_filter_rendering.py/SqlQueryPlan/DuckDB/test_query_with_multiple_metrics_in_filter__plan0_optimized.sql b/tests/snapshots/test_metric_filter_rendering.py/SqlQueryPlan/DuckDB/test_query_with_multiple_metrics_in_filter__plan0_optimized.sql index f79437fa1d..746675a7dc 100644 --- a/tests/snapshots/test_metric_filter_rendering.py/SqlQueryPlan/DuckDB/test_query_with_multiple_metrics_in_filter__plan0_optimized.sql +++ b/tests/snapshots/test_metric_filter_rendering.py/SqlQueryPlan/DuckDB/test_query_with_multiple_metrics_in_filter__plan0_optimized.sql @@ -23,7 +23,7 @@ FROM ( LEFT OUTER JOIN ( -- Aggregate Measures -- Compute Metrics via Expressions - -- Pass Only Elements: ['listing', 'bookings'] + -- Pass Only Elements: ['listing', 'listing__bookings'] SELECT listing , SUM(bookings) AS bookings @@ -47,7 +47,7 @@ FROM ( -- Pass Only Elements: ['bookers', 'listing'] -- Aggregate Measures -- Compute Metrics via Expressions - -- Pass Only Elements: ['listing', 'bookers'] + -- Pass Only Elements: ['listing', 'listing__bookers'] SELECT listing_id AS listing , COUNT(DISTINCT guest_id) AS bookers diff --git a/tests/snapshots/test_metric_filter_rendering.py/SqlQueryPlan/DuckDB/test_query_with_ratio_metric_in_where_filter__plan0.sql b/tests/snapshots/test_metric_filter_rendering.py/SqlQueryPlan/DuckDB/test_query_with_ratio_metric_in_where_filter__plan0.sql index b0c7913eb8..83ffdd692a 100644 --- a/tests/snapshots/test_metric_filter_rendering.py/SqlQueryPlan/DuckDB/test_query_with_ratio_metric_in_where_filter__plan0.sql +++ b/tests/snapshots/test_metric_filter_rendering.py/SqlQueryPlan/DuckDB/test_query_with_ratio_metric_in_where_filter__plan0.sql @@ -164,7 +164,7 @@ FROM ( ) subq_12 ) subq_13 LEFT OUTER JOIN ( - -- Pass Only Elements: ['listing', 'bookings_per_booker'] + -- Pass Only Elements: ['listing', 'listing__bookings_per_booker'] SELECT subq_25.listing , subq_25.bookings_per_booker diff --git a/tests/snapshots/test_metric_filter_rendering.py/SqlQueryPlan/DuckDB/test_query_with_simple_metric_in_where_filter__plan0.sql b/tests/snapshots/test_metric_filter_rendering.py/SqlQueryPlan/DuckDB/test_query_with_simple_metric_in_where_filter__plan0.sql index 568e713172..e81b40e399 100644 --- a/tests/snapshots/test_metric_filter_rendering.py/SqlQueryPlan/DuckDB/test_query_with_simple_metric_in_where_filter__plan0.sql +++ b/tests/snapshots/test_metric_filter_rendering.py/SqlQueryPlan/DuckDB/test_query_with_simple_metric_in_where_filter__plan0.sql @@ -164,7 +164,7 @@ FROM ( ) subq_5 ) subq_6 LEFT OUTER JOIN ( - -- Pass Only Elements: ['listing', 'bookings'] + -- Pass Only Elements: ['listing', 'listing__bookings'] SELECT subq_11.listing , subq_11.bookings diff --git a/tests/snapshots/test_metric_filter_rendering.py/SqlQueryPlan/DuckDB/test_query_with_simple_metric_in_where_filter__plan0_optimized.sql b/tests/snapshots/test_metric_filter_rendering.py/SqlQueryPlan/DuckDB/test_query_with_simple_metric_in_where_filter__plan0_optimized.sql index 15f82749c5..d453137357 100644 --- a/tests/snapshots/test_metric_filter_rendering.py/SqlQueryPlan/DuckDB/test_query_with_simple_metric_in_where_filter__plan0_optimized.sql +++ b/tests/snapshots/test_metric_filter_rendering.py/SqlQueryPlan/DuckDB/test_query_with_simple_metric_in_where_filter__plan0_optimized.sql @@ -22,7 +22,7 @@ FROM ( LEFT OUTER JOIN ( -- Aggregate Measures -- Compute Metrics via Expressions - -- Pass Only Elements: ['listing', 'bookings'] + -- Pass Only Elements: ['listing', 'listing__bookings'] SELECT listing , SUM(bookings) AS bookings diff --git a/tests/specs/patterns/test_entity_link_pattern.py b/tests/specs/patterns/test_entity_link_pattern.py index 73e5fc2562..e83ba6e5bd 100644 --- a/tests/specs/patterns/test_entity_link_pattern.py +++ b/tests/specs/patterns/test_entity_link_pattern.py @@ -56,7 +56,7 @@ def specs() -> Sequence[LinkableInstanceSpec]: # noqa: D103 GroupByMetricSpec( element_name="bookings", entity_links=(EntityReference(element_name="listing"),), - metric_subquery_entity_links=(), + metric_subquery_entity_links=(EntityReference(element_name="listing"),), ), ) @@ -131,7 +131,7 @@ def test_group_by_metric_match(specs: Sequence[LinkableInstanceSpec]) -> None: GroupByMetricSpec( element_name="bookings", entity_links=(EntityReference(element_name="listing"),), - metric_subquery_entity_links=(), + metric_subquery_entity_links=(EntityReference(element_name="listing"),), ), ) diff --git a/tests/specs/patterns/test_typed_patterns.py b/tests/specs/patterns/test_typed_patterns.py index d0625cd741..78b4017306 100644 --- a/tests/specs/patterns/test_typed_patterns.py +++ b/tests/specs/patterns/test_typed_patterns.py @@ -60,7 +60,7 @@ def specs() -> Sequence[LinkableInstanceSpec]: # noqa: D103 GroupByMetricSpec( element_name="bookings", entity_links=(EntityReference(element_name="listing"),), - metric_subquery_entity_links=(), + metric_subquery_entity_links=(EntityReference(element_name="listing"),), ), ) @@ -158,6 +158,6 @@ def test_group_by_metric_pattern(specs: Sequence[LinkableInstanceSpec]) -> None: GroupByMetricSpec( element_name="bookings", entity_links=(EntityReference("listing"),), - metric_subquery_entity_links=(), + metric_subquery_entity_links=(EntityReference(element_name="listing"),), ), ) diff --git a/tests/test_specs.py b/tests/test_specs.py index 27c3a26be6..0ee5cc52bc 100644 --- a/tests/test_specs.py +++ b/tests/test_specs.py @@ -145,7 +145,7 @@ def spec_set() -> InstanceSpecSet: # noqa: D103 GroupByMetricSpec( element_name="bookings", entity_links=(EntityReference(element_name="listing_id"),), - metric_subquery_entity_links=(), + metric_subquery_entity_links=(EntityReference(element_name="listing_id"),), ), ), ) @@ -166,7 +166,7 @@ def test_spec_set_linkable_specs(spec_set: InstanceSpecSet) -> None: # noqa: D1 GroupByMetricSpec( element_name="bookings", entity_links=(EntityReference(element_name="listing_id"),), - metric_subquery_entity_links=(), + metric_subquery_entity_links=(EntityReference(element_name="listing_id"),), ), } @@ -190,7 +190,7 @@ def test_spec_set_all_specs(spec_set: InstanceSpecSet) -> None: # noqa: D103 GroupByMetricSpec( element_name="bookings", entity_links=(EntityReference(element_name="listing_id"),), - metric_subquery_entity_links=(), + metric_subquery_entity_links=(EntityReference(element_name="listing_id"),), ), } From e6b9b7bc4b6b9f77a82c505ac128a9aad93b9489 Mon Sep 17 00:00:00 2001 From: Courtney Holcomb Date: Thu, 25 Apr 2024 17:31:14 -0700 Subject: [PATCH 31/37] Dedupe qualified name for GroupByMetricSpecs --- metricflow/specs/specs.py | 17 + ...linkable_element_set_as_spec_set__set0.txt | 2 +- ...elements_for_no_metrics_query__result0.txt | 1079 +++++++++++++---- 3 files changed, 856 insertions(+), 242 deletions(-) diff --git a/metricflow/specs/specs.py b/metricflow/specs/specs.py index e51b525da2..546f7c0e71 100644 --- a/metricflow/specs/specs.py +++ b/metricflow/specs/specs.py @@ -294,6 +294,23 @@ def metric_subquery_entity_spec(self) -> EntitySpec: entity_links=self.metric_subquery_entity_links[:-1], ) + @property + def qualified_name(self) -> str: + """Element name prefixed with entity links. + + If same entity links are used in inner & outer query, use standard qualified name (country__bookings). + Else, specify both sets of entity links (listing__country__user__country__bookings). + """ + if self.entity_links == self.metric_subquery_entity_links: + entity_links = self.entity_links + else: + entity_links = self.entity_links + self.metric_subquery_entity_links + + return StructuredLinkableSpecName( + entity_link_names=tuple(entity_link.element_name for entity_link in entity_links), + element_name=self.element_name, + ).qualified_name + def __eq__(self, other: Any) -> bool: # type: ignore[misc] # noqa: D105 if not isinstance(other, GroupByMetricSpec): return False diff --git a/tests/snapshots/test_linkable_spec_resolver.py/list/test_linkable_element_set_as_spec_set__set0.txt b/tests/snapshots/test_linkable_spec_resolver.py/list/test_linkable_element_set_as_spec_set__set0.txt index b01f907f15..43779aedd4 100644 --- a/tests/snapshots/test_linkable_spec_resolver.py/list/test_linkable_element_set_as_spec_set__set0.txt +++ b/tests/snapshots/test_linkable_spec_resolver.py/list/test_linkable_element_set_as_spec_set__set0.txt @@ -165,7 +165,6 @@ 'metric_time__year', 'user', 'user__active_listings', - 'user__bookings_per_listing', 'user__company', 'user__company__active_listings', 'user__company__current_account_balance_by_user', @@ -331,6 +330,7 @@ 'user__listing__user__bookings_join_to_time_spine', 'user__listing__user__bookings_per_booker', 'user__listing__user__bookings_per_dollar', + 'user__listing__user__bookings_per_listing', 'user__listing__user__bookings_per_lux_listing_derived', 'user__listing__user__bookings_per_view', 'user__listing__user__derived_bookings_0', diff --git a/tests/snapshots/test_semantic_model_container.py/tuple/test_linkable_elements_for_no_metrics_query__result0.txt b/tests/snapshots/test_semantic_model_container.py/tuple/test_linkable_elements_for_no_metrics_query__result0.txt index 5e869224b7..5f839385f5 100644 --- a/tests/snapshots/test_semantic_model_container.py/tuple/test_linkable_elements_for_no_metrics_query__result0.txt +++ b/tests/snapshots/test_semantic_model_container.py/tuple/test_linkable_elements_for_no_metrics_query__result0.txt @@ -43,83 +43,66 @@ 'buy__session_id', 'buy__user', 'company', - 'company__active_listings', - 'company__approximate_continuous_booking_value_p99', - 'company__approximate_discrete_booking_value_p99', - 'company__average_booking_value', - 'company__average_instant_booking_value', - 'company__bookers', - 'company__booking_fees', - 'company__booking_fees_last_week_per_booker_this_week', - 'company__booking_fees_per_booker', - 'company__booking_fees_since_start_of_month', - 'company__booking_payments', - 'company__booking_value', - 'company__booking_value_for_non_null_listing_id', - 'company__booking_value_p99', - 'company__booking_value_per_view', - 'company__booking_value_sub_instant', - 'company__booking_value_sub_instant_add_10', - 'company__bookings', - 'company__bookings_5_day_lag', - 'company__bookings_at_start_of_month', - 'company__bookings_fill_nulls_with_0', - 'company__bookings_fill_nulls_with_0_without_time_spine', - 'company__bookings_growth_2_weeks', - 'company__bookings_growth_2_weeks_fill_nulls_with_0', - 'company__bookings_growth_2_weeks_fill_nulls_with_0_for_non_offset', - 'company__bookings_growth_since_start_of_month', - 'company__bookings_join_to_time_spine', - 'company__bookings_month_start_compared_to_1_month_prior', - 'company__bookings_offset_once', - 'company__bookings_offset_twice', - 'company__bookings_per_booker', - 'company__bookings_per_dollar', - 'company__bookings_per_view', 'company__company_name', - 'company__current_account_balance_by_user', - 'company__derived_bookings_0', - 'company__derived_bookings_1', - 'company__discrete_booking_value_p99', - 'company__double_counted_delayed_bookings', - 'company__every_2_days_bookers_2_days_ago', - 'company__every_two_days_bookers', - 'company__every_two_days_bookers_fill_nulls_with_0', - 'company__identity_verifications', - 'company__instant_booking_fraction_of_max_value', - 'company__instant_booking_value', - 'company__instant_booking_value_ratio', - 'company__instant_bookings', - 'company__instant_lux_booking_value_rate', - 'company__instant_plus_non_referred_bookings_pct', - 'company__largest_listing', - 'company__listings', - 'company__lux_booking_fraction_of_max_value', - 'company__lux_booking_value_rate_expr', - 'company__lux_listings', - 'company__max_booking_value', - 'company__median_booking_value', - 'company__min_booking_value', - 'company__nested_fill_nulls_without_time_spine', - 'company__non_referred_bookings_pct', - 'company__referred_bookings', - 'company__regional_starting_balance_ratios', - 'company__revenue', - 'company__revenue_all_time', - 'company__revenue_mtd', - 'company__smallest_listing', - 'company__total_account_balance_first_day', - 'company__trailing_2_months_revenue', - 'company__trailing_2_months_revenue_sub_10', - 'company__twice_bookings_fill_nulls_with_0_without_time_spine', + 'company__listing__user__company__approximate_continuous_booking_value_p99', + 'company__listing__user__company__approximate_discrete_booking_value_p99', + 'company__listing__user__company__average_booking_value', + 'company__listing__user__company__average_instant_booking_value', + 'company__listing__user__company__bookers', + 'company__listing__user__company__booking_fees', + 'company__listing__user__company__booking_fees_per_booker', + 'company__listing__user__company__booking_payments', + 'company__listing__user__company__booking_value', + 'company__listing__user__company__booking_value_for_non_null_listing_id', + 'company__listing__user__company__booking_value_p99', + 'company__listing__user__company__booking_value_per_view', + 'company__listing__user__company__booking_value_sub_instant', + 'company__listing__user__company__booking_value_sub_instant_add_10', + 'company__listing__user__company__bookings', + 'company__listing__user__company__bookings_fill_nulls_with_0', + 'company__listing__user__company__bookings_fill_nulls_with_0_without_time_spine', + 'company__listing__user__company__bookings_join_to_time_spine', + 'company__listing__user__company__bookings_per_booker', + 'company__listing__user__company__bookings_per_dollar', + 'company__listing__user__company__bookings_per_view', + 'company__listing__user__company__derived_bookings_0', + 'company__listing__user__company__derived_bookings_1', + 'company__listing__user__company__discrete_booking_value_p99', + 'company__listing__user__company__double_counted_delayed_bookings', + 'company__listing__user__company__instant_booking_fraction_of_max_value', + 'company__listing__user__company__instant_booking_value', + 'company__listing__user__company__instant_booking_value_ratio', + 'company__listing__user__company__instant_bookings', + 'company__listing__user__company__instant_lux_booking_value_rate', + 'company__listing__user__company__instant_plus_non_referred_bookings_pct', + 'company__listing__user__company__lux_booking_fraction_of_max_value', + 'company__listing__user__company__lux_booking_value_rate_expr', + 'company__listing__user__company__max_booking_value', + 'company__listing__user__company__median_booking_value', + 'company__listing__user__company__min_booking_value', + 'company__listing__user__company__nested_fill_nulls_without_time_spine', + 'company__listing__user__company__non_referred_bookings_pct', + 'company__listing__user__company__referred_bookings', + 'company__listing__user__company__twice_bookings_fill_nulls_with_0_without_time_spine', + 'company__listing__user__company__views', + 'company__listing__user__company__views_times_booking_value', 'company__user', - 'company__views', - 'company__views_times_booking_value', - 'company__visit_buy_conversion_rate', - 'company__visit_buy_conversion_rate_7days', - 'company__visit_buy_conversion_rate_7days_fill_nulls_with_0', - 'company__visit_buy_conversion_rate_by_session', - 'company__visit_buy_conversions', + 'company__user__company__active_listings', + 'company__user__company__current_account_balance_by_user', + 'company__user__company__identity_verifications', + 'company__user__company__largest_listing', + 'company__user__company__listings', + 'company__user__company__lux_listings', + 'company__user__company__regional_starting_balance_ratios', + 'company__user__company__revenue', + 'company__user__company__revenue_all_time', + 'company__user__company__smallest_listing', + 'company__user__company__total_account_balance_first_day', + 'company__user__company__visit_buy_conversion_rate', + 'company__user__company__visit_buy_conversion_rate_7days', + 'company__user__company__visit_buy_conversion_rate_7days_fill_nulls_with_0', + 'company__user__company__visit_buy_conversion_rate_by_session', + 'company__user__company__visit_buy_conversions', 'guest', 'guest__approximate_continuous_booking_value_p99', 'guest__approximate_discrete_booking_value_p99', @@ -127,9 +110,7 @@ 'guest__average_instant_booking_value', 'guest__bookers', 'guest__booking_fees', - 'guest__booking_fees_last_week_per_booker_this_week', 'guest__booking_fees_per_booker', - 'guest__booking_fees_since_start_of_month', 'guest__booking_payments', 'guest__booking_value', 'guest__booking_value_for_non_null_listing_id', @@ -137,27 +118,15 @@ 'guest__booking_value_sub_instant', 'guest__booking_value_sub_instant_add_10', 'guest__bookings', - 'guest__bookings_5_day_lag', - 'guest__bookings_at_start_of_month', 'guest__bookings_fill_nulls_with_0', 'guest__bookings_fill_nulls_with_0_without_time_spine', - 'guest__bookings_growth_2_weeks', - 'guest__bookings_growth_2_weeks_fill_nulls_with_0', - 'guest__bookings_growth_2_weeks_fill_nulls_with_0_for_non_offset', - 'guest__bookings_growth_since_start_of_month', 'guest__bookings_join_to_time_spine', - 'guest__bookings_month_start_compared_to_1_month_prior', - 'guest__bookings_offset_once', - 'guest__bookings_offset_twice', 'guest__bookings_per_booker', 'guest__bookings_per_dollar', 'guest__derived_bookings_0', 'guest__derived_bookings_1', 'guest__discrete_booking_value_p99', 'guest__double_counted_delayed_bookings', - 'guest__every_2_days_bookers_2_days_ago', - 'guest__every_two_days_bookers', - 'guest__every_two_days_bookers_fill_nulls_with_0', 'guest__instant_booking_fraction_of_max_value', 'guest__instant_booking_value', 'guest__instant_booking_value_ratio', @@ -180,9 +149,7 @@ 'host__average_instant_booking_value', 'host__bookers', 'host__booking_fees', - 'host__booking_fees_last_week_per_booker_this_week', 'host__booking_fees_per_booker', - 'host__booking_fees_since_start_of_month', 'host__booking_payments', 'host__booking_value', 'host__booking_value_for_non_null_listing_id', @@ -190,27 +157,15 @@ 'host__booking_value_sub_instant', 'host__booking_value_sub_instant_add_10', 'host__bookings', - 'host__bookings_5_day_lag', - 'host__bookings_at_start_of_month', 'host__bookings_fill_nulls_with_0', 'host__bookings_fill_nulls_with_0_without_time_spine', - 'host__bookings_growth_2_weeks', - 'host__bookings_growth_2_weeks_fill_nulls_with_0', - 'host__bookings_growth_2_weeks_fill_nulls_with_0_for_non_offset', - 'host__bookings_growth_since_start_of_month', 'host__bookings_join_to_time_spine', - 'host__bookings_month_start_compared_to_1_month_prior', - 'host__bookings_offset_once', - 'host__bookings_offset_twice', 'host__bookings_per_booker', 'host__bookings_per_dollar', 'host__derived_bookings_0', 'host__derived_bookings_1', 'host__discrete_booking_value_p99', 'host__double_counted_delayed_bookings', - 'host__every_2_days_bookers_2_days_ago', - 'host__every_two_days_bookers', - 'host__every_two_days_bookers_fill_nulls_with_0', 'host__instant_booking_fraction_of_max_value', 'host__instant_booking_value', 'host__instant_booking_value_ratio', @@ -228,40 +183,101 @@ 'host__twice_bookings_fill_nulls_with_0_without_time_spine', 'listing', 'listing__active_listings', + 'listing__active_listings', + 'listing__active_listings', + 'listing__active_listings', + 'listing__approximate_continuous_booking_value_p99', + 'listing__approximate_continuous_booking_value_p99', 'listing__approximate_continuous_booking_value_p99', + 'listing__approximate_continuous_booking_value_p99', + 'listing__approximate_discrete_booking_value_p99', + 'listing__approximate_discrete_booking_value_p99', 'listing__approximate_discrete_booking_value_p99', + 'listing__approximate_discrete_booking_value_p99', + 'listing__average_booking_value', 'listing__average_booking_value', + 'listing__average_booking_value', + 'listing__average_booking_value', + 'listing__average_instant_booking_value', + 'listing__average_instant_booking_value', + 'listing__average_instant_booking_value', 'listing__average_instant_booking_value', 'listing__bookers', + 'listing__bookers', + 'listing__bookers', + 'listing__bookers', + 'listing__booking_fees', 'listing__booking_fees', - 'listing__booking_fees_last_week_per_booker_this_week', + 'listing__booking_fees', + 'listing__booking_fees', + 'listing__booking_fees_per_booker', + 'listing__booking_fees_per_booker', + 'listing__booking_fees_per_booker', 'listing__booking_fees_per_booker', - 'listing__booking_fees_since_start_of_month', 'listing__booking_payments', + 'listing__booking_payments', + 'listing__booking_payments', + 'listing__booking_payments', + 'listing__booking_value', 'listing__booking_value', + 'listing__booking_value', + 'listing__booking_value', + 'listing__booking_value_for_non_null_listing_id', + 'listing__booking_value_for_non_null_listing_id', + 'listing__booking_value_for_non_null_listing_id', 'listing__booking_value_for_non_null_listing_id', 'listing__booking_value_p99', + 'listing__booking_value_p99', + 'listing__booking_value_p99', + 'listing__booking_value_p99', + 'listing__booking_value_per_view', 'listing__booking_value_per_view', + 'listing__booking_value_per_view', + 'listing__booking_value_per_view', + 'listing__booking_value_sub_instant', + 'listing__booking_value_sub_instant', + 'listing__booking_value_sub_instant', 'listing__booking_value_sub_instant', 'listing__booking_value_sub_instant_add_10', + 'listing__booking_value_sub_instant_add_10', + 'listing__booking_value_sub_instant_add_10', + 'listing__booking_value_sub_instant_add_10', + 'listing__bookings', 'listing__bookings', - 'listing__bookings_5_day_lag', - 'listing__bookings_at_start_of_month', + 'listing__bookings', + 'listing__bookings', + 'listing__bookings_fill_nulls_with_0', + 'listing__bookings_fill_nulls_with_0', + 'listing__bookings_fill_nulls_with_0', 'listing__bookings_fill_nulls_with_0', 'listing__bookings_fill_nulls_with_0_without_time_spine', - 'listing__bookings_growth_2_weeks', - 'listing__bookings_growth_2_weeks_fill_nulls_with_0', - 'listing__bookings_growth_2_weeks_fill_nulls_with_0_for_non_offset', - 'listing__bookings_growth_since_start_of_month', + 'listing__bookings_fill_nulls_with_0_without_time_spine', + 'listing__bookings_fill_nulls_with_0_without_time_spine', + 'listing__bookings_fill_nulls_with_0_without_time_spine', + 'listing__bookings_join_to_time_spine', 'listing__bookings_join_to_time_spine', - 'listing__bookings_month_start_compared_to_1_month_prior', - 'listing__bookings_offset_once', - 'listing__bookings_offset_twice', + 'listing__bookings_join_to_time_spine', + 'listing__bookings_join_to_time_spine', + 'listing__bookings_per_booker', + 'listing__bookings_per_booker', + 'listing__bookings_per_booker', 'listing__bookings_per_booker', 'listing__bookings_per_dollar', + 'listing__bookings_per_dollar', + 'listing__bookings_per_dollar', + 'listing__bookings_per_dollar', + 'listing__bookings_per_listing', 'listing__bookings_per_listing', + 'listing__bookings_per_listing', + 'listing__bookings_per_listing', + 'listing__bookings_per_lux_listing_derived', + 'listing__bookings_per_lux_listing_derived', + 'listing__bookings_per_lux_listing_derived', 'listing__bookings_per_lux_listing_derived', 'listing__bookings_per_view', + 'listing__bookings_per_view', + 'listing__bookings_per_view', + 'listing__bookings_per_view', 'listing__capacity_latest', 'listing__country_latest', 'listing__created_at__day', @@ -272,8 +288,20 @@ 'listing__created_at__extract_quarter', 'listing__created_at__extract_year', 'listing__derived_bookings_0', + 'listing__derived_bookings_0', + 'listing__derived_bookings_0', + 'listing__derived_bookings_0', + 'listing__derived_bookings_1', + 'listing__derived_bookings_1', + 'listing__derived_bookings_1', 'listing__derived_bookings_1', 'listing__discrete_booking_value_p99', + 'listing__discrete_booking_value_p99', + 'listing__discrete_booking_value_p99', + 'listing__discrete_booking_value_p99', + 'listing__double_counted_delayed_bookings', + 'listing__double_counted_delayed_bookings', + 'listing__double_counted_delayed_bookings', 'listing__double_counted_delayed_bookings', 'listing__ds__day', 'listing__ds__extract_day', @@ -282,97 +310,143 @@ 'listing__ds__extract_month', 'listing__ds__extract_quarter', 'listing__ds__extract_year', - 'listing__every_2_days_bookers_2_days_ago', - 'listing__every_two_days_bookers', - 'listing__every_two_days_bookers_fill_nulls_with_0', 'listing__instant_booking_fraction_of_max_value', + 'listing__instant_booking_fraction_of_max_value', + 'listing__instant_booking_fraction_of_max_value', + 'listing__instant_booking_fraction_of_max_value', + 'listing__instant_booking_value', 'listing__instant_booking_value', + 'listing__instant_booking_value', + 'listing__instant_booking_value', + 'listing__instant_booking_value_ratio', + 'listing__instant_booking_value_ratio', 'listing__instant_booking_value_ratio', + 'listing__instant_booking_value_ratio', + 'listing__instant_bookings', + 'listing__instant_bookings', 'listing__instant_bookings', + 'listing__instant_bookings', + 'listing__instant_lux_booking_value_rate', 'listing__instant_lux_booking_value_rate', + 'listing__instant_lux_booking_value_rate', + 'listing__instant_lux_booking_value_rate', + 'listing__instant_plus_non_referred_bookings_pct', + 'listing__instant_plus_non_referred_bookings_pct', + 'listing__instant_plus_non_referred_bookings_pct', 'listing__instant_plus_non_referred_bookings_pct', 'listing__is_lux_latest', 'listing__largest_listing', + 'listing__largest_listing', + 'listing__largest_listing', + 'listing__largest_listing', + 'listing__listings', 'listing__listings', + 'listing__listings', + 'listing__listings', + 'listing__lux_booking_fraction_of_max_value', + 'listing__lux_booking_fraction_of_max_value', 'listing__lux_booking_fraction_of_max_value', + 'listing__lux_booking_fraction_of_max_value', + 'listing__lux_booking_value_rate_expr', + 'listing__lux_booking_value_rate_expr', + 'listing__lux_booking_value_rate_expr', 'listing__lux_booking_value_rate_expr', 'listing__lux_listing', 'listing__lux_listings', + 'listing__lux_listings', + 'listing__lux_listings', + 'listing__lux_listings', + 'listing__max_booking_value', + 'listing__max_booking_value', 'listing__max_booking_value', + 'listing__max_booking_value', + 'listing__median_booking_value', + 'listing__median_booking_value', 'listing__median_booking_value', + 'listing__median_booking_value', + 'listing__min_booking_value', 'listing__min_booking_value', + 'listing__min_booking_value', + 'listing__min_booking_value', + 'listing__nested_fill_nulls_without_time_spine', + 'listing__nested_fill_nulls_without_time_spine', 'listing__nested_fill_nulls_without_time_spine', + 'listing__nested_fill_nulls_without_time_spine', + 'listing__non_referred_bookings_pct', + 'listing__non_referred_bookings_pct', 'listing__non_referred_bookings_pct', + 'listing__non_referred_bookings_pct', + 'listing__referred_bookings', 'listing__referred_bookings', + 'listing__referred_bookings', + 'listing__referred_bookings', + 'listing__smallest_listing', + 'listing__smallest_listing', 'listing__smallest_listing', + 'listing__smallest_listing', + 'listing__twice_bookings_fill_nulls_with_0_without_time_spine', + 'listing__twice_bookings_fill_nulls_with_0_without_time_spine', + 'listing__twice_bookings_fill_nulls_with_0_without_time_spine', 'listing__twice_bookings_fill_nulls_with_0_without_time_spine', 'listing__user', 'listing__views', + 'listing__views', + 'listing__views', + 'listing__views', + 'listing__views_times_booking_value', + 'listing__views_times_booking_value', + 'listing__views_times_booking_value', 'listing__views_times_booking_value', 'lux_listing', - 'lux_listing__active_listings', - 'lux_listing__approximate_continuous_booking_value_p99', - 'lux_listing__approximate_discrete_booking_value_p99', - 'lux_listing__average_booking_value', - 'lux_listing__average_instant_booking_value', - 'lux_listing__bookers', - 'lux_listing__booking_fees', - 'lux_listing__booking_fees_last_week_per_booker_this_week', - 'lux_listing__booking_fees_per_booker', - 'lux_listing__booking_fees_since_start_of_month', - 'lux_listing__booking_payments', - 'lux_listing__booking_value', - 'lux_listing__booking_value_for_non_null_listing_id', - 'lux_listing__booking_value_p99', - 'lux_listing__booking_value_per_view', - 'lux_listing__booking_value_sub_instant', - 'lux_listing__booking_value_sub_instant_add_10', - 'lux_listing__bookings', - 'lux_listing__bookings_5_day_lag', - 'lux_listing__bookings_at_start_of_month', - 'lux_listing__bookings_fill_nulls_with_0', - 'lux_listing__bookings_fill_nulls_with_0_without_time_spine', - 'lux_listing__bookings_growth_2_weeks', - 'lux_listing__bookings_growth_2_weeks_fill_nulls_with_0', - 'lux_listing__bookings_growth_2_weeks_fill_nulls_with_0_for_non_offset', - 'lux_listing__bookings_growth_since_start_of_month', - 'lux_listing__bookings_join_to_time_spine', - 'lux_listing__bookings_month_start_compared_to_1_month_prior', - 'lux_listing__bookings_offset_once', - 'lux_listing__bookings_offset_twice', - 'lux_listing__bookings_per_booker', - 'lux_listing__bookings_per_dollar', - 'lux_listing__bookings_per_listing', - 'lux_listing__bookings_per_lux_listing_derived', - 'lux_listing__bookings_per_view', - 'lux_listing__derived_bookings_0', - 'lux_listing__derived_bookings_1', - 'lux_listing__discrete_booking_value_p99', - 'lux_listing__double_counted_delayed_bookings', - 'lux_listing__every_2_days_bookers_2_days_ago', - 'lux_listing__every_two_days_bookers', - 'lux_listing__every_two_days_bookers_fill_nulls_with_0', - 'lux_listing__instant_booking_fraction_of_max_value', - 'lux_listing__instant_booking_value', - 'lux_listing__instant_booking_value_ratio', - 'lux_listing__instant_bookings', - 'lux_listing__instant_lux_booking_value_rate', - 'lux_listing__instant_plus_non_referred_bookings_pct', - 'lux_listing__largest_listing', - 'lux_listing__listings', - 'lux_listing__lux_booking_fraction_of_max_value', - 'lux_listing__lux_booking_value_rate_expr', - 'lux_listing__lux_listings', - 'lux_listing__max_booking_value', - 'lux_listing__median_booking_value', - 'lux_listing__min_booking_value', - 'lux_listing__nested_fill_nulls_without_time_spine', - 'lux_listing__non_referred_bookings_pct', - 'lux_listing__referred_bookings', - 'lux_listing__smallest_listing', - 'lux_listing__twice_bookings_fill_nulls_with_0_without_time_spine', - 'lux_listing__views', - 'lux_listing__views_times_booking_value', + 'lux_listing__listing__lux_listing__active_listings', + 'lux_listing__listing__lux_listing__approximate_continuous_booking_value_p99', + 'lux_listing__listing__lux_listing__approximate_discrete_booking_value_p99', + 'lux_listing__listing__lux_listing__average_booking_value', + 'lux_listing__listing__lux_listing__average_instant_booking_value', + 'lux_listing__listing__lux_listing__bookers', + 'lux_listing__listing__lux_listing__booking_fees', + 'lux_listing__listing__lux_listing__booking_fees_per_booker', + 'lux_listing__listing__lux_listing__booking_payments', + 'lux_listing__listing__lux_listing__booking_value', + 'lux_listing__listing__lux_listing__booking_value_for_non_null_listing_id', + 'lux_listing__listing__lux_listing__booking_value_p99', + 'lux_listing__listing__lux_listing__booking_value_per_view', + 'lux_listing__listing__lux_listing__booking_value_sub_instant', + 'lux_listing__listing__lux_listing__booking_value_sub_instant_add_10', + 'lux_listing__listing__lux_listing__bookings', + 'lux_listing__listing__lux_listing__bookings_fill_nulls_with_0', + 'lux_listing__listing__lux_listing__bookings_fill_nulls_with_0_without_time_spine', + 'lux_listing__listing__lux_listing__bookings_join_to_time_spine', + 'lux_listing__listing__lux_listing__bookings_per_booker', + 'lux_listing__listing__lux_listing__bookings_per_dollar', + 'lux_listing__listing__lux_listing__bookings_per_listing', + 'lux_listing__listing__lux_listing__bookings_per_lux_listing_derived', + 'lux_listing__listing__lux_listing__bookings_per_view', + 'lux_listing__listing__lux_listing__derived_bookings_0', + 'lux_listing__listing__lux_listing__derived_bookings_1', + 'lux_listing__listing__lux_listing__discrete_booking_value_p99', + 'lux_listing__listing__lux_listing__double_counted_delayed_bookings', + 'lux_listing__listing__lux_listing__instant_booking_fraction_of_max_value', + 'lux_listing__listing__lux_listing__instant_booking_value', + 'lux_listing__listing__lux_listing__instant_booking_value_ratio', + 'lux_listing__listing__lux_listing__instant_bookings', + 'lux_listing__listing__lux_listing__instant_lux_booking_value_rate', + 'lux_listing__listing__lux_listing__instant_plus_non_referred_bookings_pct', + 'lux_listing__listing__lux_listing__largest_listing', + 'lux_listing__listing__lux_listing__listings', + 'lux_listing__listing__lux_listing__lux_booking_fraction_of_max_value', + 'lux_listing__listing__lux_listing__lux_booking_value_rate_expr', + 'lux_listing__listing__lux_listing__lux_listings', + 'lux_listing__listing__lux_listing__max_booking_value', + 'lux_listing__listing__lux_listing__median_booking_value', + 'lux_listing__listing__lux_listing__min_booking_value', + 'lux_listing__listing__lux_listing__nested_fill_nulls_without_time_spine', + 'lux_listing__listing__lux_listing__non_referred_bookings_pct', + 'lux_listing__listing__lux_listing__referred_bookings', + 'lux_listing__listing__lux_listing__smallest_listing', + 'lux_listing__listing__lux_listing__twice_bookings_fill_nulls_with_0_without_time_spine', + 'lux_listing__listing__lux_listing__views', + 'lux_listing__listing__lux_listing__views_times_booking_value', 'metric_time__day', 'revenue_instance__ds__day', 'revenue_instance__ds__extract_day', @@ -391,40 +465,15 @@ 'session_id', 'user', 'user__active_listings', - 'user__approximate_continuous_booking_value_p99', - 'user__approximate_discrete_booking_value_p99', - 'user__average_booking_value', - 'user__average_instant_booking_value', - 'user__bookers', - 'user__booking_fees', - 'user__booking_fees_last_week_per_booker_this_week', - 'user__booking_fees_per_booker', - 'user__booking_fees_since_start_of_month', - 'user__booking_payments', - 'user__booking_value', - 'user__booking_value_for_non_null_listing_id', - 'user__booking_value_p99', - 'user__booking_value_per_view', - 'user__booking_value_sub_instant', - 'user__booking_value_sub_instant_add_10', - 'user__bookings', - 'user__bookings_5_day_lag', - 'user__bookings_at_start_of_month', - 'user__bookings_fill_nulls_with_0', - 'user__bookings_fill_nulls_with_0_without_time_spine', - 'user__bookings_growth_2_weeks', - 'user__bookings_growth_2_weeks_fill_nulls_with_0', - 'user__bookings_growth_2_weeks_fill_nulls_with_0_for_non_offset', - 'user__bookings_growth_since_start_of_month', - 'user__bookings_join_to_time_spine', - 'user__bookings_month_start_compared_to_1_month_prior', - 'user__bookings_offset_once', - 'user__bookings_offset_twice', - 'user__bookings_per_booker', - 'user__bookings_per_dollar', - 'user__bookings_per_listing', - 'user__bookings_per_lux_listing_derived', - 'user__bookings_per_view', + 'user__active_listings', + 'user__active_listings', + 'user__active_listings', + 'user__active_listings', + 'user__active_listings', + 'user__active_listings', + 'user__active_listings', + 'user__active_listings', + 'user__active_listings', 'user__company', 'user__company_name', 'user__created_at__day', @@ -435,10 +484,15 @@ 'user__created_at__extract_quarter', 'user__created_at__extract_year', 'user__current_account_balance_by_user', - 'user__derived_bookings_0', - 'user__derived_bookings_1', - 'user__discrete_booking_value_p99', - 'user__double_counted_delayed_bookings', + 'user__current_account_balance_by_user', + 'user__current_account_balance_by_user', + 'user__current_account_balance_by_user', + 'user__current_account_balance_by_user', + 'user__current_account_balance_by_user', + 'user__current_account_balance_by_user', + 'user__current_account_balance_by_user', + 'user__current_account_balance_by_user', + 'user__current_account_balance_by_user', 'user__ds__day', 'user__ds__extract_day', 'user__ds__extract_dow', @@ -460,44 +514,587 @@ 'user__ds_partitioned__extract_month', 'user__ds_partitioned__extract_quarter', 'user__ds_partitioned__extract_year', - 'user__every_2_days_bookers_2_days_ago', - 'user__every_two_days_bookers', - 'user__every_two_days_bookers_fill_nulls_with_0', 'user__home_state', 'user__home_state_latest', 'user__identity_verifications', - 'user__instant_booking_fraction_of_max_value', - 'user__instant_booking_value', - 'user__instant_booking_value_ratio', - 'user__instant_bookings', - 'user__instant_lux_booking_value_rate', - 'user__instant_plus_non_referred_bookings_pct', + 'user__identity_verifications', + 'user__identity_verifications', + 'user__identity_verifications', + 'user__identity_verifications', + 'user__identity_verifications', + 'user__identity_verifications', + 'user__identity_verifications', + 'user__identity_verifications', + 'user__identity_verifications', + 'user__largest_listing', + 'user__largest_listing', + 'user__largest_listing', + 'user__largest_listing', + 'user__largest_listing', + 'user__largest_listing', + 'user__largest_listing', + 'user__largest_listing', + 'user__largest_listing', 'user__largest_listing', + 'user__listing__user__approximate_continuous_booking_value_p99', + 'user__listing__user__approximate_continuous_booking_value_p99', + 'user__listing__user__approximate_continuous_booking_value_p99', + 'user__listing__user__approximate_continuous_booking_value_p99', + 'user__listing__user__approximate_continuous_booking_value_p99', + 'user__listing__user__approximate_continuous_booking_value_p99', + 'user__listing__user__approximate_continuous_booking_value_p99', + 'user__listing__user__approximate_continuous_booking_value_p99', + 'user__listing__user__approximate_continuous_booking_value_p99', + 'user__listing__user__approximate_continuous_booking_value_p99', + 'user__listing__user__approximate_discrete_booking_value_p99', + 'user__listing__user__approximate_discrete_booking_value_p99', + 'user__listing__user__approximate_discrete_booking_value_p99', + 'user__listing__user__approximate_discrete_booking_value_p99', + 'user__listing__user__approximate_discrete_booking_value_p99', + 'user__listing__user__approximate_discrete_booking_value_p99', + 'user__listing__user__approximate_discrete_booking_value_p99', + 'user__listing__user__approximate_discrete_booking_value_p99', + 'user__listing__user__approximate_discrete_booking_value_p99', + 'user__listing__user__approximate_discrete_booking_value_p99', + 'user__listing__user__average_booking_value', + 'user__listing__user__average_booking_value', + 'user__listing__user__average_booking_value', + 'user__listing__user__average_booking_value', + 'user__listing__user__average_booking_value', + 'user__listing__user__average_booking_value', + 'user__listing__user__average_booking_value', + 'user__listing__user__average_booking_value', + 'user__listing__user__average_booking_value', + 'user__listing__user__average_booking_value', + 'user__listing__user__average_instant_booking_value', + 'user__listing__user__average_instant_booking_value', + 'user__listing__user__average_instant_booking_value', + 'user__listing__user__average_instant_booking_value', + 'user__listing__user__average_instant_booking_value', + 'user__listing__user__average_instant_booking_value', + 'user__listing__user__average_instant_booking_value', + 'user__listing__user__average_instant_booking_value', + 'user__listing__user__average_instant_booking_value', + 'user__listing__user__average_instant_booking_value', + 'user__listing__user__bookers', + 'user__listing__user__bookers', + 'user__listing__user__bookers', + 'user__listing__user__bookers', + 'user__listing__user__bookers', + 'user__listing__user__bookers', + 'user__listing__user__bookers', + 'user__listing__user__bookers', + 'user__listing__user__bookers', + 'user__listing__user__bookers', + 'user__listing__user__booking_fees', + 'user__listing__user__booking_fees', + 'user__listing__user__booking_fees', + 'user__listing__user__booking_fees', + 'user__listing__user__booking_fees', + 'user__listing__user__booking_fees', + 'user__listing__user__booking_fees', + 'user__listing__user__booking_fees', + 'user__listing__user__booking_fees', + 'user__listing__user__booking_fees', + 'user__listing__user__booking_fees_per_booker', + 'user__listing__user__booking_fees_per_booker', + 'user__listing__user__booking_fees_per_booker', + 'user__listing__user__booking_fees_per_booker', + 'user__listing__user__booking_fees_per_booker', + 'user__listing__user__booking_fees_per_booker', + 'user__listing__user__booking_fees_per_booker', + 'user__listing__user__booking_fees_per_booker', + 'user__listing__user__booking_fees_per_booker', + 'user__listing__user__booking_fees_per_booker', + 'user__listing__user__booking_payments', + 'user__listing__user__booking_payments', + 'user__listing__user__booking_payments', + 'user__listing__user__booking_payments', + 'user__listing__user__booking_payments', + 'user__listing__user__booking_payments', + 'user__listing__user__booking_payments', + 'user__listing__user__booking_payments', + 'user__listing__user__booking_payments', + 'user__listing__user__booking_payments', + 'user__listing__user__booking_value', + 'user__listing__user__booking_value', + 'user__listing__user__booking_value', + 'user__listing__user__booking_value', + 'user__listing__user__booking_value', + 'user__listing__user__booking_value', + 'user__listing__user__booking_value', + 'user__listing__user__booking_value', + 'user__listing__user__booking_value', + 'user__listing__user__booking_value', + 'user__listing__user__booking_value_for_non_null_listing_id', + 'user__listing__user__booking_value_for_non_null_listing_id', + 'user__listing__user__booking_value_for_non_null_listing_id', + 'user__listing__user__booking_value_for_non_null_listing_id', + 'user__listing__user__booking_value_for_non_null_listing_id', + 'user__listing__user__booking_value_for_non_null_listing_id', + 'user__listing__user__booking_value_for_non_null_listing_id', + 'user__listing__user__booking_value_for_non_null_listing_id', + 'user__listing__user__booking_value_for_non_null_listing_id', + 'user__listing__user__booking_value_for_non_null_listing_id', + 'user__listing__user__booking_value_p99', + 'user__listing__user__booking_value_p99', + 'user__listing__user__booking_value_p99', + 'user__listing__user__booking_value_p99', + 'user__listing__user__booking_value_p99', + 'user__listing__user__booking_value_p99', + 'user__listing__user__booking_value_p99', + 'user__listing__user__booking_value_p99', + 'user__listing__user__booking_value_p99', + 'user__listing__user__booking_value_p99', + 'user__listing__user__booking_value_per_view', + 'user__listing__user__booking_value_per_view', + 'user__listing__user__booking_value_per_view', + 'user__listing__user__booking_value_per_view', + 'user__listing__user__booking_value_per_view', + 'user__listing__user__booking_value_per_view', + 'user__listing__user__booking_value_per_view', + 'user__listing__user__booking_value_per_view', + 'user__listing__user__booking_value_per_view', + 'user__listing__user__booking_value_per_view', + 'user__listing__user__booking_value_sub_instant', + 'user__listing__user__booking_value_sub_instant', + 'user__listing__user__booking_value_sub_instant', + 'user__listing__user__booking_value_sub_instant', + 'user__listing__user__booking_value_sub_instant', + 'user__listing__user__booking_value_sub_instant', + 'user__listing__user__booking_value_sub_instant', + 'user__listing__user__booking_value_sub_instant', + 'user__listing__user__booking_value_sub_instant', + 'user__listing__user__booking_value_sub_instant', + 'user__listing__user__booking_value_sub_instant_add_10', + 'user__listing__user__booking_value_sub_instant_add_10', + 'user__listing__user__booking_value_sub_instant_add_10', + 'user__listing__user__booking_value_sub_instant_add_10', + 'user__listing__user__booking_value_sub_instant_add_10', + 'user__listing__user__booking_value_sub_instant_add_10', + 'user__listing__user__booking_value_sub_instant_add_10', + 'user__listing__user__booking_value_sub_instant_add_10', + 'user__listing__user__booking_value_sub_instant_add_10', + 'user__listing__user__booking_value_sub_instant_add_10', + 'user__listing__user__bookings', + 'user__listing__user__bookings', + 'user__listing__user__bookings', + 'user__listing__user__bookings', + 'user__listing__user__bookings', + 'user__listing__user__bookings', + 'user__listing__user__bookings', + 'user__listing__user__bookings', + 'user__listing__user__bookings', + 'user__listing__user__bookings', + 'user__listing__user__bookings_fill_nulls_with_0', + 'user__listing__user__bookings_fill_nulls_with_0', + 'user__listing__user__bookings_fill_nulls_with_0', + 'user__listing__user__bookings_fill_nulls_with_0', + 'user__listing__user__bookings_fill_nulls_with_0', + 'user__listing__user__bookings_fill_nulls_with_0', + 'user__listing__user__bookings_fill_nulls_with_0', + 'user__listing__user__bookings_fill_nulls_with_0', + 'user__listing__user__bookings_fill_nulls_with_0', + 'user__listing__user__bookings_fill_nulls_with_0', + 'user__listing__user__bookings_fill_nulls_with_0_without_time_spine', + 'user__listing__user__bookings_fill_nulls_with_0_without_time_spine', + 'user__listing__user__bookings_fill_nulls_with_0_without_time_spine', + 'user__listing__user__bookings_fill_nulls_with_0_without_time_spine', + 'user__listing__user__bookings_fill_nulls_with_0_without_time_spine', + 'user__listing__user__bookings_fill_nulls_with_0_without_time_spine', + 'user__listing__user__bookings_fill_nulls_with_0_without_time_spine', + 'user__listing__user__bookings_fill_nulls_with_0_without_time_spine', + 'user__listing__user__bookings_fill_nulls_with_0_without_time_spine', + 'user__listing__user__bookings_fill_nulls_with_0_without_time_spine', + 'user__listing__user__bookings_join_to_time_spine', + 'user__listing__user__bookings_join_to_time_spine', + 'user__listing__user__bookings_join_to_time_spine', + 'user__listing__user__bookings_join_to_time_spine', + 'user__listing__user__bookings_join_to_time_spine', + 'user__listing__user__bookings_join_to_time_spine', + 'user__listing__user__bookings_join_to_time_spine', + 'user__listing__user__bookings_join_to_time_spine', + 'user__listing__user__bookings_join_to_time_spine', + 'user__listing__user__bookings_join_to_time_spine', + 'user__listing__user__bookings_per_booker', + 'user__listing__user__bookings_per_booker', + 'user__listing__user__bookings_per_booker', + 'user__listing__user__bookings_per_booker', + 'user__listing__user__bookings_per_booker', + 'user__listing__user__bookings_per_booker', + 'user__listing__user__bookings_per_booker', + 'user__listing__user__bookings_per_booker', + 'user__listing__user__bookings_per_booker', + 'user__listing__user__bookings_per_booker', + 'user__listing__user__bookings_per_dollar', + 'user__listing__user__bookings_per_dollar', + 'user__listing__user__bookings_per_dollar', + 'user__listing__user__bookings_per_dollar', + 'user__listing__user__bookings_per_dollar', + 'user__listing__user__bookings_per_dollar', + 'user__listing__user__bookings_per_dollar', + 'user__listing__user__bookings_per_dollar', + 'user__listing__user__bookings_per_dollar', + 'user__listing__user__bookings_per_dollar', + 'user__listing__user__bookings_per_listing', + 'user__listing__user__bookings_per_listing', + 'user__listing__user__bookings_per_listing', + 'user__listing__user__bookings_per_listing', + 'user__listing__user__bookings_per_listing', + 'user__listing__user__bookings_per_listing', + 'user__listing__user__bookings_per_listing', + 'user__listing__user__bookings_per_listing', + 'user__listing__user__bookings_per_listing', + 'user__listing__user__bookings_per_listing', + 'user__listing__user__bookings_per_lux_listing_derived', + 'user__listing__user__bookings_per_lux_listing_derived', + 'user__listing__user__bookings_per_lux_listing_derived', + 'user__listing__user__bookings_per_lux_listing_derived', + 'user__listing__user__bookings_per_lux_listing_derived', + 'user__listing__user__bookings_per_lux_listing_derived', + 'user__listing__user__bookings_per_lux_listing_derived', + 'user__listing__user__bookings_per_lux_listing_derived', + 'user__listing__user__bookings_per_lux_listing_derived', + 'user__listing__user__bookings_per_lux_listing_derived', + 'user__listing__user__bookings_per_view', + 'user__listing__user__bookings_per_view', + 'user__listing__user__bookings_per_view', + 'user__listing__user__bookings_per_view', + 'user__listing__user__bookings_per_view', + 'user__listing__user__bookings_per_view', + 'user__listing__user__bookings_per_view', + 'user__listing__user__bookings_per_view', + 'user__listing__user__bookings_per_view', + 'user__listing__user__bookings_per_view', + 'user__listing__user__derived_bookings_0', + 'user__listing__user__derived_bookings_0', + 'user__listing__user__derived_bookings_0', + 'user__listing__user__derived_bookings_0', + 'user__listing__user__derived_bookings_0', + 'user__listing__user__derived_bookings_0', + 'user__listing__user__derived_bookings_0', + 'user__listing__user__derived_bookings_0', + 'user__listing__user__derived_bookings_0', + 'user__listing__user__derived_bookings_0', + 'user__listing__user__derived_bookings_1', + 'user__listing__user__derived_bookings_1', + 'user__listing__user__derived_bookings_1', + 'user__listing__user__derived_bookings_1', + 'user__listing__user__derived_bookings_1', + 'user__listing__user__derived_bookings_1', + 'user__listing__user__derived_bookings_1', + 'user__listing__user__derived_bookings_1', + 'user__listing__user__derived_bookings_1', + 'user__listing__user__derived_bookings_1', + 'user__listing__user__discrete_booking_value_p99', + 'user__listing__user__discrete_booking_value_p99', + 'user__listing__user__discrete_booking_value_p99', + 'user__listing__user__discrete_booking_value_p99', + 'user__listing__user__discrete_booking_value_p99', + 'user__listing__user__discrete_booking_value_p99', + 'user__listing__user__discrete_booking_value_p99', + 'user__listing__user__discrete_booking_value_p99', + 'user__listing__user__discrete_booking_value_p99', + 'user__listing__user__discrete_booking_value_p99', + 'user__listing__user__double_counted_delayed_bookings', + 'user__listing__user__double_counted_delayed_bookings', + 'user__listing__user__double_counted_delayed_bookings', + 'user__listing__user__double_counted_delayed_bookings', + 'user__listing__user__double_counted_delayed_bookings', + 'user__listing__user__double_counted_delayed_bookings', + 'user__listing__user__double_counted_delayed_bookings', + 'user__listing__user__double_counted_delayed_bookings', + 'user__listing__user__double_counted_delayed_bookings', + 'user__listing__user__double_counted_delayed_bookings', + 'user__listing__user__instant_booking_fraction_of_max_value', + 'user__listing__user__instant_booking_fraction_of_max_value', + 'user__listing__user__instant_booking_fraction_of_max_value', + 'user__listing__user__instant_booking_fraction_of_max_value', + 'user__listing__user__instant_booking_fraction_of_max_value', + 'user__listing__user__instant_booking_fraction_of_max_value', + 'user__listing__user__instant_booking_fraction_of_max_value', + 'user__listing__user__instant_booking_fraction_of_max_value', + 'user__listing__user__instant_booking_fraction_of_max_value', + 'user__listing__user__instant_booking_fraction_of_max_value', + 'user__listing__user__instant_booking_value', + 'user__listing__user__instant_booking_value', + 'user__listing__user__instant_booking_value', + 'user__listing__user__instant_booking_value', + 'user__listing__user__instant_booking_value', + 'user__listing__user__instant_booking_value', + 'user__listing__user__instant_booking_value', + 'user__listing__user__instant_booking_value', + 'user__listing__user__instant_booking_value', + 'user__listing__user__instant_booking_value', + 'user__listing__user__instant_booking_value_ratio', + 'user__listing__user__instant_booking_value_ratio', + 'user__listing__user__instant_booking_value_ratio', + 'user__listing__user__instant_booking_value_ratio', + 'user__listing__user__instant_booking_value_ratio', + 'user__listing__user__instant_booking_value_ratio', + 'user__listing__user__instant_booking_value_ratio', + 'user__listing__user__instant_booking_value_ratio', + 'user__listing__user__instant_booking_value_ratio', + 'user__listing__user__instant_booking_value_ratio', + 'user__listing__user__instant_bookings', + 'user__listing__user__instant_bookings', + 'user__listing__user__instant_bookings', + 'user__listing__user__instant_bookings', + 'user__listing__user__instant_bookings', + 'user__listing__user__instant_bookings', + 'user__listing__user__instant_bookings', + 'user__listing__user__instant_bookings', + 'user__listing__user__instant_bookings', + 'user__listing__user__instant_bookings', + 'user__listing__user__instant_lux_booking_value_rate', + 'user__listing__user__instant_lux_booking_value_rate', + 'user__listing__user__instant_lux_booking_value_rate', + 'user__listing__user__instant_lux_booking_value_rate', + 'user__listing__user__instant_lux_booking_value_rate', + 'user__listing__user__instant_lux_booking_value_rate', + 'user__listing__user__instant_lux_booking_value_rate', + 'user__listing__user__instant_lux_booking_value_rate', + 'user__listing__user__instant_lux_booking_value_rate', + 'user__listing__user__instant_lux_booking_value_rate', + 'user__listing__user__instant_plus_non_referred_bookings_pct', + 'user__listing__user__instant_plus_non_referred_bookings_pct', + 'user__listing__user__instant_plus_non_referred_bookings_pct', + 'user__listing__user__instant_plus_non_referred_bookings_pct', + 'user__listing__user__instant_plus_non_referred_bookings_pct', + 'user__listing__user__instant_plus_non_referred_bookings_pct', + 'user__listing__user__instant_plus_non_referred_bookings_pct', + 'user__listing__user__instant_plus_non_referred_bookings_pct', + 'user__listing__user__instant_plus_non_referred_bookings_pct', + 'user__listing__user__instant_plus_non_referred_bookings_pct', + 'user__listing__user__lux_booking_fraction_of_max_value', + 'user__listing__user__lux_booking_fraction_of_max_value', + 'user__listing__user__lux_booking_fraction_of_max_value', + 'user__listing__user__lux_booking_fraction_of_max_value', + 'user__listing__user__lux_booking_fraction_of_max_value', + 'user__listing__user__lux_booking_fraction_of_max_value', + 'user__listing__user__lux_booking_fraction_of_max_value', + 'user__listing__user__lux_booking_fraction_of_max_value', + 'user__listing__user__lux_booking_fraction_of_max_value', + 'user__listing__user__lux_booking_fraction_of_max_value', + 'user__listing__user__lux_booking_value_rate_expr', + 'user__listing__user__lux_booking_value_rate_expr', + 'user__listing__user__lux_booking_value_rate_expr', + 'user__listing__user__lux_booking_value_rate_expr', + 'user__listing__user__lux_booking_value_rate_expr', + 'user__listing__user__lux_booking_value_rate_expr', + 'user__listing__user__lux_booking_value_rate_expr', + 'user__listing__user__lux_booking_value_rate_expr', + 'user__listing__user__lux_booking_value_rate_expr', + 'user__listing__user__lux_booking_value_rate_expr', + 'user__listing__user__max_booking_value', + 'user__listing__user__max_booking_value', + 'user__listing__user__max_booking_value', + 'user__listing__user__max_booking_value', + 'user__listing__user__max_booking_value', + 'user__listing__user__max_booking_value', + 'user__listing__user__max_booking_value', + 'user__listing__user__max_booking_value', + 'user__listing__user__max_booking_value', + 'user__listing__user__max_booking_value', + 'user__listing__user__median_booking_value', + 'user__listing__user__median_booking_value', + 'user__listing__user__median_booking_value', + 'user__listing__user__median_booking_value', + 'user__listing__user__median_booking_value', + 'user__listing__user__median_booking_value', + 'user__listing__user__median_booking_value', + 'user__listing__user__median_booking_value', + 'user__listing__user__median_booking_value', + 'user__listing__user__median_booking_value', + 'user__listing__user__min_booking_value', + 'user__listing__user__min_booking_value', + 'user__listing__user__min_booking_value', + 'user__listing__user__min_booking_value', + 'user__listing__user__min_booking_value', + 'user__listing__user__min_booking_value', + 'user__listing__user__min_booking_value', + 'user__listing__user__min_booking_value', + 'user__listing__user__min_booking_value', + 'user__listing__user__min_booking_value', + 'user__listing__user__nested_fill_nulls_without_time_spine', + 'user__listing__user__nested_fill_nulls_without_time_spine', + 'user__listing__user__nested_fill_nulls_without_time_spine', + 'user__listing__user__nested_fill_nulls_without_time_spine', + 'user__listing__user__nested_fill_nulls_without_time_spine', + 'user__listing__user__nested_fill_nulls_without_time_spine', + 'user__listing__user__nested_fill_nulls_without_time_spine', + 'user__listing__user__nested_fill_nulls_without_time_spine', + 'user__listing__user__nested_fill_nulls_without_time_spine', + 'user__listing__user__nested_fill_nulls_without_time_spine', + 'user__listing__user__non_referred_bookings_pct', + 'user__listing__user__non_referred_bookings_pct', + 'user__listing__user__non_referred_bookings_pct', + 'user__listing__user__non_referred_bookings_pct', + 'user__listing__user__non_referred_bookings_pct', + 'user__listing__user__non_referred_bookings_pct', + 'user__listing__user__non_referred_bookings_pct', + 'user__listing__user__non_referred_bookings_pct', + 'user__listing__user__non_referred_bookings_pct', + 'user__listing__user__non_referred_bookings_pct', + 'user__listing__user__referred_bookings', + 'user__listing__user__referred_bookings', + 'user__listing__user__referred_bookings', + 'user__listing__user__referred_bookings', + 'user__listing__user__referred_bookings', + 'user__listing__user__referred_bookings', + 'user__listing__user__referred_bookings', + 'user__listing__user__referred_bookings', + 'user__listing__user__referred_bookings', + 'user__listing__user__referred_bookings', + 'user__listing__user__twice_bookings_fill_nulls_with_0_without_time_spine', + 'user__listing__user__twice_bookings_fill_nulls_with_0_without_time_spine', + 'user__listing__user__twice_bookings_fill_nulls_with_0_without_time_spine', + 'user__listing__user__twice_bookings_fill_nulls_with_0_without_time_spine', + 'user__listing__user__twice_bookings_fill_nulls_with_0_without_time_spine', + 'user__listing__user__twice_bookings_fill_nulls_with_0_without_time_spine', + 'user__listing__user__twice_bookings_fill_nulls_with_0_without_time_spine', + 'user__listing__user__twice_bookings_fill_nulls_with_0_without_time_spine', + 'user__listing__user__twice_bookings_fill_nulls_with_0_without_time_spine', + 'user__listing__user__twice_bookings_fill_nulls_with_0_without_time_spine', + 'user__listing__user__views', + 'user__listing__user__views', + 'user__listing__user__views', + 'user__listing__user__views', + 'user__listing__user__views', + 'user__listing__user__views', + 'user__listing__user__views', + 'user__listing__user__views', + 'user__listing__user__views', + 'user__listing__user__views', + 'user__listing__user__views_times_booking_value', + 'user__listing__user__views_times_booking_value', + 'user__listing__user__views_times_booking_value', + 'user__listing__user__views_times_booking_value', + 'user__listing__user__views_times_booking_value', + 'user__listing__user__views_times_booking_value', + 'user__listing__user__views_times_booking_value', + 'user__listing__user__views_times_booking_value', + 'user__listing__user__views_times_booking_value', + 'user__listing__user__views_times_booking_value', 'user__listings', - 'user__lux_booking_fraction_of_max_value', - 'user__lux_booking_value_rate_expr', + 'user__listings', + 'user__listings', + 'user__listings', + 'user__listings', + 'user__listings', + 'user__listings', + 'user__listings', + 'user__listings', + 'user__listings', + 'user__lux_listings', + 'user__lux_listings', + 'user__lux_listings', + 'user__lux_listings', + 'user__lux_listings', + 'user__lux_listings', + 'user__lux_listings', + 'user__lux_listings', + 'user__lux_listings', 'user__lux_listings', - 'user__max_booking_value', - 'user__median_booking_value', - 'user__min_booking_value', - 'user__nested_fill_nulls_without_time_spine', - 'user__non_referred_bookings_pct', - 'user__referred_bookings', 'user__regional_starting_balance_ratios', + 'user__regional_starting_balance_ratios', + 'user__regional_starting_balance_ratios', + 'user__regional_starting_balance_ratios', + 'user__regional_starting_balance_ratios', + 'user__regional_starting_balance_ratios', + 'user__regional_starting_balance_ratios', + 'user__regional_starting_balance_ratios', + 'user__regional_starting_balance_ratios', + 'user__regional_starting_balance_ratios', + 'user__revenue', + 'user__revenue', + 'user__revenue', + 'user__revenue', + 'user__revenue', + 'user__revenue', + 'user__revenue', + 'user__revenue', + 'user__revenue', 'user__revenue', 'user__revenue_all_time', - 'user__revenue_mtd', + 'user__revenue_all_time', + 'user__revenue_all_time', + 'user__revenue_all_time', + 'user__revenue_all_time', + 'user__revenue_all_time', + 'user__revenue_all_time', + 'user__revenue_all_time', + 'user__revenue_all_time', + 'user__revenue_all_time', + 'user__smallest_listing', + 'user__smallest_listing', + 'user__smallest_listing', + 'user__smallest_listing', + 'user__smallest_listing', + 'user__smallest_listing', + 'user__smallest_listing', + 'user__smallest_listing', + 'user__smallest_listing', 'user__smallest_listing', 'user__total_account_balance_first_day', - 'user__trailing_2_months_revenue', - 'user__trailing_2_months_revenue_sub_10', - 'user__twice_bookings_fill_nulls_with_0_without_time_spine', - 'user__views', - 'user__views_times_booking_value', + 'user__total_account_balance_first_day', + 'user__total_account_balance_first_day', + 'user__total_account_balance_first_day', + 'user__total_account_balance_first_day', + 'user__total_account_balance_first_day', + 'user__total_account_balance_first_day', + 'user__total_account_balance_first_day', + 'user__total_account_balance_first_day', + 'user__total_account_balance_first_day', + 'user__visit_buy_conversion_rate', + 'user__visit_buy_conversion_rate', + 'user__visit_buy_conversion_rate', + 'user__visit_buy_conversion_rate', + 'user__visit_buy_conversion_rate', + 'user__visit_buy_conversion_rate', + 'user__visit_buy_conversion_rate', + 'user__visit_buy_conversion_rate', + 'user__visit_buy_conversion_rate', 'user__visit_buy_conversion_rate', 'user__visit_buy_conversion_rate_7days', + 'user__visit_buy_conversion_rate_7days', + 'user__visit_buy_conversion_rate_7days', + 'user__visit_buy_conversion_rate_7days', + 'user__visit_buy_conversion_rate_7days', + 'user__visit_buy_conversion_rate_7days', + 'user__visit_buy_conversion_rate_7days', + 'user__visit_buy_conversion_rate_7days', + 'user__visit_buy_conversion_rate_7days', + 'user__visit_buy_conversion_rate_7days', + 'user__visit_buy_conversion_rate_7days_fill_nulls_with_0', + 'user__visit_buy_conversion_rate_7days_fill_nulls_with_0', + 'user__visit_buy_conversion_rate_7days_fill_nulls_with_0', + 'user__visit_buy_conversion_rate_7days_fill_nulls_with_0', + 'user__visit_buy_conversion_rate_7days_fill_nulls_with_0', + 'user__visit_buy_conversion_rate_7days_fill_nulls_with_0', + 'user__visit_buy_conversion_rate_7days_fill_nulls_with_0', + 'user__visit_buy_conversion_rate_7days_fill_nulls_with_0', + 'user__visit_buy_conversion_rate_7days_fill_nulls_with_0', 'user__visit_buy_conversion_rate_7days_fill_nulls_with_0', 'user__visit_buy_conversion_rate_by_session', + 'user__visit_buy_conversion_rate_by_session', + 'user__visit_buy_conversion_rate_by_session', + 'user__visit_buy_conversion_rate_by_session', + 'user__visit_buy_conversion_rate_by_session', + 'user__visit_buy_conversion_rate_by_session', + 'user__visit_buy_conversion_rate_by_session', + 'user__visit_buy_conversion_rate_by_session', + 'user__visit_buy_conversion_rate_by_session', + 'user__visit_buy_conversion_rate_by_session', + 'user__visit_buy_conversions', + 'user__visit_buy_conversions', + 'user__visit_buy_conversions', + 'user__visit_buy_conversions', + 'user__visit_buy_conversions', + 'user__visit_buy_conversions', + 'user__visit_buy_conversions', + 'user__visit_buy_conversions', + 'user__visit_buy_conversions', 'user__visit_buy_conversions', 'verification', 'verification__ds__day', From 82acea8997e6651cbab385c41386914b988d4a68 Mon Sep 17 00:00:00 2001 From: Courtney Holcomb Date: Fri, 26 Apr 2024 22:05:43 -0700 Subject: [PATCH 32/37] Store entity links on MetricSubqueryJoinPathElement Originally I thought this wasn't necessary since the entity links should be a duplicate of the entities in the join path. Later I reailzed that there is one scenario where they don't match the join path. We allow querying local entities both alone and prefixed with any of the other entities in the same semantic model. If you query a local entity with another entity prefix, the entity links won't match the join path. To account for that, we need to store both entity links and join path on MetricSubqueryJoinPathElement. --- .../model/semantics/linkable_spec_resolver.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/metricflow/model/semantics/linkable_spec_resolver.py b/metricflow/model/semantics/linkable_spec_resolver.py index 26f36af5a0..61541666b9 100644 --- a/metricflow/model/semantics/linkable_spec_resolver.py +++ b/metricflow/model/semantics/linkable_spec_resolver.py @@ -139,7 +139,8 @@ def metric_to_entity_join_path(self) -> Optional[SemanticModelJoinPath]: @property def metric_subquery_entity_links(self) -> Tuple[EntityReference, ...]: """Entity links used to join the metric to the entity it's grouped by in the metric subquery.""" - return self.join_path.metric_subquery_join_path_element.entity_links + metric_subquery = self.join_path.metric_subquery_join_path_element + return metric_subquery.entity_links + (metric_subquery.join_on_entity,) @dataclass(frozen=True) @@ -408,13 +409,9 @@ class MetricSubqueryJoinPathElement: metric_reference: MetricReference join_on_entity: EntityReference + entity_links: Tuple[EntityReference, ...] metric_to_entity_join_path: Optional[SemanticModelJoinPath] = None - @property - def entity_links(self) -> Tuple[EntityReference, ...]: # noqa: D102 - join_links = self.metric_to_entity_join_path.entity_links if self.metric_to_entity_join_path else () - return join_links + (self.join_on_entity,) - @dataclass(frozen=True) class SemanticModelToMetricSubqueryJoinPath: @@ -630,7 +627,10 @@ def __init__( metric_subquery_join_path_element = MetricSubqueryJoinPathElement( metric_reference=metric_reference, join_on_entity=linkable_entity.reference, - metric_to_entity_join_path=SemanticModelJoinPath(linkable_entity.join_path), + entity_links=linkable_entity.entity_links, + metric_to_entity_join_path=( + SemanticModelJoinPath(linkable_entity.join_path) if linkable_entity.join_path else None + ), ) self._joinable_metrics_for_entities[linkable_entity.reference].add( metric_subquery_join_path_element From e2b616aa04f539cc32fe5320b6e9dda5aec2d954 Mon Sep 17 00:00:00 2001 From: Courtney Holcomb Date: Mon, 29 Apr 2024 12:25:20 -0700 Subject: [PATCH 33/37] Use qualified name as ElementPathKey element name to ensure uniqueness There might be multiple linkable metrics available for a given metric_name + entity_links combo. This is because there might be multiple options for entity paths in the metric subquery, which is not accounted for here. Using the qualified name ensures we will have a unique ElementPathKey for each LinkableMetric. --- .../model/semantics/linkable_spec_resolver.py | 29 ++++++++++++++----- 1 file changed, 21 insertions(+), 8 deletions(-) diff --git a/metricflow/model/semantics/linkable_spec_resolver.py b/metricflow/model/semantics/linkable_spec_resolver.py index 61541666b9..3d49ca3ad2 100644 --- a/metricflow/model/semantics/linkable_spec_resolver.py +++ b/metricflow/model/semantics/linkable_spec_resolver.py @@ -120,8 +120,23 @@ def element_name(self) -> str: # noqa: D102 return self.reference.element_name @property - def path_key(self) -> ElementPathKey: # noqa: D102 - return ElementPathKey(element_name=self.element_name, entity_links=self.join_path.entity_links) + def path_key(self) -> ElementPathKey: + """Key that can uniquely identify an element and the joins used to realize the element. + + Use qualified name to guarantee uniqueness. + """ + return ElementPathKey( + element_name=self.as_group_by_metric_spec.qualified_name, entity_links=self.join_path.entity_links + ) + + @property + def as_group_by_metric_spec(self) -> GroupByMetricSpec: + """Convert LinkableMetric to GroupByMetricSpec.""" + return GroupByMetricSpec( + element_name=self.element_name, + entity_links=self.join_path.entity_links, + metric_subquery_entity_links=self.metric_subquery_entity_links, + ) @property def reference(self) -> MetricReference: # noqa: D102 @@ -257,7 +272,9 @@ def intersection_by_path_key(linkable_element_sets: Sequence[LinkableElementSet] for path_key, entities in join_path_to_linkable_entities.items() }, path_key_to_linkable_metrics={ - path_key: tuple(sorted(metrics, key=lambda linkable_metric: linkable_metric.element_name)) + path_key: tuple( + sorted(metrics, key=lambda linkable_metric: linkable_metric.as_group_by_metric_spec.qualified_name) + ) for path_key, metrics in join_path_to_linkable_metrics.items() }, ) @@ -355,11 +372,7 @@ def as_spec_set(self) -> LinkableSpecSet: # noqa: D102 for path_key in self.path_key_to_linkable_entities ), group_by_metric_specs=tuple( - GroupByMetricSpec( - element_name=linkable_metric.element_name, - entity_links=linkable_metric.join_path.entity_links, - metric_subquery_entity_links=linkable_metric.metric_subquery_entity_links, - ) + linkable_metric.as_group_by_metric_spec for linkable_metrics in self.path_key_to_linkable_metrics.values() for linkable_metric in linkable_metrics ), From 72d233a84b6b6b44fa902efaabb3491a8b097974 Mon Sep 17 00:00:00 2001 From: Courtney Holcomb Date: Mon, 29 Apr 2024 12:27:21 -0700 Subject: [PATCH 34/37] Update loop to ensure no LinkableMetric options are being skipped --- metricflow/model/semantics/linkable_spec_resolver.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/metricflow/model/semantics/linkable_spec_resolver.py b/metricflow/model/semantics/linkable_spec_resolver.py index 3d49ca3ad2..8c3e57d8bd 100644 --- a/metricflow/model/semantics/linkable_spec_resolver.py +++ b/metricflow/model/semantics/linkable_spec_resolver.py @@ -727,7 +727,9 @@ def _get_joinable_metrics_for_semantic_model( semantic_model_join_path=using_join_path, ), ) - path_key_to_linkable_metrics[linkable_metric.path_key] = (linkable_metric,) + path_key_to_linkable_metrics[linkable_metric.path_key] = path_key_to_linkable_metrics.get( + linkable_metric.path_key, () + ) + (linkable_metric,) return LinkableElementSet(path_key_to_linkable_metrics=path_key_to_linkable_metrics) @@ -792,6 +794,7 @@ def _get_elements_in_semantic_model(self, semantic_model: SemanticModel) -> Link else: assert_values_exhausted(dimension_type) + # TODO: are these loops erasing options? return LinkableElementSet( path_key_to_linkable_dimensions={ linkable_dimension.path_key: (linkable_dimension,) for linkable_dimension in linkable_dimensions @@ -1138,6 +1141,7 @@ def create_linkable_element_set_from_join_path( ) ) + # TODO: are these loops erasing options? return LinkableElementSet( path_key_to_linkable_dimensions={ linkable_dimension.path_key: (linkable_dimension,) for linkable_dimension in linkable_dimensions From ed3559c4bd7581ce2b32efa2f0bebb883f8d5894 Mon Sep 17 00:00:00 2001 From: Courtney Holcomb Date: Mon, 29 Apr 2024 12:29:18 -0700 Subject: [PATCH 35/37] Handle both entity paths in filter spec pattern logic --- metricflow/specs/patterns/entity_link_pattern.py | 4 ++++ metricflow/specs/patterns/typed_patterns.py | 10 +++++++--- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/metricflow/specs/patterns/entity_link_pattern.py b/metricflow/specs/patterns/entity_link_pattern.py index 28d8adcdd3..b0cd9d54e2 100644 --- a/metricflow/specs/patterns/entity_link_pattern.py +++ b/metricflow/specs/patterns/entity_link_pattern.py @@ -27,6 +27,7 @@ class ParameterSetField(Enum): ENTITY_LINKS = "entity_links" TIME_GRANULARITY = "time_granularity" DATE_PART = "date_part" + METRIC_SUBQUERY_ENTITY_LINKS = "metric_subquery_entity_links" def __lt__(self, other: Any) -> bool: # type: ignore[misc] """Allow for ordering so that a sequence of these can be consistently represented for test snapshots.""" @@ -50,6 +51,7 @@ class EntityLinkPatternParameterSet: # Properties of time dimensions to match. time_granularity: Optional[TimeGranularity] = None date_part: Optional[DatePart] = None + metric_subquery_entity_links: Optional[Tuple[EntityReference, ...]] = None @staticmethod def from_parameters( # noqa: D102 @@ -58,6 +60,7 @@ def from_parameters( # noqa: D102 entity_links: Optional[Sequence[EntityReference]] = None, time_granularity: Optional[TimeGranularity] = None, date_part: Optional[DatePart] = None, + metric_subquery_entity_links: Optional[Tuple[EntityReference, ...]] = None, ) -> EntityLinkPatternParameterSet: return EntityLinkPatternParameterSet( fields_to_compare=tuple(sorted(fields_to_compare)), @@ -65,6 +68,7 @@ def from_parameters( # noqa: D102 entity_links=tuple(entity_links) if entity_links is not None else None, time_granularity=time_granularity, date_part=date_part, + metric_subquery_entity_links=metric_subquery_entity_links, ) def __post_init__(self) -> None: diff --git a/metricflow/specs/patterns/typed_patterns.py b/metricflow/specs/patterns/typed_patterns.py index 236ada1b21..71e38c583b 100644 --- a/metricflow/specs/patterns/typed_patterns.py +++ b/metricflow/specs/patterns/typed_patterns.py @@ -137,19 +137,23 @@ def from_call_parameter_set( # noqa: D102 "Currently only one group by item is allowed for Metric filters. " "This should have been caught by validations." ) - group_by = metric_call_parameter_set.group_by[0] - structured_name = StructuredLinkableSpecName.from_name(group_by.element_name) - entity_links = tuple( + structured_name = StructuredLinkableSpecName.from_name(metric_call_parameter_set.group_by[0].element_name) + metric_subquery_entity_links = tuple( EntityReference(entity_name) for entity_name in (structured_name.entity_link_names + (structured_name.element_name,)) ) + # Temp: we don't have a parameter to specify the join path from the outer query to the metric subquery, + # so just use the last entity. Will need to add another param for that later. + entity_links = metric_subquery_entity_links[-1:] return GroupByMetricPattern( parameter_set=EntityLinkPatternParameterSet.from_parameters( fields_to_compare=( ParameterSetField.ELEMENT_NAME, ParameterSetField.ENTITY_LINKS, + ParameterSetField.METRIC_SUBQUERY_ENTITY_LINKS, ), element_name=metric_call_parameter_set.metric_reference.element_name, entity_links=entity_links, + metric_subquery_entity_links=metric_subquery_entity_links, ) ) From 2cbc0aeace66592fde1fa6afbaec4d0b34d2f432 Mon Sep 17 00:00:00 2001 From: Courtney Holcomb Date: Mon, 29 Apr 2024 12:32:50 -0700 Subject: [PATCH 36/37] Write a test to ensure all single-hop linkable metrics can be queried without error --- .../builder/test_dataflow_plan_builder.py | 25 +++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/tests/dataflow/builder/test_dataflow_plan_builder.py b/tests/dataflow/builder/test_dataflow_plan_builder.py index 1d319ea2e3..4339606e72 100644 --- a/tests/dataflow/builder/test_dataflow_plan_builder.py +++ b/tests/dataflow/builder/test_dataflow_plan_builder.py @@ -2,17 +2,20 @@ import datetime import logging +import string import pytest from _pytest.fixtures import FixtureRequest from dbt_semantic_interfaces.implementations.filters.where_filter import PydanticWhereFilter from dbt_semantic_interfaces.naming.keywords import METRIC_TIME_ELEMENT_NAME +from dbt_semantic_interfaces.references import MeasureReference from dbt_semantic_interfaces.type_enums.time_granularity import TimeGranularity from metricflow.dataflow.builder.dataflow_plan_builder import DataflowPlanBuilder from metricflow.dataset.dataset import DataSet from metricflow.errors.errors import UnableToSatisfyQueryError from metricflow.filters.time_constraint import TimeRangeConstraint +from metricflow.model.semantics.linkable_element_properties import LinkableElementProperty from metricflow.query.query_parser import MetricFlowQueryParser from metricflow.specs.column_assoc import ColumnAssociationResolver from metricflow.specs.specs import ( @@ -1319,3 +1322,25 @@ def test_metric_in_metric_where_filter( mf_test_configuration=mf_test_configuration, dag_graph=dataflow_plan, ) + + +def test_all_available_single_join_metric_filters( + dataflow_plan_builder: DataflowPlanBuilder, query_parser: MetricFlowQueryParser +) -> None: + """Checks that all allowed metric filters do not error when used in dataflow plan (single-hop for both inner and out query).""" + for group_by_metric in dataflow_plan_builder._metric_lookup.linkable_elements_for_measure( + MeasureReference("listings"), without_any_of={LinkableElementProperty.MULTI_HOP} + ).as_spec_set.group_by_metric_specs: + entity_spec = group_by_metric.metric_subquery_entity_spec + if entity_spec.entity_links: + # TODO: Will handle in a different test. + continue + query_spec = query_parser.parse_and_validate_query( + metric_names=("listings",), + where_constraint=PydanticWhereFilter( + where_sql_template=string.Template("{{ Metric('$metric_name', ['$entity_name']) }} > 2").substitute( + metric_name=group_by_metric.element_name, entity_name=entity_spec.element_name + ), + ), + ) + dataflow_plan_builder.build_plan(query_spec) From 25648122b875fa63d2a242c194b913b4d4e71c95 Mon Sep 17 00:00:00 2001 From: Courtney Holcomb Date: Mon, 29 Apr 2024 14:50:18 -0700 Subject: [PATCH 37/37] Update snapshots --- ...linkable_element_set_as_spec_set__set0.txt | 60 +++ ...le_element_set_from_join_path__result0.txt | 20 + ..._set_from_join_path_multi_hop__result0.txt | 20 + ...linkable_elements_for_measure__result0.txt | 60 +++ ...elements_for_no_metrics_query__result0.txt | 438 ++++++++++++++++++ 5 files changed, 598 insertions(+) diff --git a/tests/snapshots/test_linkable_spec_resolver.py/list/test_linkable_element_set_as_spec_set__set0.txt b/tests/snapshots/test_linkable_spec_resolver.py/list/test_linkable_element_set_as_spec_set__set0.txt index 43779aedd4..f9b213db37 100644 --- a/tests/snapshots/test_linkable_spec_resolver.py/list/test_linkable_element_set_as_spec_set__set0.txt +++ b/tests/snapshots/test_linkable_spec_resolver.py/list/test_linkable_element_set_as_spec_set__set0.txt @@ -6,6 +6,44 @@ 'listing__average_booking_value', 'listing__average_instant_booking_value', 'listing__bookers', + 'listing__booking__listing__approximate_continuous_booking_value_p99', + 'listing__booking__listing__approximate_discrete_booking_value_p99', + 'listing__booking__listing__average_booking_value', + 'listing__booking__listing__average_instant_booking_value', + 'listing__booking__listing__bookers', + 'listing__booking__listing__booking_fees', + 'listing__booking__listing__booking_fees_per_booker', + 'listing__booking__listing__booking_payments', + 'listing__booking__listing__booking_value', + 'listing__booking__listing__booking_value_for_non_null_listing_id', + 'listing__booking__listing__booking_value_p99', + 'listing__booking__listing__booking_value_sub_instant', + 'listing__booking__listing__booking_value_sub_instant_add_10', + 'listing__booking__listing__bookings', + 'listing__booking__listing__bookings_fill_nulls_with_0', + 'listing__booking__listing__bookings_fill_nulls_with_0_without_time_spine', + 'listing__booking__listing__bookings_join_to_time_spine', + 'listing__booking__listing__bookings_per_booker', + 'listing__booking__listing__bookings_per_dollar', + 'listing__booking__listing__derived_bookings_0', + 'listing__booking__listing__derived_bookings_1', + 'listing__booking__listing__discrete_booking_value_p99', + 'listing__booking__listing__double_counted_delayed_bookings', + 'listing__booking__listing__instant_booking_fraction_of_max_value', + 'listing__booking__listing__instant_booking_value', + 'listing__booking__listing__instant_booking_value_ratio', + 'listing__booking__listing__instant_bookings', + 'listing__booking__listing__instant_lux_booking_value_rate', + 'listing__booking__listing__instant_plus_non_referred_bookings_pct', + 'listing__booking__listing__lux_booking_fraction_of_max_value', + 'listing__booking__listing__lux_booking_value_rate_expr', + 'listing__booking__listing__max_booking_value', + 'listing__booking__listing__median_booking_value', + 'listing__booking__listing__min_booking_value', + 'listing__booking__listing__nested_fill_nulls_without_time_spine', + 'listing__booking__listing__non_referred_bookings_pct', + 'listing__booking__listing__referred_bookings', + 'listing__booking__listing__twice_bookings_fill_nulls_with_0_without_time_spine', 'listing__booking_fees', 'listing__booking_fees_per_booker', 'listing__booking_payments', @@ -141,6 +179,7 @@ 'listing__smallest_listing', 'listing__twice_bookings_fill_nulls_with_0_without_time_spine', 'listing__user', + 'listing__view__listing__views', 'listing__views', 'listing__views_times_booking_value', 'metric_time__day', @@ -164,6 +203,9 @@ 'metric_time__week', 'metric_time__year', 'user', + 'user__account__user__current_account_balance_by_user', + 'user__account__user__regional_starting_balance_ratios', + 'user__account__user__total_account_balance_first_day', 'user__active_listings', 'user__company', 'user__company__active_listings', @@ -219,6 +261,7 @@ 'user__company__revenue_all_time', 'user__company__smallest_listing', 'user__company__total_account_balance_first_day', + 'user__company__views', 'user__company__visit_buy_conversion_rate', 'user__company__visit_buy_conversion_rate_7days', 'user__company__visit_buy_conversion_rate_7days_fill_nulls_with_0', @@ -310,6 +353,7 @@ 'user__home_state_latest', 'user__identity_verifications', 'user__largest_listing', + 'user__listing__user__active_listings', 'user__listing__user__approximate_continuous_booking_value_p99', 'user__listing__user__approximate_discrete_booking_value_p99', 'user__listing__user__average_booking_value', @@ -331,6 +375,8 @@ 'user__listing__user__bookings_per_booker', 'user__listing__user__bookings_per_dollar', 'user__listing__user__bookings_per_listing', + 'user__listing__user__bookings_per_listing', + 'user__listing__user__bookings_per_lux_listing_derived', 'user__listing__user__bookings_per_lux_listing_derived', 'user__listing__user__bookings_per_view', 'user__listing__user__derived_bookings_0', @@ -343,14 +389,18 @@ 'user__listing__user__instant_bookings', 'user__listing__user__instant_lux_booking_value_rate', 'user__listing__user__instant_plus_non_referred_bookings_pct', + 'user__listing__user__largest_listing', + 'user__listing__user__listings', 'user__listing__user__lux_booking_fraction_of_max_value', 'user__listing__user__lux_booking_value_rate_expr', + 'user__listing__user__lux_listings', 'user__listing__user__max_booking_value', 'user__listing__user__median_booking_value', 'user__listing__user__min_booking_value', 'user__listing__user__nested_fill_nulls_without_time_spine', 'user__listing__user__non_referred_bookings_pct', 'user__listing__user__referred_bookings', + 'user__listing__user__smallest_listing', 'user__listing__user__twice_bookings_fill_nulls_with_0_without_time_spine', 'user__listing__user__views', 'user__listing__user__views_times_booking_value', @@ -359,8 +409,18 @@ 'user__regional_starting_balance_ratios', 'user__revenue', 'user__revenue_all_time', + 'user__revenue_instance__user__revenue', + 'user__revenue_instance__user__revenue_all_time', 'user__smallest_listing', 'user__total_account_balance_first_day', + 'user__verification__user__identity_verifications', + 'user__view__user__views', + 'user__views', + 'user__visit__user__visit_buy_conversion_rate', + 'user__visit__user__visit_buy_conversion_rate_7days', + 'user__visit__user__visit_buy_conversion_rate_7days_fill_nulls_with_0', + 'user__visit__user__visit_buy_conversion_rate_by_session', + 'user__visit__user__visit_buy_conversions', 'user__visit_buy_conversion_rate', 'user__visit_buy_conversion_rate_7days', 'user__visit_buy_conversion_rate_7days_fill_nulls_with_0', diff --git a/tests/snapshots/test_linkable_spec_resolver.py/str/test_create_linkable_element_set_from_join_path__result0.txt b/tests/snapshots/test_linkable_spec_resolver.py/str/test_create_linkable_element_set_from_join_path__result0.txt index 9dc5906340..ddbe427da0 100644 --- a/tests/snapshots/test_linkable_spec_resolver.py/str/test_create_linkable_element_set_from_join_path__result0.txt +++ b/tests/snapshots/test_linkable_spec_resolver.py/str/test_create_linkable_element_set_from_join_path__result0.txt @@ -45,6 +45,7 @@ listings_latest ('listing',) ds listings_latest ('listing',) is_lux_latest ['JOINED'] listings_latest ('listing',) user ['ENTITY', 'JOINED'] listings_latest ('listing', 'user') active_listings ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('listing', 'user') active_listings ['JOINED', 'METRIC', 'MULTI_HOP'] listings_latest ('listing', 'user') approximate_continuous_booking_value_p99 ['JOINED', 'METRIC', 'MULTI_HOP'] listings_latest ('listing', 'user') approximate_discrete_booking_value_p99 ['JOINED', 'METRIC', 'MULTI_HOP'] listings_latest ('listing', 'user') average_booking_value ['JOINED', 'METRIC', 'MULTI_HOP'] @@ -66,14 +67,18 @@ listings_latest ('listing', 'user') bookings_join_to_time_spine listings_latest ('listing', 'user') bookings_per_booker ['JOINED', 'METRIC', 'MULTI_HOP'] listings_latest ('listing', 'user') bookings_per_dollar ['JOINED', 'METRIC', 'MULTI_HOP'] listings_latest ('listing', 'user') bookings_per_listing ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('listing', 'user') bookings_per_listing ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('listing', 'user') bookings_per_lux_listing_derived ['JOINED', 'METRIC', 'MULTI_HOP'] listings_latest ('listing', 'user') bookings_per_lux_listing_derived ['JOINED', 'METRIC', 'MULTI_HOP'] listings_latest ('listing', 'user') bookings_per_view ['JOINED', 'METRIC', 'MULTI_HOP'] listings_latest ('listing', 'user') current_account_balance_by_user ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('listing', 'user') current_account_balance_by_user ['JOINED', 'METRIC', 'MULTI_HOP'] listings_latest ('listing', 'user') derived_bookings_0 ['JOINED', 'METRIC', 'MULTI_HOP'] listings_latest ('listing', 'user') derived_bookings_1 ['JOINED', 'METRIC', 'MULTI_HOP'] listings_latest ('listing', 'user') discrete_booking_value_p99 ['JOINED', 'METRIC', 'MULTI_HOP'] listings_latest ('listing', 'user') double_counted_delayed_bookings ['JOINED', 'METRIC', 'MULTI_HOP'] listings_latest ('listing', 'user') identity_verifications ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('listing', 'user') identity_verifications ['JOINED', 'METRIC', 'MULTI_HOP'] listings_latest ('listing', 'user') instant_booking_fraction_of_max_value ['JOINED', 'METRIC', 'MULTI_HOP'] listings_latest ('listing', 'user') instant_booking_value ['JOINED', 'METRIC', 'MULTI_HOP'] listings_latest ('listing', 'user') instant_booking_value_ratio ['JOINED', 'METRIC', 'MULTI_HOP'] @@ -81,10 +86,13 @@ listings_latest ('listing', 'user') instant_bookings listings_latest ('listing', 'user') instant_lux_booking_value_rate ['JOINED', 'METRIC', 'MULTI_HOP'] listings_latest ('listing', 'user') instant_plus_non_referred_bookings_pct ['JOINED', 'METRIC', 'MULTI_HOP'] listings_latest ('listing', 'user') largest_listing ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('listing', 'user') largest_listing ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('listing', 'user') listings ['JOINED', 'METRIC', 'MULTI_HOP'] listings_latest ('listing', 'user') listings ['JOINED', 'METRIC', 'MULTI_HOP'] listings_latest ('listing', 'user') lux_booking_fraction_of_max_value ['JOINED', 'METRIC', 'MULTI_HOP'] listings_latest ('listing', 'user') lux_booking_value_rate_expr ['JOINED', 'METRIC', 'MULTI_HOP'] listings_latest ('listing', 'user') lux_listings ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('listing', 'user') lux_listings ['JOINED', 'METRIC', 'MULTI_HOP'] listings_latest ('listing', 'user') max_booking_value ['JOINED', 'METRIC', 'MULTI_HOP'] listings_latest ('listing', 'user') median_booking_value ['JOINED', 'METRIC', 'MULTI_HOP'] listings_latest ('listing', 'user') min_booking_value ['JOINED', 'METRIC', 'MULTI_HOP'] @@ -92,15 +100,27 @@ listings_latest ('listing', 'user') nested_fill_nulls_without_time_spine listings_latest ('listing', 'user') non_referred_bookings_pct ['JOINED', 'METRIC', 'MULTI_HOP'] listings_latest ('listing', 'user') referred_bookings ['JOINED', 'METRIC', 'MULTI_HOP'] listings_latest ('listing', 'user') regional_starting_balance_ratios ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('listing', 'user') regional_starting_balance_ratios ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('listing', 'user') revenue ['JOINED', 'METRIC', 'MULTI_HOP'] listings_latest ('listing', 'user') revenue ['JOINED', 'METRIC', 'MULTI_HOP'] listings_latest ('listing', 'user') revenue_all_time ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('listing', 'user') revenue_all_time ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('listing', 'user') smallest_listing ['JOINED', 'METRIC', 'MULTI_HOP'] listings_latest ('listing', 'user') smallest_listing ['JOINED', 'METRIC', 'MULTI_HOP'] listings_latest ('listing', 'user') total_account_balance_first_day ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('listing', 'user') total_account_balance_first_day ['JOINED', 'METRIC', 'MULTI_HOP'] listings_latest ('listing', 'user') twice_bookings_fill_nulls_with_0_without_time_spine ['JOINED', 'METRIC', 'MULTI_HOP'] listings_latest ('listing', 'user') views ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('listing', 'user') views ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('listing', 'user') views ['JOINED', 'METRIC', 'MULTI_HOP'] listings_latest ('listing', 'user') views_times_booking_value ['JOINED', 'METRIC', 'MULTI_HOP'] listings_latest ('listing', 'user') visit_buy_conversion_rate ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('listing', 'user') visit_buy_conversion_rate ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('listing', 'user') visit_buy_conversion_rate_7days ['JOINED', 'METRIC', 'MULTI_HOP'] listings_latest ('listing', 'user') visit_buy_conversion_rate_7days ['JOINED', 'METRIC', 'MULTI_HOP'] listings_latest ('listing', 'user') visit_buy_conversion_rate_7days_fill_nulls_with_0 ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('listing', 'user') visit_buy_conversion_rate_7days_fill_nulls_with_0 ['JOINED', 'METRIC', 'MULTI_HOP'] listings_latest ('listing', 'user') visit_buy_conversion_rate_by_session ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('listing', 'user') visit_buy_conversion_rate_by_session ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('listing', 'user') visit_buy_conversions ['JOINED', 'METRIC', 'MULTI_HOP'] listings_latest ('listing', 'user') visit_buy_conversions ['JOINED', 'METRIC', 'MULTI_HOP'] diff --git a/tests/snapshots/test_linkable_spec_resolver.py/str/test_create_linkable_element_set_from_join_path_multi_hop__result0.txt b/tests/snapshots/test_linkable_spec_resolver.py/str/test_create_linkable_element_set_from_join_path_multi_hop__result0.txt index 281437a0a5..89a4baf7ed 100644 --- a/tests/snapshots/test_linkable_spec_resolver.py/str/test_create_linkable_element_set_from_join_path_multi_hop__result0.txt +++ b/tests/snapshots/test_linkable_spec_resolver.py/str/test_create_linkable_element_set_from_join_path_multi_hop__result0.txt @@ -45,6 +45,7 @@ listings_latest ('guest', 'listing') ds listings_latest ('guest', 'listing') is_lux_latest ['JOINED', 'MULTI_HOP'] listings_latest ('guest', 'listing') user ['ENTITY', 'JOINED', 'MULTI_HOP'] listings_latest ('guest', 'listing', 'user') active_listings ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('guest', 'listing', 'user') active_listings ['JOINED', 'METRIC', 'MULTI_HOP'] listings_latest ('guest', 'listing', 'user') approximate_continuous_booking_value_p99 ['JOINED', 'METRIC', 'MULTI_HOP'] listings_latest ('guest', 'listing', 'user') approximate_discrete_booking_value_p99 ['JOINED', 'METRIC', 'MULTI_HOP'] listings_latest ('guest', 'listing', 'user') average_booking_value ['JOINED', 'METRIC', 'MULTI_HOP'] @@ -66,14 +67,18 @@ listings_latest ('guest', 'listing', 'user') bookings_join_to_time_spine listings_latest ('guest', 'listing', 'user') bookings_per_booker ['JOINED', 'METRIC', 'MULTI_HOP'] listings_latest ('guest', 'listing', 'user') bookings_per_dollar ['JOINED', 'METRIC', 'MULTI_HOP'] listings_latest ('guest', 'listing', 'user') bookings_per_listing ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('guest', 'listing', 'user') bookings_per_listing ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('guest', 'listing', 'user') bookings_per_lux_listing_derived ['JOINED', 'METRIC', 'MULTI_HOP'] listings_latest ('guest', 'listing', 'user') bookings_per_lux_listing_derived ['JOINED', 'METRIC', 'MULTI_HOP'] listings_latest ('guest', 'listing', 'user') bookings_per_view ['JOINED', 'METRIC', 'MULTI_HOP'] listings_latest ('guest', 'listing', 'user') current_account_balance_by_user ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('guest', 'listing', 'user') current_account_balance_by_user ['JOINED', 'METRIC', 'MULTI_HOP'] listings_latest ('guest', 'listing', 'user') derived_bookings_0 ['JOINED', 'METRIC', 'MULTI_HOP'] listings_latest ('guest', 'listing', 'user') derived_bookings_1 ['JOINED', 'METRIC', 'MULTI_HOP'] listings_latest ('guest', 'listing', 'user') discrete_booking_value_p99 ['JOINED', 'METRIC', 'MULTI_HOP'] listings_latest ('guest', 'listing', 'user') double_counted_delayed_bookings ['JOINED', 'METRIC', 'MULTI_HOP'] listings_latest ('guest', 'listing', 'user') identity_verifications ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('guest', 'listing', 'user') identity_verifications ['JOINED', 'METRIC', 'MULTI_HOP'] listings_latest ('guest', 'listing', 'user') instant_booking_fraction_of_max_value ['JOINED', 'METRIC', 'MULTI_HOP'] listings_latest ('guest', 'listing', 'user') instant_booking_value ['JOINED', 'METRIC', 'MULTI_HOP'] listings_latest ('guest', 'listing', 'user') instant_booking_value_ratio ['JOINED', 'METRIC', 'MULTI_HOP'] @@ -81,10 +86,13 @@ listings_latest ('guest', 'listing', 'user') instant_bookings listings_latest ('guest', 'listing', 'user') instant_lux_booking_value_rate ['JOINED', 'METRIC', 'MULTI_HOP'] listings_latest ('guest', 'listing', 'user') instant_plus_non_referred_bookings_pct ['JOINED', 'METRIC', 'MULTI_HOP'] listings_latest ('guest', 'listing', 'user') largest_listing ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('guest', 'listing', 'user') largest_listing ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('guest', 'listing', 'user') listings ['JOINED', 'METRIC', 'MULTI_HOP'] listings_latest ('guest', 'listing', 'user') listings ['JOINED', 'METRIC', 'MULTI_HOP'] listings_latest ('guest', 'listing', 'user') lux_booking_fraction_of_max_value ['JOINED', 'METRIC', 'MULTI_HOP'] listings_latest ('guest', 'listing', 'user') lux_booking_value_rate_expr ['JOINED', 'METRIC', 'MULTI_HOP'] listings_latest ('guest', 'listing', 'user') lux_listings ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('guest', 'listing', 'user') lux_listings ['JOINED', 'METRIC', 'MULTI_HOP'] listings_latest ('guest', 'listing', 'user') max_booking_value ['JOINED', 'METRIC', 'MULTI_HOP'] listings_latest ('guest', 'listing', 'user') median_booking_value ['JOINED', 'METRIC', 'MULTI_HOP'] listings_latest ('guest', 'listing', 'user') min_booking_value ['JOINED', 'METRIC', 'MULTI_HOP'] @@ -92,15 +100,27 @@ listings_latest ('guest', 'listing', 'user') nested_fill_nulls_without_time_s listings_latest ('guest', 'listing', 'user') non_referred_bookings_pct ['JOINED', 'METRIC', 'MULTI_HOP'] listings_latest ('guest', 'listing', 'user') referred_bookings ['JOINED', 'METRIC', 'MULTI_HOP'] listings_latest ('guest', 'listing', 'user') regional_starting_balance_ratios ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('guest', 'listing', 'user') regional_starting_balance_ratios ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('guest', 'listing', 'user') revenue ['JOINED', 'METRIC', 'MULTI_HOP'] listings_latest ('guest', 'listing', 'user') revenue ['JOINED', 'METRIC', 'MULTI_HOP'] listings_latest ('guest', 'listing', 'user') revenue_all_time ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('guest', 'listing', 'user') revenue_all_time ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('guest', 'listing', 'user') smallest_listing ['JOINED', 'METRIC', 'MULTI_HOP'] listings_latest ('guest', 'listing', 'user') smallest_listing ['JOINED', 'METRIC', 'MULTI_HOP'] listings_latest ('guest', 'listing', 'user') total_account_balance_first_day ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('guest', 'listing', 'user') total_account_balance_first_day ['JOINED', 'METRIC', 'MULTI_HOP'] listings_latest ('guest', 'listing', 'user') twice_bookings_fill_nulls_with_0_without_time_spine ['JOINED', 'METRIC', 'MULTI_HOP'] listings_latest ('guest', 'listing', 'user') views ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('guest', 'listing', 'user') views ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('guest', 'listing', 'user') views ['JOINED', 'METRIC', 'MULTI_HOP'] listings_latest ('guest', 'listing', 'user') views_times_booking_value ['JOINED', 'METRIC', 'MULTI_HOP'] listings_latest ('guest', 'listing', 'user') visit_buy_conversion_rate ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('guest', 'listing', 'user') visit_buy_conversion_rate ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('guest', 'listing', 'user') visit_buy_conversion_rate_7days ['JOINED', 'METRIC', 'MULTI_HOP'] listings_latest ('guest', 'listing', 'user') visit_buy_conversion_rate_7days ['JOINED', 'METRIC', 'MULTI_HOP'] listings_latest ('guest', 'listing', 'user') visit_buy_conversion_rate_7days_fill_nulls_with_0 ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('guest', 'listing', 'user') visit_buy_conversion_rate_7days_fill_nulls_with_0 ['JOINED', 'METRIC', 'MULTI_HOP'] listings_latest ('guest', 'listing', 'user') visit_buy_conversion_rate_by_session ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('guest', 'listing', 'user') visit_buy_conversion_rate_by_session ['JOINED', 'METRIC', 'MULTI_HOP'] +listings_latest ('guest', 'listing', 'user') visit_buy_conversions ['JOINED', 'METRIC', 'MULTI_HOP'] listings_latest ('guest', 'listing', 'user') visit_buy_conversions ['JOINED', 'METRIC', 'MULTI_HOP'] diff --git a/tests/snapshots/test_semantic_model_container.py/str/test_linkable_elements_for_measure__result0.txt b/tests/snapshots/test_semantic_model_container.py/str/test_linkable_elements_for_measure__result0.txt index f3ac302c66..3e37b88205 100644 --- a/tests/snapshots/test_semantic_model_container.py/str/test_linkable_elements_for_measure__result0.txt +++ b/tests/snapshots/test_semantic_model_container.py/str/test_linkable_elements_for_measure__result0.txt @@ -2,54 +2,94 @@ Semantic Model Entity Links Name ------------------- -------------------------- --------------------------------------------------- ------------------ ----------- ------------------------------------------- ('listing',) active_listings ['JOINED', 'METRIC'] ('listing',) approximate_continuous_booking_value_p99 ['JOINED', 'METRIC'] + ('listing',) approximate_continuous_booking_value_p99 ['JOINED', 'METRIC'] + ('listing',) approximate_discrete_booking_value_p99 ['JOINED', 'METRIC'] ('listing',) approximate_discrete_booking_value_p99 ['JOINED', 'METRIC'] ('listing',) average_booking_value ['JOINED', 'METRIC'] + ('listing',) average_booking_value ['JOINED', 'METRIC'] + ('listing',) average_instant_booking_value ['JOINED', 'METRIC'] ('listing',) average_instant_booking_value ['JOINED', 'METRIC'] ('listing',) bookers ['JOINED', 'METRIC'] + ('listing',) bookers ['JOINED', 'METRIC'] + ('listing',) booking_fees ['JOINED', 'METRIC'] ('listing',) booking_fees ['JOINED', 'METRIC'] ('listing',) booking_fees_per_booker ['JOINED', 'METRIC'] + ('listing',) booking_fees_per_booker ['JOINED', 'METRIC'] + ('listing',) booking_payments ['JOINED', 'METRIC'] ('listing',) booking_payments ['JOINED', 'METRIC'] ('listing',) booking_value ['JOINED', 'METRIC'] + ('listing',) booking_value ['JOINED', 'METRIC'] + ('listing',) booking_value_for_non_null_listing_id ['JOINED', 'METRIC'] ('listing',) booking_value_for_non_null_listing_id ['JOINED', 'METRIC'] ('listing',) booking_value_p99 ['JOINED', 'METRIC'] + ('listing',) booking_value_p99 ['JOINED', 'METRIC'] ('listing',) booking_value_per_view ['JOINED', 'METRIC'] ('listing',) booking_value_sub_instant ['JOINED', 'METRIC'] + ('listing',) booking_value_sub_instant ['JOINED', 'METRIC'] ('listing',) booking_value_sub_instant_add_10 ['JOINED', 'METRIC'] + ('listing',) booking_value_sub_instant_add_10 ['JOINED', 'METRIC'] + ('listing',) bookings ['JOINED', 'METRIC'] ('listing',) bookings ['JOINED', 'METRIC'] ('listing',) bookings_fill_nulls_with_0 ['JOINED', 'METRIC'] + ('listing',) bookings_fill_nulls_with_0 ['JOINED', 'METRIC'] ('listing',) bookings_fill_nulls_with_0_without_time_spine ['JOINED', 'METRIC'] + ('listing',) bookings_fill_nulls_with_0_without_time_spine ['JOINED', 'METRIC'] + ('listing',) bookings_join_to_time_spine ['JOINED', 'METRIC'] ('listing',) bookings_join_to_time_spine ['JOINED', 'METRIC'] ('listing',) bookings_per_booker ['JOINED', 'METRIC'] + ('listing',) bookings_per_booker ['JOINED', 'METRIC'] + ('listing',) bookings_per_dollar ['JOINED', 'METRIC'] ('listing',) bookings_per_dollar ['JOINED', 'METRIC'] ('listing',) bookings_per_listing ['JOINED', 'METRIC'] ('listing',) bookings_per_lux_listing_derived ['JOINED', 'METRIC'] ('listing',) bookings_per_view ['JOINED', 'METRIC'] ('listing',) derived_bookings_0 ['JOINED', 'METRIC'] + ('listing',) derived_bookings_0 ['JOINED', 'METRIC'] + ('listing',) derived_bookings_1 ['JOINED', 'METRIC'] ('listing',) derived_bookings_1 ['JOINED', 'METRIC'] ('listing',) discrete_booking_value_p99 ['JOINED', 'METRIC'] + ('listing',) discrete_booking_value_p99 ['JOINED', 'METRIC'] + ('listing',) double_counted_delayed_bookings ['JOINED', 'METRIC'] ('listing',) double_counted_delayed_bookings ['JOINED', 'METRIC'] ('listing',) instant_booking_fraction_of_max_value ['JOINED', 'METRIC'] + ('listing',) instant_booking_fraction_of_max_value ['JOINED', 'METRIC'] + ('listing',) instant_booking_value ['JOINED', 'METRIC'] ('listing',) instant_booking_value ['JOINED', 'METRIC'] ('listing',) instant_booking_value_ratio ['JOINED', 'METRIC'] + ('listing',) instant_booking_value_ratio ['JOINED', 'METRIC'] + ('listing',) instant_bookings ['JOINED', 'METRIC'] ('listing',) instant_bookings ['JOINED', 'METRIC'] ('listing',) instant_lux_booking_value_rate ['JOINED', 'METRIC'] + ('listing',) instant_lux_booking_value_rate ['JOINED', 'METRIC'] + ('listing',) instant_plus_non_referred_bookings_pct ['JOINED', 'METRIC'] ('listing',) instant_plus_non_referred_bookings_pct ['JOINED', 'METRIC'] ('listing',) largest_listing ['JOINED', 'METRIC'] ('listing',) listings ['JOINED', 'METRIC'] ('listing',) lux_booking_fraction_of_max_value ['JOINED', 'METRIC'] + ('listing',) lux_booking_fraction_of_max_value ['JOINED', 'METRIC'] + ('listing',) lux_booking_value_rate_expr ['JOINED', 'METRIC'] ('listing',) lux_booking_value_rate_expr ['JOINED', 'METRIC'] ('listing',) lux_listings ['JOINED', 'METRIC'] ('listing',) max_booking_value ['JOINED', 'METRIC'] + ('listing',) max_booking_value ['JOINED', 'METRIC'] ('listing',) median_booking_value ['JOINED', 'METRIC'] + ('listing',) median_booking_value ['JOINED', 'METRIC'] + ('listing',) min_booking_value ['JOINED', 'METRIC'] ('listing',) min_booking_value ['JOINED', 'METRIC'] ('listing',) nested_fill_nulls_without_time_spine ['JOINED', 'METRIC'] + ('listing',) nested_fill_nulls_without_time_spine ['JOINED', 'METRIC'] + ('listing',) non_referred_bookings_pct ['JOINED', 'METRIC'] ('listing',) non_referred_bookings_pct ['JOINED', 'METRIC'] ('listing',) referred_bookings ['JOINED', 'METRIC'] + ('listing',) referred_bookings ['JOINED', 'METRIC'] ('listing',) smallest_listing ['JOINED', 'METRIC'] ('listing',) twice_bookings_fill_nulls_with_0_without_time_spine ['JOINED', 'METRIC'] + ('listing',) twice_bookings_fill_nulls_with_0_without_time_spine ['JOINED', 'METRIC'] + ('listing',) views ['JOINED', 'METRIC'] ('listing',) views ['JOINED', 'METRIC'] ('listing',) views_times_booking_value ['JOINED', 'METRIC'] ('user',) active_listings ['JOINED', 'METRIC'] + ('user',) active_listings ['JOINED', 'METRIC'] ('user',) approximate_continuous_booking_value_p99 ['JOINED', 'METRIC'] ('user',) approximate_discrete_booking_value_p99 ['JOINED', 'METRIC'] ('user',) average_booking_value ['JOINED', 'METRIC'] @@ -71,14 +111,18 @@ Semantic Model Entity Links Name ('user',) bookings_per_booker ['JOINED', 'METRIC'] ('user',) bookings_per_dollar ['JOINED', 'METRIC'] ('user',) bookings_per_listing ['JOINED', 'METRIC'] + ('user',) bookings_per_listing ['JOINED', 'METRIC'] + ('user',) bookings_per_lux_listing_derived ['JOINED', 'METRIC'] ('user',) bookings_per_lux_listing_derived ['JOINED', 'METRIC'] ('user',) bookings_per_view ['JOINED', 'METRIC'] ('user',) current_account_balance_by_user ['JOINED', 'METRIC'] + ('user',) current_account_balance_by_user ['JOINED', 'METRIC'] ('user',) derived_bookings_0 ['JOINED', 'METRIC'] ('user',) derived_bookings_1 ['JOINED', 'METRIC'] ('user',) discrete_booking_value_p99 ['JOINED', 'METRIC'] ('user',) double_counted_delayed_bookings ['JOINED', 'METRIC'] ('user',) identity_verifications ['JOINED', 'METRIC'] + ('user',) identity_verifications ['JOINED', 'METRIC'] ('user',) instant_booking_fraction_of_max_value ['JOINED', 'METRIC'] ('user',) instant_booking_value ['JOINED', 'METRIC'] ('user',) instant_booking_value_ratio ['JOINED', 'METRIC'] @@ -86,10 +130,13 @@ Semantic Model Entity Links Name ('user',) instant_lux_booking_value_rate ['JOINED', 'METRIC'] ('user',) instant_plus_non_referred_bookings_pct ['JOINED', 'METRIC'] ('user',) largest_listing ['JOINED', 'METRIC'] + ('user',) largest_listing ['JOINED', 'METRIC'] + ('user',) listings ['JOINED', 'METRIC'] ('user',) listings ['JOINED', 'METRIC'] ('user',) lux_booking_fraction_of_max_value ['JOINED', 'METRIC'] ('user',) lux_booking_value_rate_expr ['JOINED', 'METRIC'] ('user',) lux_listings ['JOINED', 'METRIC'] + ('user',) lux_listings ['JOINED', 'METRIC'] ('user',) max_booking_value ['JOINED', 'METRIC'] ('user',) median_booking_value ['JOINED', 'METRIC'] ('user',) min_booking_value ['JOINED', 'METRIC'] @@ -97,17 +144,29 @@ Semantic Model Entity Links Name ('user',) non_referred_bookings_pct ['JOINED', 'METRIC'] ('user',) referred_bookings ['JOINED', 'METRIC'] ('user',) regional_starting_balance_ratios ['JOINED', 'METRIC'] + ('user',) regional_starting_balance_ratios ['JOINED', 'METRIC'] + ('user',) revenue ['JOINED', 'METRIC'] ('user',) revenue ['JOINED', 'METRIC'] ('user',) revenue_all_time ['JOINED', 'METRIC'] + ('user',) revenue_all_time ['JOINED', 'METRIC'] + ('user',) smallest_listing ['JOINED', 'METRIC'] ('user',) smallest_listing ['JOINED', 'METRIC'] ('user',) total_account_balance_first_day ['JOINED', 'METRIC'] + ('user',) total_account_balance_first_day ['JOINED', 'METRIC'] ('user',) twice_bookings_fill_nulls_with_0_without_time_spine ['JOINED', 'METRIC'] ('user',) views ['JOINED', 'METRIC'] + ('user',) views ['JOINED', 'METRIC'] + ('user',) views ['JOINED', 'METRIC'] ('user',) views_times_booking_value ['JOINED', 'METRIC'] ('user',) visit_buy_conversion_rate ['JOINED', 'METRIC'] + ('user',) visit_buy_conversion_rate ['JOINED', 'METRIC'] ('user',) visit_buy_conversion_rate_7days ['JOINED', 'METRIC'] + ('user',) visit_buy_conversion_rate_7days ['JOINED', 'METRIC'] + ('user',) visit_buy_conversion_rate_7days_fill_nulls_with_0 ['JOINED', 'METRIC'] ('user',) visit_buy_conversion_rate_7days_fill_nulls_with_0 ['JOINED', 'METRIC'] ('user',) visit_buy_conversion_rate_by_session ['JOINED', 'METRIC'] + ('user',) visit_buy_conversion_rate_by_session ['JOINED', 'METRIC'] + ('user',) visit_buy_conversions ['JOINED', 'METRIC'] ('user',) visit_buy_conversions ['JOINED', 'METRIC'] companies ('user',) company ['ENTITY', 'JOINED'] companies ('user',) company_name ['JOINED'] @@ -163,6 +222,7 @@ companies ('user', 'company') smallest_listing companies ('user', 'company') total_account_balance_first_day ['JOINED', 'METRIC', 'MULTI_HOP'] companies ('user', 'company') twice_bookings_fill_nulls_with_0_without_time_spine ['JOINED', 'METRIC', 'MULTI_HOP'] companies ('user', 'company') views ['JOINED', 'METRIC', 'MULTI_HOP'] +companies ('user', 'company') views ['JOINED', 'METRIC', 'MULTI_HOP'] companies ('user', 'company') views_times_booking_value ['JOINED', 'METRIC', 'MULTI_HOP'] companies ('user', 'company') visit_buy_conversion_rate ['JOINED', 'METRIC', 'MULTI_HOP'] companies ('user', 'company') visit_buy_conversion_rate_7days ['JOINED', 'METRIC', 'MULTI_HOP'] diff --git a/tests/snapshots/test_semantic_model_container.py/tuple/test_linkable_elements_for_no_metrics_query__result0.txt b/tests/snapshots/test_semantic_model_container.py/tuple/test_linkable_elements_for_no_metrics_query__result0.txt index 5f839385f5..c214f5316f 100644 --- a/tests/snapshots/test_semantic_model_container.py/tuple/test_linkable_elements_for_no_metrics_query__result0.txt +++ b/tests/snapshots/test_semantic_model_container.py/tuple/test_linkable_elements_for_no_metrics_query__result0.txt @@ -98,6 +98,7 @@ 'company__user__company__revenue_all_time', 'company__user__company__smallest_listing', 'company__user__company__total_account_balance_first_day', + 'company__user__company__views', 'company__user__company__visit_buy_conversion_rate', 'company__user__company__visit_buy_conversion_rate_7days', 'company__user__company__visit_buy_conversion_rate_7days_fill_nulls_with_0', @@ -109,6 +110,44 @@ 'guest__average_booking_value', 'guest__average_instant_booking_value', 'guest__bookers', + 'guest__booking__guest__approximate_continuous_booking_value_p99', + 'guest__booking__guest__approximate_discrete_booking_value_p99', + 'guest__booking__guest__average_booking_value', + 'guest__booking__guest__average_instant_booking_value', + 'guest__booking__guest__bookers', + 'guest__booking__guest__booking_fees', + 'guest__booking__guest__booking_fees_per_booker', + 'guest__booking__guest__booking_payments', + 'guest__booking__guest__booking_value', + 'guest__booking__guest__booking_value_for_non_null_listing_id', + 'guest__booking__guest__booking_value_p99', + 'guest__booking__guest__booking_value_sub_instant', + 'guest__booking__guest__booking_value_sub_instant_add_10', + 'guest__booking__guest__bookings', + 'guest__booking__guest__bookings_fill_nulls_with_0', + 'guest__booking__guest__bookings_fill_nulls_with_0_without_time_spine', + 'guest__booking__guest__bookings_join_to_time_spine', + 'guest__booking__guest__bookings_per_booker', + 'guest__booking__guest__bookings_per_dollar', + 'guest__booking__guest__derived_bookings_0', + 'guest__booking__guest__derived_bookings_1', + 'guest__booking__guest__discrete_booking_value_p99', + 'guest__booking__guest__double_counted_delayed_bookings', + 'guest__booking__guest__instant_booking_fraction_of_max_value', + 'guest__booking__guest__instant_booking_value', + 'guest__booking__guest__instant_booking_value_ratio', + 'guest__booking__guest__instant_bookings', + 'guest__booking__guest__instant_lux_booking_value_rate', + 'guest__booking__guest__instant_plus_non_referred_bookings_pct', + 'guest__booking__guest__lux_booking_fraction_of_max_value', + 'guest__booking__guest__lux_booking_value_rate_expr', + 'guest__booking__guest__max_booking_value', + 'guest__booking__guest__median_booking_value', + 'guest__booking__guest__min_booking_value', + 'guest__booking__guest__nested_fill_nulls_without_time_spine', + 'guest__booking__guest__non_referred_bookings_pct', + 'guest__booking__guest__referred_bookings', + 'guest__booking__guest__twice_bookings_fill_nulls_with_0_without_time_spine', 'guest__booking_fees', 'guest__booking_fees_per_booker', 'guest__booking_payments', @@ -148,6 +187,44 @@ 'host__average_booking_value', 'host__average_instant_booking_value', 'host__bookers', + 'host__booking__host__approximate_continuous_booking_value_p99', + 'host__booking__host__approximate_discrete_booking_value_p99', + 'host__booking__host__average_booking_value', + 'host__booking__host__average_instant_booking_value', + 'host__booking__host__bookers', + 'host__booking__host__booking_fees', + 'host__booking__host__booking_fees_per_booker', + 'host__booking__host__booking_payments', + 'host__booking__host__booking_value', + 'host__booking__host__booking_value_for_non_null_listing_id', + 'host__booking__host__booking_value_p99', + 'host__booking__host__booking_value_sub_instant', + 'host__booking__host__booking_value_sub_instant_add_10', + 'host__booking__host__bookings', + 'host__booking__host__bookings_fill_nulls_with_0', + 'host__booking__host__bookings_fill_nulls_with_0_without_time_spine', + 'host__booking__host__bookings_join_to_time_spine', + 'host__booking__host__bookings_per_booker', + 'host__booking__host__bookings_per_dollar', + 'host__booking__host__derived_bookings_0', + 'host__booking__host__derived_bookings_1', + 'host__booking__host__discrete_booking_value_p99', + 'host__booking__host__double_counted_delayed_bookings', + 'host__booking__host__instant_booking_fraction_of_max_value', + 'host__booking__host__instant_booking_value', + 'host__booking__host__instant_booking_value_ratio', + 'host__booking__host__instant_bookings', + 'host__booking__host__instant_lux_booking_value_rate', + 'host__booking__host__instant_plus_non_referred_bookings_pct', + 'host__booking__host__lux_booking_fraction_of_max_value', + 'host__booking__host__lux_booking_value_rate_expr', + 'host__booking__host__max_booking_value', + 'host__booking__host__median_booking_value', + 'host__booking__host__min_booking_value', + 'host__booking__host__nested_fill_nulls_without_time_spine', + 'host__booking__host__non_referred_bookings_pct', + 'host__booking__host__referred_bookings', + 'host__booking__host__twice_bookings_fill_nulls_with_0_without_time_spine', 'host__booking_fees', 'host__booking_fees_per_booker', 'host__booking_payments', @@ -206,6 +283,158 @@ 'listing__bookers', 'listing__bookers', 'listing__bookers', + 'listing__booking__listing__approximate_continuous_booking_value_p99', + 'listing__booking__listing__approximate_continuous_booking_value_p99', + 'listing__booking__listing__approximate_continuous_booking_value_p99', + 'listing__booking__listing__approximate_continuous_booking_value_p99', + 'listing__booking__listing__approximate_discrete_booking_value_p99', + 'listing__booking__listing__approximate_discrete_booking_value_p99', + 'listing__booking__listing__approximate_discrete_booking_value_p99', + 'listing__booking__listing__approximate_discrete_booking_value_p99', + 'listing__booking__listing__average_booking_value', + 'listing__booking__listing__average_booking_value', + 'listing__booking__listing__average_booking_value', + 'listing__booking__listing__average_booking_value', + 'listing__booking__listing__average_instant_booking_value', + 'listing__booking__listing__average_instant_booking_value', + 'listing__booking__listing__average_instant_booking_value', + 'listing__booking__listing__average_instant_booking_value', + 'listing__booking__listing__bookers', + 'listing__booking__listing__bookers', + 'listing__booking__listing__bookers', + 'listing__booking__listing__bookers', + 'listing__booking__listing__booking_fees', + 'listing__booking__listing__booking_fees', + 'listing__booking__listing__booking_fees', + 'listing__booking__listing__booking_fees', + 'listing__booking__listing__booking_fees_per_booker', + 'listing__booking__listing__booking_fees_per_booker', + 'listing__booking__listing__booking_fees_per_booker', + 'listing__booking__listing__booking_fees_per_booker', + 'listing__booking__listing__booking_payments', + 'listing__booking__listing__booking_payments', + 'listing__booking__listing__booking_payments', + 'listing__booking__listing__booking_payments', + 'listing__booking__listing__booking_value', + 'listing__booking__listing__booking_value', + 'listing__booking__listing__booking_value', + 'listing__booking__listing__booking_value', + 'listing__booking__listing__booking_value_for_non_null_listing_id', + 'listing__booking__listing__booking_value_for_non_null_listing_id', + 'listing__booking__listing__booking_value_for_non_null_listing_id', + 'listing__booking__listing__booking_value_for_non_null_listing_id', + 'listing__booking__listing__booking_value_p99', + 'listing__booking__listing__booking_value_p99', + 'listing__booking__listing__booking_value_p99', + 'listing__booking__listing__booking_value_p99', + 'listing__booking__listing__booking_value_sub_instant', + 'listing__booking__listing__booking_value_sub_instant', + 'listing__booking__listing__booking_value_sub_instant', + 'listing__booking__listing__booking_value_sub_instant', + 'listing__booking__listing__booking_value_sub_instant_add_10', + 'listing__booking__listing__booking_value_sub_instant_add_10', + 'listing__booking__listing__booking_value_sub_instant_add_10', + 'listing__booking__listing__booking_value_sub_instant_add_10', + 'listing__booking__listing__bookings', + 'listing__booking__listing__bookings', + 'listing__booking__listing__bookings', + 'listing__booking__listing__bookings', + 'listing__booking__listing__bookings_fill_nulls_with_0', + 'listing__booking__listing__bookings_fill_nulls_with_0', + 'listing__booking__listing__bookings_fill_nulls_with_0', + 'listing__booking__listing__bookings_fill_nulls_with_0', + 'listing__booking__listing__bookings_fill_nulls_with_0_without_time_spine', + 'listing__booking__listing__bookings_fill_nulls_with_0_without_time_spine', + 'listing__booking__listing__bookings_fill_nulls_with_0_without_time_spine', + 'listing__booking__listing__bookings_fill_nulls_with_0_without_time_spine', + 'listing__booking__listing__bookings_join_to_time_spine', + 'listing__booking__listing__bookings_join_to_time_spine', + 'listing__booking__listing__bookings_join_to_time_spine', + 'listing__booking__listing__bookings_join_to_time_spine', + 'listing__booking__listing__bookings_per_booker', + 'listing__booking__listing__bookings_per_booker', + 'listing__booking__listing__bookings_per_booker', + 'listing__booking__listing__bookings_per_booker', + 'listing__booking__listing__bookings_per_dollar', + 'listing__booking__listing__bookings_per_dollar', + 'listing__booking__listing__bookings_per_dollar', + 'listing__booking__listing__bookings_per_dollar', + 'listing__booking__listing__derived_bookings_0', + 'listing__booking__listing__derived_bookings_0', + 'listing__booking__listing__derived_bookings_0', + 'listing__booking__listing__derived_bookings_0', + 'listing__booking__listing__derived_bookings_1', + 'listing__booking__listing__derived_bookings_1', + 'listing__booking__listing__derived_bookings_1', + 'listing__booking__listing__derived_bookings_1', + 'listing__booking__listing__discrete_booking_value_p99', + 'listing__booking__listing__discrete_booking_value_p99', + 'listing__booking__listing__discrete_booking_value_p99', + 'listing__booking__listing__discrete_booking_value_p99', + 'listing__booking__listing__double_counted_delayed_bookings', + 'listing__booking__listing__double_counted_delayed_bookings', + 'listing__booking__listing__double_counted_delayed_bookings', + 'listing__booking__listing__double_counted_delayed_bookings', + 'listing__booking__listing__instant_booking_fraction_of_max_value', + 'listing__booking__listing__instant_booking_fraction_of_max_value', + 'listing__booking__listing__instant_booking_fraction_of_max_value', + 'listing__booking__listing__instant_booking_fraction_of_max_value', + 'listing__booking__listing__instant_booking_value', + 'listing__booking__listing__instant_booking_value', + 'listing__booking__listing__instant_booking_value', + 'listing__booking__listing__instant_booking_value', + 'listing__booking__listing__instant_booking_value_ratio', + 'listing__booking__listing__instant_booking_value_ratio', + 'listing__booking__listing__instant_booking_value_ratio', + 'listing__booking__listing__instant_booking_value_ratio', + 'listing__booking__listing__instant_bookings', + 'listing__booking__listing__instant_bookings', + 'listing__booking__listing__instant_bookings', + 'listing__booking__listing__instant_bookings', + 'listing__booking__listing__instant_lux_booking_value_rate', + 'listing__booking__listing__instant_lux_booking_value_rate', + 'listing__booking__listing__instant_lux_booking_value_rate', + 'listing__booking__listing__instant_lux_booking_value_rate', + 'listing__booking__listing__instant_plus_non_referred_bookings_pct', + 'listing__booking__listing__instant_plus_non_referred_bookings_pct', + 'listing__booking__listing__instant_plus_non_referred_bookings_pct', + 'listing__booking__listing__instant_plus_non_referred_bookings_pct', + 'listing__booking__listing__lux_booking_fraction_of_max_value', + 'listing__booking__listing__lux_booking_fraction_of_max_value', + 'listing__booking__listing__lux_booking_fraction_of_max_value', + 'listing__booking__listing__lux_booking_fraction_of_max_value', + 'listing__booking__listing__lux_booking_value_rate_expr', + 'listing__booking__listing__lux_booking_value_rate_expr', + 'listing__booking__listing__lux_booking_value_rate_expr', + 'listing__booking__listing__lux_booking_value_rate_expr', + 'listing__booking__listing__max_booking_value', + 'listing__booking__listing__max_booking_value', + 'listing__booking__listing__max_booking_value', + 'listing__booking__listing__max_booking_value', + 'listing__booking__listing__median_booking_value', + 'listing__booking__listing__median_booking_value', + 'listing__booking__listing__median_booking_value', + 'listing__booking__listing__median_booking_value', + 'listing__booking__listing__min_booking_value', + 'listing__booking__listing__min_booking_value', + 'listing__booking__listing__min_booking_value', + 'listing__booking__listing__min_booking_value', + 'listing__booking__listing__nested_fill_nulls_without_time_spine', + 'listing__booking__listing__nested_fill_nulls_without_time_spine', + 'listing__booking__listing__nested_fill_nulls_without_time_spine', + 'listing__booking__listing__nested_fill_nulls_without_time_spine', + 'listing__booking__listing__non_referred_bookings_pct', + 'listing__booking__listing__non_referred_bookings_pct', + 'listing__booking__listing__non_referred_bookings_pct', + 'listing__booking__listing__non_referred_bookings_pct', + 'listing__booking__listing__referred_bookings', + 'listing__booking__listing__referred_bookings', + 'listing__booking__listing__referred_bookings', + 'listing__booking__listing__referred_bookings', + 'listing__booking__listing__twice_bookings_fill_nulls_with_0_without_time_spine', + 'listing__booking__listing__twice_bookings_fill_nulls_with_0_without_time_spine', + 'listing__booking__listing__twice_bookings_fill_nulls_with_0_without_time_spine', + 'listing__booking__listing__twice_bookings_fill_nulls_with_0_without_time_spine', 'listing__booking_fees', 'listing__booking_fees', 'listing__booking_fees', @@ -389,6 +618,10 @@ 'listing__twice_bookings_fill_nulls_with_0_without_time_spine', 'listing__twice_bookings_fill_nulls_with_0_without_time_spine', 'listing__user', + 'listing__view__listing__views', + 'listing__view__listing__views', + 'listing__view__listing__views', + 'listing__view__listing__views', 'listing__views', 'listing__views', 'listing__views', @@ -457,6 +690,11 @@ 'revenue_instance__ds__extract_year', 'revenue_instance__user', 'session', + 'session__visit__session__visit_buy_conversion_rate', + 'session__visit__session__visit_buy_conversion_rate_7days', + 'session__visit__session__visit_buy_conversion_rate_7days_fill_nulls_with_0', + 'session__visit__session__visit_buy_conversion_rate_by_session', + 'session__visit__session__visit_buy_conversions', 'session__visit_buy_conversion_rate', 'session__visit_buy_conversion_rate_7days', 'session__visit_buy_conversion_rate_7days_fill_nulls_with_0', @@ -464,6 +702,36 @@ 'session__visit_buy_conversions', 'session_id', 'user', + 'user__account__user__current_account_balance_by_user', + 'user__account__user__current_account_balance_by_user', + 'user__account__user__current_account_balance_by_user', + 'user__account__user__current_account_balance_by_user', + 'user__account__user__current_account_balance_by_user', + 'user__account__user__current_account_balance_by_user', + 'user__account__user__current_account_balance_by_user', + 'user__account__user__current_account_balance_by_user', + 'user__account__user__current_account_balance_by_user', + 'user__account__user__current_account_balance_by_user', + 'user__account__user__regional_starting_balance_ratios', + 'user__account__user__regional_starting_balance_ratios', + 'user__account__user__regional_starting_balance_ratios', + 'user__account__user__regional_starting_balance_ratios', + 'user__account__user__regional_starting_balance_ratios', + 'user__account__user__regional_starting_balance_ratios', + 'user__account__user__regional_starting_balance_ratios', + 'user__account__user__regional_starting_balance_ratios', + 'user__account__user__regional_starting_balance_ratios', + 'user__account__user__regional_starting_balance_ratios', + 'user__account__user__total_account_balance_first_day', + 'user__account__user__total_account_balance_first_day', + 'user__account__user__total_account_balance_first_day', + 'user__account__user__total_account_balance_first_day', + 'user__account__user__total_account_balance_first_day', + 'user__account__user__total_account_balance_first_day', + 'user__account__user__total_account_balance_first_day', + 'user__account__user__total_account_balance_first_day', + 'user__account__user__total_account_balance_first_day', + 'user__account__user__total_account_balance_first_day', 'user__active_listings', 'user__active_listings', 'user__active_listings', @@ -536,6 +804,16 @@ 'user__largest_listing', 'user__largest_listing', 'user__largest_listing', + 'user__listing__user__active_listings', + 'user__listing__user__active_listings', + 'user__listing__user__active_listings', + 'user__listing__user__active_listings', + 'user__listing__user__active_listings', + 'user__listing__user__active_listings', + 'user__listing__user__active_listings', + 'user__listing__user__active_listings', + 'user__listing__user__active_listings', + 'user__listing__user__active_listings', 'user__listing__user__approximate_continuous_booking_value_p99', 'user__listing__user__approximate_continuous_booking_value_p99', 'user__listing__user__approximate_continuous_booking_value_p99', @@ -746,6 +1024,26 @@ 'user__listing__user__bookings_per_listing', 'user__listing__user__bookings_per_listing', 'user__listing__user__bookings_per_listing', + 'user__listing__user__bookings_per_listing', + 'user__listing__user__bookings_per_listing', + 'user__listing__user__bookings_per_listing', + 'user__listing__user__bookings_per_listing', + 'user__listing__user__bookings_per_listing', + 'user__listing__user__bookings_per_listing', + 'user__listing__user__bookings_per_listing', + 'user__listing__user__bookings_per_listing', + 'user__listing__user__bookings_per_listing', + 'user__listing__user__bookings_per_listing', + 'user__listing__user__bookings_per_lux_listing_derived', + 'user__listing__user__bookings_per_lux_listing_derived', + 'user__listing__user__bookings_per_lux_listing_derived', + 'user__listing__user__bookings_per_lux_listing_derived', + 'user__listing__user__bookings_per_lux_listing_derived', + 'user__listing__user__bookings_per_lux_listing_derived', + 'user__listing__user__bookings_per_lux_listing_derived', + 'user__listing__user__bookings_per_lux_listing_derived', + 'user__listing__user__bookings_per_lux_listing_derived', + 'user__listing__user__bookings_per_lux_listing_derived', 'user__listing__user__bookings_per_lux_listing_derived', 'user__listing__user__bookings_per_lux_listing_derived', 'user__listing__user__bookings_per_lux_listing_derived', @@ -866,6 +1164,26 @@ 'user__listing__user__instant_plus_non_referred_bookings_pct', 'user__listing__user__instant_plus_non_referred_bookings_pct', 'user__listing__user__instant_plus_non_referred_bookings_pct', + 'user__listing__user__largest_listing', + 'user__listing__user__largest_listing', + 'user__listing__user__largest_listing', + 'user__listing__user__largest_listing', + 'user__listing__user__largest_listing', + 'user__listing__user__largest_listing', + 'user__listing__user__largest_listing', + 'user__listing__user__largest_listing', + 'user__listing__user__largest_listing', + 'user__listing__user__largest_listing', + 'user__listing__user__listings', + 'user__listing__user__listings', + 'user__listing__user__listings', + 'user__listing__user__listings', + 'user__listing__user__listings', + 'user__listing__user__listings', + 'user__listing__user__listings', + 'user__listing__user__listings', + 'user__listing__user__listings', + 'user__listing__user__listings', 'user__listing__user__lux_booking_fraction_of_max_value', 'user__listing__user__lux_booking_fraction_of_max_value', 'user__listing__user__lux_booking_fraction_of_max_value', @@ -886,6 +1204,16 @@ 'user__listing__user__lux_booking_value_rate_expr', 'user__listing__user__lux_booking_value_rate_expr', 'user__listing__user__lux_booking_value_rate_expr', + 'user__listing__user__lux_listings', + 'user__listing__user__lux_listings', + 'user__listing__user__lux_listings', + 'user__listing__user__lux_listings', + 'user__listing__user__lux_listings', + 'user__listing__user__lux_listings', + 'user__listing__user__lux_listings', + 'user__listing__user__lux_listings', + 'user__listing__user__lux_listings', + 'user__listing__user__lux_listings', 'user__listing__user__max_booking_value', 'user__listing__user__max_booking_value', 'user__listing__user__max_booking_value', @@ -946,6 +1274,16 @@ 'user__listing__user__referred_bookings', 'user__listing__user__referred_bookings', 'user__listing__user__referred_bookings', + 'user__listing__user__smallest_listing', + 'user__listing__user__smallest_listing', + 'user__listing__user__smallest_listing', + 'user__listing__user__smallest_listing', + 'user__listing__user__smallest_listing', + 'user__listing__user__smallest_listing', + 'user__listing__user__smallest_listing', + 'user__listing__user__smallest_listing', + 'user__listing__user__smallest_listing', + 'user__listing__user__smallest_listing', 'user__listing__user__twice_bookings_fill_nulls_with_0_without_time_spine', 'user__listing__user__twice_bookings_fill_nulls_with_0_without_time_spine', 'user__listing__user__twice_bookings_fill_nulls_with_0_without_time_spine', @@ -1026,6 +1364,26 @@ 'user__revenue_all_time', 'user__revenue_all_time', 'user__revenue_all_time', + 'user__revenue_instance__user__revenue', + 'user__revenue_instance__user__revenue', + 'user__revenue_instance__user__revenue', + 'user__revenue_instance__user__revenue', + 'user__revenue_instance__user__revenue', + 'user__revenue_instance__user__revenue', + 'user__revenue_instance__user__revenue', + 'user__revenue_instance__user__revenue', + 'user__revenue_instance__user__revenue', + 'user__revenue_instance__user__revenue', + 'user__revenue_instance__user__revenue_all_time', + 'user__revenue_instance__user__revenue_all_time', + 'user__revenue_instance__user__revenue_all_time', + 'user__revenue_instance__user__revenue_all_time', + 'user__revenue_instance__user__revenue_all_time', + 'user__revenue_instance__user__revenue_all_time', + 'user__revenue_instance__user__revenue_all_time', + 'user__revenue_instance__user__revenue_all_time', + 'user__revenue_instance__user__revenue_all_time', + 'user__revenue_instance__user__revenue_all_time', 'user__smallest_listing', 'user__smallest_listing', 'user__smallest_listing', @@ -1046,6 +1404,86 @@ 'user__total_account_balance_first_day', 'user__total_account_balance_first_day', 'user__total_account_balance_first_day', + 'user__verification__user__identity_verifications', + 'user__verification__user__identity_verifications', + 'user__verification__user__identity_verifications', + 'user__verification__user__identity_verifications', + 'user__verification__user__identity_verifications', + 'user__verification__user__identity_verifications', + 'user__verification__user__identity_verifications', + 'user__verification__user__identity_verifications', + 'user__verification__user__identity_verifications', + 'user__verification__user__identity_verifications', + 'user__view__user__views', + 'user__view__user__views', + 'user__view__user__views', + 'user__view__user__views', + 'user__view__user__views', + 'user__view__user__views', + 'user__view__user__views', + 'user__view__user__views', + 'user__view__user__views', + 'user__view__user__views', + 'user__views', + 'user__views', + 'user__views', + 'user__views', + 'user__views', + 'user__views', + 'user__views', + 'user__views', + 'user__views', + 'user__views', + 'user__visit__user__visit_buy_conversion_rate', + 'user__visit__user__visit_buy_conversion_rate', + 'user__visit__user__visit_buy_conversion_rate', + 'user__visit__user__visit_buy_conversion_rate', + 'user__visit__user__visit_buy_conversion_rate', + 'user__visit__user__visit_buy_conversion_rate', + 'user__visit__user__visit_buy_conversion_rate', + 'user__visit__user__visit_buy_conversion_rate', + 'user__visit__user__visit_buy_conversion_rate', + 'user__visit__user__visit_buy_conversion_rate', + 'user__visit__user__visit_buy_conversion_rate_7days', + 'user__visit__user__visit_buy_conversion_rate_7days', + 'user__visit__user__visit_buy_conversion_rate_7days', + 'user__visit__user__visit_buy_conversion_rate_7days', + 'user__visit__user__visit_buy_conversion_rate_7days', + 'user__visit__user__visit_buy_conversion_rate_7days', + 'user__visit__user__visit_buy_conversion_rate_7days', + 'user__visit__user__visit_buy_conversion_rate_7days', + 'user__visit__user__visit_buy_conversion_rate_7days', + 'user__visit__user__visit_buy_conversion_rate_7days', + 'user__visit__user__visit_buy_conversion_rate_7days_fill_nulls_with_0', + 'user__visit__user__visit_buy_conversion_rate_7days_fill_nulls_with_0', + 'user__visit__user__visit_buy_conversion_rate_7days_fill_nulls_with_0', + 'user__visit__user__visit_buy_conversion_rate_7days_fill_nulls_with_0', + 'user__visit__user__visit_buy_conversion_rate_7days_fill_nulls_with_0', + 'user__visit__user__visit_buy_conversion_rate_7days_fill_nulls_with_0', + 'user__visit__user__visit_buy_conversion_rate_7days_fill_nulls_with_0', + 'user__visit__user__visit_buy_conversion_rate_7days_fill_nulls_with_0', + 'user__visit__user__visit_buy_conversion_rate_7days_fill_nulls_with_0', + 'user__visit__user__visit_buy_conversion_rate_7days_fill_nulls_with_0', + 'user__visit__user__visit_buy_conversion_rate_by_session', + 'user__visit__user__visit_buy_conversion_rate_by_session', + 'user__visit__user__visit_buy_conversion_rate_by_session', + 'user__visit__user__visit_buy_conversion_rate_by_session', + 'user__visit__user__visit_buy_conversion_rate_by_session', + 'user__visit__user__visit_buy_conversion_rate_by_session', + 'user__visit__user__visit_buy_conversion_rate_by_session', + 'user__visit__user__visit_buy_conversion_rate_by_session', + 'user__visit__user__visit_buy_conversion_rate_by_session', + 'user__visit__user__visit_buy_conversion_rate_by_session', + 'user__visit__user__visit_buy_conversions', + 'user__visit__user__visit_buy_conversions', + 'user__visit__user__visit_buy_conversions', + 'user__visit__user__visit_buy_conversions', + 'user__visit__user__visit_buy_conversions', + 'user__visit__user__visit_buy_conversions', + 'user__visit__user__visit_buy_conversions', + 'user__visit__user__visit_buy_conversions', + 'user__visit__user__visit_buy_conversions', + 'user__visit__user__visit_buy_conversions', 'user__visit_buy_conversion_rate', 'user__visit_buy_conversion_rate', 'user__visit_buy_conversion_rate',