Skip to content
This repository was archived by the owner on Apr 1, 2026. It is now read-only.

Commit 5562afd

Browse files
committed
Merge remote-tracking branch 'github/main' into garrettwu-load
2 parents 82c1916 + fbd3a55 commit 5562afd

File tree

16 files changed

+292
-235
lines changed

16 files changed

+292
-235
lines changed

.librarian/state.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
image: us-central1-docker.pkg.dev/cloud-sdk-librarian-prod/images-prod/python-librarian-generator@sha256:e7cc6823efb073a8a26e7cefdd869f12ec228abfbd2a44aa9a7eacc284023677
22
libraries:
33
- id: bigframes
4-
version: 2.33.0
4+
version: 2.34.0
55
last_generated_commit: ""
66
apis: []
77
source_roots:

CHANGELOG.md

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,22 @@
44

55
[1]: https://pypi.org/project/bigframes/#history
66

7+
## [2.34.0](https://github.com/googleapis/python-bigquery-dataframes/compare/v2.33.0...v2.34.0) (2026-02-02)
8+
9+
10+
### Features
11+
12+
* add `bigframes.pandas.options.experiments.sql_compiler` for switching the backend compiler (#2417) ([7eba6ee03f07938315d99e2aeaf72368c02074cf](https://github.com/googleapis/python-bigquery-dataframes/commit/7eba6ee03f07938315d99e2aeaf72368c02074cf))
13+
* add bigquery.ml.generate_embedding function (#2422) ([35f3f5e6f8c64b47e6e7214034f96f047785e647](https://github.com/googleapis/python-bigquery-dataframes/commit/35f3f5e6f8c64b47e6e7214034f96f047785e647))
14+
* add bigquery.create_external_table method (#2415) ([76db2956e505aec4f1055118ac7ca523facc10ff](https://github.com/googleapis/python-bigquery-dataframes/commit/76db2956e505aec4f1055118ac7ca523facc10ff))
15+
* add deprecation warnings for .blob accessor and read_gbq_object_table (#2408) ([7261a4ea5cdab6b30f5bc333501648c60e70be59](https://github.com/googleapis/python-bigquery-dataframes/commit/7261a4ea5cdab6b30f5bc333501648c60e70be59))
16+
* add bigquery.ml.generate_text function (#2403) ([5ac681028624de15e31f0c2ae360b47b2dcf1e8d](https://github.com/googleapis/python-bigquery-dataframes/commit/5ac681028624de15e31f0c2ae360b47b2dcf1e8d))
17+
18+
19+
### Bug Fixes
20+
21+
* broken job url (#2411) ([fcb5bc1761c656e1aec61dbcf96a36d436833b7a](https://github.com/googleapis/python-bigquery-dataframes/commit/fcb5bc1761c656e1aec61dbcf96a36d436833b7a))
22+
723
## [2.33.0](https://github.com/googleapis/python-bigquery-dataframes/compare/v2.32.0...v2.33.0) (2026-01-22)
824

925

bigframes/_config/experiment_options.py

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
# See the License for the specific language governing permissions and
1313
# limitations under the License.
1414

15-
from typing import Optional
15+
from typing import Literal, Optional
1616
import warnings
1717

1818
import bigframes
@@ -27,6 +27,7 @@ class ExperimentOptions:
2727
def __init__(self):
2828
self._semantic_operators: bool = False
2929
self._ai_operators: bool = False
30+
self._sql_compiler: Literal["legacy", "stable", "experimental"] = "stable"
3031

3132
@property
3233
def semantic_operators(self) -> bool:
@@ -55,6 +56,24 @@ def ai_operators(self, value: bool):
5556
warnings.warn(msg, category=bfe.PreviewWarning)
5657
self._ai_operators = value
5758

59+
@property
60+
def sql_compiler(self) -> Literal["legacy", "stable", "experimental"]:
61+
return self._sql_compiler
62+
63+
@sql_compiler.setter
64+
def sql_compiler(self, value: Literal["legacy", "stable", "experimental"]):
65+
if value not in ["legacy", "stable", "experimental"]:
66+
raise ValueError(
67+
"sql_compiler must be one of 'legacy', 'stable', or 'experimental'"
68+
)
69+
if value == "experimental":
70+
msg = bfe.format_message(
71+
"The experimental SQL compiler is still under experiments, and is subject "
72+
"to change in the future."
73+
)
74+
warnings.warn(msg, category=FutureWarning)
75+
self._sql_compiler = value
76+
5877
@property
5978
def blob(self) -> bool:
6079
msg = bfe.format_message(

bigframes/bigquery/_operations/table.py

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@
1616

1717
from typing import Mapping, Optional, Union
1818

19-
import bigframes_vendored.constants
2019
import google.cloud.bigquery
2120
import pandas as pd
2221

@@ -94,9 +93,6 @@ def create_external_table(
9493
if session is None:
9594
bpd.read_gbq_query(sql)
9695
session = bpd.get_global_session()
97-
assert (
98-
session is not None
99-
), f"Missing connection to BigQuery. Please report how you encountered this error at {bigframes_vendored.constants.FEEDBACK_LINK}."
10096
else:
10197
session.read_gbq_query(sql)
10298

bigframes/core/compile/__init__.py

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,28 @@
1313
# limitations under the License.
1414
from __future__ import annotations
1515

16+
from typing import Any
17+
18+
from bigframes import options
1619
from bigframes.core.compile.api import test_only_ibis_inferred_schema
1720
from bigframes.core.compile.configs import CompileRequest, CompileResult
18-
from bigframes.core.compile.ibis_compiler.ibis_compiler import compile_sql
21+
22+
23+
def compiler() -> Any:
24+
"""Returns the appropriate compiler module based on session options."""
25+
if options.experiments.sql_compiler == "experimental":
26+
import bigframes.core.compile.sqlglot.compiler as sqlglot_compiler
27+
28+
return sqlglot_compiler
29+
else:
30+
import bigframes.core.compile.ibis_compiler.ibis_compiler as ibis_compiler
31+
32+
return ibis_compiler
33+
1934

2035
__all__ = [
2136
"test_only_ibis_inferred_schema",
22-
"compile_sql",
2337
"CompileRequest",
2438
"CompileResult",
39+
"compiler",
2540
]

bigframes/core/compile/configs.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,3 +34,4 @@ class CompileResult:
3434
sql: str
3535
sql_schema: typing.Sequence[google.cloud.bigquery.SchemaField]
3636
row_order: typing.Optional[ordering.RowOrdering]
37+
encoded_type_refs: str

bigframes/core/compile/ibis_compiler/ibis_compiler.py

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
import bigframes.core.compile.concat as concat_impl
3030
import bigframes.core.compile.configs as configs
3131
import bigframes.core.compile.explode
32+
from bigframes.core.logging import data_types as data_type_logger
3233
import bigframes.core.nodes as nodes
3334
import bigframes.core.ordering as bf_ordering
3435
import bigframes.core.rewrite as rewrites
@@ -56,23 +57,30 @@ def compile_sql(request: configs.CompileRequest) -> configs.CompileResult:
5657
)
5758
if request.sort_rows:
5859
result_node = cast(nodes.ResultNode, rewrites.column_pruning(result_node))
60+
encoded_type_refs = data_type_logger.encode_type_refs(result_node)
5961
sql = compile_result_node(result_node)
6062
return configs.CompileResult(
61-
sql, result_node.schema.to_bigquery(), result_node.order_by
63+
sql,
64+
result_node.schema.to_bigquery(),
65+
result_node.order_by,
66+
encoded_type_refs,
6267
)
6368

6469
ordering: Optional[bf_ordering.RowOrdering] = result_node.order_by
6570
result_node = dataclasses.replace(result_node, order_by=None)
6671
result_node = cast(nodes.ResultNode, rewrites.column_pruning(result_node))
6772
result_node = cast(nodes.ResultNode, rewrites.defer_selection(result_node))
73+
encoded_type_refs = data_type_logger.encode_type_refs(result_node)
6874
sql = compile_result_node(result_node)
6975
# Return the ordering iff no extra columns are needed to define the row order
7076
if ordering is not None:
7177
output_order = (
7278
ordering if ordering.referenced_columns.issubset(result_node.ids) else None
7379
)
7480
assert (not request.materialize_all_order_keys) or (output_order is not None)
75-
return configs.CompileResult(sql, result_node.schema.to_bigquery(), output_order)
81+
return configs.CompileResult(
82+
sql, result_node.schema.to_bigquery(), output_order, encoded_type_refs
83+
)
7684

7785

7886
def _replace_unsupported_ops(node: nodes.BigFrameNode):

bigframes/core/compile/sqlglot/compiler.py

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
from bigframes.core.compile.sqlglot.expressions import typed_expr
3535
import bigframes.core.compile.sqlglot.scalar_compiler as scalar_compiler
3636
import bigframes.core.compile.sqlglot.sqlglot_ir as ir
37+
from bigframes.core.logging import data_types as data_type_logger
3738
import bigframes.core.ordering as bf_ordering
3839
from bigframes.core.rewrite import schema_binding
3940

@@ -59,23 +60,29 @@ def compile_sql(request: configs.CompileRequest) -> configs.CompileResult:
5960
)
6061
if request.sort_rows:
6162
result_node = typing.cast(nodes.ResultNode, rewrite.column_pruning(result_node))
63+
encoded_type_refs = data_type_logger.encode_type_refs(result_node)
6264
sql = _compile_result_node(result_node)
6365
return configs.CompileResult(
64-
sql, result_node.schema.to_bigquery(), result_node.order_by
66+
sql,
67+
result_node.schema.to_bigquery(),
68+
result_node.order_by,
69+
encoded_type_refs,
6570
)
6671

6772
ordering: typing.Optional[bf_ordering.RowOrdering] = result_node.order_by
6873
result_node = dataclasses.replace(result_node, order_by=None)
6974
result_node = typing.cast(nodes.ResultNode, rewrite.column_pruning(result_node))
75+
encoded_type_refs = data_type_logger.encode_type_refs(result_node)
7076
sql = _compile_result_node(result_node)
71-
7277
# Return the ordering iff no extra columns are needed to define the row order
7378
if ordering is not None:
7479
output_order = (
7580
ordering if ordering.referenced_columns.issubset(result_node.ids) else None
7681
)
7782
assert (not request.materialize_all_order_keys) or (output_order is not None)
78-
return configs.CompileResult(sql, result_node.schema.to_bigquery(), output_order)
83+
return configs.CompileResult(
84+
sql, result_node.schema.to_bigquery(), output_order, encoded_type_refs
85+
)
7986

8087

8188
def _remap_variables(

bigframes/formatting_helpers.py

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -200,10 +200,12 @@ def progress_callback(
200200
display_id=current_display_id,
201201
)
202202
elif isinstance(event, bigframes.core.events.ExecutionFinished):
203-
display.update_display(
204-
display.HTML(f"✅ Completed. {previous_display_html}"),
205-
display_id=current_display_id,
206-
)
203+
if previous_display_html:
204+
display.update_display(
205+
display.HTML(f"✅ Completed. {previous_display_html}"),
206+
display_id=current_display_id,
207+
)
208+
207209
elif isinstance(event, bigframes.core.events.SessionClosed):
208210
display.update_display(
209211
display.HTML(f"Session {event.session_id} closed."),

bigframes/session/bq_caching_executor.py

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -174,7 +174,9 @@ def to_sql(
174174
else array_value.node
175175
)
176176
node = self._substitute_large_local_sources(node)
177-
compiled = compile.compile_sql(compile.CompileRequest(node, sort_rows=ordered))
177+
compiled = compile.compiler().compile_sql(
178+
compile.CompileRequest(node, sort_rows=ordered)
179+
)
178180
return compiled.sql
179181

180182
def execute(
@@ -290,7 +292,9 @@ def _export_gbq(
290292
# validate destination table
291293
existing_table = self._maybe_find_existing_table(spec)
292294

293-
compiled = compile.compile_sql(compile.CompileRequest(plan, sort_rows=False))
295+
compiled = compile.compiler().compile_sql(
296+
compile.CompileRequest(plan, sort_rows=False)
297+
)
294298
sql = compiled.sql
295299

296300
if (existing_table is not None) and _if_schema_match(
@@ -318,6 +322,8 @@ def _export_gbq(
318322
clustering_fields=spec.cluster_cols if spec.cluster_cols else None,
319323
)
320324

325+
# Attach data type usage to the job labels
326+
job_config.labels["bigframes-dtypes"] = compiled.encoded_type_refs
321327
# TODO(swast): plumb through the api_name of the user-facing api that
322328
# caused this query.
323329
iterator, job = self._run_execute_query(
@@ -641,7 +647,7 @@ def _execute_plan_gbq(
641647
]
642648
cluster_cols = cluster_cols[:_MAX_CLUSTER_COLUMNS]
643649

644-
compiled = compile.compile_sql(
650+
compiled = compile.compiler().compile_sql(
645651
compile.CompileRequest(
646652
plan,
647653
sort_rows=ordered,
@@ -661,6 +667,8 @@ def _execute_plan_gbq(
661667
)
662668
job_config.destination = destination_table
663669

670+
# Attach data type usage to the job labels
671+
job_config.labels["bigframes-dtypes"] = compiled.encoded_type_refs
664672
iterator, query_job = self._run_execute_query(
665673
sql=compiled.sql,
666674
job_config=job_config,

0 commit comments

Comments
 (0)