diff --git a/packages/bigframes/bigframes/core/compile/sqlglot/expressions/comparison_ops.py b/packages/bigframes/bigframes/core/compile/sqlglot/expressions/comparison_ops.py index 968c2c4eed83..a3331ce6fb59 100644 --- a/packages/bigframes/bigframes/core/compile/sqlglot/expressions/comparison_ops.py +++ b/packages/bigframes/bigframes/core/compile/sqlglot/expressions/comparison_ops.py @@ -46,7 +46,7 @@ def _(expr: TypedExpr, op: ops.IsInOp) -> sge.Expression: if dtypes.can_compare(expr.dtype, dtype): if must_upcast_bools and dtype == dtypes.BOOL_DTYPE: value = int(value) - values.append(sge.convert(value)) + values.append(sql.literal(value)) sg_lexpr: sge.Expression = expr.expr if expr.dtype == dtypes.BOOL_DTYPE and must_upcast_bools: diff --git a/packages/bigframes/tests/unit/core/compile/sqlglot/expressions/snapshots/test_comparison_ops/test_is_in/out.sql b/packages/bigframes/tests/unit/core/compile/sqlglot/expressions/snapshots/test_comparison_ops/test_is_in/out.sql index b6d860d47231..308e6f9cbd7e 100644 --- a/packages/bigframes/tests/unit/core/compile/sqlglot/expressions/snapshots/test_comparison_ops/test_is_in/out.sql +++ b/packages/bigframes/tests/unit/core/compile/sqlglot/expressions/snapshots/test_comparison_ops/test_is_in/out.sql @@ -4,7 +4,7 @@ SELECT `int64_col` IS NULL AS `ints_w_null`, COALESCE(`int64_col` IN (1.0, 2.0, 3.0), FALSE) AS `floats`, FALSE AS `strings`, - COALESCE(`int64_col` IN (2.5, 3), FALSE) AS `mixed`, + COALESCE(`int64_col` IN (2.5, 3, 1e-10, CAST('Infinity' AS FLOAT64), NULL, 0), FALSE) AS `mixed`, FALSE AS `empty`, FALSE AS `empty_wo_match_nulls`, COALESCE(`int64_col` IN (123456), FALSE) AS `ints_wo_match_nulls`, diff --git a/packages/bigframes/tests/unit/core/compile/sqlglot/expressions/snapshots/test_literals/test_float_literals/out.sql b/packages/bigframes/tests/unit/core/compile/sqlglot/expressions/snapshots/test_literals/test_float_literals/out.sql new file mode 100644 index 000000000000..030e733edd77 --- /dev/null +++ b/packages/bigframes/tests/unit/core/compile/sqlglot/expressions/snapshots/test_literals/test_float_literals/out.sql @@ -0,0 +1,8 @@ +SELECT + CAST('Infinity' AS FLOAT64) AS `inf`, + CAST('-Infinity' AS FLOAT64) AS `ninf`, + NULL AS `nan`, + -0.0 AS `neg_zero`, + 1e-05 AS `0.00001`, + 1e-10 AS `1E-10` +FROM `bigframes-dev`.`sqlglot_test`.`scalar_types` AS `bft_0` \ No newline at end of file diff --git a/packages/bigframes/tests/unit/core/compile/sqlglot/expressions/test_comparison_ops.py b/packages/bigframes/tests/unit/core/compile/sqlglot/expressions/test_comparison_ops.py index 4c397bcd70f8..73aceaedeebc 100644 --- a/packages/bigframes/tests/unit/core/compile/sqlglot/expressions/test_comparison_ops.py +++ b/packages/bigframes/tests/unit/core/compile/sqlglot/expressions/test_comparison_ops.py @@ -35,7 +35,17 @@ def test_is_in(scalar_types_df: bpd.DataFrame, snapshot): int_col ), "strings": ops.IsInOp(values=("1.0", "2.0")).as_expr(int_col), - "mixed": ops.IsInOp(values=("1.0", 2.5, 3)).as_expr(int_col), + "mixed": ops.IsInOp( + values=( + "1.0", + 2.5, + 3, + 1e-10, + float("inf"), + float("nan"), + 0, + ) + ).as_expr(int_col), "empty": ops.IsInOp(values=()).as_expr(int_col), "empty_wo_match_nulls": ops.IsInOp(values=(), match_nulls=False).as_expr( int_col diff --git a/packages/bigframes/tests/unit/core/compile/sqlglot/expressions/test_literals.py b/packages/bigframes/tests/unit/core/compile/sqlglot/expressions/test_literals.py new file mode 100644 index 000000000000..aa0d7a1e5b14 --- /dev/null +++ b/packages/bigframes/tests/unit/core/compile/sqlglot/expressions/test_literals.py @@ -0,0 +1,35 @@ +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import pytest + +import bigframes.core.expression as ex +import bigframes.pandas as bpd +from bigframes.testing import utils + +pytest.importorskip("pytest_snapshot") + + +def test_float_literals(scalar_types_df: bpd.DataFrame, snapshot): + bf_df = scalar_types_df[["float64_col"]] + ops_map = { + "inf": ex.const(float("inf")), + "ninf": ex.const(float("-inf")), + "nan": ex.const(float("nan")), + "neg_zero": ex.const(-0.0), + "0.00001": ex.const(0.00001), + "1E-10": ex.const(1e-10), + } + sql = utils._apply_ops_to_sql(bf_df, list(ops_map.values()), list(ops_map.keys())) + snapshot.assert_match(sql, "out.sql")