Skip to content

Commit 25ab0d5

Browse files
authored
chore: migrate 10 scalar operators to SQLGlot (#1922)
This change contains three commits generated by Gemini CLI tool: - Migrated cos, hash, isnull, notnull, and sin operators. - Migrated tan_op, arcsin_op, arccos_op, arctan_op, and sinh_op scalar operators to SQLGlot. Fixes internal issue 430133370
1 parent 6e01cbe commit 25ab0d5

File tree

13 files changed

+302
-0
lines changed

13 files changed

+302
-0
lines changed

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

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,13 +23,52 @@
2323
from bigframes.core.compile.sqlglot.expressions.op_registration import OpRegistration
2424
from bigframes.core.compile.sqlglot.expressions.typed_expr import TypedExpr
2525

26+
_NAN = sge.Cast(this=sge.convert("NaN"), to="FLOAT64")
27+
_INF = sge.Cast(this=sge.convert("Infinity"), to="FLOAT64")
28+
29+
# Approx Highest number you can pass in to EXP function and get a valid FLOAT64 result
30+
# FLOAT64 has 11 exponent bits, so max values is about 2**(2**10)
31+
# ln(2**(2**10)) == (2**10)*ln(2) ~= 709.78, so EXP(x) for x>709.78 will overflow.
32+
_FLOAT64_EXP_BOUND = sge.convert(709.78)
33+
2634
UNARY_OP_REGISTRATION = OpRegistration()
2735

2836

2937
def compile(op: ops.UnaryOp, expr: TypedExpr) -> sge.Expression:
3038
return UNARY_OP_REGISTRATION[op](op, expr)
3139

3240

41+
@UNARY_OP_REGISTRATION.register(ops.arccos_op)
42+
def _(op: ops.base_ops.UnaryOp, expr: TypedExpr) -> sge.Expression:
43+
return sge.Case(
44+
ifs=[
45+
sge.If(
46+
this=sge.func("ABS", expr.expr) > sge.convert(1),
47+
true=_NAN,
48+
)
49+
],
50+
default=sge.func("ACOS", expr.expr),
51+
)
52+
53+
54+
@UNARY_OP_REGISTRATION.register(ops.arcsin_op)
55+
def _(op: ops.base_ops.UnaryOp, expr: TypedExpr) -> sge.Expression:
56+
return sge.Case(
57+
ifs=[
58+
sge.If(
59+
this=sge.func("ABS", expr.expr) > sge.convert(1),
60+
true=_NAN,
61+
)
62+
],
63+
default=sge.func("ASIN", expr.expr),
64+
)
65+
66+
67+
@UNARY_OP_REGISTRATION.register(ops.arctan_op)
68+
def _(op: ops.base_ops.UnaryOp, expr: TypedExpr) -> sge.Expression:
69+
return sge.func("ATAN", expr.expr)
70+
71+
3372
@UNARY_OP_REGISTRATION.register(ops.ArrayToStringOp)
3473
def _(op: ops.ArrayToStringOp, expr: TypedExpr) -> sge.Expression:
3574
return sge.ArrayToString(this=expr.expr, expression=f"'{op.delimiter}'")
@@ -72,6 +111,49 @@ def _(op: ops.ArraySliceOp, expr: TypedExpr) -> sge.Expression:
72111
return sge.array(selected_elements)
73112

74113

114+
@UNARY_OP_REGISTRATION.register(ops.cos_op)
115+
def _(op: ops.base_ops.UnaryOp, expr: TypedExpr) -> sge.Expression:
116+
return sge.func("COS", expr.expr)
117+
118+
119+
@UNARY_OP_REGISTRATION.register(ops.hash_op)
120+
def _(op: ops.base_ops.UnaryOp, expr: TypedExpr) -> sge.Expression:
121+
return sge.func("FARM_FINGERPRINT", expr.expr)
122+
123+
124+
@UNARY_OP_REGISTRATION.register(ops.isnull_op)
125+
def _(op: ops.base_ops.UnaryOp, expr: TypedExpr) -> sge.Expression:
126+
return sge.Is(this=expr.expr, expression=sge.Null())
127+
128+
129+
@UNARY_OP_REGISTRATION.register(ops.notnull_op)
130+
def _(op: ops.base_ops.UnaryOp, expr: TypedExpr) -> sge.Expression:
131+
return sge.Not(this=sge.Is(this=expr.expr, expression=sge.Null()))
132+
133+
134+
@UNARY_OP_REGISTRATION.register(ops.sin_op)
135+
def _(op: ops.base_ops.UnaryOp, expr: TypedExpr) -> sge.Expression:
136+
return sge.func("SIN", expr.expr)
137+
138+
139+
@UNARY_OP_REGISTRATION.register(ops.sinh_op)
140+
def _(op: ops.base_ops.UnaryOp, expr: TypedExpr) -> sge.Expression:
141+
return sge.Case(
142+
ifs=[
143+
sge.If(
144+
this=sge.func("ABS", expr.expr) > _FLOAT64_EXP_BOUND,
145+
true=sge.func("SIGN", expr.expr) * _INF,
146+
)
147+
],
148+
default=sge.func("SINH", expr.expr),
149+
)
150+
151+
152+
@UNARY_OP_REGISTRATION.register(ops.tan_op)
153+
def _(op: ops.base_ops.UnaryOp, expr: TypedExpr) -> sge.Expression:
154+
return sge.func("TAN", expr.expr)
155+
156+
75157
# JSON Ops
76158
@UNARY_OP_REGISTRATION.register(ops.JSONExtract)
77159
def _(op: ops.JSONExtract, expr: TypedExpr) -> sge.Expression:
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
WITH `bfcte_0` AS (
2+
SELECT
3+
`float64_col` AS `bfcol_0`
4+
FROM `bigframes-dev`.`sqlglot_test`.`scalar_types`
5+
), `bfcte_1` AS (
6+
SELECT
7+
*,
8+
CASE WHEN ABS(`bfcol_0`) > 1 THEN CAST('NaN' AS FLOAT64) ELSE ACOS(`bfcol_0`) END AS `bfcol_1`
9+
FROM `bfcte_0`
10+
)
11+
SELECT
12+
`bfcol_1` AS `float64_col`
13+
FROM `bfcte_1`
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
WITH `bfcte_0` AS (
2+
SELECT
3+
`float64_col` AS `bfcol_0`
4+
FROM `bigframes-dev`.`sqlglot_test`.`scalar_types`
5+
), `bfcte_1` AS (
6+
SELECT
7+
*,
8+
CASE WHEN ABS(`bfcol_0`) > 1 THEN CAST('NaN' AS FLOAT64) ELSE ASIN(`bfcol_0`) END AS `bfcol_1`
9+
FROM `bfcte_0`
10+
)
11+
SELECT
12+
`bfcol_1` AS `float64_col`
13+
FROM `bfcte_1`
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
WITH `bfcte_0` AS (
2+
SELECT
3+
`float64_col` AS `bfcol_0`
4+
FROM `bigframes-dev`.`sqlglot_test`.`scalar_types`
5+
), `bfcte_1` AS (
6+
SELECT
7+
*,
8+
ATAN(`bfcol_0`) AS `bfcol_1`
9+
FROM `bfcte_0`
10+
)
11+
SELECT
12+
`bfcol_1` AS `float64_col`
13+
FROM `bfcte_1`
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
WITH `bfcte_0` AS (
2+
SELECT
3+
`float64_col` AS `bfcol_0`
4+
FROM `bigframes-dev`.`sqlglot_test`.`scalar_types`
5+
), `bfcte_1` AS (
6+
SELECT
7+
*,
8+
COS(`bfcol_0`) AS `bfcol_1`
9+
FROM `bfcte_0`
10+
)
11+
SELECT
12+
`bfcol_1` AS `float64_col`
13+
FROM `bfcte_1`
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
WITH `bfcte_0` AS (
2+
SELECT
3+
`string_col` AS `bfcol_0`
4+
FROM `bigframes-dev`.`sqlglot_test`.`scalar_types`
5+
), `bfcte_1` AS (
6+
SELECT
7+
*,
8+
FARM_FINGERPRINT(`bfcol_0`) AS `bfcol_1`
9+
FROM `bfcte_0`
10+
)
11+
SELECT
12+
`bfcol_1` AS `string_col`
13+
FROM `bfcte_1`
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
WITH `bfcte_0` AS (
2+
SELECT
3+
`float64_col` AS `bfcol_0`
4+
FROM `bigframes-dev`.`sqlglot_test`.`scalar_types`
5+
), `bfcte_1` AS (
6+
SELECT
7+
*,
8+
`bfcol_0` IS NULL AS `bfcol_1`
9+
FROM `bfcte_0`
10+
)
11+
SELECT
12+
`bfcol_1` AS `float64_col`
13+
FROM `bfcte_1`
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
WITH `bfcte_0` AS (
2+
SELECT
3+
`float64_col` AS `bfcol_0`
4+
FROM `bigframes-dev`.`sqlglot_test`.`scalar_types`
5+
), `bfcte_1` AS (
6+
SELECT
7+
*,
8+
NOT `bfcol_0` IS NULL AS `bfcol_1`
9+
FROM `bfcte_0`
10+
)
11+
SELECT
12+
`bfcol_1` AS `float64_col`
13+
FROM `bfcte_1`
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
WITH `bfcte_0` AS (
2+
SELECT
3+
`float64_col` AS `bfcol_0`
4+
FROM `bigframes-dev`.`sqlglot_test`.`scalar_types`
5+
), `bfcte_1` AS (
6+
SELECT
7+
*,
8+
SIN(`bfcol_0`) AS `bfcol_1`
9+
FROM `bfcte_0`
10+
)
11+
SELECT
12+
`bfcol_1` AS `float64_col`
13+
FROM `bfcte_1`
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
WITH `bfcte_0` AS (
2+
SELECT
3+
`float64_col` AS `bfcol_0`
4+
FROM `bigframes-dev`.`sqlglot_test`.`scalar_types`
5+
), `bfcte_1` AS (
6+
SELECT
7+
*,
8+
CASE
9+
WHEN ABS(`bfcol_0`) > 709.78
10+
THEN SIGN(`bfcol_0`) * CAST('Infinity' AS FLOAT64)
11+
ELSE SINH(`bfcol_0`)
12+
END AS `bfcol_1`
13+
FROM `bfcte_0`
14+
)
15+
SELECT
16+
`bfcol_1` AS `float64_col`
17+
FROM `bfcte_1`

0 commit comments

Comments
 (0)