diff --git a/tests_metricflow/integration/test_cases/itest_constraints.yaml b/tests_metricflow/integration/test_cases/itest_constraints.yaml index ea3e5f1dac..50811a201b 100644 --- a/tests_metricflow/integration/test_cases/itest_constraints.yaml +++ b/tests_metricflow/integration/test_cases/itest_constraints.yaml @@ -229,3 +229,37 @@ integration_test: FROM {{ source_schema }}.fct_bookings b LEFT OUTER JOIN {{ source_schema }}.dim_listings_latest l ON b.listing_id = l.listing_id WHERE NOT b.is_instant AND (NOT l.is_lux OR l.is_lux IS NULL) +--- +integration_test: + name: test_subdaily_time_constraint + description: Test a sub-daily time constraint on a no-metric query. + model: SIMPLE_MODEL + group_bys: ["metric_time__second"] + time_constraint: ["2020-01-01 00:00:02", "2020-01-01 00:00:08"] + check_query: | + SELECT + {{ render_date_trunc("ts", TimeGranularity.SECOND) }} AS metric_time__second + FROM {{ source_schema }}.mf_time_spine_second + WHERE {{ render_date_trunc("ts", TimeGranularity.SECOND) }} BETWEEN '2020-01-01 00:00:02' AND '2020-01-01 00:00:08' + GROUP BY {{ render_date_trunc("ts", TimeGranularity.SECOND) }} +--- +integration_test: + name: test_subdaily_time_constraint_with_metric + description: Test a sub-daily time constraint on a metric query. + model: SIMPLE_MODEL + metrics: ["subdaily_join_to_time_spine_metric"] + group_bys: ["metric_time__hour"] + time_constraint: ["2020-01-01 02:00:00", "2020-01-03 05:00:00"] + check_query: | + SELECT + ts AS metric_time__hour + , archived_users AS subdaily_join_to_time_spine_metric + FROM {{ source_schema }}.mf_time_spine_hour + LEFT OUTER JOIN ( + SELECT + {{ render_date_trunc("archived_at", TimeGranularity.HOUR) }} AS metric_time__hour + , SUM(1) AS archived_users + FROM {{ source_schema }}.dim_users + GROUP BY metric_time__hour + ) subq_4 ON ts = subq_4.metric_time__hour + WHERE ts BETWEEN '2020-01-01 02:00:00' AND '2020-01-03 05:00:00' diff --git a/tests_metricflow/query_rendering/test_granularity_date_part_rendering.py b/tests_metricflow/query_rendering/test_granularity_date_part_rendering.py index 3391e5456f..242a68fd87 100644 --- a/tests_metricflow/query_rendering/test_granularity_date_part_rendering.py +++ b/tests_metricflow/query_rendering/test_granularity_date_part_rendering.py @@ -6,11 +6,14 @@ from __future__ import annotations +import datetime as dt + import pytest from _pytest.fixtures import FixtureRequest from dbt_semantic_interfaces.references import EntityReference from dbt_semantic_interfaces.type_enums.date_part import DatePart from dbt_semantic_interfaces.type_enums.time_granularity import TimeGranularity +from metricflow_semantics.filters.time_constraint import TimeRangeConstraint from metricflow_semantics.specs.metric_spec import MetricSpec from metricflow_semantics.specs.query_spec import MetricFlowQuerySpec from metricflow_semantics.specs.time_dimension_spec import TimeDimensionSpec @@ -327,3 +330,54 @@ def test_subdaily_join_to_time_spine_metric( # noqa: D103 dataflow_plan_builder=dataflow_plan_builder, query_spec=query_spec, ) + + +@pytest.mark.sql_engine_snapshot +def test_subdaily_time_constraint_without_metrics( # noqa: D103 + request: FixtureRequest, + mf_test_configuration: MetricFlowTestConfiguration, + dataflow_plan_builder: DataflowPlanBuilder, + dataflow_to_sql_converter: DataflowToSqlQueryPlanConverter, + sql_client: SqlClient, +) -> None: + query_spec = MetricFlowQuerySpec( + time_dimension_specs=(DataSet.metric_time_dimension_spec(time_granularity=TimeGranularity.SECOND),), + time_range_constraint=TimeRangeConstraint( + start_time=dt.datetime(2020, 1, 1, 0, 0, 2), end_time=dt.datetime(2020, 1, 1, 0, 0, 8) + ), + ) + + render_and_check( + request=request, + mf_test_configuration=mf_test_configuration, + dataflow_to_sql_converter=dataflow_to_sql_converter, + sql_client=sql_client, + dataflow_plan_builder=dataflow_plan_builder, + query_spec=query_spec, + ) + + +@pytest.mark.sql_engine_snapshot +def test_subdaily_time_constraint_with_metric( # noqa: D103 + request: FixtureRequest, + mf_test_configuration: MetricFlowTestConfiguration, + dataflow_plan_builder: DataflowPlanBuilder, + dataflow_to_sql_converter: DataflowToSqlQueryPlanConverter, + sql_client: SqlClient, +) -> None: + query_spec = MetricFlowQuerySpec( + metric_specs=(MetricSpec("subdaily_join_to_time_spine_metric"),), + time_dimension_specs=(DataSet.metric_time_dimension_spec(time_granularity=TimeGranularity.HOUR),), + time_range_constraint=TimeRangeConstraint( + start_time=dt.datetime(2020, 1, 1, 2), end_time=dt.datetime(2020, 1, 1, 5) + ), + ) + + render_and_check( + request=request, + mf_test_configuration=mf_test_configuration, + dataflow_to_sql_converter=dataflow_to_sql_converter, + sql_client=sql_client, + dataflow_plan_builder=dataflow_plan_builder, + query_spec=query_spec, + ) diff --git a/tests_metricflow/snapshots/test_granularity_date_part_rendering.py/SqlQueryPlan/DuckDB/test_subdaily_time_constraint_with_metric__plan0.sql b/tests_metricflow/snapshots/test_granularity_date_part_rendering.py/SqlQueryPlan/DuckDB/test_subdaily_time_constraint_with_metric__plan0.sql new file mode 100644 index 0000000000..f1543cd157 --- /dev/null +++ b/tests_metricflow/snapshots/test_granularity_date_part_rendering.py/SqlQueryPlan/DuckDB/test_subdaily_time_constraint_with_metric__plan0.sql @@ -0,0 +1,613 @@ +-- Compute Metrics via Expressions +SELECT + subq_8.metric_time__hour + , subq_8.archived_users AS subdaily_join_to_time_spine_metric +FROM ( + -- Constrain Time Range to [2020-01-01T02:00:00, 2020-01-01T05:00:00] + SELECT + subq_7.metric_time__hour + , subq_7.archived_users + FROM ( + -- Join to Time Spine Dataset + SELECT + subq_5.metric_time__hour AS metric_time__hour + , subq_4.archived_users AS archived_users + FROM ( + -- Time Spine + SELECT + subq_6.ts AS metric_time__hour + FROM ***************************.mf_time_spine_hour subq_6 + WHERE subq_6.ts BETWEEN '2020-01-01 02:00:00' AND '2020-01-01 05:00:00' + ) subq_5 + LEFT OUTER JOIN ( + -- Aggregate Measures + SELECT + subq_3.metric_time__hour + , SUM(subq_3.archived_users) AS archived_users + FROM ( + -- Pass Only Elements: ['archived_users', 'metric_time__hour'] + SELECT + subq_2.metric_time__hour + , subq_2.archived_users + FROM ( + -- Constrain Time Range to [2020-01-01T02:00:00, 2020-01-01T05:00:00] + SELECT + subq_1.ds__day + , subq_1.ds__week + , subq_1.ds__month + , subq_1.ds__quarter + , subq_1.ds__year + , subq_1.ds__extract_year + , subq_1.ds__extract_quarter + , subq_1.ds__extract_month + , subq_1.ds__extract_day + , subq_1.ds__extract_dow + , subq_1.ds__extract_doy + , subq_1.created_at__day + , subq_1.created_at__week + , subq_1.created_at__month + , subq_1.created_at__quarter + , subq_1.created_at__year + , subq_1.created_at__extract_year + , subq_1.created_at__extract_quarter + , subq_1.created_at__extract_month + , subq_1.created_at__extract_day + , subq_1.created_at__extract_dow + , subq_1.created_at__extract_doy + , subq_1.ds_partitioned__day + , subq_1.ds_partitioned__week + , subq_1.ds_partitioned__month + , subq_1.ds_partitioned__quarter + , subq_1.ds_partitioned__year + , subq_1.ds_partitioned__extract_year + , subq_1.ds_partitioned__extract_quarter + , subq_1.ds_partitioned__extract_month + , subq_1.ds_partitioned__extract_day + , subq_1.ds_partitioned__extract_dow + , subq_1.ds_partitioned__extract_doy + , subq_1.last_profile_edit_ts__millisecond + , subq_1.last_profile_edit_ts__second + , subq_1.last_profile_edit_ts__minute + , subq_1.last_profile_edit_ts__hour + , subq_1.last_profile_edit_ts__day + , subq_1.last_profile_edit_ts__week + , subq_1.last_profile_edit_ts__month + , subq_1.last_profile_edit_ts__quarter + , subq_1.last_profile_edit_ts__year + , subq_1.last_profile_edit_ts__extract_year + , subq_1.last_profile_edit_ts__extract_quarter + , subq_1.last_profile_edit_ts__extract_month + , subq_1.last_profile_edit_ts__extract_day + , subq_1.last_profile_edit_ts__extract_dow + , subq_1.last_profile_edit_ts__extract_doy + , subq_1.bio_added_ts__second + , subq_1.bio_added_ts__minute + , subq_1.bio_added_ts__hour + , subq_1.bio_added_ts__day + , subq_1.bio_added_ts__week + , subq_1.bio_added_ts__month + , subq_1.bio_added_ts__quarter + , subq_1.bio_added_ts__year + , subq_1.bio_added_ts__extract_year + , subq_1.bio_added_ts__extract_quarter + , subq_1.bio_added_ts__extract_month + , subq_1.bio_added_ts__extract_day + , subq_1.bio_added_ts__extract_dow + , subq_1.bio_added_ts__extract_doy + , subq_1.last_login_ts__minute + , subq_1.last_login_ts__hour + , subq_1.last_login_ts__day + , subq_1.last_login_ts__week + , subq_1.last_login_ts__month + , subq_1.last_login_ts__quarter + , subq_1.last_login_ts__year + , subq_1.last_login_ts__extract_year + , subq_1.last_login_ts__extract_quarter + , subq_1.last_login_ts__extract_month + , subq_1.last_login_ts__extract_day + , subq_1.last_login_ts__extract_dow + , subq_1.last_login_ts__extract_doy + , subq_1.archived_at__hour + , subq_1.archived_at__day + , subq_1.archived_at__week + , subq_1.archived_at__month + , subq_1.archived_at__quarter + , subq_1.archived_at__year + , subq_1.archived_at__extract_year + , subq_1.archived_at__extract_quarter + , subq_1.archived_at__extract_month + , subq_1.archived_at__extract_day + , subq_1.archived_at__extract_dow + , subq_1.archived_at__extract_doy + , subq_1.user__ds__day + , subq_1.user__ds__week + , subq_1.user__ds__month + , subq_1.user__ds__quarter + , subq_1.user__ds__year + , subq_1.user__ds__extract_year + , subq_1.user__ds__extract_quarter + , subq_1.user__ds__extract_month + , subq_1.user__ds__extract_day + , subq_1.user__ds__extract_dow + , subq_1.user__ds__extract_doy + , subq_1.user__created_at__day + , subq_1.user__created_at__week + , subq_1.user__created_at__month + , subq_1.user__created_at__quarter + , subq_1.user__created_at__year + , subq_1.user__created_at__extract_year + , subq_1.user__created_at__extract_quarter + , subq_1.user__created_at__extract_month + , subq_1.user__created_at__extract_day + , subq_1.user__created_at__extract_dow + , subq_1.user__created_at__extract_doy + , subq_1.user__ds_partitioned__day + , subq_1.user__ds_partitioned__week + , subq_1.user__ds_partitioned__month + , subq_1.user__ds_partitioned__quarter + , subq_1.user__ds_partitioned__year + , subq_1.user__ds_partitioned__extract_year + , subq_1.user__ds_partitioned__extract_quarter + , subq_1.user__ds_partitioned__extract_month + , subq_1.user__ds_partitioned__extract_day + , subq_1.user__ds_partitioned__extract_dow + , subq_1.user__ds_partitioned__extract_doy + , subq_1.user__last_profile_edit_ts__millisecond + , subq_1.user__last_profile_edit_ts__second + , subq_1.user__last_profile_edit_ts__minute + , subq_1.user__last_profile_edit_ts__hour + , subq_1.user__last_profile_edit_ts__day + , subq_1.user__last_profile_edit_ts__week + , subq_1.user__last_profile_edit_ts__month + , subq_1.user__last_profile_edit_ts__quarter + , subq_1.user__last_profile_edit_ts__year + , subq_1.user__last_profile_edit_ts__extract_year + , subq_1.user__last_profile_edit_ts__extract_quarter + , subq_1.user__last_profile_edit_ts__extract_month + , subq_1.user__last_profile_edit_ts__extract_day + , subq_1.user__last_profile_edit_ts__extract_dow + , subq_1.user__last_profile_edit_ts__extract_doy + , subq_1.user__bio_added_ts__second + , subq_1.user__bio_added_ts__minute + , subq_1.user__bio_added_ts__hour + , subq_1.user__bio_added_ts__day + , subq_1.user__bio_added_ts__week + , subq_1.user__bio_added_ts__month + , subq_1.user__bio_added_ts__quarter + , subq_1.user__bio_added_ts__year + , subq_1.user__bio_added_ts__extract_year + , subq_1.user__bio_added_ts__extract_quarter + , subq_1.user__bio_added_ts__extract_month + , subq_1.user__bio_added_ts__extract_day + , subq_1.user__bio_added_ts__extract_dow + , subq_1.user__bio_added_ts__extract_doy + , subq_1.user__last_login_ts__minute + , subq_1.user__last_login_ts__hour + , subq_1.user__last_login_ts__day + , subq_1.user__last_login_ts__week + , subq_1.user__last_login_ts__month + , subq_1.user__last_login_ts__quarter + , subq_1.user__last_login_ts__year + , subq_1.user__last_login_ts__extract_year + , subq_1.user__last_login_ts__extract_quarter + , subq_1.user__last_login_ts__extract_month + , subq_1.user__last_login_ts__extract_day + , subq_1.user__last_login_ts__extract_dow + , subq_1.user__last_login_ts__extract_doy + , subq_1.user__archived_at__hour + , subq_1.user__archived_at__day + , subq_1.user__archived_at__week + , subq_1.user__archived_at__month + , subq_1.user__archived_at__quarter + , subq_1.user__archived_at__year + , subq_1.user__archived_at__extract_year + , subq_1.user__archived_at__extract_quarter + , subq_1.user__archived_at__extract_month + , subq_1.user__archived_at__extract_day + , subq_1.user__archived_at__extract_dow + , subq_1.user__archived_at__extract_doy + , subq_1.metric_time__hour + , subq_1.metric_time__day + , subq_1.metric_time__week + , subq_1.metric_time__month + , subq_1.metric_time__quarter + , subq_1.metric_time__year + , subq_1.metric_time__extract_year + , subq_1.metric_time__extract_quarter + , subq_1.metric_time__extract_month + , subq_1.metric_time__extract_day + , subq_1.metric_time__extract_dow + , subq_1.metric_time__extract_doy + , subq_1.user + , subq_1.home_state + , subq_1.user__home_state + , subq_1.archived_users + FROM ( + -- Metric Time Dimension 'archived_at' + SELECT + subq_0.ds__day + , subq_0.ds__week + , subq_0.ds__month + , subq_0.ds__quarter + , subq_0.ds__year + , subq_0.ds__extract_year + , subq_0.ds__extract_quarter + , subq_0.ds__extract_month + , subq_0.ds__extract_day + , subq_0.ds__extract_dow + , subq_0.ds__extract_doy + , subq_0.created_at__day + , subq_0.created_at__week + , subq_0.created_at__month + , subq_0.created_at__quarter + , subq_0.created_at__year + , subq_0.created_at__extract_year + , subq_0.created_at__extract_quarter + , subq_0.created_at__extract_month + , subq_0.created_at__extract_day + , subq_0.created_at__extract_dow + , subq_0.created_at__extract_doy + , subq_0.ds_partitioned__day + , subq_0.ds_partitioned__week + , subq_0.ds_partitioned__month + , subq_0.ds_partitioned__quarter + , subq_0.ds_partitioned__year + , subq_0.ds_partitioned__extract_year + , subq_0.ds_partitioned__extract_quarter + , subq_0.ds_partitioned__extract_month + , subq_0.ds_partitioned__extract_day + , subq_0.ds_partitioned__extract_dow + , subq_0.ds_partitioned__extract_doy + , subq_0.last_profile_edit_ts__millisecond + , subq_0.last_profile_edit_ts__second + , subq_0.last_profile_edit_ts__minute + , subq_0.last_profile_edit_ts__hour + , subq_0.last_profile_edit_ts__day + , subq_0.last_profile_edit_ts__week + , subq_0.last_profile_edit_ts__month + , subq_0.last_profile_edit_ts__quarter + , subq_0.last_profile_edit_ts__year + , subq_0.last_profile_edit_ts__extract_year + , subq_0.last_profile_edit_ts__extract_quarter + , subq_0.last_profile_edit_ts__extract_month + , subq_0.last_profile_edit_ts__extract_day + , subq_0.last_profile_edit_ts__extract_dow + , subq_0.last_profile_edit_ts__extract_doy + , subq_0.bio_added_ts__second + , subq_0.bio_added_ts__minute + , subq_0.bio_added_ts__hour + , subq_0.bio_added_ts__day + , subq_0.bio_added_ts__week + , subq_0.bio_added_ts__month + , subq_0.bio_added_ts__quarter + , subq_0.bio_added_ts__year + , subq_0.bio_added_ts__extract_year + , subq_0.bio_added_ts__extract_quarter + , subq_0.bio_added_ts__extract_month + , subq_0.bio_added_ts__extract_day + , subq_0.bio_added_ts__extract_dow + , subq_0.bio_added_ts__extract_doy + , subq_0.last_login_ts__minute + , subq_0.last_login_ts__hour + , subq_0.last_login_ts__day + , subq_0.last_login_ts__week + , subq_0.last_login_ts__month + , subq_0.last_login_ts__quarter + , subq_0.last_login_ts__year + , subq_0.last_login_ts__extract_year + , subq_0.last_login_ts__extract_quarter + , subq_0.last_login_ts__extract_month + , subq_0.last_login_ts__extract_day + , subq_0.last_login_ts__extract_dow + , subq_0.last_login_ts__extract_doy + , subq_0.archived_at__hour + , subq_0.archived_at__day + , subq_0.archived_at__week + , subq_0.archived_at__month + , subq_0.archived_at__quarter + , subq_0.archived_at__year + , subq_0.archived_at__extract_year + , subq_0.archived_at__extract_quarter + , subq_0.archived_at__extract_month + , subq_0.archived_at__extract_day + , subq_0.archived_at__extract_dow + , subq_0.archived_at__extract_doy + , subq_0.user__ds__day + , subq_0.user__ds__week + , subq_0.user__ds__month + , subq_0.user__ds__quarter + , subq_0.user__ds__year + , subq_0.user__ds__extract_year + , subq_0.user__ds__extract_quarter + , subq_0.user__ds__extract_month + , subq_0.user__ds__extract_day + , subq_0.user__ds__extract_dow + , subq_0.user__ds__extract_doy + , subq_0.user__created_at__day + , subq_0.user__created_at__week + , subq_0.user__created_at__month + , subq_0.user__created_at__quarter + , subq_0.user__created_at__year + , subq_0.user__created_at__extract_year + , subq_0.user__created_at__extract_quarter + , subq_0.user__created_at__extract_month + , subq_0.user__created_at__extract_day + , subq_0.user__created_at__extract_dow + , subq_0.user__created_at__extract_doy + , subq_0.user__ds_partitioned__day + , subq_0.user__ds_partitioned__week + , subq_0.user__ds_partitioned__month + , subq_0.user__ds_partitioned__quarter + , subq_0.user__ds_partitioned__year + , subq_0.user__ds_partitioned__extract_year + , subq_0.user__ds_partitioned__extract_quarter + , subq_0.user__ds_partitioned__extract_month + , subq_0.user__ds_partitioned__extract_day + , subq_0.user__ds_partitioned__extract_dow + , subq_0.user__ds_partitioned__extract_doy + , subq_0.user__last_profile_edit_ts__millisecond + , subq_0.user__last_profile_edit_ts__second + , subq_0.user__last_profile_edit_ts__minute + , subq_0.user__last_profile_edit_ts__hour + , subq_0.user__last_profile_edit_ts__day + , subq_0.user__last_profile_edit_ts__week + , subq_0.user__last_profile_edit_ts__month + , subq_0.user__last_profile_edit_ts__quarter + , subq_0.user__last_profile_edit_ts__year + , subq_0.user__last_profile_edit_ts__extract_year + , subq_0.user__last_profile_edit_ts__extract_quarter + , subq_0.user__last_profile_edit_ts__extract_month + , subq_0.user__last_profile_edit_ts__extract_day + , subq_0.user__last_profile_edit_ts__extract_dow + , subq_0.user__last_profile_edit_ts__extract_doy + , subq_0.user__bio_added_ts__second + , subq_0.user__bio_added_ts__minute + , subq_0.user__bio_added_ts__hour + , subq_0.user__bio_added_ts__day + , subq_0.user__bio_added_ts__week + , subq_0.user__bio_added_ts__month + , subq_0.user__bio_added_ts__quarter + , subq_0.user__bio_added_ts__year + , subq_0.user__bio_added_ts__extract_year + , subq_0.user__bio_added_ts__extract_quarter + , subq_0.user__bio_added_ts__extract_month + , subq_0.user__bio_added_ts__extract_day + , subq_0.user__bio_added_ts__extract_dow + , subq_0.user__bio_added_ts__extract_doy + , subq_0.user__last_login_ts__minute + , subq_0.user__last_login_ts__hour + , subq_0.user__last_login_ts__day + , subq_0.user__last_login_ts__week + , subq_0.user__last_login_ts__month + , subq_0.user__last_login_ts__quarter + , subq_0.user__last_login_ts__year + , subq_0.user__last_login_ts__extract_year + , subq_0.user__last_login_ts__extract_quarter + , subq_0.user__last_login_ts__extract_month + , subq_0.user__last_login_ts__extract_day + , subq_0.user__last_login_ts__extract_dow + , subq_0.user__last_login_ts__extract_doy + , subq_0.user__archived_at__hour + , subq_0.user__archived_at__day + , subq_0.user__archived_at__week + , subq_0.user__archived_at__month + , subq_0.user__archived_at__quarter + , subq_0.user__archived_at__year + , subq_0.user__archived_at__extract_year + , subq_0.user__archived_at__extract_quarter + , subq_0.user__archived_at__extract_month + , subq_0.user__archived_at__extract_day + , subq_0.user__archived_at__extract_dow + , subq_0.user__archived_at__extract_doy + , subq_0.archived_at__hour AS metric_time__hour + , subq_0.archived_at__day AS metric_time__day + , subq_0.archived_at__week AS metric_time__week + , subq_0.archived_at__month AS metric_time__month + , subq_0.archived_at__quarter AS metric_time__quarter + , subq_0.archived_at__year AS metric_time__year + , subq_0.archived_at__extract_year AS metric_time__extract_year + , subq_0.archived_at__extract_quarter AS metric_time__extract_quarter + , subq_0.archived_at__extract_month AS metric_time__extract_month + , subq_0.archived_at__extract_day AS metric_time__extract_day + , subq_0.archived_at__extract_dow AS metric_time__extract_dow + , subq_0.archived_at__extract_doy AS metric_time__extract_doy + , subq_0.user + , subq_0.home_state + , subq_0.user__home_state + , subq_0.archived_users + FROM ( + -- Read Elements From Semantic Model 'users_ds_source' + SELECT + 1 AS new_users + , 1 AS archived_users + , DATE_TRUNC('day', users_ds_source_src_28000.ds) AS ds__day + , DATE_TRUNC('week', users_ds_source_src_28000.ds) AS ds__week + , DATE_TRUNC('month', users_ds_source_src_28000.ds) AS ds__month + , DATE_TRUNC('quarter', users_ds_source_src_28000.ds) AS ds__quarter + , DATE_TRUNC('year', users_ds_source_src_28000.ds) AS ds__year + , EXTRACT(year FROM users_ds_source_src_28000.ds) AS ds__extract_year + , EXTRACT(quarter FROM users_ds_source_src_28000.ds) AS ds__extract_quarter + , EXTRACT(month FROM users_ds_source_src_28000.ds) AS ds__extract_month + , EXTRACT(day FROM users_ds_source_src_28000.ds) AS ds__extract_day + , EXTRACT(isodow FROM users_ds_source_src_28000.ds) AS ds__extract_dow + , EXTRACT(doy FROM users_ds_source_src_28000.ds) AS ds__extract_doy + , DATE_TRUNC('day', users_ds_source_src_28000.created_at) AS created_at__day + , DATE_TRUNC('week', users_ds_source_src_28000.created_at) AS created_at__week + , DATE_TRUNC('month', users_ds_source_src_28000.created_at) AS created_at__month + , DATE_TRUNC('quarter', users_ds_source_src_28000.created_at) AS created_at__quarter + , DATE_TRUNC('year', users_ds_source_src_28000.created_at) AS created_at__year + , EXTRACT(year FROM users_ds_source_src_28000.created_at) AS created_at__extract_year + , EXTRACT(quarter FROM users_ds_source_src_28000.created_at) AS created_at__extract_quarter + , EXTRACT(month FROM users_ds_source_src_28000.created_at) AS created_at__extract_month + , EXTRACT(day FROM users_ds_source_src_28000.created_at) AS created_at__extract_day + , EXTRACT(isodow FROM users_ds_source_src_28000.created_at) AS created_at__extract_dow + , EXTRACT(doy FROM users_ds_source_src_28000.created_at) AS created_at__extract_doy + , DATE_TRUNC('day', users_ds_source_src_28000.ds_partitioned) AS ds_partitioned__day + , DATE_TRUNC('week', users_ds_source_src_28000.ds_partitioned) AS ds_partitioned__week + , DATE_TRUNC('month', users_ds_source_src_28000.ds_partitioned) AS ds_partitioned__month + , DATE_TRUNC('quarter', users_ds_source_src_28000.ds_partitioned) AS ds_partitioned__quarter + , DATE_TRUNC('year', users_ds_source_src_28000.ds_partitioned) AS ds_partitioned__year + , EXTRACT(year FROM users_ds_source_src_28000.ds_partitioned) AS ds_partitioned__extract_year + , EXTRACT(quarter FROM users_ds_source_src_28000.ds_partitioned) AS ds_partitioned__extract_quarter + , EXTRACT(month FROM users_ds_source_src_28000.ds_partitioned) AS ds_partitioned__extract_month + , EXTRACT(day FROM users_ds_source_src_28000.ds_partitioned) AS ds_partitioned__extract_day + , EXTRACT(isodow FROM users_ds_source_src_28000.ds_partitioned) AS ds_partitioned__extract_dow + , EXTRACT(doy FROM users_ds_source_src_28000.ds_partitioned) AS ds_partitioned__extract_doy + , users_ds_source_src_28000.home_state + , DATE_TRUNC('millisecond', users_ds_source_src_28000.last_profile_edit_ts) AS last_profile_edit_ts__millisecond + , DATE_TRUNC('second', users_ds_source_src_28000.last_profile_edit_ts) AS last_profile_edit_ts__second + , DATE_TRUNC('minute', users_ds_source_src_28000.last_profile_edit_ts) AS last_profile_edit_ts__minute + , DATE_TRUNC('hour', users_ds_source_src_28000.last_profile_edit_ts) AS last_profile_edit_ts__hour + , DATE_TRUNC('day', users_ds_source_src_28000.last_profile_edit_ts) AS last_profile_edit_ts__day + , DATE_TRUNC('week', users_ds_source_src_28000.last_profile_edit_ts) AS last_profile_edit_ts__week + , DATE_TRUNC('month', users_ds_source_src_28000.last_profile_edit_ts) AS last_profile_edit_ts__month + , DATE_TRUNC('quarter', users_ds_source_src_28000.last_profile_edit_ts) AS last_profile_edit_ts__quarter + , DATE_TRUNC('year', users_ds_source_src_28000.last_profile_edit_ts) AS last_profile_edit_ts__year + , EXTRACT(year FROM users_ds_source_src_28000.last_profile_edit_ts) AS last_profile_edit_ts__extract_year + , EXTRACT(quarter FROM users_ds_source_src_28000.last_profile_edit_ts) AS last_profile_edit_ts__extract_quarter + , EXTRACT(month FROM users_ds_source_src_28000.last_profile_edit_ts) AS last_profile_edit_ts__extract_month + , EXTRACT(day FROM users_ds_source_src_28000.last_profile_edit_ts) AS last_profile_edit_ts__extract_day + , EXTRACT(isodow FROM users_ds_source_src_28000.last_profile_edit_ts) AS last_profile_edit_ts__extract_dow + , EXTRACT(doy FROM users_ds_source_src_28000.last_profile_edit_ts) AS last_profile_edit_ts__extract_doy + , DATE_TRUNC('second', users_ds_source_src_28000.bio_added_ts) AS bio_added_ts__second + , DATE_TRUNC('minute', users_ds_source_src_28000.bio_added_ts) AS bio_added_ts__minute + , DATE_TRUNC('hour', users_ds_source_src_28000.bio_added_ts) AS bio_added_ts__hour + , DATE_TRUNC('day', users_ds_source_src_28000.bio_added_ts) AS bio_added_ts__day + , DATE_TRUNC('week', users_ds_source_src_28000.bio_added_ts) AS bio_added_ts__week + , DATE_TRUNC('month', users_ds_source_src_28000.bio_added_ts) AS bio_added_ts__month + , DATE_TRUNC('quarter', users_ds_source_src_28000.bio_added_ts) AS bio_added_ts__quarter + , DATE_TRUNC('year', users_ds_source_src_28000.bio_added_ts) AS bio_added_ts__year + , EXTRACT(year FROM users_ds_source_src_28000.bio_added_ts) AS bio_added_ts__extract_year + , EXTRACT(quarter FROM users_ds_source_src_28000.bio_added_ts) AS bio_added_ts__extract_quarter + , EXTRACT(month FROM users_ds_source_src_28000.bio_added_ts) AS bio_added_ts__extract_month + , EXTRACT(day FROM users_ds_source_src_28000.bio_added_ts) AS bio_added_ts__extract_day + , EXTRACT(isodow FROM users_ds_source_src_28000.bio_added_ts) AS bio_added_ts__extract_dow + , EXTRACT(doy FROM users_ds_source_src_28000.bio_added_ts) AS bio_added_ts__extract_doy + , DATE_TRUNC('minute', users_ds_source_src_28000.last_login_ts) AS last_login_ts__minute + , DATE_TRUNC('hour', users_ds_source_src_28000.last_login_ts) AS last_login_ts__hour + , DATE_TRUNC('day', users_ds_source_src_28000.last_login_ts) AS last_login_ts__day + , DATE_TRUNC('week', users_ds_source_src_28000.last_login_ts) AS last_login_ts__week + , DATE_TRUNC('month', users_ds_source_src_28000.last_login_ts) AS last_login_ts__month + , DATE_TRUNC('quarter', users_ds_source_src_28000.last_login_ts) AS last_login_ts__quarter + , DATE_TRUNC('year', users_ds_source_src_28000.last_login_ts) AS last_login_ts__year + , EXTRACT(year FROM users_ds_source_src_28000.last_login_ts) AS last_login_ts__extract_year + , EXTRACT(quarter FROM users_ds_source_src_28000.last_login_ts) AS last_login_ts__extract_quarter + , EXTRACT(month FROM users_ds_source_src_28000.last_login_ts) AS last_login_ts__extract_month + , EXTRACT(day FROM users_ds_source_src_28000.last_login_ts) AS last_login_ts__extract_day + , EXTRACT(isodow FROM users_ds_source_src_28000.last_login_ts) AS last_login_ts__extract_dow + , EXTRACT(doy FROM users_ds_source_src_28000.last_login_ts) AS last_login_ts__extract_doy + , DATE_TRUNC('hour', users_ds_source_src_28000.archived_at) AS archived_at__hour + , DATE_TRUNC('day', users_ds_source_src_28000.archived_at) AS archived_at__day + , DATE_TRUNC('week', users_ds_source_src_28000.archived_at) AS archived_at__week + , DATE_TRUNC('month', users_ds_source_src_28000.archived_at) AS archived_at__month + , DATE_TRUNC('quarter', users_ds_source_src_28000.archived_at) AS archived_at__quarter + , DATE_TRUNC('year', users_ds_source_src_28000.archived_at) AS archived_at__year + , EXTRACT(year FROM users_ds_source_src_28000.archived_at) AS archived_at__extract_year + , EXTRACT(quarter FROM users_ds_source_src_28000.archived_at) AS archived_at__extract_quarter + , EXTRACT(month FROM users_ds_source_src_28000.archived_at) AS archived_at__extract_month + , EXTRACT(day FROM users_ds_source_src_28000.archived_at) AS archived_at__extract_day + , EXTRACT(isodow FROM users_ds_source_src_28000.archived_at) AS archived_at__extract_dow + , EXTRACT(doy FROM users_ds_source_src_28000.archived_at) AS archived_at__extract_doy + , DATE_TRUNC('day', users_ds_source_src_28000.ds) AS user__ds__day + , DATE_TRUNC('week', users_ds_source_src_28000.ds) AS user__ds__week + , DATE_TRUNC('month', users_ds_source_src_28000.ds) AS user__ds__month + , DATE_TRUNC('quarter', users_ds_source_src_28000.ds) AS user__ds__quarter + , DATE_TRUNC('year', users_ds_source_src_28000.ds) AS user__ds__year + , EXTRACT(year FROM users_ds_source_src_28000.ds) AS user__ds__extract_year + , EXTRACT(quarter FROM users_ds_source_src_28000.ds) AS user__ds__extract_quarter + , EXTRACT(month FROM users_ds_source_src_28000.ds) AS user__ds__extract_month + , EXTRACT(day FROM users_ds_source_src_28000.ds) AS user__ds__extract_day + , EXTRACT(isodow FROM users_ds_source_src_28000.ds) AS user__ds__extract_dow + , EXTRACT(doy FROM users_ds_source_src_28000.ds) AS user__ds__extract_doy + , DATE_TRUNC('day', users_ds_source_src_28000.created_at) AS user__created_at__day + , DATE_TRUNC('week', users_ds_source_src_28000.created_at) AS user__created_at__week + , DATE_TRUNC('month', users_ds_source_src_28000.created_at) AS user__created_at__month + , DATE_TRUNC('quarter', users_ds_source_src_28000.created_at) AS user__created_at__quarter + , DATE_TRUNC('year', users_ds_source_src_28000.created_at) AS user__created_at__year + , EXTRACT(year FROM users_ds_source_src_28000.created_at) AS user__created_at__extract_year + , EXTRACT(quarter FROM users_ds_source_src_28000.created_at) AS user__created_at__extract_quarter + , EXTRACT(month FROM users_ds_source_src_28000.created_at) AS user__created_at__extract_month + , EXTRACT(day FROM users_ds_source_src_28000.created_at) AS user__created_at__extract_day + , EXTRACT(isodow FROM users_ds_source_src_28000.created_at) AS user__created_at__extract_dow + , EXTRACT(doy FROM users_ds_source_src_28000.created_at) AS user__created_at__extract_doy + , DATE_TRUNC('day', users_ds_source_src_28000.ds_partitioned) AS user__ds_partitioned__day + , DATE_TRUNC('week', users_ds_source_src_28000.ds_partitioned) AS user__ds_partitioned__week + , DATE_TRUNC('month', users_ds_source_src_28000.ds_partitioned) AS user__ds_partitioned__month + , DATE_TRUNC('quarter', users_ds_source_src_28000.ds_partitioned) AS user__ds_partitioned__quarter + , DATE_TRUNC('year', users_ds_source_src_28000.ds_partitioned) AS user__ds_partitioned__year + , EXTRACT(year FROM users_ds_source_src_28000.ds_partitioned) AS user__ds_partitioned__extract_year + , EXTRACT(quarter FROM users_ds_source_src_28000.ds_partitioned) AS user__ds_partitioned__extract_quarter + , EXTRACT(month FROM users_ds_source_src_28000.ds_partitioned) AS user__ds_partitioned__extract_month + , EXTRACT(day FROM users_ds_source_src_28000.ds_partitioned) AS user__ds_partitioned__extract_day + , EXTRACT(isodow FROM users_ds_source_src_28000.ds_partitioned) AS user__ds_partitioned__extract_dow + , EXTRACT(doy FROM users_ds_source_src_28000.ds_partitioned) AS user__ds_partitioned__extract_doy + , users_ds_source_src_28000.home_state AS user__home_state + , DATE_TRUNC('millisecond', users_ds_source_src_28000.last_profile_edit_ts) AS user__last_profile_edit_ts__millisecond + , DATE_TRUNC('second', users_ds_source_src_28000.last_profile_edit_ts) AS user__last_profile_edit_ts__second + , DATE_TRUNC('minute', users_ds_source_src_28000.last_profile_edit_ts) AS user__last_profile_edit_ts__minute + , DATE_TRUNC('hour', users_ds_source_src_28000.last_profile_edit_ts) AS user__last_profile_edit_ts__hour + , DATE_TRUNC('day', users_ds_source_src_28000.last_profile_edit_ts) AS user__last_profile_edit_ts__day + , DATE_TRUNC('week', users_ds_source_src_28000.last_profile_edit_ts) AS user__last_profile_edit_ts__week + , DATE_TRUNC('month', users_ds_source_src_28000.last_profile_edit_ts) AS user__last_profile_edit_ts__month + , DATE_TRUNC('quarter', users_ds_source_src_28000.last_profile_edit_ts) AS user__last_profile_edit_ts__quarter + , DATE_TRUNC('year', users_ds_source_src_28000.last_profile_edit_ts) AS user__last_profile_edit_ts__year + , EXTRACT(year FROM users_ds_source_src_28000.last_profile_edit_ts) AS user__last_profile_edit_ts__extract_year + , EXTRACT(quarter FROM users_ds_source_src_28000.last_profile_edit_ts) AS user__last_profile_edit_ts__extract_quarter + , EXTRACT(month FROM users_ds_source_src_28000.last_profile_edit_ts) AS user__last_profile_edit_ts__extract_month + , EXTRACT(day FROM users_ds_source_src_28000.last_profile_edit_ts) AS user__last_profile_edit_ts__extract_day + , EXTRACT(isodow FROM users_ds_source_src_28000.last_profile_edit_ts) AS user__last_profile_edit_ts__extract_dow + , EXTRACT(doy FROM users_ds_source_src_28000.last_profile_edit_ts) AS user__last_profile_edit_ts__extract_doy + , DATE_TRUNC('second', users_ds_source_src_28000.bio_added_ts) AS user__bio_added_ts__second + , DATE_TRUNC('minute', users_ds_source_src_28000.bio_added_ts) AS user__bio_added_ts__minute + , DATE_TRUNC('hour', users_ds_source_src_28000.bio_added_ts) AS user__bio_added_ts__hour + , DATE_TRUNC('day', users_ds_source_src_28000.bio_added_ts) AS user__bio_added_ts__day + , DATE_TRUNC('week', users_ds_source_src_28000.bio_added_ts) AS user__bio_added_ts__week + , DATE_TRUNC('month', users_ds_source_src_28000.bio_added_ts) AS user__bio_added_ts__month + , DATE_TRUNC('quarter', users_ds_source_src_28000.bio_added_ts) AS user__bio_added_ts__quarter + , DATE_TRUNC('year', users_ds_source_src_28000.bio_added_ts) AS user__bio_added_ts__year + , EXTRACT(year FROM users_ds_source_src_28000.bio_added_ts) AS user__bio_added_ts__extract_year + , EXTRACT(quarter FROM users_ds_source_src_28000.bio_added_ts) AS user__bio_added_ts__extract_quarter + , EXTRACT(month FROM users_ds_source_src_28000.bio_added_ts) AS user__bio_added_ts__extract_month + , EXTRACT(day FROM users_ds_source_src_28000.bio_added_ts) AS user__bio_added_ts__extract_day + , EXTRACT(isodow FROM users_ds_source_src_28000.bio_added_ts) AS user__bio_added_ts__extract_dow + , EXTRACT(doy FROM users_ds_source_src_28000.bio_added_ts) AS user__bio_added_ts__extract_doy + , DATE_TRUNC('minute', users_ds_source_src_28000.last_login_ts) AS user__last_login_ts__minute + , DATE_TRUNC('hour', users_ds_source_src_28000.last_login_ts) AS user__last_login_ts__hour + , DATE_TRUNC('day', users_ds_source_src_28000.last_login_ts) AS user__last_login_ts__day + , DATE_TRUNC('week', users_ds_source_src_28000.last_login_ts) AS user__last_login_ts__week + , DATE_TRUNC('month', users_ds_source_src_28000.last_login_ts) AS user__last_login_ts__month + , DATE_TRUNC('quarter', users_ds_source_src_28000.last_login_ts) AS user__last_login_ts__quarter + , DATE_TRUNC('year', users_ds_source_src_28000.last_login_ts) AS user__last_login_ts__year + , EXTRACT(year FROM users_ds_source_src_28000.last_login_ts) AS user__last_login_ts__extract_year + , EXTRACT(quarter FROM users_ds_source_src_28000.last_login_ts) AS user__last_login_ts__extract_quarter + , EXTRACT(month FROM users_ds_source_src_28000.last_login_ts) AS user__last_login_ts__extract_month + , EXTRACT(day FROM users_ds_source_src_28000.last_login_ts) AS user__last_login_ts__extract_day + , EXTRACT(isodow FROM users_ds_source_src_28000.last_login_ts) AS user__last_login_ts__extract_dow + , EXTRACT(doy FROM users_ds_source_src_28000.last_login_ts) AS user__last_login_ts__extract_doy + , DATE_TRUNC('hour', users_ds_source_src_28000.archived_at) AS user__archived_at__hour + , DATE_TRUNC('day', users_ds_source_src_28000.archived_at) AS user__archived_at__day + , DATE_TRUNC('week', users_ds_source_src_28000.archived_at) AS user__archived_at__week + , DATE_TRUNC('month', users_ds_source_src_28000.archived_at) AS user__archived_at__month + , DATE_TRUNC('quarter', users_ds_source_src_28000.archived_at) AS user__archived_at__quarter + , DATE_TRUNC('year', users_ds_source_src_28000.archived_at) AS user__archived_at__year + , EXTRACT(year FROM users_ds_source_src_28000.archived_at) AS user__archived_at__extract_year + , EXTRACT(quarter FROM users_ds_source_src_28000.archived_at) AS user__archived_at__extract_quarter + , EXTRACT(month FROM users_ds_source_src_28000.archived_at) AS user__archived_at__extract_month + , EXTRACT(day FROM users_ds_source_src_28000.archived_at) AS user__archived_at__extract_day + , EXTRACT(isodow FROM users_ds_source_src_28000.archived_at) AS user__archived_at__extract_dow + , EXTRACT(doy FROM users_ds_source_src_28000.archived_at) AS user__archived_at__extract_doy + , users_ds_source_src_28000.user_id AS user + FROM ***************************.dim_users users_ds_source_src_28000 + ) subq_0 + ) subq_1 + WHERE subq_1.metric_time__hour BETWEEN '2020-01-01 02:00:00' AND '2020-01-01 05:00:00' + ) subq_2 + ) subq_3 + GROUP BY + subq_3.metric_time__hour + ) subq_4 + ON + subq_5.metric_time__hour = subq_4.metric_time__hour + ) subq_7 + WHERE subq_7.metric_time__hour BETWEEN '2020-01-01 02:00:00' AND '2020-01-01 05:00:00' +) subq_8 diff --git a/tests_metricflow/snapshots/test_granularity_date_part_rendering.py/SqlQueryPlan/DuckDB/test_subdaily_time_constraint_with_metric__plan0_optimized.sql b/tests_metricflow/snapshots/test_granularity_date_part_rendering.py/SqlQueryPlan/DuckDB/test_subdaily_time_constraint_with_metric__plan0_optimized.sql new file mode 100644 index 0000000000..7fef407456 --- /dev/null +++ b/tests_metricflow/snapshots/test_granularity_date_part_rendering.py/SqlQueryPlan/DuckDB/test_subdaily_time_constraint_with_metric__plan0_optimized.sql @@ -0,0 +1,35 @@ +-- Join to Time Spine Dataset +-- Constrain Time Range to [2020-01-01T02:00:00, 2020-01-01T05:00:00] +-- Compute Metrics via Expressions +SELECT + subq_14.metric_time__hour AS metric_time__hour + , subq_13.archived_users AS subdaily_join_to_time_spine_metric +FROM ( + -- Time Spine + SELECT + ts AS metric_time__hour + FROM ***************************.mf_time_spine_hour subq_15 + WHERE ts BETWEEN '2020-01-01 02:00:00' AND '2020-01-01 05:00:00' +) subq_14 +LEFT OUTER JOIN ( + -- Aggregate Measures + SELECT + metric_time__hour + , SUM(archived_users) AS archived_users + FROM ( + -- Read Elements From Semantic Model 'users_ds_source' + -- Metric Time Dimension 'archived_at' + -- Constrain Time Range to [2020-01-01T02:00:00, 2020-01-01T05:00:00] + -- Pass Only Elements: ['archived_users', 'metric_time__hour'] + SELECT + DATE_TRUNC('hour', archived_at) AS metric_time__hour + , 1 AS archived_users + FROM ***************************.dim_users users_ds_source_src_28000 + WHERE DATE_TRUNC('hour', archived_at) BETWEEN '2020-01-01 02:00:00' AND '2020-01-01 05:00:00' + ) subq_12 + GROUP BY + metric_time__hour +) subq_13 +ON + subq_14.metric_time__hour = subq_13.metric_time__hour +WHERE subq_14.metric_time__hour BETWEEN '2020-01-01 02:00:00' AND '2020-01-01 05:00:00' diff --git a/tests_metricflow/snapshots/test_granularity_date_part_rendering.py/SqlQueryPlan/DuckDB/test_subdaily_time_constraint_without_metrics__plan0.sql b/tests_metricflow/snapshots/test_granularity_date_part_rendering.py/SqlQueryPlan/DuckDB/test_subdaily_time_constraint_without_metrics__plan0.sql new file mode 100644 index 0000000000..43dbe48625 --- /dev/null +++ b/tests_metricflow/snapshots/test_granularity_date_part_rendering.py/SqlQueryPlan/DuckDB/test_subdaily_time_constraint_without_metrics__plan0.sql @@ -0,0 +1,89 @@ +-- Pass Only Elements: ['metric_time__second',] +SELECT + subq_2.metric_time__second +FROM ( + -- Constrain Time Range to [2020-01-01T00:00:02, 2020-01-01T00:00:08] + SELECT + subq_1.ts__second + , subq_1.ts__minute + , subq_1.ts__hour + , subq_1.ts__day + , subq_1.ts__week + , subq_1.ts__month + , subq_1.ts__quarter + , subq_1.ts__year + , subq_1.ts__extract_year + , subq_1.ts__extract_quarter + , subq_1.ts__extract_month + , subq_1.ts__extract_day + , subq_1.ts__extract_dow + , subq_1.ts__extract_doy + , subq_1.metric_time__second + , subq_1.metric_time__minute + , subq_1.metric_time__hour + , subq_1.metric_time__day + , subq_1.metric_time__week + , subq_1.metric_time__month + , subq_1.metric_time__quarter + , subq_1.metric_time__year + , subq_1.metric_time__extract_year + , subq_1.metric_time__extract_quarter + , subq_1.metric_time__extract_month + , subq_1.metric_time__extract_day + , subq_1.metric_time__extract_dow + , subq_1.metric_time__extract_doy + FROM ( + -- Metric Time Dimension 'ts' + SELECT + subq_0.ts__second + , subq_0.ts__minute + , subq_0.ts__hour + , subq_0.ts__day + , subq_0.ts__week + , subq_0.ts__month + , subq_0.ts__quarter + , subq_0.ts__year + , subq_0.ts__extract_year + , subq_0.ts__extract_quarter + , subq_0.ts__extract_month + , subq_0.ts__extract_day + , subq_0.ts__extract_dow + , subq_0.ts__extract_doy + , subq_0.ts__second AS metric_time__second + , subq_0.ts__minute AS metric_time__minute + , subq_0.ts__hour AS metric_time__hour + , subq_0.ts__day AS metric_time__day + , subq_0.ts__week AS metric_time__week + , subq_0.ts__month AS metric_time__month + , subq_0.ts__quarter AS metric_time__quarter + , subq_0.ts__year AS metric_time__year + , subq_0.ts__extract_year AS metric_time__extract_year + , subq_0.ts__extract_quarter AS metric_time__extract_quarter + , subq_0.ts__extract_month AS metric_time__extract_month + , subq_0.ts__extract_day AS metric_time__extract_day + , subq_0.ts__extract_dow AS metric_time__extract_dow + , subq_0.ts__extract_doy AS metric_time__extract_doy + FROM ( + -- Time Spine + SELECT + DATE_TRUNC('second', time_spine_src_28003.ts) AS ts__second + , DATE_TRUNC('minute', time_spine_src_28003.ts) AS ts__minute + , DATE_TRUNC('hour', time_spine_src_28003.ts) AS ts__hour + , DATE_TRUNC('day', time_spine_src_28003.ts) AS ts__day + , DATE_TRUNC('week', time_spine_src_28003.ts) AS ts__week + , DATE_TRUNC('month', time_spine_src_28003.ts) AS ts__month + , DATE_TRUNC('quarter', time_spine_src_28003.ts) AS ts__quarter + , DATE_TRUNC('year', time_spine_src_28003.ts) AS ts__year + , EXTRACT(year FROM time_spine_src_28003.ts) AS ts__extract_year + , EXTRACT(quarter FROM time_spine_src_28003.ts) AS ts__extract_quarter + , EXTRACT(month FROM time_spine_src_28003.ts) AS ts__extract_month + , EXTRACT(day FROM time_spine_src_28003.ts) AS ts__extract_day + , EXTRACT(isodow FROM time_spine_src_28003.ts) AS ts__extract_dow + , EXTRACT(doy FROM time_spine_src_28003.ts) AS ts__extract_doy + FROM ***************************.mf_time_spine_second time_spine_src_28003 + ) subq_0 + ) subq_1 + WHERE subq_1.metric_time__second BETWEEN '2020-01-01 00:00:02' AND '2020-01-01 00:00:08' +) subq_2 +GROUP BY + subq_2.metric_time__second diff --git a/tests_metricflow/snapshots/test_granularity_date_part_rendering.py/SqlQueryPlan/DuckDB/test_subdaily_time_constraint_without_metrics__plan0_optimized.sql b/tests_metricflow/snapshots/test_granularity_date_part_rendering.py/SqlQueryPlan/DuckDB/test_subdaily_time_constraint_without_metrics__plan0_optimized.sql new file mode 100644 index 0000000000..da3180d776 --- /dev/null +++ b/tests_metricflow/snapshots/test_granularity_date_part_rendering.py/SqlQueryPlan/DuckDB/test_subdaily_time_constraint_without_metrics__plan0_optimized.sql @@ -0,0 +1,10 @@ +-- Time Spine +-- Metric Time Dimension 'ts' +-- Constrain Time Range to [2020-01-01T00:00:02, 2020-01-01T00:00:08] +-- Pass Only Elements: ['metric_time__second',] +SELECT + DATE_TRUNC('second', ts) AS metric_time__second +FROM ***************************.mf_time_spine_second time_spine_src_28003 +WHERE DATE_TRUNC('second', ts) BETWEEN '2020-01-01 00:00:02' AND '2020-01-01 00:00:08' +GROUP BY + DATE_TRUNC('second', ts)