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,
)
| 1102 | /// |
| 1103 | /// More rewrite rules are still in progress. |
| 1104 | fn 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 |
searching dependent graphs…