@@ -133,3 +133,184 @@ def test_execute_projection_add_with_datafusion():
133133 assert "b" in result_table .column_names
134134 assert "a" in result_table .column_names
135135 assert result_table .column ("b" ).to_pylist () == [43 , 44 , 45 ]
136+
137+
138+ def test_execute_filter_with_datafusion ():
139+ from bigframes .session .substrait_executor import DataFusionSubstraitConsumer
140+ from bigframes .operations .comparison_ops import gt_op
141+
142+ consumer = DataFusionSubstraitConsumer ()
143+ executor = substrait_executor .SubstraitExecutor (consumer )
144+
145+ read_node = create_read_local_node ()
146+
147+ # a > 1
148+ filter_expr = ex .OpExpression (
149+ op = gt_op ,
150+ inputs = (
151+ ex .DerefOp (identifiers .ColumnId ("a" )),
152+ ex .ScalarConstantExpression (1 ),
153+ ),
154+ )
155+ plan = nodes .FilterNode (
156+ child = read_node ,
157+ predicate = filter_expr ,
158+ )
159+
160+ result = executor .execute (plan , ordered = True )
161+ assert result is not None
162+
163+ result_table = pa .Table .from_batches (result .batches ().arrow_batches )
164+ assert result_table .num_rows == 2
165+ assert "a" in result_table .column_names
166+ assert result_table .column ("a" ).to_pylist () == [2 , 3 ]
167+
168+
169+ def test_execute_aggregate_sum_with_datafusion ():
170+ from bigframes .session .substrait_executor import DataFusionSubstraitConsumer
171+ from bigframes .operations .aggregations import sum_op
172+ from bigframes .core .agg_expressions import UnaryAggregation
173+
174+ consumer = DataFusionSubstraitConsumer ()
175+ executor = substrait_executor .SubstraitExecutor (consumer )
176+
177+ read_node = create_read_local_node ()
178+
179+ # sum(a)
180+ sum_agg = UnaryAggregation (
181+ op = sum_op ,
182+ arg = ex .DerefOp (identifiers .ColumnId ("a" )),
183+ )
184+
185+ plan = nodes .AggregateNode (
186+ child = read_node ,
187+ aggregations = ((sum_agg , identifiers .ColumnId ("sum_a" )),),
188+ by_column_ids = (),
189+ )
190+
191+ result = executor .execute (plan , ordered = True )
192+ assert result is not None
193+
194+ result_table = pa .Table .from_batches (result .batches ().arrow_batches )
195+ assert result_table .num_rows == 1
196+ assert "sum_a" in result_table .column_names
197+ assert result_table .column ("sum_a" ).to_pylist () == [6 ]
198+
199+
200+ def test_execute_aggregate_max_with_datafusion ():
201+ from bigframes .session .substrait_executor import DataFusionSubstraitConsumer
202+ from bigframes .operations .aggregations import max_op
203+ from bigframes .core .agg_expressions import UnaryAggregation
204+
205+ consumer = DataFusionSubstraitConsumer ()
206+ executor = substrait_executor .SubstraitExecutor (consumer )
207+
208+ read_node = create_read_local_node ()
209+
210+ # max(a)
211+ max_agg = UnaryAggregation (
212+ op = max_op ,
213+ arg = ex .DerefOp (identifiers .ColumnId ("a" )),
214+ )
215+
216+ plan = nodes .AggregateNode (
217+ child = read_node ,
218+ aggregations = ((max_agg , identifiers .ColumnId ("max_a" )),),
219+ by_column_ids = (),
220+ )
221+
222+ result = executor .execute (plan , ordered = True )
223+ assert result is not None
224+
225+ result_table = pa .Table .from_batches (result .batches ().arrow_batches )
226+ assert result_table .num_rows == 1
227+ assert "max_a" in result_table .column_names
228+ assert result_table .column ("max_a" ).to_pylist () == [3 ]
229+
230+
231+ def test_execute_join_with_datafusion ():
232+ from bigframes .session .substrait_executor import DataFusionSubstraitConsumer
233+
234+ consumer = DataFusionSubstraitConsumer ()
235+ executor = substrait_executor .SubstraitExecutor (consumer )
236+
237+ # Table 1: a
238+ session1 = mocks .create_bigquery_session ()
239+ table1 = pa .Table .from_pydict ({"a" : [1 , 2 , 3 ]})
240+ source1 = local_data .ManagedArrowTable .from_pyarrow (table1 )
241+ col_id_a = identifiers .ColumnId ("a" )
242+ read_node1 = nodes .ReadLocalNode (
243+ local_data_source = source1 ,
244+ session = session1 ,
245+ scan_list = nodes .ScanList (items = (nodes .ScanItem (id = col_id_a , source_id = "a" ),)),
246+ )
247+
248+ # Table 2: b
249+ session2 = mocks .create_bigquery_session ()
250+ table2 = pa .Table .from_pydict ({"b" : [2 , 3 , 4 ]})
251+ source2 = local_data .ManagedArrowTable .from_pyarrow (table2 )
252+ col_id_b = identifiers .ColumnId ("b" )
253+ read_node2 = nodes .ReadLocalNode (
254+ local_data_source = source2 ,
255+ session = session2 ,
256+ scan_list = nodes .ScanList (items = (nodes .ScanItem (id = col_id_b , source_id = "b" ),)),
257+ )
258+
259+ # Join on a = b
260+ join_node = nodes .JoinNode (
261+ left_child = read_node1 ,
262+ right_child = read_node2 ,
263+ conditions = ((ex .DerefOp (col_id_a ), ex .DerefOp (col_id_b )),),
264+ type = "inner" ,
265+ propogate_order = False ,
266+ )
267+
268+ result = executor .execute (join_node , ordered = True )
269+ assert result is not None
270+
271+ result_table = pa .Table .from_batches (result .batches ().arrow_batches )
272+ assert result_table .num_rows == 2
273+ assert "a" in result_table .column_names
274+ assert "b" in result_table .column_names
275+ assert result_table .column ("a" ).to_pylist () == [2 , 3 ]
276+ assert result_table .column ("b" ).to_pylist () == [2 , 3 ]
277+
278+
279+ def test_execute_selection_with_datafusion ():
280+ from bigframes .session .substrait_executor import DataFusionSubstraitConsumer
281+ from bigframes .core .nodes import AliasedRef
282+
283+ consumer = DataFusionSubstraitConsumer ()
284+ executor = substrait_executor .SubstraitExecutor (consumer )
285+
286+ # Table with a and b
287+ session = mocks .create_bigquery_session ()
288+ table = pa .Table .from_pydict ({"a" : [1 , 2 , 3 ], "b" : [4 , 5 , 6 ]})
289+ source = local_data .ManagedArrowTable .from_pyarrow (table )
290+ col_id_a = identifiers .ColumnId ("a" )
291+ col_id_b = identifiers .ColumnId ("b" )
292+ read_node = nodes .ReadLocalNode (
293+ local_data_source = source ,
294+ session = session ,
295+ scan_list = nodes .ScanList (
296+ items = (
297+ nodes .ScanItem (id = col_id_a , source_id = "a" ),
298+ nodes .ScanItem (id = col_id_b , source_id = "b" ),
299+ )
300+ ),
301+ )
302+
303+ # Select only a, and rename it to c
304+ col_id_c = identifiers .ColumnId ("c" )
305+ selection_node = nodes .SelectionNode (
306+ child = read_node ,
307+ input_output_pairs = (AliasedRef (ex .DerefOp (col_id_a ), col_id_c ),),
308+ )
309+
310+ result = executor .execute (selection_node , ordered = True )
311+ assert result is not None
312+
313+ result_table = pa .Table .from_batches (result .batches ().arrow_batches )
314+ assert result_table .num_rows == 3
315+ assert result_table .column_names == ["c" ]
316+ assert result_table .column ("c" ).to_pylist () == [1 , 2 , 3 ]
0 commit comments