From e61836ccb96d8f22fc58f296639d1e4d27e5a29b Mon Sep 17 00:00:00 2001 From: Courtney Holcomb Date: Tue, 4 Jun 2024 21:24:05 -0700 Subject: [PATCH] WIP - enable entity object syntax in metric filters --- .../specs/where_filter_metric.py | 16 +- .../simple_manifest/metrics.yaml | 8 + ...linkable_element_set_as_spec_set__set0.txt | 3 + ...linkable_elements_for_measure__result0.txt | 3 + ...elements_for_no_metrics_query__result0.txt | 5 + pyproject.toml | 2 +- ...ilter_with_entity_object_syntax__plan0.sql | 403 ++++++++++++++++++ ..._entity_object_syntax__plan0_optimized.sql | 49 +++ 8 files changed, 485 insertions(+), 4 deletions(-) create mode 100644 tests_metricflow/snapshots/test_metric_filter_rendering.py/SqlQueryPlan/DuckDB/test_metric_filter_with_entity_object_syntax__plan0.sql create mode 100644 tests_metricflow/snapshots/test_metric_filter_rendering.py/SqlQueryPlan/DuckDB/test_metric_filter_with_entity_object_syntax__plan0_optimized.sql diff --git a/metricflow-semantics/metricflow_semantics/specs/where_filter_metric.py b/metricflow-semantics/metricflow_semantics/specs/where_filter_metric.py index 72000e7579..9fe8af21f8 100644 --- a/metricflow-semantics/metricflow_semantics/specs/where_filter_metric.py +++ b/metricflow-semantics/metricflow_semantics/specs/where_filter_metric.py @@ -1,6 +1,6 @@ from __future__ import annotations -from typing import Sequence +from typing import Sequence, Union from dbt_semantic_interfaces.call_parameter_sets import ( MetricCallParameterSet, @@ -19,6 +19,8 @@ from metricflow_semantics.specs.column_assoc import ColumnAssociationResolver from metricflow_semantics.specs.rendered_spec_tracker import RenderedSpecTracker +from metricflow_semantics.specs.where_filter_entity import WhereFilterEntity + class WhereFilterMetric(ProtocolHint[QueryInterfaceMetric]): """A metric that is passed in through the where filter parameter.""" @@ -94,7 +96,7 @@ def __init__( # noqa self._where_filter_location = where_filter_location self._rendered_spec_tracker = rendered_spec_tracker - def create(self, metric_name: str, group_by: Sequence[str] = ()) -> WhereFilterMetric: + def create(self, metric_name: str, group_by: Sequence[Union[str, WhereFilterEntity]] = ()) -> WhereFilterMetric: """Create a WhereFilterMetric.""" return WhereFilterMetric( column_association_resolver=self._column_association_resolver, @@ -102,5 +104,13 @@ def create(self, metric_name: str, group_by: Sequence[str] = ()) -> WhereFilterM where_filter_location=self._where_filter_location, rendered_spec_tracker=self._rendered_spec_tracker, element_name=metric_name, - group_by=tuple(LinkableElementReference(group_by_name.lower()) for group_by_name in group_by), + group_by=tuple( + LinkableElementReference( + # TODO: add entity links + group_by_item.lower() + if isinstance(group_by_item, str) + else group_by_item._element_name + ) + for group_by_item in group_by + ), ) diff --git a/metricflow-semantics/metricflow_semantics/test_helpers/semantic_manifest_yamls/simple_manifest/metrics.yaml b/metricflow-semantics/metricflow_semantics/test_helpers/semantic_manifest_yamls/simple_manifest/metrics.yaml index 121f50ab1b..16c785db0d 100644 --- a/metricflow-semantics/metricflow_semantics/test_helpers/semantic_manifest_yamls/simple_manifest/metrics.yaml +++ b/metricflow-semantics/metricflow_semantics/test_helpers/semantic_manifest_yamls/simple_manifest/metrics.yaml @@ -772,3 +772,11 @@ metric: denominator: name: listings filter: "{{ Metric('views', ['listing']) }} > 10" +--- +metric: + name: really_active_listings + description: Listings with at least 5 bookings + type: simple + type_params: + measure: listings + filter: "{{ Metric('bookings', [Entity('listing')]) }} > 5" diff --git a/metricflow-semantics/tests_metricflow_semantics/snapshots/test_linkable_spec_resolver.py/list/test_linkable_element_set_as_spec_set__set0.txt b/metricflow-semantics/tests_metricflow_semantics/snapshots/test_linkable_spec_resolver.py/list/test_linkable_element_set_as_spec_set__set0.txt index 042892a632..169a7c82e5 100644 --- a/metricflow-semantics/tests_metricflow_semantics/snapshots/test_linkable_spec_resolver.py/list/test_linkable_element_set_as_spec_set__set0.txt +++ b/metricflow-semantics/tests_metricflow_semantics/snapshots/test_linkable_spec_resolver.py/list/test_linkable_element_set_as_spec_set__set0.txt @@ -127,6 +127,7 @@ 'listing__nested_fill_nulls_without_time_spine', 'listing__non_referred_bookings_pct', 'listing__popular_listing_bookings_per_booker', + 'listing__really_active_listings', 'listing__referred_bookings', 'listing__smallest_listing', 'listing__twice_bookings_fill_nulls_with_0_without_time_spine', @@ -291,6 +292,7 @@ 'user__listing__user__nested_fill_nulls_without_time_spine', 'user__listing__user__non_referred_bookings_pct', 'user__listing__user__popular_listing_bookings_per_booker', + 'user__listing__user__really_active_listings', 'user__listing__user__referred_bookings', 'user__listing__user__smallest_listing', 'user__listing__user__twice_bookings_fill_nulls_with_0_without_time_spine', @@ -299,6 +301,7 @@ 'user__listings', 'user__lux_listings', 'user__popular_listing_bookings_per_booker', + 'user__really_active_listings', 'user__regional_starting_balance_ratios', 'user__revenue', 'user__revenue_all_time', diff --git a/metricflow-semantics/tests_metricflow_semantics/snapshots/test_semantic_model_container.py/str/test_linkable_elements_for_measure__result0.txt b/metricflow-semantics/tests_metricflow_semantics/snapshots/test_semantic_model_container.py/str/test_linkable_elements_for_measure__result0.txt index e9c4f19333..7b91f5352e 100644 --- a/metricflow-semantics/tests_metricflow_semantics/snapshots/test_semantic_model_container.py/str/test_linkable_elements_for_measure__result0.txt +++ b/metricflow-semantics/tests_metricflow_semantics/snapshots/test_semantic_model_container.py/str/test_linkable_elements_for_measure__result0.txt @@ -109,6 +109,7 @@ Model Join-Path Entity Links ('listings_latest',) ("('listing',)", "('listing',)") nested_fill_nulls_without_time_spine ['JOINED', 'METRIC'] ('listings_latest',) ("('listing',)", "('listing',)") non_referred_bookings_pct ['JOINED', 'METRIC'] ('listings_latest',) ("('listing',)", "('listing',)") popular_listing_bookings_per_booker ['JOINED', 'METRIC'] +('listings_latest',) ("('listing',)", "('listing',)") really_active_listings ['JOINED', 'METRIC'] ('listings_latest',) ("('listing',)", "('listing',)") referred_bookings ['JOINED', 'METRIC'] ('listings_latest',) ("('listing',)", "('listing',)") smallest_listing ['JOINED', 'METRIC'] ('listings_latest',) ("('listing',)", "('listing',)") twice_bookings_fill_nulls_with_0_without_time_spine ['JOINED', 'METRIC'] @@ -168,6 +169,7 @@ Model Join-Path Entity Links ('listings_latest',) ("('user',)", "('listing', 'user')") nested_fill_nulls_without_time_spine ['JOINED', 'METRIC'] ('listings_latest',) ("('user',)", "('listing', 'user')") non_referred_bookings_pct ['JOINED', 'METRIC'] ('listings_latest',) ("('user',)", "('listing', 'user')") popular_listing_bookings_per_booker ['JOINED', 'METRIC'] +('listings_latest',) ("('user',)", "('listing', 'user')") really_active_listings ['JOINED', 'METRIC'] ('listings_latest',) ("('user',)", "('listing', 'user')") referred_bookings ['JOINED', 'METRIC'] ('listings_latest',) ("('user',)", "('listing', 'user')") smallest_listing ['JOINED', 'METRIC'] ('listings_latest',) ("('user',)", "('listing', 'user')") twice_bookings_fill_nulls_with_0_without_time_spine ['JOINED', 'METRIC'] @@ -183,6 +185,7 @@ Model Join-Path Entity Links ('listings_latest',) ("('user',)", "('user',)") listings ['JOINED', 'METRIC'] ('listings_latest',) ("('user',)", "('user',)") lux_listings ['JOINED', 'METRIC'] ('listings_latest',) ("('user',)", "('user',)") popular_listing_bookings_per_booker ['JOINED', 'METRIC'] +('listings_latest',) ("('user',)", "('user',)") really_active_listings ['JOINED', 'METRIC'] ('listings_latest',) ("('user',)", "('user',)") regional_starting_balance_ratios ['JOINED', 'METRIC'] ('listings_latest',) ("('user',)", "('user',)") revenue ['JOINED', 'METRIC'] ('listings_latest',) ("('user',)", "('user',)") revenue_all_time ['JOINED', 'METRIC'] diff --git a/metricflow-semantics/tests_metricflow_semantics/snapshots/test_semantic_model_container.py/tuple/test_linkable_elements_for_no_metrics_query__result0.txt b/metricflow-semantics/tests_metricflow_semantics/snapshots/test_semantic_model_container.py/tuple/test_linkable_elements_for_no_metrics_query__result0.txt index 949b0180f2..89f45ac663 100644 --- a/metricflow-semantics/tests_metricflow_semantics/snapshots/test_semantic_model_container.py/tuple/test_linkable_elements_for_no_metrics_query__result0.txt +++ b/metricflow-semantics/tests_metricflow_semantics/snapshots/test_semantic_model_container.py/tuple/test_linkable_elements_for_no_metrics_query__result0.txt @@ -94,6 +94,7 @@ 'company__user__company__listings', 'company__user__company__lux_listings', 'company__user__company__popular_listing_bookings_per_booker', + 'company__user__company__really_active_listings', 'company__user__company__regional_starting_balance_ratios', 'company__user__company__revenue', 'company__user__company__revenue_all_time', @@ -361,6 +362,7 @@ 'listing__nested_fill_nulls_without_time_spine', 'listing__non_referred_bookings_pct', 'listing__popular_listing_bookings_per_booker', + 'listing__really_active_listings', 'listing__referred_bookings', 'listing__smallest_listing', 'listing__twice_bookings_fill_nulls_with_0_without_time_spine', @@ -414,6 +416,7 @@ '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__popular_listing_bookings_per_booker', + 'lux_listing__listing__lux_listing__really_active_listings', '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', @@ -525,6 +528,7 @@ 'user__listing__user__nested_fill_nulls_without_time_spine', 'user__listing__user__non_referred_bookings_pct', 'user__listing__user__popular_listing_bookings_per_booker', + 'user__listing__user__really_active_listings', 'user__listing__user__referred_bookings', 'user__listing__user__smallest_listing', 'user__listing__user__twice_bookings_fill_nulls_with_0_without_time_spine', @@ -533,6 +537,7 @@ 'user__listings', 'user__lux_listings', 'user__popular_listing_bookings_per_booker', + 'user__really_active_listings', 'user__regional_starting_balance_ratios', 'user__revenue', 'user__revenue_all_time', diff --git a/pyproject.toml b/pyproject.toml index 5baa9d9ae2..76030a113f 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -28,7 +28,6 @@ classifiers = [ dependencies = [ "Jinja2>=3.1.3", "PyYAML>=6.0, <7.0.0", - "dbt-semantic-interfaces>=0.5.1, <0.6.0", "graphviz>=0.18.2, <0.21", "more-itertools>=8.10.0, <10.2.0", "pydantic>=1.10.0, <1.11.0", @@ -114,6 +113,7 @@ description = "Environment for development. Includes a DuckDB-backed client." pre-install-commands = [ "pip install -e ./metricflow-semantics", "pip install -e ./dbt-metricflow[duckdb]", + "pip install -e ../dbt-semantic-interfaces", ] features = [ diff --git a/tests_metricflow/snapshots/test_metric_filter_rendering.py/SqlQueryPlan/DuckDB/test_metric_filter_with_entity_object_syntax__plan0.sql b/tests_metricflow/snapshots/test_metric_filter_rendering.py/SqlQueryPlan/DuckDB/test_metric_filter_with_entity_object_syntax__plan0.sql new file mode 100644 index 0000000000..573c4e0c39 --- /dev/null +++ b/tests_metricflow/snapshots/test_metric_filter_rendering.py/SqlQueryPlan/DuckDB/test_metric_filter_with_entity_object_syntax__plan0.sql @@ -0,0 +1,403 @@ +-- Compute Metrics via Expressions +SELECT + subq_17.metric_time__day + , subq_17.listings AS really_active_listings +FROM ( + -- Aggregate Measures + SELECT + subq_16.metric_time__day + , SUM(subq_16.listings) AS listings + FROM ( + -- Pass Only Elements: ['listings', 'metric_time__day'] + SELECT + subq_15.metric_time__day + , subq_15.listings + FROM ( + -- Constrain Output with WHERE + SELECT + subq_14.metric_time__day + , subq_14.listing__bookings + , subq_14.listings + FROM ( + -- Pass Only Elements: ['listings', 'metric_time__day', 'listing__bookings'] + SELECT + subq_13.metric_time__day + , subq_13.listing__bookings + , subq_13.listings + FROM ( + -- Join Standard Outputs + SELECT + subq_6.metric_time__day AS metric_time__day + , subq_6.listing AS listing + , subq_12.listing__bookings AS listing__bookings + , subq_6.listings AS listings + FROM ( + -- Pass Only Elements: ['listings', 'metric_time__day', 'listing'] + SELECT + subq_5.metric_time__day + , subq_5.listing + , subq_5.listings + 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.created_at__day + , subq_4.created_at__week + , subq_4.created_at__month + , subq_4.created_at__quarter + , subq_4.created_at__year + , subq_4.created_at__extract_year + , subq_4.created_at__extract_quarter + , subq_4.created_at__extract_month + , subq_4.created_at__extract_day + , subq_4.created_at__extract_dow + , subq_4.created_at__extract_doy + , subq_4.listing__ds__day + , subq_4.listing__ds__week + , subq_4.listing__ds__month + , subq_4.listing__ds__quarter + , subq_4.listing__ds__year + , subq_4.listing__ds__extract_year + , subq_4.listing__ds__extract_quarter + , subq_4.listing__ds__extract_month + , subq_4.listing__ds__extract_day + , subq_4.listing__ds__extract_dow + , subq_4.listing__ds__extract_doy + , subq_4.listing__created_at__day + , subq_4.listing__created_at__week + , subq_4.listing__created_at__month + , subq_4.listing__created_at__quarter + , subq_4.listing__created_at__year + , subq_4.listing__created_at__extract_year + , subq_4.listing__created_at__extract_quarter + , subq_4.listing__created_at__extract_month + , subq_4.listing__created_at__extract_day + , subq_4.listing__created_at__extract_dow + , subq_4.listing__created_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.user + , subq_4.listing__user + , subq_4.country_latest + , subq_4.is_lux_latest + , subq_4.capacity_latest + , subq_4.listing__country_latest + , subq_4.listing__is_lux_latest + , subq_4.listing__capacity_latest + , subq_4.listings + , subq_4.largest_listing + , subq_4.smallest_listing + FROM ( + -- Read Elements From Semantic Model 'listings_latest' + SELECT + 1 AS listings + , listings_latest_src_28000.capacity AS largest_listing + , listings_latest_src_28000.capacity AS smallest_listing + , DATE_TRUNC('day', listings_latest_src_28000.created_at) AS ds__day + , DATE_TRUNC('week', listings_latest_src_28000.created_at) AS ds__week + , DATE_TRUNC('month', listings_latest_src_28000.created_at) AS ds__month + , DATE_TRUNC('quarter', listings_latest_src_28000.created_at) AS ds__quarter + , DATE_TRUNC('year', listings_latest_src_28000.created_at) AS ds__year + , EXTRACT(year FROM listings_latest_src_28000.created_at) AS ds__extract_year + , EXTRACT(quarter FROM listings_latest_src_28000.created_at) AS ds__extract_quarter + , EXTRACT(month FROM listings_latest_src_28000.created_at) AS ds__extract_month + , EXTRACT(day FROM listings_latest_src_28000.created_at) AS ds__extract_day + , EXTRACT(isodow FROM listings_latest_src_28000.created_at) AS ds__extract_dow + , EXTRACT(doy FROM listings_latest_src_28000.created_at) AS ds__extract_doy + , DATE_TRUNC('day', listings_latest_src_28000.created_at) AS created_at__day + , DATE_TRUNC('week', listings_latest_src_28000.created_at) AS created_at__week + , DATE_TRUNC('month', listings_latest_src_28000.created_at) AS created_at__month + , DATE_TRUNC('quarter', listings_latest_src_28000.created_at) AS created_at__quarter + , DATE_TRUNC('year', listings_latest_src_28000.created_at) AS created_at__year + , EXTRACT(year FROM listings_latest_src_28000.created_at) AS created_at__extract_year + , EXTRACT(quarter FROM listings_latest_src_28000.created_at) AS created_at__extract_quarter + , EXTRACT(month FROM listings_latest_src_28000.created_at) AS created_at__extract_month + , EXTRACT(day FROM listings_latest_src_28000.created_at) AS created_at__extract_day + , EXTRACT(isodow FROM listings_latest_src_28000.created_at) AS created_at__extract_dow + , EXTRACT(doy FROM listings_latest_src_28000.created_at) AS created_at__extract_doy + , listings_latest_src_28000.country AS country_latest + , listings_latest_src_28000.is_lux AS is_lux_latest + , listings_latest_src_28000.capacity AS capacity_latest + , DATE_TRUNC('day', listings_latest_src_28000.created_at) AS listing__ds__day + , DATE_TRUNC('week', listings_latest_src_28000.created_at) AS listing__ds__week + , DATE_TRUNC('month', listings_latest_src_28000.created_at) AS listing__ds__month + , DATE_TRUNC('quarter', listings_latest_src_28000.created_at) AS listing__ds__quarter + , DATE_TRUNC('year', listings_latest_src_28000.created_at) AS listing__ds__year + , EXTRACT(year FROM listings_latest_src_28000.created_at) AS listing__ds__extract_year + , EXTRACT(quarter FROM listings_latest_src_28000.created_at) AS listing__ds__extract_quarter + , EXTRACT(month FROM listings_latest_src_28000.created_at) AS listing__ds__extract_month + , EXTRACT(day FROM listings_latest_src_28000.created_at) AS listing__ds__extract_day + , EXTRACT(isodow FROM listings_latest_src_28000.created_at) AS listing__ds__extract_dow + , EXTRACT(doy FROM listings_latest_src_28000.created_at) AS listing__ds__extract_doy + , DATE_TRUNC('day', listings_latest_src_28000.created_at) AS listing__created_at__day + , DATE_TRUNC('week', listings_latest_src_28000.created_at) AS listing__created_at__week + , DATE_TRUNC('month', listings_latest_src_28000.created_at) AS listing__created_at__month + , DATE_TRUNC('quarter', listings_latest_src_28000.created_at) AS listing__created_at__quarter + , DATE_TRUNC('year', listings_latest_src_28000.created_at) AS listing__created_at__year + , EXTRACT(year FROM listings_latest_src_28000.created_at) AS listing__created_at__extract_year + , EXTRACT(quarter FROM listings_latest_src_28000.created_at) AS listing__created_at__extract_quarter + , EXTRACT(month FROM listings_latest_src_28000.created_at) AS listing__created_at__extract_month + , EXTRACT(day FROM listings_latest_src_28000.created_at) AS listing__created_at__extract_day + , EXTRACT(isodow FROM listings_latest_src_28000.created_at) AS listing__created_at__extract_dow + , EXTRACT(doy FROM listings_latest_src_28000.created_at) AS listing__created_at__extract_doy + , listings_latest_src_28000.country AS listing__country_latest + , listings_latest_src_28000.is_lux AS listing__is_lux_latest + , listings_latest_src_28000.capacity AS listing__capacity_latest + , listings_latest_src_28000.listing_id AS listing + , listings_latest_src_28000.user_id AS user + , listings_latest_src_28000.user_id AS listing__user + FROM ***************************.dim_listings_latest listings_latest_src_28000 + ) subq_4 + ) subq_5 + ) subq_6 + LEFT OUTER JOIN ( + -- Pass Only Elements: ['listing', 'listing__bookings'] + SELECT + subq_11.listing + , subq_11.listing__bookings + FROM ( + -- Compute Metrics via Expressions + SELECT + subq_10.listing + , subq_10.bookings AS listing__bookings + FROM ( + -- Aggregate Measures + SELECT + subq_9.listing + , SUM(subq_9.bookings) AS bookings + FROM ( + -- Pass Only Elements: ['bookings', 'listing'] + SELECT + subq_8.listing + , subq_8.bookings + 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.listing + ) subq_10 + ) subq_11 + ) subq_12 + ON + subq_6.listing = subq_12.listing + ) subq_13 + ) subq_14 + WHERE listing__bookings > 5 + ) subq_15 + ) subq_16 + GROUP BY + subq_16.metric_time__day +) subq_17 diff --git a/tests_metricflow/snapshots/test_metric_filter_rendering.py/SqlQueryPlan/DuckDB/test_metric_filter_with_entity_object_syntax__plan0_optimized.sql b/tests_metricflow/snapshots/test_metric_filter_rendering.py/SqlQueryPlan/DuckDB/test_metric_filter_with_entity_object_syntax__plan0_optimized.sql new file mode 100644 index 0000000000..bda7425ecb --- /dev/null +++ b/tests_metricflow/snapshots/test_metric_filter_rendering.py/SqlQueryPlan/DuckDB/test_metric_filter_with_entity_object_syntax__plan0_optimized.sql @@ -0,0 +1,49 @@ +-- Constrain Output with WHERE +-- Pass Only Elements: ['listings', 'metric_time__day'] +-- Aggregate Measures +-- Compute Metrics via Expressions +SELECT + metric_time__day + , SUM(listings) AS really_active_listings +FROM ( + -- Join Standard Outputs + -- Pass Only Elements: ['listings', 'metric_time__day', 'listing__bookings'] + SELECT + subq_20.metric_time__day AS metric_time__day + , subq_26.listing__bookings AS listing__bookings + , subq_20.listings AS listings + FROM ( + -- Read Elements From Semantic Model 'listings_latest' + -- Metric Time Dimension 'ds' + -- Pass Only Elements: ['listings', 'metric_time__day', 'listing'] + SELECT + DATE_TRUNC('day', created_at) AS metric_time__day + , listing_id AS listing + , 1 AS listings + FROM ***************************.dim_listings_latest listings_latest_src_28000 + ) subq_20 + LEFT OUTER JOIN ( + -- Aggregate Measures + -- Compute Metrics via Expressions + -- Pass Only Elements: ['listing', 'listing__bookings'] + SELECT + listing + , SUM(bookings) AS listing__bookings + FROM ( + -- Read Elements From Semantic Model 'bookings_source' + -- Metric Time Dimension 'ds' + -- Pass Only Elements: ['bookings', 'listing'] + SELECT + listing_id AS listing + , 1 AS bookings + FROM ***************************.fct_bookings bookings_source_src_28000 + ) subq_23 + GROUP BY + listing + ) subq_26 + ON + subq_20.listing = subq_26.listing +) subq_28 +WHERE listing__bookings > 5 +GROUP BY + metric_time__day