use crate::{LogicalPlan, NodeOp, PlanNode};
use super::OptimizerRule;
pub const DEFAULT_BROADCAST_THRESHOLD_ROWS: u64 = 1_000_000;
pub struct BroadcastAutoRule {
max_rows: u64,
}
impl BroadcastAutoRule {
pub fn new(max_rows: u64) -> Self {
Self { max_rows }
}
}
impl OptimizerRule for BroadcastAutoRule {
fn name(&self) -> &str {
"broadcast-auto"
}
fn apply(&self, plan: &LogicalPlan) -> Option<LogicalPlan> {
let nodes = plan.nodes();
let mut changed = false;
let mut new_nodes: Vec<PlanNode> = Vec::with_capacity(nodes.len());
for node in nodes {
let is_small_scan = matches!(node.op(), Some(NodeOp::Scan { .. }))
&& node.estimated_rows().is_some_and(|r| r <= self.max_rows);
if is_small_scan && !node.broadcast_eligible() {
changed = true;
new_nodes.push(node.clone().with_broadcast_eligible(true));
} else {
new_nodes.push(node.clone());
}
}
if !changed {
return None;
}
let mut new_plan = LogicalPlan::new(plan.name(), plan.kind());
for n in new_nodes {
new_plan = new_plan.with_node(n);
}
Some(new_plan)
}
}