Skip to content

Commit 09b67da

Browse files
authored
chore: implement ge, gt, le, gt compilers (#2009)
1 parent 26df6e6 commit 09b67da

File tree

7 files changed

+294
-7
lines changed

7 files changed

+294
-7
lines changed

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

Lines changed: 29 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -140,14 +140,37 @@ def _(op, left: TypedExpr, right: TypedExpr) -> sge.Expression:
140140

141141
@BINARY_OP_REGISTRATION.register(ops.ge_op)
142142
def _(op, left: TypedExpr, right: TypedExpr) -> sge.Expression:
143-
return sge.GTE(this=left.expr, expression=right.expr)
143+
left_expr = _coerce_bool_to_int(left)
144+
right_expr = _coerce_bool_to_int(right)
145+
return sge.GTE(this=left_expr, expression=right_expr)
146+
147+
148+
@BINARY_OP_REGISTRATION.register(ops.gt_op)
149+
def _(op, left: TypedExpr, right: TypedExpr) -> sge.Expression:
150+
left_expr = _coerce_bool_to_int(left)
151+
right_expr = _coerce_bool_to_int(right)
152+
return sge.GT(this=left_expr, expression=right_expr)
144153

145154

146155
@BINARY_OP_REGISTRATION.register(ops.JSONSet)
147156
def _(op, left: TypedExpr, right: TypedExpr) -> sge.Expression:
148157
return sge.func("JSON_SET", left.expr, sge.convert(op.json_path), right.expr)
149158

150159

160+
@BINARY_OP_REGISTRATION.register(ops.lt_op)
161+
def _(op, left: TypedExpr, right: TypedExpr) -> sge.Expression:
162+
left_expr = _coerce_bool_to_int(left)
163+
right_expr = _coerce_bool_to_int(right)
164+
return sge.LT(this=left_expr, expression=right_expr)
165+
166+
167+
@BINARY_OP_REGISTRATION.register(ops.le_op)
168+
def _(op, left: TypedExpr, right: TypedExpr) -> sge.Expression:
169+
left_expr = _coerce_bool_to_int(left)
170+
right_expr = _coerce_bool_to_int(right)
171+
return sge.LTE(this=left_expr, expression=right_expr)
172+
173+
151174
@BINARY_OP_REGISTRATION.register(ops.mul_op)
152175
def _(op, left: TypedExpr, right: TypedExpr) -> sge.Expression:
153176
left_expr = _coerce_bool_to_int(left)
@@ -170,6 +193,11 @@ def _(op, left: TypedExpr, right: TypedExpr) -> sge.Expression:
170193
return sge.NEQ(this=left_expr, expression=right_expr)
171194

172195

196+
@BINARY_OP_REGISTRATION.register(ops.obj_make_ref_op)
197+
def _(op, left: TypedExpr, right: TypedExpr) -> sge.Expression:
198+
return sge.func("OBJ.MAKE_REF", left.expr, right.expr)
199+
200+
173201
@BINARY_OP_REGISTRATION.register(ops.sub_op)
174202
def _(op, left: TypedExpr, right: TypedExpr) -> sge.Expression:
175203
if dtypes.is_numeric(left.dtype) and dtypes.is_numeric(right.dtype):
@@ -202,11 +230,6 @@ def _(op, left: TypedExpr, right: TypedExpr) -> sge.Expression:
202230
)
203231

204232

205-
@BINARY_OP_REGISTRATION.register(ops.obj_make_ref_op)
206-
def _(op, left: TypedExpr, right: TypedExpr) -> sge.Expression:
207-
return sge.func("OBJ.MAKE_REF", left.expr, right.expr)
208-
209-
210233
def _coerce_bool_to_int(typed_expr: TypedExpr) -> sge.Expression:
211234
"""Coerce boolean expression to integer."""
212235
if typed_expr.dtype == dtypes.BOOL_DTYPE:

