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