I think I fixed it from the last time, when I didn't swap the filters
correctly:

  public void onMatch(RelOptRuleCall call) {
    final Filter filter = call.rel(0);
    final Filter secFilter = call.rel(1);
    final LogicalFilter newFilter =
LogicalFilter.create(secFilter.getInput(), filter.getCondition());
    final LogicalFilter newSecFilter = LogicalFilter.create(newFilter,
secFilter.getCondition());
    call.transformTo(newSecFilter);
 }

I haven't thought of special cases, and for now it chooses to swap filter
according to the number of rows in the output (and selectivity of
operators). In the current cost model it makes a little difference, but in
a more accurate approximation of selectivities it could be very helpful for
optimizing the final plan.


2016-11-16 2:09 GMT+02:00 Julian Hyde <jh...@apache.org>:

> Can you log a JIRA case, and include the full error stack?
> (VolcanoRuleCall.java:236 is just a “re-throw”).
>
> > On Nov 15, 2016, at 3:59 PM, Γιώργος Θεοδωράκης <giwrgosrth...@gmail.com>
> wrote:
> >
> > Hello Julian,
> >
> > I get no matter what I do this exception:
> > Exception in thread "main" java.lang.AssertionError: Internal error:
> Error
> > while applying rule FilterPushThroughFilter, args
> > [rel#15:LogicalFilter.NONE.[[0]](input=rel#12:Subset#1.
> NONE.[0],condition==($1,
> > 5)), rel#11:LogicalFilter.NONE.[[0]](input=rel#10:Subset#0.NONE.[
> 0],condition=>($1,
> > 5))]
> > at org.apache.calcite.util.Util.newInternal(Util.java:792)
> > at org.apache.calcite.plan.volcano.VolcanoRuleCall.
> onMatch(VolcanoRuleCall
> > .java:236)
> > at org.apache.calcite.plan.volcano.VolcanoPlanner.
> findBestExp(VolcanoPlanner
> > .java:819)
> > at org.apache.calcite.tools.Programs$RuleSetProgram.run(
> Programs.java:334)
> > at org.apache.calcite.prepare.PlannerImpl.transform(
> PlannerImpl.java:308)
> > at calcite.planner.SaberPlanner.getLogicalPlan(SaberPlanner.java:287)
> > at calcite.Tester.main(Tester.java:68)
> > ...
> >
> > I try to use something like :
> >
> > final Filter filter = call.rel(0);
> > final Filter secFilter = call.rel(1);
> > final LogicalFilter newFilter = LogicalFilter.create(filter.getInput(),
> > secFilter.getCondition());
> > final LogicalFilter newSecFilter = LogicalFilter.create(newFilter,
> filter.
> > getCondition());
> > call.transformTo(newSecFilter);
> >
> > but nothing hapens. Volcano does nothing and Hep crushes. Also I think
> > RelBuilder doesn't try to merge them. Do you have any suggestions?
> >
> > Thanks,
> > George
> >
> > 2016-11-14 21:17 GMT+02:00 Julian Hyde <jh...@apache.org>:
> >
> >> You have two calls to “build”. That looks wrong, because “build” pops an
> >> entry off the stack.
> >>
> >> If your intention is to swap the filters then you should push them in
> the
> >> reverse order than you are currently pushing them.
> >>
> >> Lastly, RelBuilder.filter might try to merge consecutive filter nodes.
> If
> >> it does — and I don’t recall whether it does — your filter had better be
> >> flagged non-deterministic (or something) to prevent the merge from
> >> happening.
> >>
> >> Julian
> >>
> >>> On Nov 14, 2016, at 1:06 AM, Γιώργος Θεοδωράκης <
> giwrgosrth...@gmail.com>
> >> wrote:
> >>>
> >>> Hello,
> >>>
> >>> I want to create a rule that pushes a filter through another filter ( I
> >>> don't merge them) according to their selectivities to optimize the
> final
> >>> plan. I am using other rules as templates to create it but I keep
> getting
> >>> errors, as I haven't understood correctly the basics. I want to have
> >>> something like this :
> >>>
> >>> public void onMatch(RelOptRuleCall call) {
> >>>   final Filter filter = call.rel(0);
> >>>   final Filter secFilter = call.rel(1);
> >>>   final RelBuilder relBuilder = call.builder();
> >>>   relBuilder.push(filter)
> >>>   .filter(secFilter.getCondition())
> >>>   .build();
> >>>   call.transformTo(relBuilder.build());
> >>> }
> >>
> >>
>
>

Reply via email to