Skip to content
This repository was archived by the owner on Apr 1, 2026. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
30e1eb6
Refactor IsNullOp and NotNullOp logic
google-labs-jules[bot] Jun 13, 2025
92870fd
Merge remote-tracking branch 'origin/main' into refactor-isnull-op
tswast Jul 8, 2025
1b711aa
fix circular imports
tswast Jul 8, 2025
7ede976
Merge remote-tracking branch 'origin/main' into refactor-isnull-op
tswast Jul 8, 2025
9c17725
bad merge
tswast Jul 8, 2025
78e4585
fix local pytest
tswast Jul 8, 2025
333f9e2
Merge branch 'main' into refactor-isnull-op
tswast Jul 8, 2025
53e0a3e
dont construct polars compiler if no polars
tswast Jul 8, 2025
65e9fd4
Merge remote-tracking branch 'origin/refactor-isnull-op' into refacto…
tswast Jul 8, 2025
360edb3
Merge remote-tracking branch 'origin/main' into refactor-isnull-op
tswast Jul 14, 2025
9cd1fde
limit scope to just splitting large files
tswast Jul 14, 2025
ec47c37
Update bigframes/core/compile/compiled.py
tswast Jul 15, 2025
a475b72
Merge branch 'main' into refactor-isnull-op
tswast Jul 15, 2025
5990732
Merge branch 'main' into refactor-isnull-op
tswast Jul 16, 2025
8adafdd
Merge remote-tracking branch 'origin/main' into refactor-isnull-op
tswast Aug 5, 2025
b1cf81c
revert unneeded circular import workaround
tswast Aug 5, 2025
57c1c98
Merge branch 'main' into refactor-isnull-op
tswast Aug 5, 2025
de5a12c
Merge remote-tracking branch 'origin/main' into refactor-isnull-op
tswast Aug 6, 2025
87fd788
combine null ops into generic_ops files
tswast Aug 6, 2025
6372a23
revert expression change
tswast Aug 6, 2025
ef06d65
Update bigframes/core/compile/polars/operations/__init__.py
tswast Aug 6, 2025
7c19d8b
skip polars test for old polars
tswast Aug 6, 2025
3d50dae
Merge remote-tracking branch 'origin/refactor-isnull-op' into refacto…
tswast Aug 6, 2025
7babc87
Update bigframes/core/compile/ibis_compiler/operations/__init__.py
tswast Aug 6, 2025
aa5c47d
add minversion to skips
tswast Aug 6, 2025
b56cbbd
Merge remote-tracking branch 'origin/refactor-isnull-op' into refacto…
tswast Aug 6, 2025
0c9802d
more skips
tswast Aug 6, 2025
a9152ba
Merge remote-tracking branch 'origin/main' into refactor-isnull-op
tswast Aug 6, 2025
c2f1ca8
fix minimum polars version detection
tswast Aug 6, 2025
863b8ed
update colab constraints
tswast Aug 6, 2025
f42800e
skip polars on 3.10
tswast Aug 6, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions bigframes/core/array_value.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,10 +37,10 @@
from bigframes.core.window_spec import WindowSpec
import bigframes.dtypes
import bigframes.exceptions as bfe
import bigframes.operations as ops
import bigframes.operations.aggregations as agg_ops

if typing.TYPE_CHECKING:
# Avoid circular imports.
import bigframes.operations.aggregations as agg_ops
from bigframes.session import Session

ORDER_ID_COLUMN = "bigframes_ordering_id"
Expand Down Expand Up @@ -185,6 +185,8 @@ def get_column_type(self, key: str) -> bigframes.dtypes.Dtype:

def row_count(self) -> ArrayValue:
"""Get number of rows in ArrayValue as a single-entry ArrayValue."""
import bigframes.operations.aggregations as agg_ops # Avoid circular imports.
Comment thread
tswast marked this conversation as resolved.
Outdated

