hi 丰斌,

The exception message has told you the reason:

> Missing conversion is LogicalTableScan[convention: NONE -> ENUMERABLE]


This is mostly because your `MyRelOptSchema` returns a `Table` that cannot
be transformed to Enumerable Convention. You can refer the code[1] to
see why your Table cannot satisfy the requirements.

[1]
https://github.com/apache/calcite/blob/94dc303ed0a5ccd4e4f972abf7a41f155cbe5546/core/src/main/java/org/apache/calcite/adapter/enumerable/EnumerableTableScanRule.java#L38


Julian Hyde <jhyde.apa...@gmail.com> 于2022年6月25日周六 00:40写道:

> I had to moderate your message. Can you subscribe to the list so that you
> receive updates.
>
> Julian
>
> > On Jun 24, 2022, at 09:37, 方丰斌 <8692182...@zju.edu.cn> wrote:
> >
> > Hey all,
> >
> >
> >
> >
> >    I'm trying to use VolcanoPlanner. I have encountered the following
> problems. I hope I can ask for some help. Thank you very much!
> >
> >    Test code:
> >
> > `````
> >
> >        VolcanoPlanner planner = new VolcanoPlanner();
> >        planner.addRelTraitDef(ConventionTraitDef.INSTANCE);
> >
> >        // Below two lines are important for the planner to use collation
> trait and generate merge join
> >        planner.addRelTraitDef(RelCollationTraitDef.INSTANCE);
> >        planner.registerAbstractRelationalRules();
> >
> >        planner.addRule(EnumerableRules.ENUMERABLE_TABLE_SCAN_RULE);
> >        planner.addRule(EnumerableRules.ENUMERABLE_PROJECT_RULE);
> >        planner.addRule(CoreRules.PROJECT_TABLE_SCAN);
> >
> >        RelOptCluster cluster = newCluster(planner);
> >
> >        // NOTE:I mock x MyRelOptSchema to ensure that the SQL
> verification is successful.
> >        MyRelOptSchema relOptSchema = new MyRelOptSchema();
> >        RelBuilder relBuilder =
> RelFactories.LOGICAL_BUILDER.create(cluster, relOptSchema);
> >        RelNode logicalPlan = relBuilder
> >                .scan("t1")
> >                .project(relBuilder.field("attr1"))
> >                .build();
> >
> >        RelTraitSet desiredTraits =
> >                cluster.traitSet().replace(EnumerableConvention.INSTANCE);
> >        final RelNode newRoot = planner.changeTraits(logicalPlan,
> desiredTraits);
> >        planner.setRoot(newRoot);
> >
> >        RelNode bestExp = planner.findBestExp();
> >        System.out.println("Plan is: " + RelOptUtil.toString(bestExp));
> >
> > ```
> >
> >    The exception is:
> >
> > ```
> >
> > org.apache.calcite.plan.RelOptPlanner$CannotPlanException: There are not
> enough rules to produce a node with desired properties:
> convention=ENUMERABLE, sort=[].
> > Missing conversion is LogicalTableScan[convention: NONE -> ENUMERABLE]
> > There is 1 empty subset: rel#7:RelSubset#0.ENUMERABLE.[], the relevant
> part of the original plan is as follows
> > 0:LogicalTableScan(table=[[t1]])
> >
> > Root: rel#5:RelSubset#1.ENUMERABLE.[]
> > Original rel:
> > LogicalProject(subset=[rel#5:RelSubset#1.ENUMERABLE.[]], attr1=[$0]):
> rowcount = 1.0, cumulative cost = {1.0 rows, 1.0 cpu, 0.0 io}, id = 3
> >  LogicalTableScan(subset=[rel#2:RelSubset#0.NONE.[]], table=[[t1]]):
> rowcount = 1.0, cumulative cost = {0.0 rows, 1.0 cpu, 0.0 io}, id = 0
> >
> > Sets:
> > Set#0, type:
> com.dipeak.disql.query.SimpleSqlTest$MyRelOptSchema$1@67f77f6e
> > rel#2:RelSubset#0.NONE.[], best=null
> > rel#0:LogicalTableScan.NONE.[](table=[t1]), rowcount=1.0, cumulative
> cost={inf}
> > rel#7:RelSubset#0.ENUMERABLE.[], best=null
> > Set#1, type: RecordType(INTEGER attr1)
> > rel#4:RelSubset#1.NONE.[], best=null
> > rel#3:LogicalProject.NONE.[](input=RelSubset#2,inputs=0), rowcount=1.0,
> cumulative cost={inf}
> > rel#5:RelSubset#1.ENUMERABLE.[], best=null
> >
> rel#6:AbstractConverter.ENUMERABLE.[](input=RelSubset#4,convention=ENUMERABLE,sort=[]),
> rowcount=1.0, cumulative cost={inf}
> > rel#8:EnumerableProject.ENUMERABLE.[](input=RelSubset#7,inputs=0),
> rowcount=1.0, cumulative cost={inf}
> >
> > Graphviz:
> > digraph G {
> > root [style=filled,label="Root"];
> > subgraph cluster0{
> > label="Set 0
> com.dipeak.disql.query.SimpleSqlTest$MyRelOptSchema$1@67f77f6e";
> > rel0 [label="rel#0:LogicalTableScan\ntable=[t1]\nrows=1.0,
> cost={inf}",shape=box]
> > subset2 [label="rel#2:RelSubset#0.NONE.[]"]
> > subset7 [label="rel#7:RelSubset#0.ENUMERABLE.[]",color=red]
> > }
> > subgraph cluster1{
> > label="Set 1 RecordType(INTEGER attr1)";
> > rel3 [label="rel#3:LogicalProject\ninput=RelSubset#2,inputs=0\nrows=1.0,
> cost={inf}",shape=box]
> > rel6
> [label="rel#6:AbstractConverter\ninput=RelSubset#4,convention=ENUMERABLE,sort=[]\nrows=1.0,
> cost={inf}",shape=box]
> > rel8
> [label="rel#8:EnumerableProject\ninput=RelSubset#7,inputs=0\nrows=1.0,
> cost={inf}",shape=box]
> > subset4 [label="rel#4:RelSubset#1.NONE.[]"]
> > subset5 [label="rel#5:RelSubset#1.ENUMERABLE.[]"]
> > }
> > root -> subset5;
> > subset2 -> rel0;
> > subset4 -> rel3; rel3 -> subset2;
> > subset5 -> rel6; rel6 -> subset4;
> > subset5 -> rel8; rel8 -> subset7;
> > }
> >
> > at
> org.apache.calcite.plan.volcano.RelSubset$CheapestPlanReplacer.visit(RelSubset.java:709)
> > at
> org.apache.calcite.plan.volcano.RelSubset.buildCheapestPlan(RelSubset.java:390)
> > at
> org.apache.calcite.plan.volcano.VolcanoPlanner.findBestExp(VolcanoPlanner.java:533)
> >
> >
> > ```
>


-- 

Best,
Benchao Li

Reply via email to