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

Function rewrite_expr_to_prunable

datafusion/pruning/src/pruning_predicate.rs:1104–1179  ·  view source on GitHub ↗

This function is designed to rewrite the column_expr to ensure the column_expr is monotonically increasing. For example, 1. `col > 10` 2. `-col > 10` should be rewritten to `col < -10` 3. `!col = true` would be rewritten to `col = !true` 4. `abs(a - 10) > 0` not supported 5. `cast(can_prunable_expr) > 10` 6. `try_cast(can_prunable_expr) > 10` More rewrite rules are still in progress.

(
    column_expr: &PhysicalExprRef,
    op: Operator,
    scalar_expr: &PhysicalExprRef,
    schema: DFSchema,
)

Source from the content-addressed store, hash-verified

1102///
1103/// More rewrite rules are still in progress.
1104fn rewrite_expr_to_prunable(
1105 column_expr: &PhysicalExprRef,
1106 op: Operator,
1107 scalar_expr: &PhysicalExprRef,
1108 schema: DFSchema,
1109) -> Result<(PhysicalExprRef, Operator, PhysicalExprRef)> {
1110 if !is_compare_op(op) {
1111 return plan_err!("rewrite_expr_to_prunable only support compare expression");
1112 }
1113
1114 if column_expr.downcast_ref::<phys_expr::Column>().is_some() {
1115 // `col op lit()`
1116 Ok((Arc::clone(column_expr), op, Arc::clone(scalar_expr)))
1117 } else if let Some(cast) = column_expr.downcast_ref::<phys_expr::CastExpr>() {
1118 // `cast(col) op lit()`
1119 let (left, op, right) = rewrite_cast_child_to_prunable(
1120 cast.expr(),
1121 cast.cast_type(),
1122 op,
1123 scalar_expr,
1124 schema,
1125 )?;
1126 let left = Arc::new(phys_expr::CastExpr::new_with_target_field(
1127 left,
1128 Arc::clone(cast.target_field()),
1129 None,
1130 ));
1131 // PruningPredicate does not support pruning on nested fields yet.
1132 // End-to-end nested-field pruning also requires Parquet statistics
1133 // extraction to agree with PruningPredicate on a stats representation
1134 // for nested field expressions.
1135 Ok((left, op, right))
1136 } else if let Some(try_cast) = column_expr.downcast_ref::<phys_expr::TryCastExpr>() {
1137 // `try_cast(col) op lit()`
1138 let (left, op, right) = rewrite_cast_child_to_prunable(
1139 try_cast.expr(),
1140 try_cast.cast_type(),
1141 op,
1142 scalar_expr,
1143 schema,
1144 )?;
1145 let left = Arc::new(phys_expr::TryCastExpr::new(
1146 left,
1147 try_cast.cast_type().clone(),
1148 ));
1149 Ok((left, op, right))
1150 } else if let Some(neg) = column_expr.downcast_ref::<phys_expr::NegativeExpr>() {
1151 // `-col > lit()` --> `col < -lit()`
1152 let (left, op, right) =
1153 rewrite_expr_to_prunable(neg.arg(), op, scalar_expr, schema)?;
1154 let right = Arc::new(phys_expr::NegativeExpr::new(right));
1155 Ok((left, reverse_operator(op)?, right))
1156 } else if let Some(not) = column_expr.downcast_ref::<phys_expr::NotExpr>() {
1157 // `!col = true` --> `col = !true`
1158 if !matches!(
1159 op,
1160 Operator::Eq
1161 | Operator::NotEq

Callers 4

try_newMethod · 0.85

Calls 9

is_compare_opFunction · 0.85
newFunction · 0.85
reverse_operatorFunction · 0.85
target_fieldMethod · 0.80
exprMethod · 0.45
cast_typeMethod · 0.45
cloneMethod · 0.45
argMethod · 0.45

Tested by 2

Used in the wild real call sites across dependent graphs

searching dependent graphs…