risingwave_frontend/optimizer/rule/
intersect_merge_rule.rs1use super::{BoxedRule, Rule};
16use crate::optimizer::PlanRef;
17use crate::optimizer::plan_node::{LogicalIntersect, PlanTreeNode};
18
19pub struct IntersectMergeRule {}
20impl Rule for IntersectMergeRule {
21 fn apply(&self, plan: PlanRef) -> Option<PlanRef> {
22 let top_intersect: &LogicalIntersect = plan.as_logical_intersect()?;
23 let top_all = top_intersect.all();
24 let mut new_inputs = vec![];
25 let mut has_merge = false;
26 for input in top_intersect.inputs() {
27 if let Some(bottom_intersect) = input.as_logical_intersect()
28 && bottom_intersect.all() == top_all
29 {
30 new_inputs.extend(bottom_intersect.inputs());
31 has_merge = true;
32 } else {
33 new_inputs.push(input);
34 }
35 }
36
37 if has_merge {
38 Some(top_intersect.clone_with_inputs(&new_inputs))
39 } else {
40 None
41 }
42 }
43}
44
45impl IntersectMergeRule {
46 pub fn create() -> BoxedRule {
47 Box::new(IntersectMergeRule {})
48 }
49}