cmu-db / optd

CMU-DB's Cascades optimizer framework
https://cmu-db.github.io/optd/
MIT License
383 stars 22 forks source link

Rule macro refactor to support predicates #222

Closed jurplel closed 3 weeks ago

jurplel commented 3 weeks ago

Seeking design feedback.

Implemented on eliminate_limit, not tested with anything yet.

Example expansion:

define_rule!(
    EliminateLimitRule,
    apply_eliminate_limit,
    (Limit, [child], [skip, fetch])
);

->

// Recursive expansion of define_rule! macro
// ==========================================

pub struct EliminateLimitRule {
    matcher:RuleMatcher<DfNodeType>,
}
impl EliminateLimitRule {
    pub fn new() -> Self {
        #[allow(unused_imports)]
        use DfNodeType::*;
        let mut pick_num = 0;
        let matcher = RuleMatcher::MatchNode {
            typ:Limit,children:(<[_]>::into_vec(#[rustc_box]
            alloc::boxed::Box::new([(RuleMatcher::PickOne {
                pick_to:{
                    let x = pick_num;
                    pick_num+=1;
                    x
                },
            })]))),predicates:(<[_]>::into_vec(#[rustc_box]
            alloc::boxed::Box::new([(RuleMatcher::PickPred),(RuleMatcher::PickPred)]))),
        };
        let _ = pick_num;
        Self {
            matcher
        }
    }

    }
pub struct EliminateLimitRulePicks {
    pub child:PlanNodeOrGroup<DfNodeType>,pub skip:ArcPredNode<DfNodeType>,pub fetch:ArcPredNode<DfNodeType>,
}
impl <O:Optimizer<DfNodeType>>Rule<DfNodeType,O>for EliminateLimitRule {
    fn matcher(&self) ->  &RuleMatcher<DfNodeType>{
        &self.matcher
    }
    fn apply(&self,optimizer: &O,mut input:HashMap<usize,PlanNodeOrGroup<DfNodeType>>,mut pred_input:HashMap<usize,ArcPredNode<DfNodeType>>,) -> Vec<PlanNode<DfNodeType>>{
        let child:PlanNodeOrGroup<DfNodeType>;
        ;
        let skip:ArcPredNode<DfNodeType>;
        ;
        let fetch:ArcPredNode<DfNodeType>;
        ;
        ;
        let mut pick_num = 0;
        let mut pred_pick_num = 0;
        {
            child = input.remove(&pick_num).unwrap();
            pick_num+=1;
        };
        {
            skip = pred_input.remove(&pred_pick_num).unwrap();
            pred_pick_num+=1;
        };
        {
            fetch = pred_input.remove(&pred_pick_num).unwrap();
            pred_pick_num+=1;
        };
        ;
        let res;
        res = pub struct EliminateLimitRulePicks {
            child,skip,fetch,
        };
        let _ = pick_num;
        apply_eliminate_limit(optimizer,res)
    }
    fn name(&self) ->  &'static str {
        "eliminate_limit_rule"
    }
    fn is_impl_rule(&self) -> bool {
        false
    }

    }