Translate logical filter expression into pruning predicate expression that will evaluate to FALSE if it can be determined no rows between the min/max values could pass the predicates. Any predicates that can not be translated will be passed to `unhandled_hook`. Returns the pruning predicate as an [`PhysicalExpr`] Notice: Does not handle [`phys_expr::InListExpr`] greater than 20, which will fall
(
expr: &Arc<dyn PhysicalExpr>,
schema: &SchemaRef,
required_columns: &mut RequiredColumns,
unhandled_hook: &Arc<dyn UnhandledPredicateHook>,
)
| 1425 | /// |
| 1426 | /// Notice: Does not handle [`phys_expr::InListExpr`] greater than 20, which will fall back to calling `unhandled_hook` |
| 1427 | fn build_predicate_expression( |
| 1428 | expr: &Arc<dyn PhysicalExpr>, |
| 1429 | schema: &SchemaRef, |
| 1430 | required_columns: &mut RequiredColumns, |
| 1431 | unhandled_hook: &Arc<dyn UnhandledPredicateHook>, |
| 1432 | ) -> Arc<dyn PhysicalExpr> { |
| 1433 | if is_always_false(expr) { |
| 1434 | // Shouldn't return `unhandled_hook.handle(expr)` |
| 1435 | // Because it will transfer false to true. |
| 1436 | return Arc::clone(expr); |
| 1437 | } |
| 1438 | // predicate expression can only be a binary expression |
| 1439 | if let Some(is_null) = expr.downcast_ref::<phys_expr::IsNullExpr>() { |
| 1440 | return build_is_null_column_expr(is_null.arg(), schema, required_columns, false) |
| 1441 | .unwrap_or_else(|| unhandled_hook.handle(expr)); |
| 1442 | } |
| 1443 | if let Some(is_not_null) = expr.downcast_ref::<phys_expr::IsNotNullExpr>() { |
| 1444 | return build_is_null_column_expr( |
| 1445 | is_not_null.arg(), |
| 1446 | schema, |
| 1447 | required_columns, |
| 1448 | true, |
| 1449 | ) |
| 1450 | .unwrap_or_else(|| unhandled_hook.handle(expr)); |
| 1451 | } |
| 1452 | if let Some(col) = expr.downcast_ref::<phys_expr::Column>() { |
| 1453 | return build_single_column_expr(col, schema, required_columns, false) |
| 1454 | .unwrap_or_else(|| unhandled_hook.handle(expr)); |
| 1455 | } |
| 1456 | if let Some(not) = expr.downcast_ref::<phys_expr::NotExpr>() { |
| 1457 | // match !col (don't do so recursively) |
| 1458 | if let Some(col) = not.arg().downcast_ref::<phys_expr::Column>() { |
| 1459 | return build_single_column_expr(col, schema, required_columns, true) |
| 1460 | .unwrap_or_else(|| unhandled_hook.handle(expr)); |
| 1461 | } else { |
| 1462 | return unhandled_hook.handle(expr); |
| 1463 | } |
| 1464 | } |
| 1465 | if let Some(in_list) = expr.downcast_ref::<phys_expr::InListExpr>() { |
| 1466 | if !in_list.list().is_empty() |
| 1467 | && in_list.list().len() <= MAX_LIST_VALUE_SIZE_REWRITE |
| 1468 | { |
| 1469 | let eq_op = if in_list.negated() { |
| 1470 | Operator::NotEq |
| 1471 | } else { |
| 1472 | Operator::Eq |
| 1473 | }; |
| 1474 | let re_op = if in_list.negated() { |
| 1475 | Operator::And |
| 1476 | } else { |
| 1477 | Operator::Or |
| 1478 | }; |
| 1479 | let change_expr = in_list |
| 1480 | .list() |
| 1481 | .iter() |
| 1482 | .map(|e| { |
| 1483 | Arc::new(phys_expr::BinaryExpr::new( |
| 1484 | Arc::clone(in_list.expr()), |
searching dependent graphs…