Skip to content

Commit a3d93af

Browse files
fix(bigframes): Fix IsInOp literal bug with sqlglot (#17356)
Thank you for opening a Pull Request! Before submitting your PR, there are a few things you can do to make sure it goes smoothly: - [ ] Make sure to open an issue as a [bug/issue](https://github.com/googleapis/google-cloud-python/issues) before writing your code! That way we can discuss the change, evaluate designs, and agree on the general idea - [ ] Ensure the tests and linter pass - [ ] Code coverage does not decrease (if any source code was changed) - [ ] Appropriate docs were updated (if necessary) Fixes #<issue_number_goes_here> 🦕
1 parent 6cc890b commit a3d93af

5 files changed

Lines changed: 56 additions & 3 deletions

File tree

packages/bigframes/bigframes/core/compile/sqlglot/expressions/comparison_ops.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ def _(expr: TypedExpr, op: ops.IsInOp) -> sge.Expression:
4646
if dtypes.can_compare(expr.dtype, dtype):
4747
if must_upcast_bools and dtype == dtypes.BOOL_DTYPE:
4848
value = int(value)
49-
values.append(sge.convert(value))
49+
values.append(sql.literal(value))
5050

5151
sg_lexpr: sge.Expression = expr.expr
5252
if expr.dtype == dtypes.BOOL_DTYPE and must_upcast_bools:

packages/bigframes/tests/unit/core/compile/sqlglot/expressions/snapshots/test_comparison_ops/test_is_in/out.sql

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ SELECT
44
`int64_col` IS NULL AS `ints_w_null`,
55
COALESCE(`int64_col` IN (1.0, 2.0, 3.0), FALSE) AS `floats`,
66
FALSE AS `strings`,
7-
COALESCE(`int64_col` IN (2.5, 3), FALSE) AS `mixed`,
7+
COALESCE(`int64_col` IN (2.5, 3, 1e-10, CAST('Infinity' AS FLOAT64), NULL, 0), FALSE) AS `mixed`,
88
FALSE AS `empty`,
99
FALSE AS `empty_wo_match_nulls`,
1010
COALESCE(`int64_col` IN (123456), FALSE) AS `ints_wo_match_nulls`,
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
SELECT
2+
CAST('Infinity' AS FLOAT64) AS `inf`,
3+
CAST('-Infinity' AS FLOAT64) AS `ninf`,
4+
NULL AS `nan`,
5+
-0.0 AS `neg_zero`,
6+
1e-05 AS `0.00001`,
7+
1e-10 AS `1E-10`
8+
FROM `bigframes-dev`.`sqlglot_test`.`scalar_types` AS `bft_0`

packages/bigframes/tests/unit/core/compile/sqlglot/expressions/test_comparison_ops.py

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,17 @@ def test_is_in(scalar_types_df: bpd.DataFrame, snapshot):
3535
int_col
3636
),
3737
"strings": ops.IsInOp(values=("1.0", "2.0")).as_expr(int_col),
38-
"mixed": ops.IsInOp(values=("1.0", 2.5, 3)).as_expr(int_col),
38+
"mixed": ops.IsInOp(
39+
values=(
40+
"1.0",
41+
2.5,
42+
3,
43+
1e-10,
44+
float("inf"),
45+
float("nan"),
46+
0,
47+
)
48+
).as_expr(int_col),
3949
"empty": ops.IsInOp(values=()).as_expr(int_col),
4050
"empty_wo_match_nulls": ops.IsInOp(values=(), match_nulls=False).as_expr(
4151
int_col
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
# Copyright 2025 Google LLC
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
import pytest
16+
17+
import bigframes.core.expression as ex
18+
import bigframes.pandas as bpd
19+
from bigframes.testing import utils
20+
21+
pytest.importorskip("pytest_snapshot")
22+
23+
24+
def test_float_literals(scalar_types_df: bpd.DataFrame, snapshot):
25+
bf_df = scalar_types_df[["float64_col"]]
26+
ops_map = {
27+
"inf": ex.const(float("inf")),
28+
"ninf": ex.const(float("-inf")),
29+
"nan": ex.const(float("nan")),
30+
"neg_zero": ex.const(-0.0),
31+
"0.00001": ex.const(0.00001),
32+
"1E-10": ex.const(1e-10),
33+
}
34+
sql = utils._apply_ops_to_sql(bf_df, list(ops_map.values()), list(ops_map.keys()))
35+
snapshot.assert_match(sql, "out.sql")

0 commit comments

Comments
 (0)