1515from __future__ import annotations
1616
1717import dataclasses
18- from typing import cast , Dict , Tuple
1918
19+ import bigframes .dtypes as dtypes
20+ import bigframes .operations as ops
21+ import bigframes .operations .aggregations as agg_ops
2022from bigframes .core import (
2123 agg_expressions ,
2224 expression ,
2325 identifiers ,
2426 nodes ,
2527)
26- import bigframes .dtypes as dtypes
27- import bigframes .operations as ops
28- import bigframes .operations .aggregations as agg_ops
2928
3029
3130def rewrite_substrait_aggregations (node : nodes .BigFrameNode ) -> nodes .BigFrameNode :
@@ -58,22 +57,21 @@ def rewrite_substrait_aggregations(node: nodes.BigFrameNode) -> nodes.BigFrameNo
5857 is_bool = col_dtype == dtypes .BOOL_DTYPE
5958 if isinstance (
6059 agg .op , (agg_ops .StdOp , agg_ops .VarOp , agg_ops .PopVarOp )
61- ) or (
62- isinstance (agg .op , agg_ops .MeanOp )
63- and is_bool
64- ):
60+ ) or (isinstance (agg .op , agg_ops .MeanOp ) and is_bool ):
6561 cast_aggs .append ((agg_idx , col_id , dtypes .FLOAT_DTYPE ))
6662 elif isinstance (agg .op , agg_ops .SumOp ) and is_bool :
6763 cast_aggs .append ((agg_idx , col_id , dtypes .INT_DTYPE ))
6864
6965 # If we need pre-projection (casts or size constants)
7066 if size_aggs or cast_aggs :
7167 assignments = []
72-
68+
7369 cast_agg_to_col_id = {}
7470 for agg_idx , col_id , target_dtype in cast_aggs :
7571 new_id = identifiers .ColumnId (f"bf_cast_{ col_id .name } _{ agg_idx } " )
76- cast_expr = ops .AsTypeOp (to_type = target_dtype ).as_expr (expression .deref (col_id .name ))
72+ cast_expr = ops .AsTypeOp (to_type = target_dtype ).as_expr (
73+ expression .deref (col_id .name )
74+ )
7775 assignments .append ((cast_expr , new_id ))
7876 cast_agg_to_col_id [(agg_idx , col_id )] = new_id
7977
@@ -103,10 +101,12 @@ def rewrite_substrait_aggregations(node: nodes.BigFrameNode) -> nodes.BigFrameNo
103101 new_exprs = []
104102 for col_id in agg .column_references :
105103 if (agg_idx , col_id ) in cast_agg_to_col_id :
106- new_exprs .append (expression .deref (cast_agg_to_col_id [(agg_idx , col_id )].name ))
104+ new_exprs .append (
105+ expression .deref (cast_agg_to_col_id [(agg_idx , col_id )].name )
106+ )
107107 else :
108108 new_exprs .append (expression .deref (col_id .name ))
109-
109+
110110 if isinstance (agg , agg_expressions .UnaryAggregation ):
111111 rewritten_agg = agg_expressions .UnaryAggregation (
112112 agg .op , new_exprs [0 ]
@@ -132,16 +132,20 @@ def rewrite_substrait_aggregations(node: nodes.BigFrameNode) -> nodes.BigFrameNo
132132 output_ids = group_ids + agg_ids
133133
134134 expected_types = [item .dtype for item in node .schema .items ]
135-
135+
136136 assignments = []
137137 selection_pairs = []
138138 for idx , (out_id , target_dtype ) in enumerate (zip (output_ids , expected_types )):
139139 cast_id = identifiers .ColumnId (f"bf_out_cast_{ out_id .name } " )
140- cast_expr = ops .AsTypeOp (to_type = target_dtype ).as_expr (expression .deref (out_id .name ))
140+ cast_expr = ops .AsTypeOp (to_type = target_dtype ).as_expr (
141+ expression .deref (out_id .name )
142+ )
141143 assignments .append ((cast_expr , cast_id ))
142-
143- selection_pairs .append ((nodes .AliasedRef (expression .deref (cast_id .name ), out_id ), out_id ))
144-
144+
145+ selection_pairs .append (
146+ (nodes .AliasedRef (expression .deref (cast_id .name ), out_id ), out_id )
147+ )
148+
145149 post_project = nodes .ProjectionNode (
146150 node ,
147151 assignments = tuple (assignments ),
@@ -150,7 +154,7 @@ def rewrite_substrait_aggregations(node: nodes.BigFrameNode) -> nodes.BigFrameNo
150154 post_project ,
151155 input_output_pairs = tuple (ref for ref , _ in selection_pairs ),
152156 )
153-
157+
154158 return post_selection
155159
156160
@@ -170,7 +174,7 @@ def rewrite_substrait_windows(node: nodes.BigFrameNode) -> nodes.BigFrameNode:
170174 # Collect size and cast requirements for the window agg expressions
171175 size_aggs = []
172176 cast_aggs = []
173-
177+
174178 for agg_idx , col_def in enumerate (node .agg_exprs ):
175179 agg = col_def .expression
176180 if isinstance (agg .op , (agg_ops .SizeOp , agg_ops .SizeUnaryOp )):
@@ -182,22 +186,21 @@ def rewrite_substrait_windows(node: nodes.BigFrameNode) -> nodes.BigFrameNode:
182186 is_bool = col_dtype == dtypes .BOOL_DTYPE
183187 if isinstance (
184188 agg .op , (agg_ops .StdOp , agg_ops .VarOp , agg_ops .PopVarOp )
185- ) or (
186- isinstance (agg .op , agg_ops .MeanOp )
187- and is_bool
188- ):
189+ ) or (isinstance (agg .op , agg_ops .MeanOp ) and is_bool ):
189190 cast_aggs .append ((agg_idx , col_id , dtypes .FLOAT_DTYPE ))
190191 elif isinstance (agg .op , agg_ops .SumOp ) and is_bool :
191192 cast_aggs .append ((agg_idx , col_id , dtypes .INT_DTYPE ))
192193
193194 # If we need pre-projection (casts or size constants)
194195 if size_aggs or cast_aggs :
195196 assignments = []
196-
197+
197198 cast_agg_to_col_id = {}
198199 for agg_idx , col_id , target_dtype in cast_aggs :
199200 new_id = identifiers .ColumnId (f"bf_window_cast_{ col_id .name } _{ agg_idx } " )
200- cast_expr = ops .AsTypeOp (to_type = target_dtype ).as_expr (expression .deref (col_id .name ))
201+ cast_expr = ops .AsTypeOp (to_type = target_dtype ).as_expr (
202+ expression .deref (col_id .name )
203+ )
201204 assignments .append ((cast_expr , new_id ))
202205 cast_agg_to_col_id [(agg_idx , col_id )] = new_id
203206
@@ -220,7 +223,7 @@ def rewrite_substrait_windows(node: nodes.BigFrameNode) -> nodes.BigFrameNode:
220223 for agg_idx , col_def in enumerate (node .agg_exprs ):
221224 agg = col_def .expression
222225 out_col_id = col_def .id
223-
226+
224227 if isinstance (agg .op , (agg_ops .SizeOp , agg_ops .SizeUnaryOp )):
225228 new_col_id = size_agg_to_col_id [agg_idx ]
226229 rewritten_agg = agg_expressions .UnaryAggregation (
@@ -230,10 +233,12 @@ def rewrite_substrait_windows(node: nodes.BigFrameNode) -> nodes.BigFrameNode:
230233 new_exprs = []
231234 for col_id in agg .column_references :
232235 if (agg_idx , col_id ) in cast_agg_to_col_id :
233- new_exprs .append (expression .deref (cast_agg_to_col_id [(agg_idx , col_id )].name ))
236+ new_exprs .append (
237+ expression .deref (cast_agg_to_col_id [(agg_idx , col_id )].name )
238+ )
234239 else :
235240 new_exprs .append (expression .deref (col_id .name ))
236-
241+
237242 if isinstance (agg , agg_expressions .UnaryAggregation ):
238243 rewritten_agg = agg_expressions .UnaryAggregation (
239244 agg .op , new_exprs [0 ]
@@ -245,9 +250,7 @@ def rewrite_substrait_windows(node: nodes.BigFrameNode) -> nodes.BigFrameNode:
245250 else :
246251 rewritten_agg = agg
247252
248- rewritten_agg_exprs .append (
249- nodes .ColumnDef (rewritten_agg , out_col_id )
250- )
253+ rewritten_agg_exprs .append (nodes .ColumnDef (rewritten_agg , out_col_id ))
251254
252255 node = dataclasses .replace (
253256 node ,
@@ -256,24 +259,32 @@ def rewrite_substrait_windows(node: nodes.BigFrameNode) -> nodes.BigFrameNode:
256259 )
257260
258261 # Post-projection to enforce output schema types for newly introduced window columns:
259- child_output_ids = list (node .child .ids ) if not isinstance (child , nodes .ProjectionNode ) else list (child .child .ids )
260-
262+ child_output_ids = (
263+ list (node .child .ids )
264+ if not isinstance (child , nodes .ProjectionNode )
265+ else list (child .child .ids )
266+ )
267+
261268 assignments = []
262269 selection_pairs = []
263-
270+
264271 for child_id in child_output_ids :
265272 selection_pairs .append ((nodes .AliasedRef .identity (child_id ), child_id ))
266-
273+
267274 for col_def , field in zip (node .agg_exprs , node .added_fields ):
268275 out_id = col_def .id
269276 target_dtype = field .dtype
270-
277+
271278 cast_id = identifiers .ColumnId (f"bf_window_out_cast_{ out_id .name } " )
272- cast_expr = ops .AsTypeOp (to_type = target_dtype ).as_expr (expression .deref (out_id .name ))
279+ cast_expr = ops .AsTypeOp (to_type = target_dtype ).as_expr (
280+ expression .deref (out_id .name )
281+ )
273282 assignments .append ((cast_expr , cast_id ))
274-
275- selection_pairs .append ((nodes .AliasedRef (expression .deref (cast_id .name ), out_id ), out_id ))
276-
283+
284+ selection_pairs .append (
285+ (nodes .AliasedRef (expression .deref (cast_id .name ), out_id ), out_id )
286+ )
287+
277288 post_project = nodes .ProjectionNode (
278289 node ,
279290 assignments = tuple (assignments ),
@@ -282,5 +293,5 @@ def rewrite_substrait_windows(node: nodes.BigFrameNode) -> nodes.BigFrameNode:
282293 post_project ,
283294 input_output_pairs = tuple (ref for ref , _ in selection_pairs ),
284295 )
285-
296+
286297 return post_selection
0 commit comments