MCPcopy Create free account
hub / github.com/apache/datafusion / nullable

Method nullable

datafusion/expr/src/expr_schema.rs:248–398  ·  view source on GitHub ↗

Returns the nullability of the expression based on [ExprSchema]. Note: [`DFSchema`] implements [ExprSchema]. [`DFSchema`]: datafusion_common::DFSchema # Errors This function errors when it is not possible to compute its nullability. This happens when the expression refers to a column that does not exist in the schema.

(&self, input_schema: &dyn ExprSchema)

Source from the content-addressed store, hash-verified

246 /// nullability. This happens when the expression refers to a
247 /// column that does not exist in the schema.
248 fn nullable(&self, input_schema: &dyn ExprSchema) -> Result<bool> {
249 match self {
250 Expr::Alias(Alias { expr, .. }) | Expr::Not(expr) | Expr::Negative(expr) => {
251 expr.nullable(input_schema)
252 }
253
254 Expr::InList(InList { expr, list, .. }) => {
255 // Avoid inspecting too many expressions.
256 const MAX_INSPECT_LIMIT: usize = 6;
257 // Stop if a nullable expression is found or an error occurs.
258 let has_nullable = std::iter::once(expr.as_ref())
259 .chain(list)
260 .take(MAX_INSPECT_LIMIT)
261 .find_map(|e| {
262 e.nullable(input_schema)
263 .map(|nullable| if nullable { Some(()) } else { None })
264 .transpose()
265 })
266 .transpose()?;
267 Ok(match has_nullable {
268 // If a nullable subexpression is found, the result may also be nullable.
269 Some(_) => true,
270 // If the list is too long, we assume it is nullable.
271 None if list.len() + 1 > MAX_INSPECT_LIMIT => true,
272 // All the subexpressions are non-nullable, so the result must be non-nullable.
273 _ => false,
274 })
275 }
276
277 Expr::Between(Between {
278 expr, low, high, ..
279 }) => Ok(expr.nullable(input_schema)?
280 || low.nullable(input_schema)?
281 || high.nullable(input_schema)?),
282
283 Expr::Column(c) => input_schema.nullable(c),
284 Expr::OuterReferenceColumn(field, _) => Ok(field.is_nullable()),
285 Expr::Literal(value, _) => Ok(value.is_null()),
286 Expr::Case(case) => {
287 let nullable_then = case
288 .when_then_expr
289 .iter()
290 .filter_map(|(w, t)| {
291 let is_nullable = match t.nullable(input_schema) {
292 Err(e) => return Some(Err(e)),
293 Ok(n) => n,
294 };
295
296 // Branches with a then expression that is not nullable do not impact the
297 // nullability of the case expression.
298 if !is_nullable {
299 return None;
300 }
301
302 // For case-with-expression assume all 'then' expressions are reachable
303 if case.expr.is_some() {
304 return Some(Ok(()));
305 }

Callers 1

to_fieldMethod · 0.45

Calls 14

evaluate_boundsFunction · 0.85
contains_valueMethod · 0.80
to_fieldMethod · 0.80
takeMethod · 0.45
as_refMethod · 0.45
mapMethod · 0.45
lenMethod · 0.45
is_nullableMethod · 0.45
is_nullMethod · 0.45
nextMethod · 0.45
iterMethod · 0.45

Tested by

no test coverage detected