Path: blob/main/crates/polars-plan/src/plans/aexpr/function_expr/boolean.rs
7889 views
use polars_core::utils::SuperTypeFlags;1#[cfg(feature = "is_close")]2use polars_utils::total_ord::TotalOrdWrap;34use super::*;56#[cfg_attr(feature = "ir_serde", derive(serde::Serialize, serde::Deserialize))]7#[derive(Clone, PartialEq, Debug, Eq, Hash)]8pub enum IRBooleanFunction {9Any {10ignore_nulls: bool,11},12All {13ignore_nulls: bool,14},15IsNull,16IsNotNull,17IsFinite,18IsInfinite,19IsNan,20IsNotNan,21#[cfg(feature = "is_first_distinct")]22IsFirstDistinct,23#[cfg(feature = "is_last_distinct")]24IsLastDistinct,25#[cfg(feature = "is_unique")]26IsUnique,27#[cfg(feature = "is_unique")]28IsDuplicated,29#[cfg(feature = "is_between")]30IsBetween {31closed: ClosedInterval,32},33#[cfg(feature = "is_in")]34IsIn {35nulls_equal: bool,36},37#[cfg(feature = "is_close")]38IsClose {39abs_tol: TotalOrdWrap<f64>,40rel_tol: TotalOrdWrap<f64>,41nans_equal: bool,42},43AllHorizontal,44AnyHorizontal,45// Also bitwise negate46Not,47}4849impl IRBooleanFunction {50pub(super) fn get_field(&self, mapper: FieldsMapper) -> PolarsResult<Field> {51match self {52IRBooleanFunction::Not => {53mapper.try_map_dtype(|dtype| {54match dtype {55DataType::Boolean => Ok(DataType::Boolean),56dt if dt.is_integer() => Ok(dt.clone()),57dt => polars_bail!(InvalidOperation: "dtype {:?} not supported in 'not' operation", dt)58}59})6061},62_ => mapper.with_dtype(DataType::Boolean),63}64}6566pub fn function_options(&self) -> FunctionOptions {67use IRBooleanFunction as B;68match self {69B::Any { .. } | B::All { .. } => {70FunctionOptions::aggregation().flag(FunctionFlags::NON_ORDER_OBSERVING)71},72B::IsNull | B::IsNotNull => FunctionOptions::elementwise(),73B::IsFinite | B::IsInfinite | B::IsNan | B::IsNotNan => FunctionOptions::elementwise()74.with_flags(|f| f | FunctionFlags::PRESERVES_NULL_FIRST_INPUT),75#[cfg(feature = "is_first_distinct")]76B::IsFirstDistinct => FunctionOptions::length_preserving(),77#[cfg(feature = "is_last_distinct")]78B::IsLastDistinct => FunctionOptions::length_preserving(),79#[cfg(feature = "is_unique")]80B::IsUnique => FunctionOptions::length_preserving(),81#[cfg(feature = "is_unique")]82B::IsDuplicated => FunctionOptions::length_preserving(),83#[cfg(feature = "is_between")]84B::IsBetween { .. } => FunctionOptions::elementwise()85.with_supertyping(86(SuperTypeFlags::default() & !SuperTypeFlags::ALLOW_PRIMITIVE_TO_STRING).into(),87)88.with_flags(|f| f | FunctionFlags::PRESERVES_NULL_ALL_INPUTS),89#[cfg(feature = "is_in")]90B::IsIn { nulls_equal } => FunctionOptions::elementwise()91.with_supertyping(Default::default())92.with_flags(|f| {93if !*nulls_equal {94f | FunctionFlags::PRESERVES_NULL_FIRST_INPUT95} else {96f97}98}),99#[cfg(feature = "is_close")]100B::IsClose { .. } => FunctionOptions::elementwise()101.with_supertyping(102(SuperTypeFlags::default() & !SuperTypeFlags::ALLOW_PRIMITIVE_TO_STRING).into(),103)104.with_flags(|f| f | FunctionFlags::PRESERVES_NULL_ALL_INPUTS),105B::AllHorizontal | B::AnyHorizontal => FunctionOptions::elementwise().with_flags(|f| {106f | FunctionFlags::INPUT_WILDCARD_EXPANSION | FunctionFlags::ALLOW_EMPTY_INPUTS107}),108B::Not => FunctionOptions::elementwise()109.with_flags(|f| f | FunctionFlags::PRESERVES_NULL_FIRST_INPUT),110}111}112}113114impl Display for IRBooleanFunction {115fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {116use IRBooleanFunction::*;117let s = match self {118All { .. } => "all",119Any { .. } => "any",120IsNull => "is_null",121IsNotNull => "is_not_null",122IsFinite => "is_finite",123IsInfinite => "is_infinite",124IsNan => "is_nan",125IsNotNan => "is_not_nan",126#[cfg(feature = "is_first_distinct")]127IsFirstDistinct => "is_first_distinct",128#[cfg(feature = "is_last_distinct")]129IsLastDistinct => "is_last_distinct",130#[cfg(feature = "is_unique")]131IsUnique => "is_unique",132#[cfg(feature = "is_unique")]133IsDuplicated => "is_duplicated",134#[cfg(feature = "is_between")]135IsBetween { .. } => "is_between",136#[cfg(feature = "is_in")]137IsIn { .. } => "is_in",138#[cfg(feature = "is_close")]139IsClose { .. } => "is_close",140AnyHorizontal => "any_horizontal",141AllHorizontal => "all_horizontal",142Not => "not",143};144write!(f, "{s}")145}146}147148impl From<IRBooleanFunction> for IRFunctionExpr {149fn from(func: IRBooleanFunction) -> Self {150IRFunctionExpr::Boolean(func)151}152}153154155