2323import bigframes_vendored .ibis .expr .datatypes as ibis_dtypes
2424import bigframes_vendored .ibis .expr .operations as ibis_ops
2525import bigframes_vendored .ibis .expr .types as ibis_types
26+ import bigframes_vendored .sqlglot .expressions as sge
2627from google .cloud import bigquery
2728import pyarrow as pa
2829
2930from bigframes .core import agg_expressions , rewrite
3031import bigframes .core .agg_expressions as ex_types
31- import bigframes .core .compile .googlesql
3232import bigframes .core .compile .ibis_compiler .aggregate_compiler as agg_compiler
3333import bigframes .core .compile .ibis_compiler .scalar_op_compiler as op_compilers
3434import bigframes .core .compile .ibis_types
@@ -82,13 +82,21 @@ def to_sql(
8282 )
8383
8484 if order_by or limit or not is_noop_selection :
85- sql = ibis_bigquery .Backend ().compile (ibis_table )
86- sql = (
87- bigframes .core .compile .googlesql .Select ()
88- .from_ (sql )
89- .select (selection_strings )
90- .sql ()
91- )
85+ # selections are (ref.id.sql, name) where ref.id.sql is escaped identifier
86+ to_select = [
87+ sge .Alias (
88+ this = sge .to_identifier (src , quoted = True ),
89+ alias = sge .to_identifier (alias , quoted = True ),
90+ )
91+ if src != alias
92+ else sge .to_identifier (src , quoted = True )
93+ for src , alias in selection_strings
94+ ]
95+ # Use string formatting for FROM clause to avoid re-parsing potentially complex SQL (like ARRAY<STRUCT<...>>)
96+ # that sqlglot might not handle perfectly when parsing BigQuery dialect strings.
97+ select_sql = sge .Select ().select (* to_select ).sql (dialect = "bigquery" )
98+ ibis_sql = ibis_bigquery .Backend ().compile (ibis_table )
99+ sql = f"{ select_sql } FROM ({ ibis_sql } ) AS `t`"
92100
93101 # Single row frames may not have any ordering columns
94102 if len (order_by ) > 0 :
@@ -99,7 +107,7 @@ def to_sql(
99107 raise TypeError (f"Limit param: { limit } must be an int." )
100108 sql += f"\n LIMIT { limit } "
101109 else :
102- sql = ibis_bigquery .Backend ().compile (self . _to_ibis_expr () )
110+ sql = ibis_bigquery .Backend ().compile (ibis_table )
103111 return typing .cast (str , sql )
104112
105113 @property
0 commit comments