Skip to content

Commit ce5fd50

Browse files
authored
fix: emit bracketed inline array syntax for scalar subquery expressions (#17716)
Fixes a SQLGlot transpilation bug in BigQuery array generation where single-element arrays containing scalar subqueries wrapped in expressions (e.g., `COALESCE(CAST(...))` or `ROUND(...)`) produced invalid BigQuery SQL syntax `ARRAY(COALESCE(...))`, causing BigQuery `400 Syntax error: Unexpected identifier "COALESCE"` errors on `.cache()`. Verified at: before: screen/9AmutJHVDJuafwm after: screen/u7aW9tTLB8ybUFW Fixes #<534824500> 🦕
1 parent 2c3c213 commit ce5fd50

3 files changed

Lines changed: 31 additions & 1 deletion

File tree

  • packages/bigframes
    • tests/unit/core/compile/sqlglot/expressions
    • third_party/bigframes_vendored/sqlglot/dialects
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
SELECT
2+
[
3+
COALESCE(
4+
(
5+
SELECT
6+
COALESCE(SUM(bf_arr_reduce_uid), 0)
7+
FROM UNNEST(`float_list_col`) AS bf_arr_reduce_uid
8+
),
9+
0.0
10+
)
11+
] AS `arr_subquery_coalesce`
12+
FROM `bigframes-dev`.`sqlglot_test`.`repeated_types` AS `bft_0`

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

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,3 +104,14 @@ def test_to_array_op(scalar_types_df: bpd.DataFrame, snapshot):
104104

105105
sql = utils._apply_ops_to_sql(bf_df, list(ops_map.values()), list(ops_map.keys()))
106106
snapshot.assert_match(sql, "out.sql")
107+
108+
109+
def test_to_array_with_subquery_expression(repeated_types_df: bpd.DataFrame, snapshot):
110+
reduced = ops.ArrayReduceOp(agg_ops.SumOp()).as_expr("float_list_col")
111+
coalesced_reduced = ops.coalesce_op.as_expr(reduced, expression.const(0.0))
112+
array_expr = ops.ToArrayOp().as_expr(coalesced_reduced)
113+
114+
sql = utils._apply_ops_to_sql(
115+
repeated_types_df, [array_expr], ["arr_subquery_coalesce"]
116+
)
117+
snapshot.assert_match(sql, "out.sql")

packages/bigframes/third_party/bigframes_vendored/sqlglot/dialects/dialect.py

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1236,7 +1236,14 @@ def inline_array_sql(self: Generator, expression: exp.Expression) -> str:
12361236

12371237
def inline_array_unless_query(self: Generator, expression: exp.Expression) -> str:
12381238
elem = seq_get(expression.expressions, 0)
1239-
if isinstance(elem, exp.Expression) and elem.find(exp.Query):
1239+
if (
1240+
len(expression.expressions) == 1
1241+
and isinstance(elem, exp.Expression)
1242+
and (
1243+
isinstance(elem, exp.Query)
1244+
or (isinstance(elem, exp.Subquery) and isinstance(elem.this, exp.Query))
1245+
)
1246+
):
12401247
return self.func("ARRAY", elem)
12411248
return inline_array_sql(self, expression)
12421249

0 commit comments

Comments
 (0)