Skip to content

Commit 196f6df

Browse files
authored
chore: Migrate coalesce_op operator to SQLGlot (#2211)
* chore: Migrate coalesce_op operator to SQLGlot Migrated the coalesce_op operator from Ibis to SQLGlot. * fix test * fix lint * enable engine test
1 parent c9ca02c commit 196f6df

File tree

4 files changed

+39
-1
lines changed

4 files changed

+39
-1
lines changed

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

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
import bigframes.core.compile.sqlglot.scalar_compiler as scalar_compiler
2525

2626
register_unary_op = scalar_compiler.scalar_op_compiler.register_unary_op
27+
register_binary_op = scalar_compiler.scalar_op_compiler.register_binary_op
2728
register_nary_op = scalar_compiler.scalar_op_compiler.register_nary_op
2829
register_ternary_op = scalar_compiler.scalar_op_compiler.register_ternary_op
2930

@@ -159,6 +160,13 @@ def _(*cases_and_outputs: TypedExpr) -> sge.Expression:
159160
)
160161

161162

163+
@register_binary_op(ops.coalesce_op)
164+
def _(left: TypedExpr, right: TypedExpr) -> sge.Expression:
165+
if left.expr == right.expr:
166+
return left.expr
167+
return sge.Coalesce(this=left.expr, expressions=[right.expr])
168+
169+
162170
@register_nary_op(ops.RowKey)
163171
def _(*values: TypedExpr) -> sge.Expression:
164172
# All inputs into hash must be non-null or resulting hash will be null

tests/system/small/engines/test_generic_ops.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -329,7 +329,7 @@ def test_engines_where_op(scalars_array_value: array_value.ArrayValue, engine):
329329
assert_equivalence_execution(arr.node, REFERENCE_ENGINE, engine)
330330

331331

332-
@pytest.mark.parametrize("engine", ["polars", "bq"], indirect=True)
332+
@pytest.mark.parametrize("engine", ["polars", "bq", "bq-sqlglot"], indirect=True)
333333
def test_engines_coalesce_op(scalars_array_value: array_value.ArrayValue, engine):
334334
arr, _ = scalars_array_value.compute_values(
335335
[
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
WITH `bfcte_0` AS (
2+
SELECT
3+
`int64_col` AS `bfcol_0`,
4+
`int64_too` AS `bfcol_1`
5+
FROM `bigframes-dev`.`sqlglot_test`.`scalar_types`
6+
), `bfcte_1` AS (
7+
SELECT
8+
*,
9+
`bfcol_0` AS `bfcol_2`,
10+
COALESCE(`bfcol_1`, `bfcol_0`) AS `bfcol_3`
11+
FROM `bfcte_0`
12+
)
13+
SELECT
14+
`bfcol_2` AS `int64_col`,
15+
`bfcol_3` AS `int64_too`
16+
FROM `bfcte_1`

tests/unit/core/compile/sqlglot/expressions/test_generic_ops.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,20 @@ def test_case_when_op(scalar_types_df: bpd.DataFrame, snapshot):
209209
snapshot.assert_match(sql, "out.sql")
210210

211211

212+
def test_coalesce(scalar_types_df: bpd.DataFrame, snapshot):
213+
bf_df = scalar_types_df[["int64_col", "int64_too"]]
214+
215+
sql = utils._apply_ops_to_sql(
216+
bf_df,
217+
[
218+
ops.coalesce_op.as_expr("int64_col", "int64_col"),
219+
ops.coalesce_op.as_expr("int64_too", "int64_col"),
220+
],
221+
["int64_col", "int64_too"],
222+
)
223+
snapshot.assert_match(sql, "out.sql")
224+
225+
212226
def test_clip(scalar_types_df: bpd.DataFrame, snapshot):
213227
op_expr = ops.clip_op.as_expr("rowindex", "int64_col", "int64_too")
214228

0 commit comments

Comments
 (0)