tests/system/small/engines/test_comparison_ops.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ def apply_op_pairwise(
4848
return new_arr
4949

5050

51-
@pytest.mark.parametrize("engine", ["polars", "bq"], indirect=True)
51+
@pytest.mark.parametrize("engine", ["polars", "bq", "bq-sqlglot"], indirect=True)
5252
@pytest.mark.parametrize(
5353
"op",
5454
[
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
WITH `bfcte_0` AS (
2+
SELECT
3+
`bool_col` AS `bfcol_0`,
4+
`int64_col` AS `bfcol_1`,
5+
`rowindex` AS `bfcol_2`
6+
FROM `bigframes-dev`.`sqlglot_test`.`scalar_types`
7+
), `bfcte_1` AS (
8+
SELECT
9+
*,
10+
`bfcol_2` AS `bfcol_6`,
11+
`bfcol_1` AS `bfcol_7`,
12+
`bfcol_0` AS `bfcol_8`,
13+
`bfcol_1` >= `bfcol_1` AS `bfcol_9`
14+
FROM `bfcte_0`
15+
), `bfcte_2` AS (
16+
SELECT
17+
*,
18+
`bfcol_6` AS `bfcol_14`,
19+
`bfcol_7` AS `bfcol_15`,
20+
`bfcol_8` AS `bfcol_16`,
21+
`bfcol_9` AS `bfcol_17`,
22+
`bfcol_7` >= 1 AS `bfcol_18`
23+
FROM `bfcte_1`
24+
), `bfcte_3` AS (
25+
SELECT
26+
*,
27+
`bfcol_14` AS `bfcol_24`,
28+
`bfcol_15` AS `bfcol_25`,
29+
`bfcol_16` AS `bfcol_26`,
30+
`bfcol_17` AS `bfcol_27`,
31+
`bfcol_18` AS `bfcol_28`,
32+
`bfcol_15` >= CAST(`bfcol_16` AS INT64) AS `bfcol_29`
33+
FROM `bfcte_2`
34+
), `bfcte_4` AS (
35+
SELECT
36+
*,
37+
`bfcol_24` AS `bfcol_36`,
38+
`bfcol_25` AS `bfcol_37`,
39+
`bfcol_26` AS `bfcol_38`,
40+
`bfcol_27` AS `bfcol_39`,
41+
`bfcol_28` AS `bfcol_40`,
42+
`bfcol_29` AS `bfcol_41`,
43+
CAST(`bfcol_26` AS INT64) >= `bfcol_25` AS `bfcol_42`
44+
FROM `bfcte_3`
45+
)
46+
SELECT
47+
`bfcol_36` AS `rowindex`,
48+
`bfcol_37` AS `int64_col`,
49+
`bfcol_38` AS `bool_col`,
50+
`bfcol_39` AS `int_ge_int`,
51+
`bfcol_40` AS `int_ge_1`,
52+
`bfcol_41` AS `int_ge_bool`,
53+
`bfcol_42` AS `bool_ge_int`
54+
FROM `bfcte_4`
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
WITH `bfcte_0` AS (
2+
SELECT
3+
`bool_col` AS `bfcol_0`,
4+
`int64_col` AS `bfcol_1`,
5+
`rowindex` AS `bfcol_2`
6+
FROM `bigframes-dev`.`sqlglot_test`.`scalar_types`
7+
), `bfcte_1` AS (
8+
SELECT
9+
*,
10+
`bfcol_2` AS `bfcol_6`,
11+
`bfcol_1` AS `bfcol_7`,
12+
`bfcol_0` AS `bfcol_8`,
13+
`bfcol_1` > `bfcol_1` AS `bfcol_9`
14+
FROM `bfcte_0`
15+
), `bfcte_2` AS (
16+
SELECT
17+
*,
18+
`bfcol_6` AS `bfcol_14`,
19+
`bfcol_7` AS `bfcol_15`,
20+
`bfcol_8` AS `bfcol_16`,
21+
`bfcol_9` AS `bfcol_17`,
22+
`bfcol_7` > 1 AS `bfcol_18`
23+
FROM `bfcte_1`
24+
), `bfcte_3` AS (
25+
SELECT
26+
*,
27+
`bfcol_14` AS `bfcol_24`,
28+
`bfcol_15` AS `bfcol_25`,
29+
`bfcol_16` AS `bfcol_26`,
30+
`bfcol_17` AS `bfcol_27`,
31+
`bfcol_18` AS `bfcol_28`,
32+
`bfcol_15` > CAST(`bfcol_16` AS INT64) AS `bfcol_29`
33+
FROM `bfcte_2`
34+
), `bfcte_4` AS (
35+
SELECT
36+
*,
37+
`bfcol_24` AS `bfcol_36`,
38+
`bfcol_25` AS `bfcol_37`,
39+
`bfcol_26` AS `bfcol_38`,
40+
`bfcol_27` AS `bfcol_39`,
41+
`bfcol_28` AS `bfcol_40`,
42+
`bfcol_29` AS `bfcol_41`,
43+
CAST(`bfcol_26` AS INT64) > `bfcol_25` AS `bfcol_42`
44+
FROM `bfcte_3`
45+
)
46+
SELECT
47+
`bfcol_36` AS `rowindex`,
48+
`bfcol_37` AS `int64_col`,
49+
`bfcol_38` AS `bool_col`,
50+
`bfcol_39` AS `int_gt_int`,
51+
`bfcol_40` AS `int_gt_1`,
52+
`bfcol_41` AS `int_gt_bool`,
53+
`bfcol_42` AS `bool_gt_int`
54+
FROM `bfcte_4`
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
WITH `bfcte_0` AS (
2+
SELECT
3+
`bool_col` AS `bfcol_0`,
4+
`int64_col` AS `bfcol_1`,
5+
`rowindex` AS `bfcol_2`
6+
FROM `bigframes-dev`.`sqlglot_test`.`scalar_types`
7+
), `bfcte_1` AS (
8+
SELECT
9+
*,
10+
`bfcol_2` AS `bfcol_6`,
11+
`bfcol_1` AS `bfcol_7`,
12+
`bfcol_0` AS `bfcol_8`,
13+
`bfcol_1` <= `bfcol_1` AS `bfcol_9`
14+
FROM `bfcte_0`
15+
), `bfcte_2` AS (
16+
SELECT
17+
*,
18+
`bfcol_6` AS `bfcol_14`,
19+
`bfcol_7` AS `bfcol_15`,
20+
`bfcol_8` AS `bfcol_16`,
21+
`bfcol_9` AS `bfcol_17`,
22+
`bfcol_7` <= 1 AS `bfcol_18`
23+
FROM `bfcte_1`
24+
), `bfcte_3` AS (
25+
SELECT
26+
*,
27+
`bfcol_14` AS `bfcol_24`,
28+
`bfcol_15` AS `bfcol_25`,
29+
`bfcol_16` AS `bfcol_26`,
30+
`bfcol_17` AS `bfcol_27`,
31+
`bfcol_18` AS `bfcol_28`,
32+
`bfcol_15` <= CAST(`bfcol_16` AS INT64) AS `bfcol_29`
33+
FROM `bfcte_2`
34+
), `bfcte_4` AS (
35+
SELECT
36+
*,
37+
`bfcol_24` AS `bfcol_36`,
38+
`bfcol_25` AS `bfcol_37`,
39+
`bfcol_26` AS `bfcol_38`,
40+
`bfcol_27` AS `bfcol_39`,
41+
`bfcol_28` AS `bfcol_40`,
42+
`bfcol_29` AS `bfcol_41`,
43+
CAST(`bfcol_26` AS INT64) <= `bfcol_25` AS `bfcol_42`
44+
FROM `bfcte_3`
45+
)
46+
SELECT
47+
`bfcol_36` AS `rowindex`,
48+
`bfcol_37` AS `int64_col`,
49+
`bfcol_38` AS `bool_col`,
50+
`bfcol_39` AS `int_le_int`,
51+
`bfcol_40` AS `int_le_1`,
52+
`bfcol_41` AS `int_le_bool`,
53+
`bfcol_42` AS `bool_le_int`
54+
FROM `bfcte_4`
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
WITH `bfcte_0` AS (
2+
SELECT
3+
`bool_col` AS `bfcol_0`,
4+
`int64_col` AS `bfcol_1`,
5+
`rowindex` AS `bfcol_2`
6+
FROM `bigframes-dev`.`sqlglot_test`.`scalar_types`
7+
), `bfcte_1` AS (
8+
SELECT
9+
*,
10+
`bfcol_2` AS `bfcol_6`,
11+
`bfcol_1` AS `bfcol_7`,
12+
`bfcol_0` AS `bfcol_8`,
13+
`bfcol_1` < `bfcol_1` AS `bfcol_9`
14+
FROM `bfcte_0`
15+
), `bfcte_2` AS (
16+
SELECT
17+
*,
18+
`bfcol_6` AS `bfcol_14`,
19+
`bfcol_7` AS `bfcol_15`,
20+
`bfcol_8` AS `bfcol_16`,
21+
`bfcol_9` AS `bfcol_17`,
22+
`bfcol_7` < 1 AS `bfcol_18`
23+
FROM `bfcte_1`
24+
), `bfcte_3` AS (
25+
SELECT
26+
*,
27+
`bfcol_14` AS `bfcol_24`,
28+
`bfcol_15` AS `bfcol_25`,
29+
`bfcol_16` AS `bfcol_26`,
30+
`bfcol_17` AS `bfcol_27`,
31+
`bfcol_18` AS `bfcol_28`,
32+
`bfcol_15` < CAST(`bfcol_16` AS INT64) AS `bfcol_29`
33+
FROM `bfcte_2`
34+
), `bfcte_4` AS (
35+
SELECT
36+
*,
37+
`bfcol_24` AS `bfcol_36`,
38+
`bfcol_25` AS `bfcol_37`,
39+
`bfcol_26` AS `bfcol_38`,
40+
`bfcol_27` AS `bfcol_39`,
41+
`bfcol_28` AS `bfcol_40`,
42+
`bfcol_29` AS `bfcol_41`,
43+
CAST(`bfcol_26` AS INT64) < `bfcol_25` AS `bfcol_42`
44+
FROM `bfcte_3`
45+
)
46+
SELECT
47+
`bfcol_36` AS `rowindex`,
48+
`bfcol_37` AS `int64_col`,
49+
`bfcol_38` AS `bool_col`,
50+
`bfcol_39` AS `int_lt_int`,
51+
`bfcol_40` AS `int_lt_1`,
52+
`bfcol_41` AS `int_lt_bool`,
53+
`bfcol_42` AS `bool_lt_int`
54+
FROM `bfcte_4`

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

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,30 @@ def test_floordiv_timedelta(scalar_types_df: bpd.DataFrame, snapshot):
149149
snapshot.assert_match(bf_df.sql, "out.sql")
150150

151151

152+
def test_gt_numeric(scalar_types_df: bpd.DataFrame, snapshot):
153+
bf_df = scalar_types_df[["int64_col", "bool_col"]]
154+
155+
bf_df["int_gt_int"] = bf_df["int64_col"] > bf_df["int64_col"]
156+
bf_df["int_gt_1"] = bf_df["int64_col"] > 1
157+
158+
bf_df["int_gt_bool"] = bf_df["int64_col"] > bf_df["bool_col"]
159+
bf_df["bool_gt_int"] = bf_df["bool_col"] > bf_df["int64_col"]
160+
161+
snapshot.assert_match(bf_df.sql, "out.sql")
162+
163+
164+
def test_ge_numeric(scalar_types_df: bpd.DataFrame, snapshot):
165+
bf_df = scalar_types_df[["int64_col", "bool_col"]]
166+
167+
bf_df["int_ge_int"] = bf_df["int64_col"] >= bf_df["int64_col"]
168+
bf_df["int_ge_1"] = bf_df["int64_col"] >= 1
169+
170+
bf_df["int_ge_bool"] = bf_df["int64_col"] >= bf_df["bool_col"]
171+
bf_df["bool_ge_int"] = bf_df["bool_col"] >= bf_df["int64_col"]
172+
173+
snapshot.assert_match(bf_df.sql, "out.sql")
174+
175+
152176
def test_json_set(json_types_df: bpd.DataFrame, snapshot):
153177
bf_df = json_types_df[["json_col"]]
154178
sql = _apply_binary_op(
@@ -158,6 +182,30 @@ def test_json_set(json_types_df: bpd.DataFrame, snapshot):
158182
snapshot.assert_match(sql, "out.sql")
159183

160184

185+
def test_lt_numeric(scalar_types_df: bpd.DataFrame, snapshot):
186+
bf_df = scalar_types_df[["int64_col", "bool_col"]]
187+
188+
bf_df["int_lt_int"] = bf_df["int64_col"] < bf_df["int64_col"]
189+
bf_df["int_lt_1"] = bf_df["int64_col"] < 1
190+
191+
bf_df["int_lt_bool"] = bf_df["int64_col"] < bf_df["bool_col"]
192+
bf_df["bool_lt_int"] = bf_df["bool_col"] < bf_df["int64_col"]
193+
194+
snapshot.assert_match(bf_df.sql, "out.sql")
195+
196+
197+
def test_le_numeric(scalar_types_df: bpd.DataFrame, snapshot):
198+
bf_df = scalar_types_df[["int64_col", "bool_col"]]
199+
200+
bf_df["int_le_int"] = bf_df["int64_col"] <= bf_df["int64_col"]
201+
bf_df["int_le_1"] = bf_df["int64_col"] <= 1
202+
203+
bf_df["int_le_bool"] = bf_df["int64_col"] <= bf_df["bool_col"]
204+
bf_df["bool_le_int"] = bf_df["bool_col"] <= bf_df["int64_col"]
205+
206+
snapshot.assert_match(bf_df.sql, "out.sql")
207+
208+
161209
def test_sub_numeric(scalar_types_df: bpd.DataFrame, snapshot):
162210
bf_df = scalar_types_df[["int64_col", "bool_col"]]
163211

0 commit comments

Comments
 (0)