Skip to content
This repository was archived by the owner on Apr 1, 2026. It is now read-only.

Commit 915cce5

Browse files
authored
refactor: increase test coverages on sqlglot compiler (#2527)
1 parent e8c4603 commit 915cce5

File tree

40 files changed

+335
-98
lines changed

40 files changed

+335
-98
lines changed

bigframes/core/compile/ibis_compiler/scalar_op_registry.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -663,7 +663,7 @@ def datetime_to_integer_label_non_fixed_frequency(
663663
.else_((x_int - first - 1) // us + 1) # type: ignore
664664
.end()
665665
)
666-
elif rule_code == "ME": # Monthly
666+
elif rule_code in ("M", "ME"): # Monthly
667667
x_int = x.year() * 12 + x.month() - 1 # type: ignore
668668
first = y.year() * 12 + y.month() - 1 # type: ignore
669669
x_int_label = (
@@ -672,7 +672,7 @@ def datetime_to_integer_label_non_fixed_frequency(
672672
.else_((x_int - first - 1) // n + 1) # type: ignore
673673
.end()
674674
)
675-
elif rule_code == "QE-DEC": # Quarterly
675+
elif rule_code in ("Q-DEC", "QE-DEC"): # Quarterly
676676
x_int = x.year() * 4 + x.quarter() - 1 # type: ignore
677677
first = y.year() * 4 + y.quarter() - 1 # type: ignore
678678
x_int_label = (
@@ -681,7 +681,7 @@ def datetime_to_integer_label_non_fixed_frequency(
681681
.else_((x_int - first - 1) // n + 1) # type: ignore
682682
.end()
683683
)
684-
elif rule_code == "YE-DEC": # Yearly
684+
elif rule_code in ("A-DEC", "Y-DEC", "YE-DEC"): # Yearly
685685
x_int = x.year() # type: ignore
686686
first = y.year() # type: ignore
687687
x_int_label = (
@@ -749,7 +749,7 @@ def integer_label_to_datetime_op_non_fixed_frequency(
749749
.cast(ibis_dtypes.Timestamp(timezone="UTC"))
750750
.cast(y.type())
751751
)
752-
elif rule_code == "ME": # Monthly
752+
elif rule_code in ("M", "ME"): # Monthly
753753
one = ibis_types.literal(1)
754754
twelve = ibis_types.literal(12)
755755
first = y.year() * twelve + y.month() - one # type: ignore
@@ -769,7 +769,7 @@ def integer_label_to_datetime_op_non_fixed_frequency(
769769
0,
770770
)
771771
x_label = next_month_date - ibis_api.interval(days=1)
772-
elif rule_code == "QE-DEC": # Quarterly
772+
elif rule_code in ("Q-DEC", "QE-DEC"): # Quarterly
773773
one = ibis_types.literal(1)
774774
three = ibis_types.literal(3)
775775
four = ibis_types.literal(4)
@@ -792,7 +792,7 @@ def integer_label_to_datetime_op_non_fixed_frequency(
792792
)
793793

794794
x_label = next_month_date - ibis_api.interval(days=1)
795-
elif rule_code == "YE-DEC": # Yearly
795+
elif rule_code in ("A-DEC", "Y-DEC", "YE-DEC"): # Yearly
796796
one = ibis_types.literal(1)
797797
first = y.year() # type: ignore
798798
x = x * n + first # type: ignore

bigframes/core/compile/sqlglot/aggregate_compiler.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,5 @@ def compile_analytic(
7070
aggregate.arg.output_type,
7171
)
7272
return unary_compiler.compile(aggregate.op, column, window)
73-
elif isinstance(aggregate, agg_expressions.BinaryAggregation):
74-
raise NotImplementedError("binary analytic operations not yet supported")
7573
else:
7674
raise ValueError(f"Unexpected analytic operation: {aggregate}")

bigframes/core/compile/sqlglot/expressions/array_ops.py

Lines changed: 0 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -105,31 +105,6 @@ def _coerce_bool_to_int(typed_expr: TypedExpr) -> sge.Expression:
105105
return typed_expr.expr
106106

107107

108-
def _string_slice(expr: TypedExpr, op: ops.ArraySliceOp) -> sge.Expression:
109-
# local name for each element in the array
110-
el = sg.to_identifier("el")
111-
# local name for the index in the array
112-
slice_idx = sg.to_identifier("slice_idx")
113-
114-
conditions: typing.List[sge.Predicate] = [slice_idx >= op.start]
115-
if op.stop is not None:
116-
conditions.append(slice_idx < op.stop)
117-
118-
selected_elements = (
119-
sge.select(el)
120-
.from_(
121-
sge.Unnest(
122-
expressions=[expr.expr],
123-
alias=sge.TableAlias(columns=[el]),
124-
offset=slice_idx,
125-
)
126-
)
127-
.where(*conditions)
128-
)
129-
130-
return sge.array(selected_elements)
131-
132-
133108
def _array_slice(expr: TypedExpr, op: ops.ArraySliceOp) -> sge.Expression:
134109
# local name for each element in the array
135110
el = sg.to_identifier("el")

bigframes/core/compile/sqlglot/expressions/datetime_ops.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ def _datetime_to_integer_label_non_fixed_frequency(
125125
expression=sge.convert(1),
126126
),
127127
)
128-
elif rule_code == "ME": # Monthly
128+
elif rule_code in ("M", "ME"): # Monthly
129129
x_int = sge.Paren( # type: ignore
130130
this=sge.Add(
131131
this=sge.Mul(
@@ -182,7 +182,7 @@ def _datetime_to_integer_label_non_fixed_frequency(
182182
expression=sge.convert(1),
183183
),
184184
)
185-
elif rule_code == "QE-DEC": # Quarterly
185+
elif rule_code in ("Q-DEC", "QE-DEC"): # Quarterly
186186
x_int = sge.Paren( # type: ignore
187187
this=sge.Add(
188188
this=sge.Mul(
@@ -239,7 +239,7 @@ def _datetime_to_integer_label_non_fixed_frequency(
239239
expression=sge.convert(1),
240240
),
241241
)
242-
elif rule_code == "YE-DEC": # Yearly
242+
elif rule_code in ("A-DEC", "Y-DEC", "YE-DEC"): # Yearly
243243
x_int = sge.Extract(this=sge.Identifier(this="YEAR"), expression=x.expr)
244244
first = sge.Extract(this=sge.Identifier(this="YEAR"), expression=y.expr)
245245
return sge.Case(

tests/unit/core/compile/sqlglot/aggregations/test_op_registration.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,3 +42,23 @@ def test_func(input: sge.Expression) -> sge.Expression:
4242
ValueError, match=r".*first parameter must be a window operator.*"
4343
):
4444
test_func(sge.to_identifier("A"))
45+
46+
47+
def test_register_already_registered_raise_error():
48+
reg = op_registration.OpRegistration()
49+
50+
@reg.register(agg_ops.SizeOp)
51+
def test_func1(op, input):
52+
return input
53+
54+
with pytest.raises(ValueError, match=r".*is already registered.*"):
55+
56+
@reg.register(agg_ops.SizeOp)
57+
def test_func2(op, input):
58+
return input
59+
60+
61+
def test_getitem_not_registered_raise_error():
62+
reg = op_registration.OpRegistration()
63+
with pytest.raises(ValueError, match=r".*is not registered.*"):
64+
_ = reg[agg_ops.SizeOp()]
Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
SELECT
2-
`string_list_col`[SAFE_OFFSET(1)] AS `string_list_col`
3-
FROM `bigframes-dev`.`sqlglot_test`.`repeated_types` AS `bft_0`
2+
IF(SUBSTRING(`string_col`, 2, 1) <> '', SUBSTRING(`string_col`, 2, 1), NULL) AS `string_index`,
3+
[`int64_col`, `int64_too`][SAFE_OFFSET(1)] AS `array_index`
4+
FROM `bigframes-dev`.`sqlglot_test`.`scalar_types` AS `bft_0`

tests/unit/core/compile/sqlglot/expressions/snapshots/test_array_ops/test_array_reduce_op/out.sql

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,5 +18,10 @@ SELECT
1818
SELECT
1919
COALESCE(LOGICAL_OR(bf_arr_reduce_uid), FALSE)
2020
FROM UNNEST(`bool_list_col`) AS bf_arr_reduce_uid
21-
) AS `any_bool`
21+
) AS `any_bool`,
22+
(
23+
SELECT
24+
ARRAY_AGG(bf_arr_reduce_uid IGNORE NULLS)
25+
FROM UNNEST(`string_list_col`) AS bf_arr_reduce_uid
26+
) AS `array_agg_str`
2227
FROM `bigframes-dev`.`sqlglot_test`.`repeated_types` AS `bft_0`
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
SELECT
2+
SUBSTRING(`string_col`, 2, 4) AS `string_slice`,
3+
ARRAY(
4+
SELECT
5+
el
6+
FROM UNNEST([`int64_col`, `int64_too`]) AS el WITH OFFSET AS slice_idx
7+
WHERE
8+
slice_idx >= 1
9+
) AS `slice_only_start`,
10+
ARRAY(
11+
SELECT
12+
el
13+
FROM UNNEST([`int64_col`, `int64_too`]) AS el WITH OFFSET AS slice_idx
14+
WHERE
15+
slice_idx >= 1 AND slice_idx < 5
16+
) AS `slice_start_stop`
17+
FROM `bigframes-dev`.`sqlglot_test`.`scalar_types` AS `bft_0`

tests/unit/core/compile/sqlglot/expressions/snapshots/test_array_ops/test_array_slice_with_only_start/out.sql

Lines changed: 0 additions & 9 deletions
This file was deleted.

tests/unit/core/compile/sqlglot/expressions/snapshots/test_array_ops/test_array_slice_with_start_and_stop/out.sql

Lines changed: 0 additions & 9 deletions
This file was deleted.

0 commit comments

Comments
 (0)