(
&self,
plan: LogicalPlan,
config: &dyn OptimizerConfig,
)
| 59 | } |
| 60 | |
| 61 | fn rewrite( |
| 62 | &self, |
| 63 | plan: LogicalPlan, |
| 64 | config: &dyn OptimizerConfig, |
| 65 | ) -> Result<Transformed<LogicalPlan>> { |
| 66 | let plan = plan |
| 67 | .map_subqueries(|subquery| { |
| 68 | subquery.transform_down(|p| self.rewrite(p, config)) |
| 69 | })? |
| 70 | .data; |
| 71 | |
| 72 | let LogicalPlan::Filter(filter) = plan else { |
| 73 | return Ok(Transformed::no(plan)); |
| 74 | }; |
| 75 | |
| 76 | if !has_subquery(&filter.predicate) { |
| 77 | return Ok(Transformed::no(LogicalPlan::Filter(filter))); |
| 78 | } |
| 79 | |
| 80 | let (with_subqueries, mut other_exprs): (Vec<_>, Vec<_>) = |
| 81 | split_conjunction_owned(filter.predicate) |
| 82 | .into_iter() |
| 83 | .partition(has_subquery); |
| 84 | |
| 85 | assert_or_internal_err!( |
| 86 | !with_subqueries.is_empty(), |
| 87 | "can not find expected subqueries in DecorrelatePredicateSubquery" |
| 88 | ); |
| 89 | |
| 90 | // iterate through all exists clauses in predicate, turning each into a join |
| 91 | let mut cur_input = Arc::unwrap_or_clone(filter.input); |
| 92 | let original_schema = cur_input.schema().columns(); |
| 93 | for subquery_expr in with_subqueries { |
| 94 | match extract_subquery_info(subquery_expr) { |
| 95 | // The subquery expression is at the top level of the filter |
| 96 | SubqueryPredicate::Top(subquery) => { |
| 97 | match build_join_top(&subquery, &cur_input, config.alias_generator())? |
| 98 | { |
| 99 | Some(plan) => cur_input = plan, |
| 100 | // If the subquery can not be converted to a Join, reconstruct the subquery expression and add it to the Filter |
| 101 | None => other_exprs.push(subquery.expr()), |
| 102 | } |
| 103 | } |
| 104 | // The subquery expression is embedded within another expression |
| 105 | SubqueryPredicate::Embedded(expr) => { |
| 106 | let (plan, expr_without_subqueries) = |
| 107 | rewrite_inner_subqueries(cur_input, expr, config)?; |
| 108 | cur_input = plan; |
| 109 | other_exprs.push(expr_without_subqueries); |
| 110 | } |
| 111 | } |
| 112 | } |
| 113 | |
| 114 | let expr = conjunction(other_exprs); |
| 115 | if let Some(expr) = expr { |
| 116 | let new_filter = Filter::try_new(expr, Arc::new(cur_input))?; |
| 117 | cur_input = LogicalPlan::Filter(new_filter); |
| 118 | } |
no test coverage detected