19
19
from typing import cast , List , Optional
20
20
21
21
import bigframes_vendored .constants as constants
22
- import bigframes_vendored .ibis .expr .operations as vendored_ibis_ops
23
- import ibis
24
- import ibis .expr .datatypes as ibis_dtypes
25
- import ibis .expr .operations as ibis_ops
26
- import ibis .expr .types as ibis_types
22
+ import bigframes_vendored .ibis .expr .api as ibis_api
23
+ import bigframes_vendored . ibis . expr . datatypes as ibis_dtypes
24
+ import bigframes_vendored . ibis .expr .operations as ibis_ops
25
+ import bigframes_vendored . ibis .expr .operations . udf as ibis_udf
26
+ import bigframes_vendored . ibis .expr .types as ibis_types
27
27
import pandas as pd
28
28
29
29
import bigframes .core .compile .ibis_types as compile_ibis_types
37
37
38
38
# TODO(swast): We can remove this if ibis adds general approx_quantile
39
39
# See: https://github.com/ibis-project/ibis/issues/9541
40
- @ibis . udf .agg .builtin
40
+ @ibis_udf .agg .builtin
41
41
def approx_quantiles (expression : float , number ) -> List [float ]:
42
42
"""APPROX_QUANTILES
43
43
@@ -56,13 +56,13 @@ def compile_aggregate(
56
56
if isinstance (aggregate , ex .UnaryAggregation ):
57
57
input = scalar_compiler .compile_expression (aggregate .arg , bindings = bindings )
58
58
if aggregate .op .can_order_by :
59
- return compile_ordered_unary_agg (aggregate .op , input , order_by = order_by )
59
+ return compile_ordered_unary_agg (aggregate .op , input , order_by = order_by ) # type: ignore
60
60
else :
61
- return compile_unary_agg (aggregate .op , input )
61
+ return compile_unary_agg (aggregate .op , input ) # type: ignore
62
62
elif isinstance (aggregate , ex .BinaryAggregation ):
63
63
left = scalar_compiler .compile_expression (aggregate .left , bindings = bindings )
64
64
right = scalar_compiler .compile_expression (aggregate .right , bindings = bindings )
65
- return compile_binary_agg (aggregate .op , left , right )
65
+ return compile_binary_agg (aggregate .op , left , right ) # type: ignore
66
66
else :
67
67
raise ValueError (f"Unexpected aggregation: { aggregate } " )
68
68
@@ -76,7 +76,7 @@ def compile_analytic(
76
76
return compile_nullary_agg (aggregate .op , window )
77
77
elif isinstance (aggregate , ex .UnaryAggregation ):
78
78
input = scalar_compiler .compile_expression (aggregate .arg , bindings = bindings )
79
- return compile_unary_agg (aggregate .op , input , window )
79
+ return compile_unary_agg (aggregate .op , input , window ) # type: ignore
80
80
elif isinstance (aggregate , ex .BinaryAggregation ):
81
81
raise NotImplementedError ("binary analytic operations not yet supported" )
82
82
else :
@@ -147,7 +147,7 @@ def constrained_op(
147
147
148
148
@compile_nullary_agg .register
149
149
def _ (op : agg_ops .SizeOp , window = None ) -> ibis_types .NumericValue :
150
- return _apply_window_if_present (vendored_ibis_ops .count (1 ), window )
150
+ return _apply_window_if_present (ibis_ops .count (1 ), window )
151
151
152
152
153
153
@compile_unary_agg .register
@@ -160,7 +160,7 @@ def _(
160
160
# Will be null if all inputs are null. Pandas defaults to zero sum though.
161
161
bq_sum = _apply_window_if_present (column .sum (), window )
162
162
return (
163
- ibis .case ().when (bq_sum .isnull (), ibis_types .literal (0 )).else_ (bq_sum ).end () # type: ignore
163
+ ibis_api .case ().when (bq_sum .isnull (), ibis_types .literal (0 )).else_ (bq_sum ).end () # type: ignore
164
164
)
165
165
166
166
@@ -217,15 +217,15 @@ def _(
217
217
def approx_top_count (expression , number : ibis_dtypes .int64 ): # type: ignore
218
218
...
219
219
220
- return_type = ibis_dtypes .Array (
221
- ibis_dtypes .Struct .from_tuples (
220
+ ibis_return_type = ibis_dtypes .Array (
221
+ value_type = ibis_dtypes .Struct .from_tuples (
222
222
[("value" , column .type ()), ("count" , ibis_dtypes .int64 )]
223
223
)
224
- )
225
- approx_top_count .__annotations__ ["return" ] = return_type
224
+ ) # type: ignore
225
+ approx_top_count .__annotations__ ["return" ] = ibis_return_type
226
226
udf_op = ibis_ops .udf .agg .builtin (approx_top_count )
227
227
228
- return udf_op (expression = column , number = op .number )
228
+ return udf_op (expression = column , number = op .number ) # type: ignore
229
229
230
230
231
231
@compile_unary_agg .register
@@ -263,29 +263,29 @@ def _(
263
263
# apply power after. Note, log and power base must be equal! This impl uses base 2.
264
264
logs = cast (
265
265
ibis_types .NumericColumn ,
266
- ibis .case ().when (is_zero , 0 ).else_ (column .abs ().log2 ()).end (),
266
+ ibis_api .case ().when (is_zero , 0 ).else_ (column .abs ().log2 ()).end (),
267
267
)
268
268
logs_sum = _apply_window_if_present (logs .sum (), window )
269
269
magnitude = cast (ibis_types .NumericValue , ibis_types .literal (2 )).pow (logs_sum )
270
270
271
271
# Can't determine sign from logs, so have to determine parity of count of negative inputs
272
272
is_negative = cast (
273
273
ibis_types .NumericColumn ,
274
- ibis .case ().when (column .sign () == - 1 , 1 ).else_ (0 ).end (),
274
+ ibis_api .case ().when (column .sign () == - 1 , 1 ).else_ (0 ).end (),
275
275
)
276
276
negative_count = _apply_window_if_present (is_negative .sum (), window )
277
277
negative_count_parity = negative_count % cast (
278
- ibis_types .NumericValue , ibis .literal (2 )
278
+ ibis_types .NumericValue , ibis_types .literal (2 )
279
279
) # 1 if result should be negative, otherwise 0
280
280
281
281
any_zeroes = _apply_window_if_present (is_zero .any (), window )
282
282
float_result = (
283
- ibis .case ()
283
+ ibis_api .case ()
284
284
.when (any_zeroes , ibis_types .literal (0 ))
285
285
.else_ (magnitude * pow (- 1 , negative_count_parity ))
286
286
.end ()
287
287
)
288
- return float_result
288
+ return cast ( ibis_types . NumericValue , float_result )
289
289
290
290
291
291
@compile_unary_agg .register
@@ -353,7 +353,7 @@ def _(
353
353
x : ibis_types .Column ,
354
354
window = None ,
355
355
):
356
- out = ibis .case ()
356
+ out = ibis_api .case ()
357
357
if isinstance (op .bins , int ):
358
358
col_min = _apply_window_if_present (x .min (), window )
359
359
col_max = _apply_window_if_present (x .max (), window )
@@ -376,7 +376,7 @@ def _(
376
376
col_min + this_bin * bin_width - (0 if this_bin > 0 else adj )
377
377
)
378
378
right_edge = col_min + (this_bin + 1 ) * bin_width
379
- interval_struct = ibis .struct (
379
+ interval_struct = ibis_types .struct (
380
380
{
381
381
"left_exclusive" : left_edge ,
382
382
"right_inclusive" : right_edge ,
@@ -395,7 +395,7 @@ def _(
395
395
left = compile_ibis_types .literal_to_ibis_scalar (interval [0 ])
396
396
right = compile_ibis_types .literal_to_ibis_scalar (interval [1 ])
397
397
condition = (x > left ) & (x <= right )
398
- interval_struct = ibis .struct (
398
+ interval_struct = ibis_types .struct (
399
399
{"left_exclusive" : left , "right_inclusive" : right }
400
400
)
401
401
out = out .when (condition , interval_struct )
@@ -422,7 +422,7 @@ def _(
422
422
ibis_types .FloatingColumn ,
423
423
_apply_window_if_present (column .percent_rank (), window ),
424
424
)
425
- out = ibis .case ()
425
+ out = ibis_api .case ()
426
426
first_ibis_quantile = compile_ibis_types .literal_to_ibis_scalar (
427
427
self .quantiles [0 ]
428
428
)
@@ -466,7 +466,7 @@ def _(
466
466
window = None ,
467
467
) -> ibis_types .IntegerValue :
468
468
# Ibis produces 0-based ranks, while pandas creates 1-based ranks
469
- return _apply_window_if_present (ibis .rank (), window ) + 1
469
+ return _apply_window_if_present (ibis_api .rank (), window ) + 1
470
470
471
471
472
472
@compile_unary_agg .register
@@ -491,7 +491,7 @@ def _(
491
491
window = None ,
492
492
) -> ibis_types .Value :
493
493
return _apply_window_if_present (
494
- vendored_ibis_ops .FirstNonNullValue (column ).to_expr (), window # type: ignore
494
+ ibis_ops .FirstNonNullValue (column ).to_expr (), window # type: ignore
495
495
)
496
496
497
497
@@ -511,7 +511,7 @@ def _(
511
511
window = None ,
512
512
) -> ibis_types .Value :
513
513
return _apply_window_if_present (
514
- vendored_ibis_ops .LastNonNullValue (column ).to_expr (), window # type: ignore
514
+ ibis_ops .LastNonNullValue (column ).to_expr (), window # type: ignore
515
515
)
516
516
517
517
@@ -602,9 +602,9 @@ def _(
602
602
f"ArrayAgg with windowing is not supported. { constants .FEEDBACK_LINK } "
603
603
)
604
604
605
- return vendored_ibis_ops .ArrayAggregate (
606
- column ,
607
- order_by = order_by ,
605
+ return ibis_ops .ArrayAggregate (
606
+ column , # type: ignore
607
+ order_by = order_by , # type: ignore
608
608
).to_expr ()
609
609
610
610
@@ -641,8 +641,9 @@ def _apply_window_if_present(value: ibis_types.Value, window):
641
641
def _map_to_literal (
642
642
original : ibis_types .Value , literal : ibis_types .Scalar
643
643
) -> ibis_types .Column :
644
- # Hack required to perform aggregations on literals in ibis, even though bigquery will let you directly aggregate literals (eg. 'SELECT COUNT(1) from table1')
645
- return ibis .ifelse (original .isnull (), literal , literal ) # type: ignore
644
+ # Hack required to perform aggregations on literals in ibis, even though bigquery
645
+ # will let you directly aggregate literals (eg. 'SELECT COUNT(1) from table1')
646
+ return ibis_api .ifelse (original .isnull (), literal , literal ) # type: ignore
646
647
647
648
648
649
def _ibis_num (number : float ):
0 commit comments