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