Determines if the given expression can evaluate to `NULL`. This method only returns sets containing `TRUE`, `FALSE`, or both.
(&self, expr: &Expr)
| 156 | /// |
| 157 | /// This method only returns sets containing `TRUE`, `FALSE`, or both. |
| 158 | fn is_null(&self, expr: &Expr) -> NullableInterval { |
| 159 | // Fast path for literals |
| 160 | if let Expr::Literal(scalar, _) = expr { |
| 161 | if scalar.is_null() { |
| 162 | return NullableInterval::TRUE; |
| 163 | } else { |
| 164 | return NullableInterval::FALSE; |
| 165 | } |
| 166 | } |
| 167 | |
| 168 | // If `expr` is not nullable, we can be certain `expr` is not null |
| 169 | if let Ok(false) = expr.nullable(self.input_schema) { |
| 170 | return NullableInterval::FALSE; |
| 171 | } |
| 172 | |
| 173 | // Check if the expression is the `certainly_null_expr` that was passed in. |
| 174 | if let Some(certainly_null_expr) = &self.certainly_null_expr |
| 175 | && expr.eq(certainly_null_expr) |
| 176 | { |
| 177 | return NullableInterval::TRUE; |
| 178 | } |
| 179 | |
| 180 | // `expr` is nullable, so our default answer for `is null` is going to be `{ TRUE, FALSE }`. |
| 181 | // Try to see if we can narrow it down to just one option. |
| 182 | match expr { |
| 183 | Expr::BinaryExpr(BinaryExpr { op, .. }) if op.returns_null_on_null() => { |
| 184 | self.is_null_if_any_child_null(expr) |
| 185 | } |
| 186 | Expr::Alias(_) |
| 187 | | Expr::Cast(_) |
| 188 | | Expr::Like(_) |
| 189 | | Expr::Negative(_) |
| 190 | | Expr::Not(_) |
| 191 | | Expr::SimilarTo(_) => self.is_null_if_any_child_null(expr), |
| 192 | Expr::Between(Between { |
| 193 | expr, low, high, .. |
| 194 | }) if self.is_null(expr).is_certainly_true() |
| 195 | || (self.is_null(low.as_ref()).is_certainly_true() |
| 196 | && self.is_null(high.as_ref()).is_certainly_true()) => |
| 197 | { |
| 198 | // Between is always null if the left side is null |
| 199 | // or both the low and high bounds are null |
| 200 | NullableInterval::TRUE |
| 201 | } |
| 202 | _ => NullableInterval::TRUE_OR_FALSE, |
| 203 | } |
| 204 | } |
| 205 | |
| 206 | fn is_null_if_any_child_null(&self, expr: &Expr) -> NullableInterval { |
| 207 | // These expressions are null if any of their direct children is null |
no test coverage detected