| 271 | } |
| 272 | |
| 273 | fn evaluate(&self, batch: &RecordBatch) -> Result<ColumnarValue> { |
| 274 | use arrow::compute::kernels::numeric::*; |
| 275 | |
| 276 | // Evaluate left-hand side expression. |
| 277 | let lhs = self.left.evaluate(batch)?; |
| 278 | |
| 279 | // Check if we can apply short-circuit evaluation. |
| 280 | match check_short_circuit(&lhs, &self.op) { |
| 281 | ShortCircuitStrategy::None => {} |
| 282 | ShortCircuitStrategy::ReturnLeft => return Ok(lhs), |
| 283 | ShortCircuitStrategy::ReturnRight => { |
| 284 | let rhs = self.right.evaluate(batch)?; |
| 285 | return Ok(rhs); |
| 286 | } |
| 287 | ShortCircuitStrategy::PreSelection(selection) => { |
| 288 | // The function `evaluate_selection` was not called for filtering and calculation, |
| 289 | // as it takes into account cases where the selection contains null values. |
| 290 | let batch = filter_record_batch(batch, selection)?; |
| 291 | let right_ret = self.right.evaluate(&batch)?; |
| 292 | |
| 293 | match &right_ret { |
| 294 | ColumnarValue::Array(array) => { |
| 295 | // When the array on the right is all true or all false, skip the scatter process |
| 296 | let boolean_array = array.as_boolean(); |
| 297 | if boolean_array.null_count() == 0 && !boolean_array.has_false() { |
| 298 | return Ok(lhs); |
| 299 | } else if boolean_array.null_count() == 0 |
| 300 | && !boolean_array.has_true() |
| 301 | { |
| 302 | // If the right-hand array is returned at this point,the lengths will be inconsistent; |
| 303 | // returning a scalar can avoid this issue |
| 304 | return Ok(ColumnarValue::Scalar(ScalarValue::Boolean( |
| 305 | Some(false), |
| 306 | ))); |
| 307 | } |
| 308 | |
| 309 | return pre_selection_scatter(selection, Some(boolean_array)); |
| 310 | } |
| 311 | ColumnarValue::Scalar(scalar) => { |
| 312 | if let ScalarValue::Boolean(v) = scalar { |
| 313 | // When the scalar is true or false, skip the scatter process |
| 314 | if let Some(v) = v { |
| 315 | if *v { |
| 316 | return Ok(lhs); |
| 317 | } else { |
| 318 | return Ok(right_ret); |
| 319 | } |
| 320 | } else { |
| 321 | return pre_selection_scatter(selection, None); |
| 322 | } |
| 323 | } else { |
| 324 | return internal_err!( |
| 325 | "Expected boolean scalar value, found: {right_ret:?}" |
| 326 | ); |
| 327 | } |
| 328 | } |
| 329 | } |
| 330 | } |