From 9bbc0cd5cbf135fc161bdb1f8da4ec667c766988 Mon Sep 17 00:00:00 2001 From: jialuo Date: Mon, 10 Nov 2025 18:22:22 +0000 Subject: [PATCH 1/3] chore: Migrate fillna_op operator to SQLGlot --- .../compile/sqlglot/expressions/generic_ops.py | 6 ++++++ .../snapshots/test_generic_ops/test_fillna/out.sql | 14 ++++++++++++++ .../sqlglot/expressions/test_generic_ops.py | 6 ++++++ 3 files changed, 26 insertions(+) create mode 100644 tests/unit/core/compile/sqlglot/expressions/snapshots/test_generic_ops/test_fillna/out.sql diff --git a/bigframes/core/compile/sqlglot/expressions/generic_ops.py b/bigframes/core/compile/sqlglot/expressions/generic_ops.py index 07505855e1..6ada8428f7 100644 --- a/bigframes/core/compile/sqlglot/expressions/generic_ops.py +++ b/bigframes/core/compile/sqlglot/expressions/generic_ops.py @@ -24,6 +24,7 @@ import bigframes.core.compile.sqlglot.scalar_compiler as scalar_compiler register_unary_op = scalar_compiler.scalar_op_compiler.register_unary_op +register_binary_op = scalar_compiler.scalar_op_compiler.register_binary_op register_nary_op = scalar_compiler.scalar_op_compiler.register_nary_op register_ternary_op = scalar_compiler.scalar_op_compiler.register_ternary_op @@ -133,6 +134,11 @@ def _( ) +@register_binary_op(ops.fillna_op) +def _(left: TypedExpr, right: TypedExpr) -> sge.Expression: + return sge.Coalesce(this=left.expr, expressions=[right.expr]) + + @register_nary_op(ops.case_when_op) def _(*cases_and_outputs: TypedExpr) -> sge.Expression: # Need to upcast BOOL to INT if any output is numeric diff --git a/tests/unit/core/compile/sqlglot/expressions/snapshots/test_generic_ops/test_fillna/out.sql b/tests/unit/core/compile/sqlglot/expressions/snapshots/test_generic_ops/test_fillna/out.sql new file mode 100644 index 0000000000..2cf07c2f5b --- /dev/null +++ b/tests/unit/core/compile/sqlglot/expressions/snapshots/test_generic_ops/test_fillna/out.sql @@ -0,0 +1,14 @@ +WITH `bfcte_0` AS ( + SELECT + `int64_col` AS `bfcol_0`, + `float64_col` AS `bfcol_1` + FROM `bigframes-dev`.`sqlglot_test`.`scalar_types` +), `bfcte_1` AS ( + SELECT + *, + COALESCE(`bfcol_0`, `bfcol_1`) AS `bfcol_2` + FROM `bfcte_0` +) +SELECT + `bfcol_2` AS `int64_col` +FROM `bfcte_1` \ No newline at end of file diff --git a/tests/unit/core/compile/sqlglot/expressions/test_generic_ops.py b/tests/unit/core/compile/sqlglot/expressions/test_generic_ops.py index aa40c21fd9..f77a5f72cb 100644 --- a/tests/unit/core/compile/sqlglot/expressions/test_generic_ops.py +++ b/tests/unit/core/compile/sqlglot/expressions/test_generic_ops.py @@ -225,6 +225,12 @@ def test_clip(scalar_types_df: bpd.DataFrame, snapshot): snapshot.assert_match(sql, "out.sql") +def test_fillna(scalar_types_df: bpd.DataFrame, snapshot): + bf_df = scalar_types_df[["int64_col", "float64_col"]] + sql = utils._apply_binary_op(bf_df, ops.fillna_op, "int64_col", "float64_col") + snapshot.assert_match(sql, "out.sql") + + def test_hash(scalar_types_df: bpd.DataFrame, snapshot): col_name = "string_col" bf_df = scalar_types_df[[col_name]] From 94b7f0d2a1d0b5bcac399e87d6aff40f2358aa61 Mon Sep 17 00:00:00 2001 From: jialuo Date: Tue, 11 Nov 2025 00:12:17 +0000 Subject: [PATCH 2/3] engine test --- tests/system/small/engines/test_generic_ops.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/system/small/engines/test_generic_ops.py b/tests/system/small/engines/test_generic_ops.py index 5641f91a9a..2bf1ae1522 100644 --- a/tests/system/small/engines/test_generic_ops.py +++ b/tests/system/small/engines/test_generic_ops.py @@ -343,7 +343,7 @@ def test_engines_coalesce_op(scalars_array_value: array_value.ArrayValue, engine assert_equivalence_execution(arr.node, REFERENCE_ENGINE, engine) -@pytest.mark.parametrize("engine", ["polars", "bq"], indirect=True) +@pytest.mark.parametrize("engine", ["polars", "bq", "bq-sqlglot"], indirect=True) def test_engines_fillna_op(scalars_array_value: array_value.ArrayValue, engine): arr, _ = scalars_array_value.compute_values( [ From c64d73fa6001936ee91f7b2677bca6315b70157a Mon Sep 17 00:00:00 2001 From: jialuo Date: Tue, 11 Nov 2025 00:54:17 +0000 Subject: [PATCH 3/3] update sql --- .../snapshots/test_generic_ops/test_fillna/out.sql | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/unit/core/compile/sqlglot/expressions/snapshots/test_generic_ops/test_fillna/out.sql b/tests/unit/core/compile/sqlglot/expressions/snapshots/test_generic_ops/test_fillna/out.sql index 2cf07c2f5b..07f2877e74 100644 --- a/tests/unit/core/compile/sqlglot/expressions/snapshots/test_generic_ops/test_fillna/out.sql +++ b/tests/unit/core/compile/sqlglot/expressions/snapshots/test_generic_ops/test_fillna/out.sql @@ -1,12 +1,12 @@ WITH `bfcte_0` AS ( SELECT - `int64_col` AS `bfcol_0`, - `float64_col` AS `bfcol_1` + `float64_col`, + `int64_col` FROM `bigframes-dev`.`sqlglot_test`.`scalar_types` ), `bfcte_1` AS ( SELECT *, - COALESCE(`bfcol_0`, `bfcol_1`) AS `bfcol_2` + COALESCE(`int64_col`, `float64_col`) AS `bfcol_2` FROM `bfcte_0` ) SELECT