diff --git a/metricflow-semantics/metricflow_semantics/sql/sql_exprs.py b/metricflow-semantics/metricflow_semantics/sql/sql_exprs.py index 926ea5a39..7d432661f 100644 --- a/metricflow-semantics/metricflow_semantics/sql/sql_exprs.py +++ b/metricflow-semantics/metricflow_semantics/sql/sql_exprs.py @@ -1034,6 +1034,20 @@ def requires_ordering(self) -> bool: else: assert_values_exhausted(self) + @property + def allows_frame_clause(self) -> bool: + """Whether the function allows a frame clause, e.g., 'ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING'.""" + if ( + self is SqlWindowFunction.FIRST_VALUE + or self is SqlWindowFunction.LAST_VALUE + or self is SqlWindowFunction.AVERAGE + ): + return True + if self is SqlWindowFunction.ROW_NUMBER or self is SqlWindowFunction.LAG: + return False + else: + assert_values_exhausted(self) + @classmethod def get_window_function_for_period_agg(cls, period_agg: PeriodAggregation) -> SqlWindowFunction: """Get the window function to use for given period agg option.""" diff --git a/metricflow/sql/render/expr_renderer.py b/metricflow/sql/render/expr_renderer.py index a89dc2abb..158c074ed 100644 --- a/metricflow/sql/render/expr_renderer.py +++ b/metricflow/sql/render/expr_renderer.py @@ -428,7 +428,7 @@ def visit_window_function_expr(self, node: SqlWindowFunctionExpression) -> SqlEx ) ) - if len(order_by_args_rendered) > 0: + if len(order_by_args_rendered) > 0 and node.sql_function.allows_frame_clause: window_string_lines.append("ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING") window_string = "\n".join(window_string_lines)