I noticed that rules ProjectCalcMergeRule and FilterCalcMergeRule strictly dependent on LogicalCalc class (e.g. casting call.rel to LogicalCalc, using LogicalCalc.create method and etc). I suggest making them more generalized (like CalcMergeRule) and use only Project, Filter and Calc interfaces, which will expand the range of their applying.
1. In FilterCalcMergeRule get rid of casting to LogicalCalc and LogicalFilter:
2. In FilterCalcMergeRule and FilterCalcMergeRule replace LogicalCalc.create with calc.copy:
3. In ProjectCalcMergeRule replace the code:
with a simple one:
because special rule ProjectToCalcRule convert LogicalProject to LogicalCalc.