没有足够的规则来生成具有所需属性的节点

There are not enough rules to produce a node with desired properties

我想使用方解石火山规划器来优化查询。它不起作用,return 我是个例外:

没有足够的规则来生成具有所需属性的节点:约定=NONE、排序=[]。所有输入都有相关节点,但成本仍然是无限的。 根目录:rel#18:RelSubset#4.NONE.[]

原始版本:

LogicalJoin(condition=[=($0, $3)], joinType=[inner]): rowcount = 81495.22499999999, cumulative cost = {686245.725 rows, 61452.0 cpu, 0.0 io }, id = 4

LogicalJoin(condition=[=($0, $1)], joinType=[inner]): rowcount = 543301.5, cumulative cost = {604750.5 rows, 61451.0 cpu, 0.0 io }, id = 2

LogicalTableScan(table=[[CALCITE_TEST, TTLA_ONE]]): rowcount = 59.0, cumulative cost = {59.0 rows , 60.0 cpu, 0.0 io}, id = 0

LogicalTableScan(table=[[CALCITE_TEST, TTLR_ONE]]): rowcount = 61390.0, cumulative cost = {61390.0 rows , 61391.0 cpu, 0.0 io}, id = 1

LogicalTableScan(table=[[CALCITE_TEST, EMPTY_T]]): rowcount = 1.0, cumulative cost = {0.0 行, 1.0 cpu, 0.0 io}, id = 3

这是导致问题的代码:

val rootSchema = CalciteSchema.createRootSchema(true).plus
val schema = rootSchema.add("CALCITE_TEST", new AbstractSchema())
schema.add("TTLA_ONE", TableA())
schema.add("EMPTY_T", TableS())
schema.add("TTLR_ONE", TableR())
val config = Frameworks.newConfigBuilder.defaultSchema(schema).build
val builder = RelBuilder.create(config)

val opTree: RelNode = builder
  .scan("TTLA_ONE")
  .scan("TTLR_ONE")
  .join(JoinRelType.INNER, "X")
  .scan("EMPTY_T")
  .join(JoinRelType.INNER, "X")
  .build()

val rw = new RelWriterImpl(new PrintWriter(System.out, true))

opTree.explain(rw)
println()
val program = HepProgram.builder
  .addRuleInstance(FilterJoinRule.FILTER_ON_JOIN).build

val hepPlanner = new HepPlanner(program)
hepPlanner.setRoot(opTree)
hepPlanner.findBestExp.explain(rw)

println()

val cluster = opTree.getCluster
val planner = cluster.getPlanner().asInstanceOf[VolcanoPlanner]
planner.setRoot(opTree)

// add rules
planner.addRule(PruneEmptyRules.PROJECT_INSTANCE)
//     add ConverterRule
planner.addRule(EnumerableRules.ENUMERABLE_MERGE_JOIN_RULE)
planner.addRule(EnumerableRules.ENUMERABLE_SORT_RULE)
planner.addRule(EnumerableRules.ENUMERABLE_VALUES_RULE)
planner.addRule(EnumerableRules.ENUMERABLE_PROJECT_RULE)
planner.addRule(EnumerableRules.ENUMERABLE_FILTER_RULE)
planner.addRule(Bindables.BINDABLE_TABLE_SCAN_RULE)
val optimized = planner.findBestExp

optimized.explain(rw)

它产生了爱的输出:

4:LogicalJoin(condition=[=([=11=], )], joinType=[inner])
  2:LogicalJoin(condition=[=([=11=], )], joinType=[inner])
    0:LogicalTableScan(table=[[CALCITE_TEST, TTLA_ONE]])
    1:LogicalTableScan(table=[[CALCITE_TEST, TTLR_ONE]])
  3:LogicalTableScan(table=[[CALCITE_TEST, EMPTY_T]])

10:LogicalJoin(condition=[=([=11=], )], joinType=[inner])
  7:LogicalJoin(condition=[=([=11=], )], joinType=[inner])
    0:LogicalTableScan(table=[[CALCITE_TEST, TTLA_ONE]])
    1:LogicalTableScan(table=[[CALCITE_TEST, TTLR_ONE]])
  3:LogicalTableScan(table=[[CALCITE_TEST, EMPTY_T]])


There are not enough rules to produce a node with desired properties: convention=NONE, sort=[]. All the inputs have relevant nodes, however the cost is still infinite.
Root: rel#18:RelSubset#4.NONE.[]

我在 VolcanoPlanner 上添加了一些规则,可能是什么问题?

已更改

val cluster = opTree.getCluster
val planner = cluster.getPlanner().asInstanceOf[VolcanoPlanner]
planner.setRoot(opTree)

val cluster = opTree.getCluster
val desiredTraits = cluster.traitSet.replace(EnumerableConvention.INSTANCE)
val planner = cluster.getPlanner.asInstanceOf[VolcanoPlanner]
val newRoot = planner.changeTraits(opTree, desiredTraits)
planner.setRoot(newRoot)

通过介绍

val desiredTraits = cluster.traitSet.replace(EnumerableConvention.INSTANCE)

并从 desiredTraits

创建一个新的根
val newRoot = planner.changeTraits(opTree, desiredTraits) 

我还在查询中添加了一些预测,但这对于 Volcano 运行 来说不是必需的。

这是现在的输出:

6:LogicalProject(X=[[=14=]], X0=[])
  5:LogicalJoin(condition=[=([=14=], )], joinType=[inner])
    3:LogicalProject(X=[[=14=]], X0=[])
      2:LogicalJoin(condition=[=([=14=], )], joinType=[inner])
        0:LogicalTableScan(table=[[CALCITE_TEST, TTLA_ONE]])
        1:LogicalTableScan(table=[[CALCITE_TEST, TTLR_ONE]])
    4:LogicalTableScan(table=[[CALCITE_TEST, EMPTY_T]])

16:LogicalProject(X=[[=14=]], X0=[])
  14:LogicalJoin(condition=[=([=14=], )], joinType=[inner])
    11:LogicalProject(X=[[=14=]], X0=[])
      9:LogicalJoin(condition=[=([=14=], )], joinType=[inner])
        0:LogicalTableScan(table=[[CALCITE_TEST, TTLA_ONE]])
        1:LogicalTableScan(table=[[CALCITE_TEST, TTLR_ONE]])
    4:LogicalTableScan(table=[[CALCITE_TEST, EMPTY_T]])

103:EnumerableProject(X=[], X0=[[=14=]])
  102:EnumerableHashJoin(condition=[=([=14=], )], joinType=[inner])
    52:EnumerableTableScan(table=[[CALCITE_TEST, EMPTY_T]])
    101:EnumerableProject(X=[[=14=]], X0=[])
      100:EnumerableMergeJoin(condition=[=([=14=], )], joinType=[inner])
        33:EnumerableTableScan(table=[[CALCITE_TEST, TTLA_ONE]])
        37:EnumerableTableScan(table=[[CALCITE_TEST, TTLR_ONE]])