use super::OptimizationRule;
use crate::error::DbxResult;
use crate::sql::planner::LogicalPlan;
pub struct SubqueryUnnestingRule;
impl OptimizationRule for SubqueryUnnestingRule {
fn name(&self) -> &str {
"SubqueryUnnesting"
}
fn apply(&self, plan: LogicalPlan) -> DbxResult<LogicalPlan> {
self.unnest(plan)
}
}
impl SubqueryUnnestingRule {
fn unnest(&self, plan: LogicalPlan) -> DbxResult<LogicalPlan> {
match plan {
LogicalPlan::Filter { input, predicate } => {
let optimized_input = self.unnest(*input)?;
Ok(LogicalPlan::Filter {
input: Box::new(optimized_input),
predicate,
})
}
LogicalPlan::Project { input, projections } => Ok(LogicalPlan::Project {
input: Box::new(self.unnest(*input)?),
projections,
}),
LogicalPlan::Aggregate {
input,
group_by,
aggregates,
mode,
} => Ok(LogicalPlan::Aggregate {
input: Box::new(self.unnest(*input)?),
group_by,
aggregates,
mode,
}),
LogicalPlan::Sort { input, order_by } => Ok(LogicalPlan::Sort {
input: Box::new(self.unnest(*input)?),
order_by,
}),
LogicalPlan::Limit {
input,
count,
offset,
} => Ok(LogicalPlan::Limit {
input: Box::new(self.unnest(*input)?),
count,
offset,
}),
LogicalPlan::Join {
left,
right,
join_type,
on,
} => Ok(LogicalPlan::Join {
left: Box::new(self.unnest(*left)?),
right: Box::new(self.unnest(*right)?),
join_type,
on,
}),
other => Ok(other),
}
}
}
#[cfg(test)]
mod tests {
}