return ArrayValue(
nodes.AggregateNode(
child=self.node,
Expand All @@ -200,6 +202,8 @@ def row_count(self) -> ArrayValue:
# Operations
def filter_by_id(self, predicate_id: str, keep_null: bool = False) -> ArrayValue:
"""Filter the table on a given expression, the predicate must be a boolean series aligned with the table expression."""
import bigframes.operations as ops # Avoid circular imports.

predicate: ex.Expression = ex.deref(predicate_id)
if keep_null:
predicate = ops.fillna_op.as_expr(predicate, ex.const(True))
Expand Down
11 changes: 9 additions & 2 deletions bigframes/core/compile/compiled.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@
import bigframes.core.compile.googlesql
import bigframes.core.compile.ibis_types
import bigframes.core.compile.scalar_op_compiler as op_compilers
import bigframes.core.compile.scalar_op_compiler as scalar_op_compiler
import bigframes.core.expression as ex
from bigframes.core.ordering import OrderingExpression
import bigframes.core.sql
Expand All @@ -45,6 +44,12 @@
op_compiler = op_compilers.scalar_op_compiler


# This must be the last import. Currently depending on side-effects.
# TODO(tswast): Refactor all ops to register in the same file as where they are
# defined so we don't need this.
import bigframes.core.compile.scalar_op_registry # noqa: F401,E402


# Ibis Implementations
class UnorderedIR:
def __init__(
Expand Down Expand Up @@ -679,13 +684,15 @@ def _join_condition(


def _as_groupable(value: ibis_types.Value):
from bigframes.core.compile import scalar_op_registry

# Some types need to be converted to another type to enable groupby
if value.type().is_float64():
return value.cast(ibis_dtypes.str)
elif value.type().is_geospatial():
return typing.cast(ibis_types.GeoSpatialColumn, value).as_binary()
elif value.type().is_json():
return scalar_op_compiler.to_json_string(value)
return scalar_op_registry.to_json_string(value)
else:
return value

Expand Down
5 changes: 3 additions & 2 deletions bigframes/core/compile/compiler.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@
import bigframes.core.compile.concat as concat_impl
import bigframes.core.compile.configs as configs
import bigframes.core.compile.explode
import bigframes.core.compile.scalar_op_compiler as compile_scalar
import bigframes.core.nodes as nodes
import bigframes.core.ordering as bf_ordering
import bigframes.core.rewrite as rewrites
Expand Down Expand Up @@ -178,6 +177,8 @@ def compile_readlocal(node: nodes.ReadLocalNode, *args):

@_compile_node.register
def compile_readtable(node: nodes.ReadTableNode, *args):
from bigframes.core.compile import scalar_op_registry

ibis_table = _table_to_ibis(
node.source, scan_cols=[col.source_id for col in node.scan_list.items]
)
Expand All @@ -188,7 +189,7 @@ def compile_readtable(node: nodes.ReadTableNode, *args):
scan_item.dtype == dtypes.JSON_DTYPE
and ibis_table[scan_item.source_id].type() == ibis_dtypes.string
):
json_column = compile_scalar.parse_json(
json_column = scalar_op_registry.parse_json(
ibis_table[scan_item.source_id]
).name(scan_item.source_id)
ibis_table = ibis_table.mutate(json_column)
Expand Down
8 changes: 0 additions & 8 deletions bigframes/core/compile/polars/compiler.py
Original file line number Diff line number Diff line change
Expand Up @@ -233,14 +233,6 @@ def _(self, op: ops.ScalarOp, input: pl.Expr) -> pl.Expr:
else:
return input.is_in(op.values) or input.is_null()

@compile_op.register(gen_ops.IsNullOp)
def _(self, op: ops.ScalarOp, input: pl.Expr) -> pl.Expr:
return input.is_null()

@compile_op.register(gen_ops.NotNullOp)
def _(self, op: ops.ScalarOp, input: pl.Expr) -> pl.Expr:
return input.is_not_null()

@compile_op.register(gen_ops.FillNaOp)
@compile_op.register(gen_ops.CoalesceOp)
def _(self, op: ops.ScalarOp, l_input: pl.Expr, r_input: pl.Expr) -> pl.Expr:
Expand Down
Loading
Loading