Hello team,
I am currently following a tutorial on VolcanoPlanner called  "Assembling a
query optimizer with Apache Calcite"[1].
But I am facing an issue with an error thrown.

The following method works OK with CalciteAssert.SchemaSpec.HR
    public RelNode costOptimize(RelNode relNode) {
        // volcano planner
        System.out.println("Logical plan:");
        RelOptCluster cluster = relNode.getCluster();
        VolcanoPlanner planner = (VolcanoPlanner) cluster.getPlanner();
        RelTraitSet desiredTraits =
cluster.traitSet().replace(EnumerableConvention.INSTANCE);
        relNode = planner.changeTraits(relNode, desiredTraits);
        planner.setRoot(relNode);
        RelNode optimized = planner.findBestExp();
        RelWriter rw = new RelWriterImpl(new PrintWriter(System.out, true));
        optimized.explain(rw);
        return optimized;
    }
It outputs the plan as expected.

But when I try to optimize one of my own tables, an implementation
of AbstractTable, the costOptimize method displays an error:
Logical plan:
Exception in thread "main" java.lang.AssertionError: Relational expression
rel#4:LogicalTableScan.NONE.[](table=[tutorial, role]) belongs to a
different planner than is currently being used.
        at
org.apache.calcite.plan.volcano.VolcanoPlanner.registerImpl(VolcanoPlanner.java:1251)
        at
org.apache.calcite.plan.volcano.VolcanoPlanner.register(VolcanoPlanner.java:599)
        at
org.apache.calcite.plan.volcano.VolcanoPlanner.ensureRegistered(VolcanoPlanner.java:614)
        at
org.apache.calcite.plan.volcano.VolcanoPlanner.ensureRegistered(VolcanoPlanner.java:95)
        at
org.apache.calcite.rel.AbstractRelNode.onRegister(AbstractRelNode.java:275)
        at
org.apache.calcite.plan.volcano.VolcanoPlanner.registerImpl(VolcanoPlanner.java:1274)
        at
org.apache.calcite.plan.volcano.VolcanoPlanner.register(VolcanoPlanner.java:599)
        at
org.apache.calcite.plan.volcano.VolcanoPlanner.ensureRegistered(VolcanoPlanner.java:614)
        at
org.apache.calcite.plan.volcano.VolcanoPlanner.ensureRegistered(VolcanoPlanner.java:95)
        at
org.apache.calcite.rel.AbstractRelNode.onRegister(AbstractRelNode.java:275)
        at
org.apache.calcite.plan.volcano.VolcanoPlanner.registerImpl(VolcanoPlanner.java:1274)
        at
org.apache.calcite.plan.volcano.VolcanoPlanner.register(VolcanoPlanner.java:599)
        at
org.apache.calcite.plan.volcano.VolcanoPlanner.ensureRegistered(VolcanoPlanner.java:614)
        at
org.apache.calcite.plan.volcano.VolcanoPlanner.changeTraits(VolcanoPlanner.java:499)
        at hugh.App.costOptimize(App.java:274)

If I make the suggested fix ("belongs to a different planner than is
currently being used"[2]) to use RelNode.copy
    public RelNode costOptimize(RelNode relNode) {
        // volcano planner
        System.out.println("Logical plan:");
        RelOptCluster cluster = relNode.getCluster();
        VolcanoPlanner planner = (VolcanoPlanner) cluster.getPlanner();
        RelTraitSet desiredTraits =
cluster.traitSet().replace(EnumerableConvention.INSTANCE);
        RelNode copy = relNode.copy(desiredTraits, List.of(relNode));
        copy = planner.changeTraits(copy, desiredTraits);
        planner.setRoot(copy);
        RelNode optimized = planner.findBestExp();
        RelWriter rw = new RelWriterImpl(new PrintWriter(System.out, true));
        optimized.explain(rw);
        return optimized;
    }

It then throws a different error
Exception in thread "main" java.lang.AssertionError: Relational expression
rel#10:LogicalFilter.ENUMERABLE.[](input=LogicalFilter#6,condition==($1,
'Smith')) has calling-convention ENUMERABLE but does not implement the
required interface 'interface
org.apache.calcite.adapter.enumerable.EnumerableRel' of that convention
        at
org.apache.calcite.plan.volcano.VolcanoPlanner.registerImpl(VolcanoPlanner.java:1265)
        at
org.apache.calcite.plan.volcano.VolcanoPlanner.register(VolcanoPlanner.java:599)
        at
org.apache.calcite.plan.volcano.VolcanoPlanner.ensureRegistered(VolcanoPlanner.java:614)
        at
org.apache.calcite.plan.volcano.VolcanoPlanner.changeTraits(VolcanoPlanner.java:499)
        at hugh.App.costOptimize(App.java:275)
        at hugh.App.driver(App.java:567)
        at hugh.App.main(App.java:574)

Any suggestions to get this working?

Kindest regards
From,
Hugh Pearse
Dublin.

References
1. "Assembling a query optimizer with Apache Calcite" -
https://www.querifylabs.com/blog/assembling-a-query-optimizer-with-apache-calcite
2. "belongs to a different planner than is currently being used" -
https://www.mail-archive.com/dev@calcite.apache.org/msg02939.html

Reply via email to