Julian

Thanks for your comment,  I am using Calcite 1.25 currently by the way.
Here is a simplified version of the code that runs the rule


@Override
  public RelRoot rel(SqlNode sql) {
    RelRoot root = super.rel(sql);
    root = applyInjectFilterRule(root, restriction);
    return root;
}

  private RelRoot applyInjectFilterRule(RelRoot root, Restriction
restriction) {
    final InjectFilterRule injectFilterRule =
            InjectFilterRule.Config.DEFAULT.toRule(restriction);

    final HepProgram program =
            HepProgram.builder().addRuleInstance(injectFilterRule).build();
    HepPlanner prePlanner = new HepPlanner(program);
    prePlanner.setRoot(root.rel);
    final RelNode rootRelNode = prePlanner.findBestExp();
    return root.withRel(rootRelNode);
  }

Does this look reasonable?

I can produce a complete test program to try to reproduce in isolation if
nothing in this code jumps out.

thanks
Michael.

On Fri, Feb 12, 2021 at 3:43 PM Julian Hyde <[email protected]> wrote:

> It looks like you’ve defined it right. It should fire once for each
> LogicalTableScan in the plan.
>
> Make sure that you have registered a rule instance in the planner.
>
> > On Feb 11, 2021, at 11:19 PM, Michael Thomson <[email protected]>
> wrote:
> >
> > Hi,
> >
> > I suspect I am doing something wrong but it's not obvious to me and
> hoping
> > someone can spot what my issue is.
> >
> > I am trying to add a simple filter after detection of LogicalTableScans
> on
> > particular tables
> >
> > I have a rule that looks like this
> >
> > public interface Config extends RelRule.Config {
> >    Config DEFAULT =
> >            EMPTY.withOperandSupplier(b0 ->
> > b0.operand(LogicalTableScan.class).anyInputs())
> >                    .as(Config.class);
> >
> >    @Override
> >    default InjectFilterRule toRule() {
> >      return new InjectFilterRule(this, null);
> >    }
> >  }
> >
> > Everything works as expected with most sql
> >
> > but when using a subqueries like this
> >
> > select * from t6  where t6.t1 in (select t1 from t6);
> >
> > The result I see is
> >
> > LogicalProject(t1=[$0], i1=[$1])
> >  LogicalFilter(condition=[IN($0, {
> > LogicalProject(t1=[$0])
> >  LogicalTableScan(table=[[database, t6]])
> > })])
> >    LogicalFilter(condition=[OR(=($0, 'a'), =($0, 'b'), =($0, 'c'))])
> >      LogicalTableScan(table=[[database, t6]])
> >
> > You will note the bogus FILTER added to the first LogicalTableScan
> >
> > LogicalFilter(condition=[OR(=($0, 'a'), =($0, 'b'), =($0, 'c'))])
> >
> > but nothing was added to the one in the IN subquery
> >
> > When I look in the debug it seems the onMatch code never receives an
> > invocation for the subquery Scan.
> >
> > The rules are run as part of the planner.rel() call.
> >
> > Any ideas of what I am overlooking or misunderstanding would be much
> > appreciated
> >
> > thanks
> > Michael.
>
>

Reply via email to