From 3b1eeec62b3614815c0b8d42de4acb8224c35ed2 Mon Sep 17 00:00:00 2001 From: Courtney Holcomb Date: Tue, 4 Jun 2024 20:33:52 -0700 Subject: [PATCH 1/3] Update funky test case --- .../test_metric_filter_rendering.py | 27 +++++++++++++- .../test_metric_filtered_by_itself__plan0.sql | 36 +++++++++---------- ...ic_filtered_by_itself__plan0_optimized.sql | 22 ++++++------ .../test_metric_filtered_by_itself__plan0.sql | 36 +++++++++---------- ...ic_filtered_by_itself__plan0_optimized.sql | 22 ++++++------ .../test_metric_filtered_by_itself__plan0.sql | 36 +++++++++---------- ...ic_filtered_by_itself__plan0_optimized.sql | 22 ++++++------ .../test_metric_filtered_by_itself__plan0.sql | 36 +++++++++---------- ...ic_filtered_by_itself__plan0_optimized.sql | 22 ++++++------ .../test_metric_filtered_by_itself__plan0.sql | 36 +++++++++---------- ...ic_filtered_by_itself__plan0_optimized.sql | 22 ++++++------ .../test_metric_filtered_by_itself__plan0.sql | 36 +++++++++---------- ...ic_filtered_by_itself__plan0_optimized.sql | 22 ++++++------ .../test_metric_filtered_by_itself__plan0.sql | 36 +++++++++---------- ...ic_filtered_by_itself__plan0_optimized.sql | 22 ++++++------ 15 files changed, 229 insertions(+), 204 deletions(-) diff --git a/tests_metricflow/query_rendering/test_metric_filter_rendering.py b/tests_metricflow/query_rendering/test_metric_filter_rendering.py index 4a688910d5..8d37f0d635 100644 --- a/tests_metricflow/query_rendering/test_metric_filter_rendering.py +++ b/tests_metricflow/query_rendering/test_metric_filter_rendering.py @@ -64,6 +64,31 @@ def test_metric_with_metric_in_where_filter( ) +@pytest.mark.sql_engine_snapshot +def test_metric_filter_with_entity_object_syntax( + 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 with a metric in the metric-level where filter.""" + query_spec = query_parser.parse_and_validate_query( + metric_names=("really_active_listings",), + group_by_names=("metric_time__day",), + ).query_spec + 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_node, + ) + + @pytest.mark.sql_engine_snapshot def test_query_with_derived_metric_in_where_filter( request: FixtureRequest, @@ -242,7 +267,7 @@ def test_metric_filtered_by_itself( query_spec = query_parser.parse_and_validate_query( metric_names=("bookers",), where_constraint=PydanticWhereFilter( - where_sql_template="{{ Metric('bookers', ['guest']) }} > 1.00", + where_sql_template="{{ Metric('bookers', ['listing']) }} > 1.00", ), ).query_spec dataflow_plan = dataflow_plan_builder.build_plan(query_spec) diff --git a/tests_metricflow/snapshots/test_metric_filter_rendering.py/SqlQueryPlan/BigQuery/test_metric_filtered_by_itself__plan0.sql b/tests_metricflow/snapshots/test_metric_filter_rendering.py/SqlQueryPlan/BigQuery/test_metric_filtered_by_itself__plan0.sql index 2ded91a17a..cc551ee5ef 100644 --- a/tests_metricflow/snapshots/test_metric_filter_rendering.py/SqlQueryPlan/BigQuery/test_metric_filtered_by_itself__plan0.sql +++ b/tests_metricflow/snapshots/test_metric_filter_rendering.py/SqlQueryPlan/BigQuery/test_metric_filtered_by_itself__plan0.sql @@ -12,23 +12,23 @@ FROM ( FROM ( -- Constrain Output with WHERE SELECT - subq_14.guest__bookers + subq_14.listing__bookers , subq_14.bookers FROM ( - -- Pass Only Elements: ['bookers', 'guest__bookers'] + -- Pass Only Elements: ['bookers', 'listing__bookers'] SELECT - subq_13.guest__bookers + subq_13.listing__bookers , subq_13.bookers FROM ( -- Join Standard Outputs SELECT - subq_6.guest AS guest - , subq_12.guest__bookers AS guest__bookers + subq_6.listing AS listing + , subq_12.listing__bookers AS listing__bookers , subq_6.bookers AS bookers FROM ( - -- Pass Only Elements: ['bookers', 'guest'] + -- Pass Only Elements: ['bookers', 'listing'] SELECT - subq_5.guest + subq_5.listing , subq_5.bookers FROM ( -- Metric Time Dimension 'ds' @@ -227,24 +227,24 @@ FROM ( ) subq_5 ) subq_6 LEFT OUTER JOIN ( - -- Pass Only Elements: ['guest', 'guest__bookers'] + -- Pass Only Elements: ['listing', 'listing__bookers'] SELECT - subq_11.guest - , subq_11.guest__bookers + subq_11.listing + , subq_11.listing__bookers FROM ( -- Compute Metrics via Expressions SELECT - subq_10.guest - , subq_10.bookers AS guest__bookers + subq_10.listing + , subq_10.bookers AS listing__bookers FROM ( -- Aggregate Measures SELECT - subq_9.guest + subq_9.listing , COUNT(DISTINCT subq_9.bookers) AS bookers FROM ( - -- Pass Only Elements: ['bookers', 'guest'] + -- Pass Only Elements: ['bookers', 'listing'] SELECT - subq_8.guest + subq_8.listing , subq_8.bookers FROM ( -- Metric Time Dimension 'ds' @@ -443,15 +443,15 @@ FROM ( ) subq_8 ) subq_9 GROUP BY - guest + listing ) subq_10 ) subq_11 ) subq_12 ON - subq_6.guest = subq_12.guest + subq_6.listing = subq_12.listing ) subq_13 ) subq_14 - WHERE guest__bookers > 1.00 + WHERE listing__bookers > 1.00 ) subq_15 ) subq_16 ) subq_17 diff --git a/tests_metricflow/snapshots/test_metric_filter_rendering.py/SqlQueryPlan/BigQuery/test_metric_filtered_by_itself__plan0_optimized.sql b/tests_metricflow/snapshots/test_metric_filter_rendering.py/SqlQueryPlan/BigQuery/test_metric_filtered_by_itself__plan0_optimized.sql index 51371a5776..35e217f1da 100644 --- a/tests_metricflow/snapshots/test_metric_filter_rendering.py/SqlQueryPlan/BigQuery/test_metric_filtered_by_itself__plan0_optimized.sql +++ b/tests_metricflow/snapshots/test_metric_filter_rendering.py/SqlQueryPlan/BigQuery/test_metric_filtered_by_itself__plan0_optimized.sql @@ -6,34 +6,34 @@ SELECT COUNT(DISTINCT bookers) AS bookers FROM ( -- Join Standard Outputs - -- Pass Only Elements: ['bookers', 'guest__bookers'] + -- Pass Only Elements: ['bookers', 'listing__bookers'] SELECT - subq_26.guest__bookers AS guest__bookers + subq_26.listing__bookers AS listing__bookers , subq_20.bookers AS bookers FROM ( -- Read Elements From Semantic Model 'bookings_source' -- Metric Time Dimension 'ds' - -- Pass Only Elements: ['bookers', 'guest'] + -- Pass Only Elements: ['bookers', 'listing'] SELECT - guest_id AS guest + listing_id AS listing , 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'] + -- Pass Only Elements: ['bookers', 'listing'] -- Aggregate Measures -- Compute Metrics via Expressions - -- Pass Only Elements: ['guest', 'guest__bookers'] + -- Pass Only Elements: ['listing', 'listing__bookers'] SELECT - guest_id AS guest - , COUNT(DISTINCT guest_id) AS guest__bookers + listing_id AS listing + , COUNT(DISTINCT guest_id) AS listing__bookers FROM ***************************.fct_bookings bookings_source_src_28000 GROUP BY - guest + listing ) subq_26 ON - subq_20.guest = subq_26.guest + subq_20.listing = subq_26.listing ) subq_28 -WHERE guest__bookers > 1.00 +WHERE listing__bookers > 1.00 diff --git a/tests_metricflow/snapshots/test_metric_filter_rendering.py/SqlQueryPlan/Databricks/test_metric_filtered_by_itself__plan0.sql b/tests_metricflow/snapshots/test_metric_filter_rendering.py/SqlQueryPlan/Databricks/test_metric_filtered_by_itself__plan0.sql index eac39e68f9..7a3c4f00fe 100644 --- a/tests_metricflow/snapshots/test_metric_filter_rendering.py/SqlQueryPlan/Databricks/test_metric_filtered_by_itself__plan0.sql +++ b/tests_metricflow/snapshots/test_metric_filter_rendering.py/SqlQueryPlan/Databricks/test_metric_filtered_by_itself__plan0.sql @@ -12,23 +12,23 @@ FROM ( FROM ( -- Constrain Output with WHERE SELECT - subq_14.guest__bookers + subq_14.listing__bookers , subq_14.bookers FROM ( - -- Pass Only Elements: ['bookers', 'guest__bookers'] + -- Pass Only Elements: ['bookers', 'listing__bookers'] SELECT - subq_13.guest__bookers + subq_13.listing__bookers , subq_13.bookers FROM ( -- Join Standard Outputs SELECT - subq_6.guest AS guest - , subq_12.guest__bookers AS guest__bookers + subq_6.listing AS listing + , subq_12.listing__bookers AS listing__bookers , subq_6.bookers AS bookers FROM ( - -- Pass Only Elements: ['bookers', 'guest'] + -- Pass Only Elements: ['bookers', 'listing'] SELECT - subq_5.guest + subq_5.listing , subq_5.bookers FROM ( -- Metric Time Dimension 'ds' @@ -227,24 +227,24 @@ FROM ( ) subq_5 ) subq_6 LEFT OUTER JOIN ( - -- Pass Only Elements: ['guest', 'guest__bookers'] + -- Pass Only Elements: ['listing', 'listing__bookers'] SELECT - subq_11.guest - , subq_11.guest__bookers + subq_11.listing + , subq_11.listing__bookers FROM ( -- Compute Metrics via Expressions SELECT - subq_10.guest - , subq_10.bookers AS guest__bookers + subq_10.listing + , subq_10.bookers AS listing__bookers FROM ( -- Aggregate Measures SELECT - subq_9.guest + subq_9.listing , COUNT(DISTINCT subq_9.bookers) AS bookers FROM ( - -- Pass Only Elements: ['bookers', 'guest'] + -- Pass Only Elements: ['bookers', 'listing'] SELECT - subq_8.guest + subq_8.listing , subq_8.bookers FROM ( -- Metric Time Dimension 'ds' @@ -443,15 +443,15 @@ FROM ( ) subq_8 ) subq_9 GROUP BY - subq_9.guest + subq_9.listing ) subq_10 ) subq_11 ) subq_12 ON - subq_6.guest = subq_12.guest + subq_6.listing = subq_12.listing ) subq_13 ) subq_14 - WHERE guest__bookers > 1.00 + WHERE listing__bookers > 1.00 ) subq_15 ) subq_16 ) subq_17 diff --git a/tests_metricflow/snapshots/test_metric_filter_rendering.py/SqlQueryPlan/Databricks/test_metric_filtered_by_itself__plan0_optimized.sql b/tests_metricflow/snapshots/test_metric_filter_rendering.py/SqlQueryPlan/Databricks/test_metric_filtered_by_itself__plan0_optimized.sql index 8660fddf26..ed25561015 100644 --- a/tests_metricflow/snapshots/test_metric_filter_rendering.py/SqlQueryPlan/Databricks/test_metric_filtered_by_itself__plan0_optimized.sql +++ b/tests_metricflow/snapshots/test_metric_filter_rendering.py/SqlQueryPlan/Databricks/test_metric_filtered_by_itself__plan0_optimized.sql @@ -6,34 +6,34 @@ SELECT COUNT(DISTINCT bookers) AS bookers FROM ( -- Join Standard Outputs - -- Pass Only Elements: ['bookers', 'guest__bookers'] + -- Pass Only Elements: ['bookers', 'listing__bookers'] SELECT - subq_26.guest__bookers AS guest__bookers + subq_26.listing__bookers AS listing__bookers , subq_20.bookers AS bookers FROM ( -- Read Elements From Semantic Model 'bookings_source' -- Metric Time Dimension 'ds' - -- Pass Only Elements: ['bookers', 'guest'] + -- Pass Only Elements: ['bookers', 'listing'] SELECT - guest_id AS guest + listing_id AS listing , 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'] + -- Pass Only Elements: ['bookers', 'listing'] -- Aggregate Measures -- Compute Metrics via Expressions - -- Pass Only Elements: ['guest', 'guest__bookers'] + -- Pass Only Elements: ['listing', 'listing__bookers'] SELECT - guest_id AS guest - , COUNT(DISTINCT guest_id) AS guest__bookers + listing_id AS listing + , COUNT(DISTINCT guest_id) AS listing__bookers FROM ***************************.fct_bookings bookings_source_src_28000 GROUP BY - guest_id + listing_id ) subq_26 ON - subq_20.guest = subq_26.guest + subq_20.listing = subq_26.listing ) subq_28 -WHERE guest__bookers > 1.00 +WHERE listing__bookers > 1.00 diff --git a/tests_metricflow/snapshots/test_metric_filter_rendering.py/SqlQueryPlan/DuckDB/test_metric_filtered_by_itself__plan0.sql b/tests_metricflow/snapshots/test_metric_filter_rendering.py/SqlQueryPlan/DuckDB/test_metric_filtered_by_itself__plan0.sql index c2f0d2cd83..732f693611 100644 --- a/tests_metricflow/snapshots/test_metric_filter_rendering.py/SqlQueryPlan/DuckDB/test_metric_filtered_by_itself__plan0.sql +++ b/tests_metricflow/snapshots/test_metric_filter_rendering.py/SqlQueryPlan/DuckDB/test_metric_filtered_by_itself__plan0.sql @@ -12,23 +12,23 @@ FROM ( FROM ( -- Constrain Output with WHERE SELECT - subq_14.guest__bookers + subq_14.listing__bookers , subq_14.bookers FROM ( - -- Pass Only Elements: ['bookers', 'guest__bookers'] + -- Pass Only Elements: ['bookers', 'listing__bookers'] SELECT - subq_13.guest__bookers + subq_13.listing__bookers , subq_13.bookers FROM ( -- Join Standard Outputs SELECT - subq_6.guest AS guest - , subq_12.guest__bookers AS guest__bookers + subq_6.listing AS listing + , subq_12.listing__bookers AS listing__bookers , subq_6.bookers AS bookers FROM ( - -- Pass Only Elements: ['bookers', 'guest'] + -- Pass Only Elements: ['bookers', 'listing'] SELECT - subq_5.guest + subq_5.listing , subq_5.bookers FROM ( -- Metric Time Dimension 'ds' @@ -227,24 +227,24 @@ FROM ( ) subq_5 ) subq_6 LEFT OUTER JOIN ( - -- Pass Only Elements: ['guest', 'guest__bookers'] + -- Pass Only Elements: ['listing', 'listing__bookers'] SELECT - subq_11.guest - , subq_11.guest__bookers + subq_11.listing + , subq_11.listing__bookers FROM ( -- Compute Metrics via Expressions SELECT - subq_10.guest - , subq_10.bookers AS guest__bookers + subq_10.listing + , subq_10.bookers AS listing__bookers FROM ( -- Aggregate Measures SELECT - subq_9.guest + subq_9.listing , COUNT(DISTINCT subq_9.bookers) AS bookers FROM ( - -- Pass Only Elements: ['bookers', 'guest'] + -- Pass Only Elements: ['bookers', 'listing'] SELECT - subq_8.guest + subq_8.listing , subq_8.bookers FROM ( -- Metric Time Dimension 'ds' @@ -443,15 +443,15 @@ FROM ( ) subq_8 ) subq_9 GROUP BY - subq_9.guest + subq_9.listing ) subq_10 ) subq_11 ) subq_12 ON - subq_6.guest = subq_12.guest + subq_6.listing = subq_12.listing ) subq_13 ) subq_14 - WHERE guest__bookers > 1.00 + WHERE listing__bookers > 1.00 ) subq_15 ) subq_16 ) subq_17 diff --git a/tests_metricflow/snapshots/test_metric_filter_rendering.py/SqlQueryPlan/DuckDB/test_metric_filtered_by_itself__plan0_optimized.sql b/tests_metricflow/snapshots/test_metric_filter_rendering.py/SqlQueryPlan/DuckDB/test_metric_filtered_by_itself__plan0_optimized.sql index 8660fddf26..ed25561015 100644 --- a/tests_metricflow/snapshots/test_metric_filter_rendering.py/SqlQueryPlan/DuckDB/test_metric_filtered_by_itself__plan0_optimized.sql +++ b/tests_metricflow/snapshots/test_metric_filter_rendering.py/SqlQueryPlan/DuckDB/test_metric_filtered_by_itself__plan0_optimized.sql @@ -6,34 +6,34 @@ SELECT COUNT(DISTINCT bookers) AS bookers FROM ( -- Join Standard Outputs - -- Pass Only Elements: ['bookers', 'guest__bookers'] + -- Pass Only Elements: ['bookers', 'listing__bookers'] SELECT - subq_26.guest__bookers AS guest__bookers + subq_26.listing__bookers AS listing__bookers , subq_20.bookers AS bookers FROM ( -- Read Elements From Semantic Model 'bookings_source' -- Metric Time Dimension 'ds' - -- Pass Only Elements: ['bookers', 'guest'] + -- Pass Only Elements: ['bookers', 'listing'] SELECT - guest_id AS guest + listing_id AS listing , 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'] + -- Pass Only Elements: ['bookers', 'listing'] -- Aggregate Measures -- Compute Metrics via Expressions - -- Pass Only Elements: ['guest', 'guest__bookers'] + -- Pass Only Elements: ['listing', 'listing__bookers'] SELECT - guest_id AS guest - , COUNT(DISTINCT guest_id) AS guest__bookers + listing_id AS listing + , COUNT(DISTINCT guest_id) AS listing__bookers FROM ***************************.fct_bookings bookings_source_src_28000 GROUP BY - guest_id + listing_id ) subq_26 ON - subq_20.guest = subq_26.guest + subq_20.listing = subq_26.listing ) subq_28 -WHERE guest__bookers > 1.00 +WHERE listing__bookers > 1.00 diff --git a/tests_metricflow/snapshots/test_metric_filter_rendering.py/SqlQueryPlan/Postgres/test_metric_filtered_by_itself__plan0.sql b/tests_metricflow/snapshots/test_metric_filter_rendering.py/SqlQueryPlan/Postgres/test_metric_filtered_by_itself__plan0.sql index c2f0d2cd83..732f693611 100644 --- a/tests_metricflow/snapshots/test_metric_filter_rendering.py/SqlQueryPlan/Postgres/test_metric_filtered_by_itself__plan0.sql +++ b/tests_metricflow/snapshots/test_metric_filter_rendering.py/SqlQueryPlan/Postgres/test_metric_filtered_by_itself__plan0.sql @@ -12,23 +12,23 @@ FROM ( FROM ( -- Constrain Output with WHERE SELECT - subq_14.guest__bookers + subq_14.listing__bookers , subq_14.bookers FROM ( - -- Pass Only Elements: ['bookers', 'guest__bookers'] + -- Pass Only Elements: ['bookers', 'listing__bookers'] SELECT - subq_13.guest__bookers + subq_13.listing__bookers , subq_13.bookers FROM ( -- Join Standard Outputs SELECT - subq_6.guest AS guest - , subq_12.guest__bookers AS guest__bookers + subq_6.listing AS listing + , subq_12.listing__bookers AS listing__bookers , subq_6.bookers AS bookers FROM ( - -- Pass Only Elements: ['bookers', 'guest'] + -- Pass Only Elements: ['bookers', 'listing'] SELECT - subq_5.guest + subq_5.listing , subq_5.bookers FROM ( -- Metric Time Dimension 'ds' @@ -227,24 +227,24 @@ FROM ( ) subq_5 ) subq_6 LEFT OUTER JOIN ( - -- Pass Only Elements: ['guest', 'guest__bookers'] + -- Pass Only Elements: ['listing', 'listing__bookers'] SELECT - subq_11.guest - , subq_11.guest__bookers + subq_11.listing + , subq_11.listing__bookers FROM ( -- Compute Metrics via Expressions SELECT - subq_10.guest - , subq_10.bookers AS guest__bookers + subq_10.listing + , subq_10.bookers AS listing__bookers FROM ( -- Aggregate Measures SELECT - subq_9.guest + subq_9.listing , COUNT(DISTINCT subq_9.bookers) AS bookers FROM ( - -- Pass Only Elements: ['bookers', 'guest'] + -- Pass Only Elements: ['bookers', 'listing'] SELECT - subq_8.guest + subq_8.listing , subq_8.bookers FROM ( -- Metric Time Dimension 'ds' @@ -443,15 +443,15 @@ FROM ( ) subq_8 ) subq_9 GROUP BY - subq_9.guest + subq_9.listing ) subq_10 ) subq_11 ) subq_12 ON - subq_6.guest = subq_12.guest + subq_6.listing = subq_12.listing ) subq_13 ) subq_14 - WHERE guest__bookers > 1.00 + WHERE listing__bookers > 1.00 ) subq_15 ) subq_16 ) subq_17 diff --git a/tests_metricflow/snapshots/test_metric_filter_rendering.py/SqlQueryPlan/Postgres/test_metric_filtered_by_itself__plan0_optimized.sql b/tests_metricflow/snapshots/test_metric_filter_rendering.py/SqlQueryPlan/Postgres/test_metric_filtered_by_itself__plan0_optimized.sql index 8660fddf26..ed25561015 100644 --- a/tests_metricflow/snapshots/test_metric_filter_rendering.py/SqlQueryPlan/Postgres/test_metric_filtered_by_itself__plan0_optimized.sql +++ b/tests_metricflow/snapshots/test_metric_filter_rendering.py/SqlQueryPlan/Postgres/test_metric_filtered_by_itself__plan0_optimized.sql @@ -6,34 +6,34 @@ SELECT COUNT(DISTINCT bookers) AS bookers FROM ( -- Join Standard Outputs - -- Pass Only Elements: ['bookers', 'guest__bookers'] + -- Pass Only Elements: ['bookers', 'listing__bookers'] SELECT - subq_26.guest__bookers AS guest__bookers + subq_26.listing__bookers AS listing__bookers , subq_20.bookers AS bookers FROM ( -- Read Elements From Semantic Model 'bookings_source' -- Metric Time Dimension 'ds' - -- Pass Only Elements: ['bookers', 'guest'] + -- Pass Only Elements: ['bookers', 'listing'] SELECT - guest_id AS guest + listing_id AS listing , 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'] + -- Pass Only Elements: ['bookers', 'listing'] -- Aggregate Measures -- Compute Metrics via Expressions - -- Pass Only Elements: ['guest', 'guest__bookers'] + -- Pass Only Elements: ['listing', 'listing__bookers'] SELECT - guest_id AS guest - , COUNT(DISTINCT guest_id) AS guest__bookers + listing_id AS listing + , COUNT(DISTINCT guest_id) AS listing__bookers FROM ***************************.fct_bookings bookings_source_src_28000 GROUP BY - guest_id + listing_id ) subq_26 ON - subq_20.guest = subq_26.guest + subq_20.listing = subq_26.listing ) subq_28 -WHERE guest__bookers > 1.00 +WHERE listing__bookers > 1.00 diff --git a/tests_metricflow/snapshots/test_metric_filter_rendering.py/SqlQueryPlan/Redshift/test_metric_filtered_by_itself__plan0.sql b/tests_metricflow/snapshots/test_metric_filter_rendering.py/SqlQueryPlan/Redshift/test_metric_filtered_by_itself__plan0.sql index 4f55280ee4..32af484217 100644 --- a/tests_metricflow/snapshots/test_metric_filter_rendering.py/SqlQueryPlan/Redshift/test_metric_filtered_by_itself__plan0.sql +++ b/tests_metricflow/snapshots/test_metric_filter_rendering.py/SqlQueryPlan/Redshift/test_metric_filtered_by_itself__plan0.sql @@ -12,23 +12,23 @@ FROM ( FROM ( -- Constrain Output with WHERE SELECT - subq_14.guest__bookers + subq_14.listing__bookers , subq_14.bookers FROM ( - -- Pass Only Elements: ['bookers', 'guest__bookers'] + -- Pass Only Elements: ['bookers', 'listing__bookers'] SELECT - subq_13.guest__bookers + subq_13.listing__bookers , subq_13.bookers FROM ( -- Join Standard Outputs SELECT - subq_6.guest AS guest - , subq_12.guest__bookers AS guest__bookers + subq_6.listing AS listing + , subq_12.listing__bookers AS listing__bookers , subq_6.bookers AS bookers FROM ( - -- Pass Only Elements: ['bookers', 'guest'] + -- Pass Only Elements: ['bookers', 'listing'] SELECT - subq_5.guest + subq_5.listing , subq_5.bookers FROM ( -- Metric Time Dimension 'ds' @@ -227,24 +227,24 @@ FROM ( ) subq_5 ) subq_6 LEFT OUTER JOIN ( - -- Pass Only Elements: ['guest', 'guest__bookers'] + -- Pass Only Elements: ['listing', 'listing__bookers'] SELECT - subq_11.guest - , subq_11.guest__bookers + subq_11.listing + , subq_11.listing__bookers FROM ( -- Compute Metrics via Expressions SELECT - subq_10.guest - , subq_10.bookers AS guest__bookers + subq_10.listing + , subq_10.bookers AS listing__bookers FROM ( -- Aggregate Measures SELECT - subq_9.guest + subq_9.listing , COUNT(DISTINCT subq_9.bookers) AS bookers FROM ( - -- Pass Only Elements: ['bookers', 'guest'] + -- Pass Only Elements: ['bookers', 'listing'] SELECT - subq_8.guest + subq_8.listing , subq_8.bookers FROM ( -- Metric Time Dimension 'ds' @@ -443,15 +443,15 @@ FROM ( ) subq_8 ) subq_9 GROUP BY - subq_9.guest + subq_9.listing ) subq_10 ) subq_11 ) subq_12 ON - subq_6.guest = subq_12.guest + subq_6.listing = subq_12.listing ) subq_13 ) subq_14 - WHERE guest__bookers > 1.00 + WHERE listing__bookers > 1.00 ) subq_15 ) subq_16 ) subq_17 diff --git a/tests_metricflow/snapshots/test_metric_filter_rendering.py/SqlQueryPlan/Redshift/test_metric_filtered_by_itself__plan0_optimized.sql b/tests_metricflow/snapshots/test_metric_filter_rendering.py/SqlQueryPlan/Redshift/test_metric_filtered_by_itself__plan0_optimized.sql index 8660fddf26..ed25561015 100644 --- a/tests_metricflow/snapshots/test_metric_filter_rendering.py/SqlQueryPlan/Redshift/test_metric_filtered_by_itself__plan0_optimized.sql +++ b/tests_metricflow/snapshots/test_metric_filter_rendering.py/SqlQueryPlan/Redshift/test_metric_filtered_by_itself__plan0_optimized.sql @@ -6,34 +6,34 @@ SELECT COUNT(DISTINCT bookers) AS bookers FROM ( -- Join Standard Outputs - -- Pass Only Elements: ['bookers', 'guest__bookers'] + -- Pass Only Elements: ['bookers', 'listing__bookers'] SELECT - subq_26.guest__bookers AS guest__bookers + subq_26.listing__bookers AS listing__bookers , subq_20.bookers AS bookers FROM ( -- Read Elements From Semantic Model 'bookings_source' -- Metric Time Dimension 'ds' - -- Pass Only Elements: ['bookers', 'guest'] + -- Pass Only Elements: ['bookers', 'listing'] SELECT - guest_id AS guest + listing_id AS listing , 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'] + -- Pass Only Elements: ['bookers', 'listing'] -- Aggregate Measures -- Compute Metrics via Expressions - -- Pass Only Elements: ['guest', 'guest__bookers'] + -- Pass Only Elements: ['listing', 'listing__bookers'] SELECT - guest_id AS guest - , COUNT(DISTINCT guest_id) AS guest__bookers + listing_id AS listing + , COUNT(DISTINCT guest_id) AS listing__bookers FROM ***************************.fct_bookings bookings_source_src_28000 GROUP BY - guest_id + listing_id ) subq_26 ON - subq_20.guest = subq_26.guest + subq_20.listing = subq_26.listing ) subq_28 -WHERE guest__bookers > 1.00 +WHERE listing__bookers > 1.00 diff --git a/tests_metricflow/snapshots/test_metric_filter_rendering.py/SqlQueryPlan/Snowflake/test_metric_filtered_by_itself__plan0.sql b/tests_metricflow/snapshots/test_metric_filter_rendering.py/SqlQueryPlan/Snowflake/test_metric_filtered_by_itself__plan0.sql index d002278acc..f4bbf1d2bf 100644 --- a/tests_metricflow/snapshots/test_metric_filter_rendering.py/SqlQueryPlan/Snowflake/test_metric_filtered_by_itself__plan0.sql +++ b/tests_metricflow/snapshots/test_metric_filter_rendering.py/SqlQueryPlan/Snowflake/test_metric_filtered_by_itself__plan0.sql @@ -12,23 +12,23 @@ FROM ( FROM ( -- Constrain Output with WHERE SELECT - subq_14.guest__bookers + subq_14.listing__bookers , subq_14.bookers FROM ( - -- Pass Only Elements: ['bookers', 'guest__bookers'] + -- Pass Only Elements: ['bookers', 'listing__bookers'] SELECT - subq_13.guest__bookers + subq_13.listing__bookers , subq_13.bookers FROM ( -- Join Standard Outputs SELECT - subq_6.guest AS guest - , subq_12.guest__bookers AS guest__bookers + subq_6.listing AS listing + , subq_12.listing__bookers AS listing__bookers , subq_6.bookers AS bookers FROM ( - -- Pass Only Elements: ['bookers', 'guest'] + -- Pass Only Elements: ['bookers', 'listing'] SELECT - subq_5.guest + subq_5.listing , subq_5.bookers FROM ( -- Metric Time Dimension 'ds' @@ -227,24 +227,24 @@ FROM ( ) subq_5 ) subq_6 LEFT OUTER JOIN ( - -- Pass Only Elements: ['guest', 'guest__bookers'] + -- Pass Only Elements: ['listing', 'listing__bookers'] SELECT - subq_11.guest - , subq_11.guest__bookers + subq_11.listing + , subq_11.listing__bookers FROM ( -- Compute Metrics via Expressions SELECT - subq_10.guest - , subq_10.bookers AS guest__bookers + subq_10.listing + , subq_10.bookers AS listing__bookers FROM ( -- Aggregate Measures SELECT - subq_9.guest + subq_9.listing , COUNT(DISTINCT subq_9.bookers) AS bookers FROM ( - -- Pass Only Elements: ['bookers', 'guest'] + -- Pass Only Elements: ['bookers', 'listing'] SELECT - subq_8.guest + subq_8.listing , subq_8.bookers FROM ( -- Metric Time Dimension 'ds' @@ -443,15 +443,15 @@ FROM ( ) subq_8 ) subq_9 GROUP BY - subq_9.guest + subq_9.listing ) subq_10 ) subq_11 ) subq_12 ON - subq_6.guest = subq_12.guest + subq_6.listing = subq_12.listing ) subq_13 ) subq_14 - WHERE guest__bookers > 1.00 + WHERE listing__bookers > 1.00 ) subq_15 ) subq_16 ) subq_17 diff --git a/tests_metricflow/snapshots/test_metric_filter_rendering.py/SqlQueryPlan/Snowflake/test_metric_filtered_by_itself__plan0_optimized.sql b/tests_metricflow/snapshots/test_metric_filter_rendering.py/SqlQueryPlan/Snowflake/test_metric_filtered_by_itself__plan0_optimized.sql index 8660fddf26..ed25561015 100644 --- a/tests_metricflow/snapshots/test_metric_filter_rendering.py/SqlQueryPlan/Snowflake/test_metric_filtered_by_itself__plan0_optimized.sql +++ b/tests_metricflow/snapshots/test_metric_filter_rendering.py/SqlQueryPlan/Snowflake/test_metric_filtered_by_itself__plan0_optimized.sql @@ -6,34 +6,34 @@ SELECT COUNT(DISTINCT bookers) AS bookers FROM ( -- Join Standard Outputs - -- Pass Only Elements: ['bookers', 'guest__bookers'] + -- Pass Only Elements: ['bookers', 'listing__bookers'] SELECT - subq_26.guest__bookers AS guest__bookers + subq_26.listing__bookers AS listing__bookers , subq_20.bookers AS bookers FROM ( -- Read Elements From Semantic Model 'bookings_source' -- Metric Time Dimension 'ds' - -- Pass Only Elements: ['bookers', 'guest'] + -- Pass Only Elements: ['bookers', 'listing'] SELECT - guest_id AS guest + listing_id AS listing , 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'] + -- Pass Only Elements: ['bookers', 'listing'] -- Aggregate Measures -- Compute Metrics via Expressions - -- Pass Only Elements: ['guest', 'guest__bookers'] + -- Pass Only Elements: ['listing', 'listing__bookers'] SELECT - guest_id AS guest - , COUNT(DISTINCT guest_id) AS guest__bookers + listing_id AS listing + , COUNT(DISTINCT guest_id) AS listing__bookers FROM ***************************.fct_bookings bookings_source_src_28000 GROUP BY - guest_id + listing_id ) subq_26 ON - subq_20.guest = subq_26.guest + subq_20.listing = subq_26.listing ) subq_28 -WHERE guest__bookers > 1.00 +WHERE listing__bookers > 1.00 diff --git a/tests_metricflow/snapshots/test_metric_filter_rendering.py/SqlQueryPlan/Trino/test_metric_filtered_by_itself__plan0.sql b/tests_metricflow/snapshots/test_metric_filter_rendering.py/SqlQueryPlan/Trino/test_metric_filtered_by_itself__plan0.sql index 150eb321d4..8214758700 100644 --- a/tests_metricflow/snapshots/test_metric_filter_rendering.py/SqlQueryPlan/Trino/test_metric_filtered_by_itself__plan0.sql +++ b/tests_metricflow/snapshots/test_metric_filter_rendering.py/SqlQueryPlan/Trino/test_metric_filtered_by_itself__plan0.sql @@ -12,23 +12,23 @@ FROM ( FROM ( -- Constrain Output with WHERE SELECT - subq_14.guest__bookers + subq_14.listing__bookers , subq_14.bookers FROM ( - -- Pass Only Elements: ['bookers', 'guest__bookers'] + -- Pass Only Elements: ['bookers', 'listing__bookers'] SELECT - subq_13.guest__bookers + subq_13.listing__bookers , subq_13.bookers FROM ( -- Join Standard Outputs SELECT - subq_6.guest AS guest - , subq_12.guest__bookers AS guest__bookers + subq_6.listing AS listing + , subq_12.listing__bookers AS listing__bookers , subq_6.bookers AS bookers FROM ( - -- Pass Only Elements: ['bookers', 'guest'] + -- Pass Only Elements: ['bookers', 'listing'] SELECT - subq_5.guest + subq_5.listing , subq_5.bookers FROM ( -- Metric Time Dimension 'ds' @@ -227,24 +227,24 @@ FROM ( ) subq_5 ) subq_6 LEFT OUTER JOIN ( - -- Pass Only Elements: ['guest', 'guest__bookers'] + -- Pass Only Elements: ['listing', 'listing__bookers'] SELECT - subq_11.guest - , subq_11.guest__bookers + subq_11.listing + , subq_11.listing__bookers FROM ( -- Compute Metrics via Expressions SELECT - subq_10.guest - , subq_10.bookers AS guest__bookers + subq_10.listing + , subq_10.bookers AS listing__bookers FROM ( -- Aggregate Measures SELECT - subq_9.guest + subq_9.listing , COUNT(DISTINCT subq_9.bookers) AS bookers FROM ( - -- Pass Only Elements: ['bookers', 'guest'] + -- Pass Only Elements: ['bookers', 'listing'] SELECT - subq_8.guest + subq_8.listing , subq_8.bookers FROM ( -- Metric Time Dimension 'ds' @@ -443,15 +443,15 @@ FROM ( ) subq_8 ) subq_9 GROUP BY - subq_9.guest + subq_9.listing ) subq_10 ) subq_11 ) subq_12 ON - subq_6.guest = subq_12.guest + subq_6.listing = subq_12.listing ) subq_13 ) subq_14 - WHERE guest__bookers > 1.00 + WHERE listing__bookers > 1.00 ) subq_15 ) subq_16 ) subq_17 diff --git a/tests_metricflow/snapshots/test_metric_filter_rendering.py/SqlQueryPlan/Trino/test_metric_filtered_by_itself__plan0_optimized.sql b/tests_metricflow/snapshots/test_metric_filter_rendering.py/SqlQueryPlan/Trino/test_metric_filtered_by_itself__plan0_optimized.sql index 8660fddf26..ed25561015 100644 --- a/tests_metricflow/snapshots/test_metric_filter_rendering.py/SqlQueryPlan/Trino/test_metric_filtered_by_itself__plan0_optimized.sql +++ b/tests_metricflow/snapshots/test_metric_filter_rendering.py/SqlQueryPlan/Trino/test_metric_filtered_by_itself__plan0_optimized.sql @@ -6,34 +6,34 @@ SELECT COUNT(DISTINCT bookers) AS bookers FROM ( -- Join Standard Outputs - -- Pass Only Elements: ['bookers', 'guest__bookers'] + -- Pass Only Elements: ['bookers', 'listing__bookers'] SELECT - subq_26.guest__bookers AS guest__bookers + subq_26.listing__bookers AS listing__bookers , subq_20.bookers AS bookers FROM ( -- Read Elements From Semantic Model 'bookings_source' -- Metric Time Dimension 'ds' - -- Pass Only Elements: ['bookers', 'guest'] + -- Pass Only Elements: ['bookers', 'listing'] SELECT - guest_id AS guest + listing_id AS listing , 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'] + -- Pass Only Elements: ['bookers', 'listing'] -- Aggregate Measures -- Compute Metrics via Expressions - -- Pass Only Elements: ['guest', 'guest__bookers'] + -- Pass Only Elements: ['listing', 'listing__bookers'] SELECT - guest_id AS guest - , COUNT(DISTINCT guest_id) AS guest__bookers + listing_id AS listing + , COUNT(DISTINCT guest_id) AS listing__bookers FROM ***************************.fct_bookings bookings_source_src_28000 GROUP BY - guest_id + listing_id ) subq_26 ON - subq_20.guest = subq_26.guest + subq_20.listing = subq_26.listing ) subq_28 -WHERE guest__bookers > 1.00 +WHERE listing__bookers > 1.00 From e61836ccb96d8f22fc58f296639d1e4d27e5a29b Mon Sep 17 00:00:00 2001 From: Courtney Holcomb Date: Tue, 4 Jun 2024 21:24:05 -0700 Subject: [PATCH 2/3] 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 From c64eb7c088e5fdfe73b5b88b291f271142015417 Mon Sep 17 00:00:00 2001 From: Courtney Holcomb Date: Thu, 6 Jun 2024 15:29:07 -0700 Subject: [PATCH 3/3] WIP --- .../specs/where_filter_dimension.py | 4 ---- .../specs/where_filter_entity.py | 22 ++++--------------- .../specs/where_filter_metric.py | 1 - .../time/dateutil_adjuster.py | 13 +++++------ 4 files changed, 10 insertions(+), 30 deletions(-) diff --git a/metricflow-semantics/metricflow_semantics/specs/where_filter_dimension.py b/metricflow-semantics/metricflow_semantics/specs/where_filter_dimension.py index 77c6faa5cc..d95a1f4bf3 100644 --- a/metricflow-semantics/metricflow_semantics/specs/where_filter_dimension.py +++ b/metricflow-semantics/metricflow_semantics/specs/where_filter_dimension.py @@ -83,10 +83,6 @@ def date_part(self, date_part_name: str) -> QueryInterfaceDimension: date_part=DatePart(date_part_name.lower()), ) - def descending(self, _is_descending: bool) -> QueryInterfaceDimension: - """Set the sort order for order-by.""" - raise InvalidQuerySyntax("descending is invalid in the where parameter") - def __str__(self) -> str: """Returns the column name. diff --git a/metricflow-semantics/metricflow_semantics/specs/where_filter_entity.py b/metricflow-semantics/metricflow_semantics/specs/where_filter_entity.py index 080beabfcd..8cc56523ea 100644 --- a/metricflow-semantics/metricflow_semantics/specs/where_filter_entity.py +++ b/metricflow-semantics/metricflow_semantics/specs/where_filter_entity.py @@ -23,13 +23,9 @@ from metricflow_semantics.specs.rendered_spec_tracker import RenderedSpecTracker -class WhereFilterEntity(ProtocolHint[QueryInterfaceEntity]): +class RenderedWhereFilterEntity: """An entity that is passed in through the where filter parameter.""" - @override - def _implements_protocol(self) -> QueryInterfaceEntity: - return self - def __init__( # noqa self, column_association_resolver: ColumnAssociationResolver, @@ -50,12 +46,6 @@ def __init__( # noqa self._time_grain = time_grain self._date_part = date_part - def descending(self, _is_descending: bool) -> QueryInterfaceEntity: - """Set the sort order for order-by.""" - raise InvalidQuerySyntax( - "Can't set descending in the where clause. Try setting descending in the order_by clause instead" - ) - def __str__(self) -> str: """Returns the column name. @@ -79,16 +69,12 @@ def __str__(self) -> str: return column_association.column_name -class WhereFilterEntityFactory(ProtocolHint[QueryInterfaceEntityFactory]): - """Creates a WhereFilterEntity. +class RenderedWhereFilterEntityFactory(ProtocolHint[QueryInterfaceEntityFactory]): + """Creates a RenderedWhereFilterEntity. Each call to `create` adds an EntitySpec to entity_specs. """ - @override - def _implements_protocol(self) -> QueryInterfaceEntityFactory: - return self - def __init__( # noqa self, column_association_resolver: ColumnAssociationResolver, @@ -105,7 +91,7 @@ def create(self, entity_name: str, entity_path: Sequence[str] = ()) -> WhereFilt """Create a WhereFilterEntity.""" structured_name = DunderedNameFormatter.parse_name(entity_name.lower()) - return WhereFilterEntity( + return RenderedWhereFilterEntity( column_association_resolver=self._column_association_resolver, resolved_spec_lookup=self._resolved_spec_lookup, where_filter_location=self._where_filter_location, diff --git a/metricflow-semantics/metricflow_semantics/specs/where_filter_metric.py b/metricflow-semantics/metricflow_semantics/specs/where_filter_metric.py index 9fe8af21f8..2c81332490 100644 --- a/metricflow-semantics/metricflow_semantics/specs/where_filter_metric.py +++ b/metricflow-semantics/metricflow_semantics/specs/where_filter_metric.py @@ -18,7 +18,6 @@ ) 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 diff --git a/metricflow-semantics/metricflow_semantics/time/dateutil_adjuster.py b/metricflow-semantics/metricflow_semantics/time/dateutil_adjuster.py index cf553ce49e..9c601d8c4e 100644 --- a/metricflow-semantics/metricflow_semantics/time/dateutil_adjuster.py +++ b/metricflow-semantics/metricflow_semantics/time/dateutil_adjuster.py @@ -5,7 +5,6 @@ import dateutil.relativedelta from dateutil.relativedelta import relativedelta -from dbt_semantic_interfaces.enum_extension import assert_values_exhausted from dbt_semantic_interfaces.type_enums import TimeGranularity from typing_extensions import override @@ -32,8 +31,8 @@ def _relative_delta_for_window(self, time_granularity: TimeGranularity, count: i return relativedelta(months=count * 3) elif time_granularity is TimeGranularity.YEAR: return relativedelta(years=count) - else: - assert_values_exhausted(time_granularity) + # else: + # assert_values_exhausted(time_granularity) @override def expand_time_constraint_to_fill_granularity( @@ -70,8 +69,8 @@ def adjust_to_start_of_period( return date_to_adjust + relativedelta(month=10, day=1) elif time_granularity is TimeGranularity.YEAR: return date_to_adjust + relativedelta(month=1, day=1) - else: - assert_values_exhausted(time_granularity) + # else: + # assert_values_exhausted(time_granularity) @override def adjust_to_end_of_period( @@ -94,8 +93,8 @@ def adjust_to_end_of_period( return date_to_adjust + relativedelta(month=12, day=31) elif time_granularity is TimeGranularity.YEAR: return date_to_adjust + relativedelta(month=12, day=31) - else: - assert_values_exhausted(time_granularity) + # else: + # assert_values_exhausted(time_granularity) @override def expand_time_constraint_for_cumulative_metric(