From 687300c2aaa0f87d25a9b70d0d16d2192827768c Mon Sep 17 00:00:00 2001 From: Paul Yang Date: Wed, 6 Nov 2024 08:22:50 -0800 Subject: [PATCH] Move `_make_time_range_comparison_expr`. --- metricflow/plan_conversion/dataflow_to_sql.py | 72 ++++++++++--------- 1 file changed, 37 insertions(+), 35 deletions(-) diff --git a/metricflow/plan_conversion/dataflow_to_sql.py b/metricflow/plan_conversion/dataflow_to_sql.py index 3dc687380..d283592e8 100644 --- a/metricflow/plan_conversion/dataflow_to_sql.py +++ b/metricflow/plan_conversion/dataflow_to_sql.py @@ -210,39 +210,6 @@ def convert_to_sql_query_plan( ) -def _make_time_range_comparison_expr( - table_alias: str, column_alias: str, time_range_constraint: TimeRangeConstraint -) -> SqlExpressionNode: - """Build an expression like "ds BETWEEN CAST('2020-01-01' AS TIMESTAMP) AND CAST('2020-01-02' AS TIMESTAMP). - - If the constraint uses day or larger grain, only render to the date level. Otherwise, render to the timestamp level. - """ - - def strip_time_from_dt(ts: dt.datetime) -> dt.datetime: - date_obj = ts.date() - return dt.datetime(date_obj.year, date_obj.month, date_obj.day) - - constraint_uses_day_or_larger_grain = True - for constraint_input in (time_range_constraint.start_time, time_range_constraint.end_time): - if strip_time_from_dt(constraint_input) != constraint_input: - constraint_uses_day_or_larger_grain = False - break - - time_format_to_render = ISO8601_PYTHON_FORMAT if constraint_uses_day_or_larger_grain else ISO8601_PYTHON_TS_FORMAT - - return SqlBetweenExpression.create( - column_arg=SqlColumnReferenceExpression.create( - SqlColumnReference(table_alias=table_alias, column_name=column_alias) - ), - start_expr=SqlStringLiteralExpression.create( - literal_value=time_range_constraint.start_time.strftime(time_format_to_render), - ), - end_expr=SqlStringLiteralExpression.create( - literal_value=time_range_constraint.end_time.strftime(time_format_to_render), - ), - ) - - class DataflowNodeToSqlSubqueryVisitor(DataflowPlanNodeVisitor[SqlDataSet]): """Generates a SQL query plan by converting a node's parents to sub-queries. @@ -360,7 +327,7 @@ def _make_time_spine_data_set( from_source_alias=time_spine_table_alias, group_bys=select_columns if apply_group_by else (), where=( - _make_time_range_comparison_expr( + DataflowNodeToSqlSubqueryVisitor._make_time_range_comparison_expr( table_alias=time_spine_table_alias, column_alias=time_spine_source.base_column, time_range_constraint=time_range_constraint, @@ -1125,7 +1092,7 @@ def visit_constrain_time_range_node(self, node: ConstrainTimeRangeNode) -> SqlDa time_dimension_instance_for_metric_time = time_dimension_instances_for_metric_time[0] # Build an expression like "ds >= CAST('2020-01-01' AS TIMESTAMP) AND ds <= CAST('2020-01-02' AS TIMESTAMP)" - constrain_metric_time_column_condition = _make_time_range_comparison_expr( + constrain_metric_time_column_condition = DataflowNodeToSqlSubqueryVisitor._make_time_range_comparison_expr( table_alias=from_data_set_alias, column_alias=time_dimension_instance_for_metric_time.associated_column.column_name, time_range_constraint=node.time_range_constraint, @@ -1956,3 +1923,38 @@ def visit_window_reaggregation_node(self, node: WindowReaggregationNode) -> SqlD group_bys=outer_query_select_columns, ), ) + + @staticmethod + def _make_time_range_comparison_expr( + table_alias: str, column_alias: str, time_range_constraint: TimeRangeConstraint + ) -> SqlExpressionNode: + """Build an expression like "ds BETWEEN CAST('2020-01-01' AS TIMESTAMP) AND CAST('2020-01-02' AS TIMESTAMP). + + If the constraint uses day or larger grain, only render to the date level. Otherwise, render to the timestamp level. + """ + + def strip_time_from_dt(ts: dt.datetime) -> dt.datetime: + date_obj = ts.date() + return dt.datetime(date_obj.year, date_obj.month, date_obj.day) + + constraint_uses_day_or_larger_grain = True + for constraint_input in (time_range_constraint.start_time, time_range_constraint.end_time): + if strip_time_from_dt(constraint_input) != constraint_input: + constraint_uses_day_or_larger_grain = False + break + + time_format_to_render = ( + ISO8601_PYTHON_FORMAT if constraint_uses_day_or_larger_grain else ISO8601_PYTHON_TS_FORMAT + ) + + return SqlBetweenExpression.create( + column_arg=SqlColumnReferenceExpression.create( + SqlColumnReference(table_alias=table_alias, column_name=column_alias) + ), + start_expr=SqlStringLiteralExpression.create( + literal_value=time_range_constraint.start_time.strftime(time_format_to_render), + ), + end_expr=SqlStringLiteralExpression.create( + literal_value=time_range_constraint.end_time.strftime(time_format_to_render), + ), + )