use glaredb_error::Result;
use super::OptimizeRule;
use crate::logical::binder::bind_context::BindContext;
use crate::logical::operator::{LocationRequirement, LogicalOperator};
#[derive(Debug, Clone)]
pub struct LocationRule {}
impl OptimizeRule for LocationRule {
fn optimize(
&mut self,
_bind_context: &mut BindContext,
mut plan: LogicalOperator,
) -> Result<LogicalOperator> {
plan.walk_mut(
&mut |op| {
if op.location() == &LocationRequirement::Any {
return Ok(());
}
let loc = *op.location();
op.for_each_child_mut(&mut |child| {
if child.location() == &LocationRequirement::Any {
*child.location_mut() = loc;
}
Ok(())
})
},
&mut |op| {
if op.location() != &LocationRequirement::Any {
return Ok(());
}
let mut loc = None;
op.for_each_child_mut(&mut |child| {
if child.location() != &LocationRequirement::Any {
loc = Some(*child.location())
}
Ok(())
})?;
if let Some(loc) = loc {
*op.location_mut() = loc;
}
Ok(())
},
)?;
Ok(plan)
}
}