Skip to content

Commit 876b504

Browse files
authored
Simplify comparisons and binary operations involving NULL (#17088)
* Use correct types for arithemtics in tests * Simplify comparisons and binary operations involving NULL There were optimizations simplifying some arithmetic operations (`*`, `/`, `%` and some bitwise operations) when one operand is constant `NULL`. This can be extended to almost all other binary operators. * Convert to method on Operator * Add clarifying comments to returns_null_on_null
1 parent 9463cf6 commit 876b504

File tree

8 files changed

+154
-199
lines changed

8 files changed

+154
-199
lines changed

datafusion/expr-common/src/operator.rs

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -328,6 +328,60 @@ impl Operator {
328328
Operator::Multiply | Operator::Divide | Operator::Modulo => 45,
329329
}
330330
}
331+
332+
/// Returns true if the `Expr::BinaryOperator` with this operator
333+
/// is guaranteed to return null if either side is null.
334+
pub fn returns_null_on_null(&self) -> bool {
335+
match self {
336+
Operator::Eq
337+
| Operator::NotEq
338+
| Operator::Lt
339+
| Operator::LtEq
340+
| Operator::Gt
341+
| Operator::GtEq
342+
| Operator::Plus
343+
| Operator::Minus
344+
| Operator::Multiply
345+
| Operator::Divide
346+
| Operator::Modulo
347+
| Operator::RegexMatch
348+
| Operator::RegexIMatch
349+
| Operator::RegexNotMatch
350+
| Operator::RegexNotIMatch
351+
| Operator::LikeMatch
352+
| Operator::ILikeMatch
353+
| Operator::NotLikeMatch
354+
| Operator::NotILikeMatch
355+
| Operator::BitwiseAnd
356+
| Operator::BitwiseOr
357+
| Operator::BitwiseXor
358+
| Operator::BitwiseShiftRight
359+
| Operator::BitwiseShiftLeft
360+
| Operator::AtArrow
361+
| Operator::ArrowAt
362+
| Operator::Arrow
363+
| Operator::LongArrow
364+
| Operator::HashArrow
365+
| Operator::HashLongArrow
366+
| Operator::AtAt
367+
| Operator::IntegerDivide
368+
| Operator::HashMinus
369+
| Operator::AtQuestion
370+
| Operator::Question
371+
| Operator::QuestionAnd
372+
| Operator::QuestionPipe => true,
373+
374+
// E.g. `TRUE OR NULL` is `TRUE`
375+
Operator::Or
376+
// E.g. `FALSE AND NULL` is `FALSE`
377+
| Operator::And
378+
// IS DISTINCT FROM and IS NOT DISTINCT FROM always return a TRUE/FALSE value, never NULL
379+
| Operator::IsDistinctFrom
380+
| Operator::IsNotDistinctFrom
381+
// DataFusion string concatenation operator treats NULL as an empty string
382+
| Operator::StringConcat => false,
383+
}
384+
}
331385
}
332386

333387
impl fmt::Display for Operator {

0 commit comments

Comments
 (0)