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.
>
>