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

Method rewrite

datafusion/optimizer/src/decorrelate_predicate_subquery.rs:61–127  ·  view source on GitHub ↗
(
        &self,
        plan: LogicalPlan,
        config: &dyn OptimizerConfig,
    )

Source from the content-addressed store, hash-verified

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 }

Callers 1

build_joinFunction · 0.45

Calls 15

has_subqueryFunction · 0.85
split_conjunction_ownedFunction · 0.85
extract_subquery_infoFunction · 0.85
build_join_topFunction · 0.85
rewrite_inner_subqueriesFunction · 0.85
newFunction · 0.85
map_subqueriesMethod · 0.80
transform_downMethod · 0.80
columnsMethod · 0.80
FilterClass · 0.50
conjunctionFunction · 0.50
partitionMethod · 0.45

Tested by

no test coverage detected