diff --git a/crates/polars-core/src/frame/group_by/mod.rs b/crates/polars-core/src/frame/group_by/mod.rs index 2a5aa2c40e45..8d79b1992f44 100644 --- a/crates/polars-core/src/frame/group_by/mod.rs +++ b/crates/polars-core/src/frame/group_by/mod.rs @@ -875,22 +875,10 @@ pub enum GroupByMethod { Groups, NUnique, Quantile(f64, QuantileMethod), - Count { - include_nulls: bool, - }, + Count { include_nulls: bool }, Implode, Std(u8), Var(u8), - #[cfg(feature = "bitwise")] - Bitwise(GroupByBitwiseMethod), -} - -#[cfg(feature = "bitwise")] -#[derive(Copy, Clone, Debug)] -pub enum GroupByBitwiseMethod { - And, - Or, - Xor, } impl Display for GroupByMethod { @@ -913,27 +901,11 @@ impl Display for GroupByMethod { Implode => "list", Std(_) => "std", Var(_) => "var", - #[cfg(feature = "bitwise")] - Bitwise(t) => { - f.write_str("bitwise_")?; - return Display::fmt(t, f); - }, }; write!(f, "{s}") } } -#[cfg(feature = "bitwise")] -impl Display for GroupByBitwiseMethod { - fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { - match self { - Self::And => f.write_str("and"), - Self::Or => f.write_str("or"), - Self::Xor => f.write_str("xor"), - } - } -} - // Formatting functions used in eager and lazy code for renaming grouped columns pub fn fmt_group_by_column(name: &str, method: GroupByMethod) -> PlSmallStr { use GroupByMethod::*; @@ -954,8 +926,6 @@ pub fn fmt_group_by_column(name: &str, method: GroupByMethod) -> PlSmallStr { Quantile(quantile, _interpol) => format_pl_smallstr!("{name}_quantile_{quantile:.2}"), Std(_) => format_pl_smallstr!("{name}_agg_std"), Var(_) => format_pl_smallstr!("{name}_agg_var"), - #[cfg(feature = "bitwise")] - Bitwise(f) => format_pl_smallstr!("{name}_agg_bitwise_{f}"), } } diff --git a/crates/polars-expr/src/expressions/aggregation.rs b/crates/polars-expr/src/expressions/aggregation.rs index 883598789622..7f233cdbe63e 100644 --- a/crates/polars-expr/src/expressions/aggregation.rs +++ b/crates/polars-expr/src/expressions/aggregation.rs @@ -177,24 +177,6 @@ impl PhysicalExpr for AggregationExpr { .var_reduce(ddof) .map(|sc| sc.into_column(s.name().clone())), GroupByMethod::Quantile(_, _) => unimplemented!(), - #[cfg(feature = "bitwise")] - GroupByMethod::Bitwise(f) => match f { - GroupByBitwiseMethod::And => parallel_op_columns( - |s| s.and_reduce().map(|sc| sc.into_column(s.name().clone())), - s, - allow_threading, - ), - GroupByBitwiseMethod::Or => parallel_op_columns( - |s| s.or_reduce().map(|sc| sc.into_column(s.name().clone())), - s, - allow_threading, - ), - GroupByBitwiseMethod::Xor => parallel_op_columns( - |s| s.xor_reduce().map(|sc| sc.into_column(s.name().clone())), - s, - allow_threading, - ), - }, } } #[allow(clippy::ptr_arg)] @@ -429,16 +411,6 @@ impl PhysicalExpr for AggregationExpr { // implemented explicitly in AggQuantile struct unimplemented!() }, - #[cfg(feature = "bitwise")] - GroupByMethod::Bitwise(f) => { - let (c, groups) = ac.get_final_aggregation(); - let agg_c = match f { - GroupByBitwiseMethod::And => c.agg_and(&groups), - GroupByBitwiseMethod::Or => c.agg_or(&groups), - GroupByBitwiseMethod::Xor => c.agg_xor(&groups), - }; - AggregatedScalar(agg_c.with_name(keep_name)) - }, GroupByMethod::NanMin => { #[cfg(feature = "propagate_nans")] { diff --git a/crates/polars-expr/src/planner.rs b/crates/polars-expr/src/planner.rs index 9b5bc0a6a5b3..915cbca39188 100644 --- a/crates/polars-expr/src/planner.rs +++ b/crates/polars-expr/src/planner.rs @@ -386,8 +386,6 @@ fn create_physical_expr_inner( }, I::Std(_, ddof) => GBM::Std(*ddof), I::Var(_, ddof) => GBM::Var(*ddof), - #[cfg(feature = "bitwise")] - I::Bitwise(_, f) => GBM::Bitwise((*f).into()), I::AggGroups(_) => { polars_bail!(InvalidOperation: "agg groups expression only supported in aggregation context") }, diff --git a/crates/polars-plan/src/dsl/bitwise.rs b/crates/polars-plan/src/dsl/bitwise.rs index b9e66c2c632e..749bf51d32d2 100644 --- a/crates/polars-plan/src/dsl/bitwise.rs +++ b/crates/polars-plan/src/dsl/bitwise.rs @@ -1,6 +1,4 @@ -use std::sync::Arc; - -use super::{AggExpr, BitwiseAggFunction, BitwiseFunction, Expr, FunctionExpr}; +use super::{BitwiseFunction, Expr, FunctionExpr, FunctionFlags}; impl Expr { /// Evaluate the number of set bits. @@ -35,16 +33,28 @@ impl Expr { /// Perform an aggregation of bitwise ANDs pub fn bitwise_and(self) -> Self { - Expr::Agg(AggExpr::Bitwise(Arc::new(self), BitwiseAggFunction::And)) + self.apply_private(FunctionExpr::Bitwise(BitwiseFunction::And)) + .with_function_options(|mut options| { + options.flags |= FunctionFlags::RETURNS_SCALAR; + options + }) } /// Perform an aggregation of bitwise ORs pub fn bitwise_or(self) -> Self { - Expr::Agg(AggExpr::Bitwise(Arc::new(self), BitwiseAggFunction::Or)) + self.apply_private(FunctionExpr::Bitwise(BitwiseFunction::Or)) + .with_function_options(|mut options| { + options.flags |= FunctionFlags::RETURNS_SCALAR; + options + }) } /// Perform an aggregation of bitwise XORs pub fn bitwise_xor(self) -> Self { - Expr::Agg(AggExpr::Bitwise(Arc::new(self), BitwiseAggFunction::Xor)) + self.apply_private(FunctionExpr::Bitwise(BitwiseFunction::Xor)) + .with_function_options(|mut options| { + options.flags |= FunctionFlags::RETURNS_SCALAR; + options + }) } } diff --git a/crates/polars-plan/src/dsl/expr.rs b/crates/polars-plan/src/dsl/expr.rs index c28b1d5d329f..5851e0d20a2b 100644 --- a/crates/polars-plan/src/dsl/expr.rs +++ b/crates/polars-plan/src/dsl/expr.rs @@ -39,8 +39,6 @@ pub enum AggExpr { AggGroups(Arc), Std(Arc, u8), Var(Arc, u8), - #[cfg(feature = "bitwise")] - Bitwise(Arc, super::function_expr::BitwiseAggFunction), } impl AsRef for AggExpr { @@ -61,8 +59,6 @@ impl AsRef for AggExpr { AggGroups(e) => e, Std(e, _) => e, Var(e, _) => e, - #[cfg(feature = "bitwise")] - Bitwise(e, _) => e, } } } diff --git a/crates/polars-plan/src/dsl/function_expr/bitwise.rs b/crates/polars-plan/src/dsl/function_expr/bitwise.rs index 1f0be9247993..14531795e53f 100644 --- a/crates/polars-plan/src/dsl/function_expr/bitwise.rs +++ b/crates/polars-plan/src/dsl/function_expr/bitwise.rs @@ -9,7 +9,8 @@ use crate::dsl::FieldsMapper; use crate::map; #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] -#[derive(Clone, Copy, PartialEq, Debug, Eq, Hash)] +#[derive(Clone, Copy, PartialEq, Debug, Eq, Hash, IntoStaticStr)] +#[strum(serialize_all = "snake_case")] pub enum BitwiseFunction { CountOnes, CountZeros, @@ -19,12 +20,8 @@ pub enum BitwiseFunction { TrailingOnes, TrailingZeros, -} -#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] -#[derive(Clone, Copy, PartialEq, Debug, Eq, Hash, IntoStaticStr)] -#[strum(serialize_all = "snake_case")] -pub enum BitwiseAggFunction { + // Bitwise Aggregations And, Or, Xor, @@ -41,6 +38,10 @@ impl fmt::Display for BitwiseFunction { B::LeadingZeros => "leading_zeros", B::TrailingOnes => "trailing_ones", B::TrailingZeros => "trailing_zeros", + + B::And => "and", + B::Or => "or", + B::Xor => "xor", }; f.write_str(s) @@ -58,16 +59,10 @@ impl From for SpecialEq> { B::LeadingZeros => map!(leading_zeros), B::TrailingOnes => map!(trailing_ones), B::TrailingZeros => map!(trailing_zeros), - } - } -} -impl From for GroupByBitwiseMethod { - fn from(value: BitwiseAggFunction) -> Self { - match value { - BitwiseAggFunction::And => Self::And, - BitwiseAggFunction::Or => Self::Or, - BitwiseAggFunction::Xor => Self::Xor, + B::And => map!(reduce_and), + B::Or => map!(reduce_or), + B::Xor => map!(reduce_xor), } } } @@ -86,7 +81,17 @@ impl BitwiseFunction { polars_bail!(InvalidOperation: "dtype {} not supported in '{}' operation", dtype, self); } - Ok(DataType::UInt32) + match self { + Self::CountOnes | + Self::CountZeros | + Self::LeadingOnes | + Self::LeadingZeros | + Self::TrailingOnes | + Self::TrailingZeros => Ok(DataType::UInt32), + Self::And | + Self::Or | + Self::Xor => Ok(dtype.clone()), + } }) } } @@ -114,3 +119,15 @@ fn trailing_ones(c: &Column) -> PolarsResult { fn trailing_zeros(c: &Column) -> PolarsResult { c.try_apply_unary_elementwise(polars_ops::series::trailing_zeros) } + +fn reduce_and(c: &Column) -> PolarsResult { + c.and_reduce().map(|v| v.into_column(c.name().clone())) +} + +fn reduce_or(c: &Column) -> PolarsResult { + c.or_reduce().map(|v| v.into_column(c.name().clone())) +} + +fn reduce_xor(c: &Column) -> PolarsResult { + c.xor_reduce().map(|v| v.into_column(c.name().clone())) +} diff --git a/crates/polars-plan/src/dsl/function_expr/mod.rs b/crates/polars-plan/src/dsl/function_expr/mod.rs index d694fcd0409e..e25a60b5ca28 100644 --- a/crates/polars-plan/src/dsl/function_expr/mod.rs +++ b/crates/polars-plan/src/dsl/function_expr/mod.rs @@ -93,7 +93,7 @@ use serde::{Deserialize, Serialize}; pub(crate) use self::binary::BinaryFunction; #[cfg(feature = "bitwise")] -pub use self::bitwise::{BitwiseAggFunction, BitwiseFunction}; +pub use self::bitwise::BitwiseFunction; pub use self::boolean::BooleanFunction; #[cfg(feature = "business")] pub(super) use self::business::BusinessFunction; diff --git a/crates/polars-plan/src/plans/aexpr/mod.rs b/crates/polars-plan/src/plans/aexpr/mod.rs index f480e4ffc7bc..95dee57901e4 100644 --- a/crates/polars-plan/src/plans/aexpr/mod.rs +++ b/crates/polars-plan/src/plans/aexpr/mod.rs @@ -51,8 +51,6 @@ pub enum IRAggExpr { Count(Node, bool), Std(Node, u8), Var(Node, u8), - #[cfg(feature = "bitwise")] - Bitwise(Node, BitwiseAggFunction), AggGroups(Node), } @@ -67,8 +65,6 @@ impl Hash for IRAggExpr { method: interpol, .. } => interpol.hash(state), Self::Std(_, v) | Self::Var(_, v) => v.hash(state), - #[cfg(feature = "bitwise")] - Self::Bitwise(_, f) => f.hash(state), _ => {}, } } @@ -98,8 +94,6 @@ impl IRAggExpr { (Quantile { method: l, .. }, Quantile { method: r, .. }) => l == r, (Std(_, l), Std(_, r)) => l == r, (Var(_, l), Var(_, r)) => l == r, - #[cfg(feature = "bitwise")] - (Bitwise(_, l), Bitwise(_, r)) => l == r, _ => std::mem::discriminant(self) == std::mem::discriminant(other), } } @@ -133,8 +127,6 @@ impl From for GroupByMethod { Count(_, include_nulls) => GroupByMethod::Count { include_nulls }, Std(_, ddof) => GroupByMethod::Std(ddof), Var(_, ddof) => GroupByMethod::Var(ddof), - #[cfg(feature = "bitwise")] - Bitwise(_, f) => GroupByMethod::Bitwise(f.into()), AggGroups(_) => GroupByMethod::Groups, Quantile { .. } => unreachable!(), } diff --git a/crates/polars-plan/src/plans/aexpr/schema.rs b/crates/polars-plan/src/plans/aexpr/schema.rs index e273c1818f35..fad154c216ee 100644 --- a/crates/polars-plan/src/plans/aexpr/schema.rs +++ b/crates/polars-plan/src/plans/aexpr/schema.rs @@ -301,13 +301,6 @@ impl AExpr { float_type(&mut field); Ok(field) }, - #[cfg(feature = "bitwise")] - Bitwise(expr, _) => { - *agg_list = false; - let field = ctx.arena.get(*expr).to_field_impl(ctx, &mut false)?; - // @Q? Do we need to coerce here? - Ok(field) - }, } }, Cast { expr, dtype, .. } => { diff --git a/crates/polars-plan/src/plans/aexpr/traverse.rs b/crates/polars-plan/src/plans/aexpr/traverse.rs index 3850cbafca6e..80277619a9a3 100644 --- a/crates/polars-plan/src/plans/aexpr/traverse.rs +++ b/crates/polars-plan/src/plans/aexpr/traverse.rs @@ -184,8 +184,6 @@ impl IRAggExpr { Std(input, _) => Single(*input), Var(input, _) => Single(*input), AggGroups(input) => Single(*input), - #[cfg(feature = "bitwise")] - Bitwise(input, _) => Single(*input), } } pub fn set_input(&mut self, input: Node) { @@ -205,8 +203,6 @@ impl IRAggExpr { Std(input, _) => input, Var(input, _) => input, AggGroups(input) => input, - #[cfg(feature = "bitwise")] - Bitwise(input, _) => input, }; *node = input; } diff --git a/crates/polars-plan/src/plans/conversion/expr_to_ir.rs b/crates/polars-plan/src/plans/conversion/expr_to_ir.rs index d3e0c17f8098..b66b2df35aa9 100644 --- a/crates/polars-plan/src/plans/conversion/expr_to_ir.rs +++ b/crates/polars-plan/src/plans/conversion/expr_to_ir.rs @@ -257,11 +257,6 @@ pub(super) fn to_aexpr_impl( AggExpr::AggGroups(expr) => { IRAggExpr::AggGroups(to_aexpr_impl_materialized_lit(owned(expr), arena, state)?) }, - #[cfg(feature = "bitwise")] - AggExpr::Bitwise(expr, f) => IRAggExpr::Bitwise( - to_aexpr_impl_materialized_lit(owned(expr), arena, state)?, - f, - ), }; AExpr::Agg(a_agg) }, diff --git a/crates/polars-plan/src/plans/conversion/ir_to_dsl.rs b/crates/polars-plan/src/plans/conversion/ir_to_dsl.rs index 160b70951962..bee5cd3b8b4d 100644 --- a/crates/polars-plan/src/plans/conversion/ir_to_dsl.rs +++ b/crates/polars-plan/src/plans/conversion/ir_to_dsl.rs @@ -160,11 +160,6 @@ pub fn node_to_expr(node: Node, expr_arena: &Arena) -> Expr { let expr = node_to_expr(expr, expr_arena); AggExpr::Count(Arc::new(expr), include_nulls).into() }, - #[cfg(feature = "bitwise")] - IRAggExpr::Bitwise(expr, f) => { - let expr = node_to_expr(expr, expr_arena); - AggExpr::Bitwise(Arc::new(expr), f).into() - }, }, AExpr::Ternary { predicate, diff --git a/crates/polars-plan/src/plans/format.rs b/crates/polars-plan/src/plans/format.rs index c72cfad20e39..d39f3dd35cc9 100644 --- a/crates/polars-plan/src/plans/format.rs +++ b/crates/polars-plan/src/plans/format.rs @@ -120,16 +120,6 @@ impl fmt::Debug for Expr { Var(expr, _) => write!(f, "{expr:?}.var()"), Std(expr, _) => write!(f, "{expr:?}.std()"), Quantile { expr, .. } => write!(f, "{expr:?}.quantile()"), - #[cfg(feature = "bitwise")] - Bitwise(expr, t) => { - let t = match t { - BitwiseAggFunction::And => "and", - BitwiseAggFunction::Or => "or", - BitwiseAggFunction::Xor => "xor", - }; - - write!(f, "{expr:?}.bitwise.{t}()") - }, } }, Cast { diff --git a/crates/polars-plan/src/plans/ir/format.rs b/crates/polars-plan/src/plans/ir/format.rs index 89ce6763bba9..a0373499a00c 100644 --- a/crates/polars-plan/src/plans/ir/format.rs +++ b/crates/polars-plan/src/plans/ir/format.rs @@ -591,16 +591,6 @@ impl Display for ExprIRDisplay<'_> { Var(expr, _) => write!(f, "{}.var()", self.with_root(expr)), Std(expr, _) => write!(f, "{}.std()", self.with_root(expr)), Quantile { expr, .. } => write!(f, "{}.quantile()", self.with_root(expr)), - #[cfg(feature = "bitwise")] - Bitwise(expr, t) => { - let t = match t { - BitwiseAggFunction::And => "and", - BitwiseAggFunction::Or => "or", - BitwiseAggFunction::Xor => "xor", - }; - - write!(f, "{}.bitwise.{t}()", self.with_root(expr)) - }, } }, Cast { diff --git a/crates/polars-plan/src/plans/iterator.rs b/crates/polars-plan/src/plans/iterator.rs index 997e38fa9d12..2dc13870b553 100644 --- a/crates/polars-plan/src/plans/iterator.rs +++ b/crates/polars-plan/src/plans/iterator.rs @@ -56,8 +56,6 @@ macro_rules! push_expr { AggGroups(e) => $push($c, e), Std(e, _) => $push($c, e), Var(e, _) => $push($c, e), - #[cfg(feature = "bitwise")] - Bitwise(e, _) => $push($c, e), } }, Ternary { diff --git a/crates/polars-plan/src/plans/visitor/expr.rs b/crates/polars-plan/src/plans/visitor/expr.rs index 62a64319ae2e..fd5b17f8a7fe 100644 --- a/crates/polars-plan/src/plans/visitor/expr.rs +++ b/crates/polars-plan/src/plans/visitor/expr.rs @@ -72,8 +72,6 @@ impl TreeWalker for Expr { AggGroups(x) => AggGroups(am(x, f)?), Std(x, ddf) => Std(am(x, f)?, ddf), Var(x, ddf) => Var(am(x, f)?, ddf), - #[cfg(feature = "bitwise")] - Bitwise(x, t) => Bitwise(am(x, f)?, t), }), Ternary { predicate, truthy, falsy } => Ternary { predicate: am(predicate, &mut f)?, truthy: am(truthy, &mut f)?, falsy: am(falsy, f)? }, Function { input, function, options } => Function { input: input.into_iter().map(f).collect::>()?, function, options }, diff --git a/crates/polars-python/src/lazyframe/visitor/expr_nodes.rs b/crates/polars-python/src/lazyframe/visitor/expr_nodes.rs index 604398d78857..d477d076e2e4 100644 --- a/crates/polars-python/src/lazyframe/visitor/expr_nodes.rs +++ b/crates/polars-python/src/lazyframe/visitor/expr_nodes.rs @@ -764,11 +764,6 @@ pub(crate) fn into_py(py: Python<'_>, expr: &AExpr) -> PyResult { arguments: vec![n.0], options: py.None(), }, - IRAggExpr::Bitwise(n, f) => Agg { - name: "bitwise".to_object(py), - arguments: vec![n.0], - options: Into::<&str>::into(f).to_object(py), - }, } .into_py(py), AExpr::Ternary { diff --git a/crates/polars-stream/src/physical_plan/lower_expr.rs b/crates/polars-stream/src/physical_plan/lower_expr.rs index 4d75fd98bfe5..5cd7e92cd620 100644 --- a/crates/polars-stream/src/physical_plan/lower_expr.rs +++ b/crates/polars-stream/src/physical_plan/lower_expr.rs @@ -584,12 +584,6 @@ fn lower_exprs_with_ctx( fallback_subset.push(ExprIR::new(expr, OutputName::Alias(out_name.clone()))); transformed_exprs.push(ctx.expr_arena.add(AExpr::Column(out_name))); }, - #[cfg(feature = "bitwise")] - IRAggExpr::Bitwise(_, _) => { - let out_name = unique_column_name(); - fallback_subset.push(ExprIR::new(expr, OutputName::Alias(out_name.clone()))); - transformed_exprs.push(ctx.expr_arena.add(AExpr::Column(out_name))); - }, }, AExpr::Len => { let out_name = unique_column_name();