Skip to content

Commit f94a5d2

Browse files
cpcloudkszucs
authored andcommitted
feat(clickhouse): implement bit aggs
1 parent d5fd215 commit f94a5d2

File tree

2 files changed

+24
-9
lines changed

2 files changed

+24
-9
lines changed

ibis/backends/clickhouse/registry.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
import ibis
55
import ibis.common.exceptions as com
6+
import ibis.expr.datatypes as dt
67
import ibis.expr.operations as ops
78
import ibis.expr.types as ir
89
import ibis.util as util
@@ -591,6 +592,23 @@ def _cotangent(translator, expr):
591592
return f"cos({arg}) / sin({arg})"
592593

593594

595+
def _bit_agg(func):
596+
def compile(translator, expr):
597+
op = expr.op()
598+
raw_arg = op.arg
599+
arg = translator.translate(raw_arg)
600+
if not isinstance((type := raw_arg.type()), dt.UnsignedInteger):
601+
nbits = type._nbytes * 8
602+
arg = f"reinterpretAsUInt{nbits}({arg})"
603+
604+
if (where := op.where) is not None:
605+
return f"{func}If({arg}, {translator.translate(where)})"
606+
else:
607+
return f"{func}({arg})"
608+
609+
return compile
610+
611+
594612
# TODO: clickhouse uses different string functions
595613
# for ascii and utf-8 encodings,
596614

@@ -738,6 +756,9 @@ def _cotangent(translator, expr):
738756
ops.ArrayRepeat: _array_repeat_op,
739757
ops.ArraySlice: _array_slice_op,
740758
ops.Unnest: _unary("arrayJoin"),
759+
ops.BitAnd: _bit_agg("groupBitAnd"),
760+
ops.BitOr: _bit_agg("groupBitOr"),
761+
ops.BitXor: _bit_agg("groupBitXor"),
741762
}
742763

743764

ibis/backends/tests/test_aggregation.py

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -254,25 +254,19 @@ def test_aggregate_grouped(
254254
lambda t, where: t.bigint_col.bit_and(where=where),
255255
lambda t, where: np.bitwise_and.reduce(t.bigint_col[where].values),
256256
id='bit_and',
257-
marks=pytest.mark.notimpl(
258-
["clickhouse", "dask", "pandas", "sqlite"]
259-
),
257+
marks=pytest.mark.notimpl(["dask", "pandas", "sqlite"]),
260258
),
261259
param(
262260
lambda t, where: t.bigint_col.bit_or(where=where),
263261
lambda t, where: np.bitwise_or.reduce(t.bigint_col[where].values),
264262
id='bit_or',
265-
marks=pytest.mark.notimpl(
266-
["clickhouse", "dask", "pandas", "sqlite"]
267-
),
263+
marks=pytest.mark.notimpl(["dask", "pandas", "sqlite"]),
268264
),
269265
param(
270266
lambda t, where: t.bigint_col.bit_xor(where=where),
271267
lambda t, where: np.bitwise_xor.reduce(t.bigint_col[where].values),
272268
id='bit_xor',
273-
marks=pytest.mark.notimpl(
274-
["clickhouse", "dask", "pandas", "sqlite"]
275-
),
269+
marks=pytest.mark.notimpl(["dask", "pandas", "sqlite"]),
276270
),
277271
],
278272
)

0 commit comments

Comments
 (0)