添加 FilterRule 以在适配器中下推过滤器时出现问题:RelSubset 无法转换为 HepRelVertex
Problem while adding FilterRule to push down filter in adapter: RelSubset cannot be cast to HepRelVertex
我写了一个适配器并添加了一些规则来下推谓词。
但是,当我添加FilterRule下推过滤器时,在测试中出现了问题:
Caused by: java.lang.ClassCastException: org.apache.calcite.plan.volcano.RelSubset cannot be cast to org.apache.calcite.plan.hep.HepRelVertex
at org.apache.calcite.plan.hep.HepPlanner.addRelToGraph(HepPlanner.java:840)
at org.apache.calcite.plan.hep.HepPlanner.addRelToGraph(HepPlanner.java:810)
at org.apache.calcite.plan.hep.HepPlanner.setRoot(HepPlanner.java:153)
at org.apache.calcite.tools.Programs.lambda$of[=10=](Programs.java:189)
at org.apache.calcite.tools.Programs$SequenceProgram.run(Programs.java:347)
at org.apache.calcite.prepare.Prepare.optimize(Prepare.java:189)
at org.apache.calcite.prepare.Prepare.prepareSql(Prepare.java:320)
at org.apache.calcite.prepare.Prepare.prepareSql(Prepare.java:231)
我尝试调试这个问题,发现错误的节点是:
enter image description here
RelSubset中的集合为:
enter image description here
错误发生在 HepPlanner.setRoot()
函数中。
我不知道是什么导致了这个错误。其他规则如 ProjectRule 和 LimitRule 运行 很好。如果您需要更多详细信息,请发表评论,我会添加。
我的过滤规则和其他适配器一样:
private static class IoTDBFilterRule extends ConverterRule {
private static final IoTDBFilterRule INSTANCE = new IoTDBFilterRule();
private IoTDBFilterRule() {
super(LogicalFilter.class, Convention.NONE, IoTDBRel.CONVENTION, "IoTDBFilterRule");
}
public RelNode convert(RelNode rel) {
final LogicalFilter filter = (LogicalFilter) rel;
final RelTraitSet traitSet = filter.getTraitSet().replace(IoTDBRel.CONVENTION);
try {
return new IoTDBFilter(filter.getCluster(), traitSet,
convert(filter.getInput(), IoTDBRel.CONVENTION), filter.getCondition());
} catch (LogicalOptimizeException e) {
throw new AssertionError(e.getMessage());
}
}
}
抱歉,我发现了错误。这是过滤器的 copy
功能。
在VolcanoPlanner中,它选择最便宜的节点作为输入,需要复制一个新节点,
copy
函数应该是这样的
public Filter copy(RelTraitSet traitSet, RelNode input, RexNode condition){
return new Filter(getCluster(), traitSet, input, condition);
}
但是忘记改参数名了,结果是这样的:
public Filter copy(RelTraitSet traitSet, RelNode relNode, RexNode rexNode)
并且在执行复制函数时,它访问过滤器的原点输入作为输入参数,而不是函数定义中的 RelNode。
费了我很多时间才找到这个,请不要像我一样。
我写了一个适配器并添加了一些规则来下推谓词。
但是,当我添加FilterRule下推过滤器时,在测试中出现了问题:
Caused by: java.lang.ClassCastException: org.apache.calcite.plan.volcano.RelSubset cannot be cast to org.apache.calcite.plan.hep.HepRelVertex
at org.apache.calcite.plan.hep.HepPlanner.addRelToGraph(HepPlanner.java:840)
at org.apache.calcite.plan.hep.HepPlanner.addRelToGraph(HepPlanner.java:810)
at org.apache.calcite.plan.hep.HepPlanner.setRoot(HepPlanner.java:153)
at org.apache.calcite.tools.Programs.lambda$of[=10=](Programs.java:189)
at org.apache.calcite.tools.Programs$SequenceProgram.run(Programs.java:347)
at org.apache.calcite.prepare.Prepare.optimize(Prepare.java:189)
at org.apache.calcite.prepare.Prepare.prepareSql(Prepare.java:320)
at org.apache.calcite.prepare.Prepare.prepareSql(Prepare.java:231)
我尝试调试这个问题,发现错误的节点是: enter image description here
RelSubset中的集合为: enter image description here
错误发生在 HepPlanner.setRoot()
函数中。
我不知道是什么导致了这个错误。其他规则如 ProjectRule 和 LimitRule 运行 很好。如果您需要更多详细信息,请发表评论,我会添加。
我的过滤规则和其他适配器一样:
private static class IoTDBFilterRule extends ConverterRule {
private static final IoTDBFilterRule INSTANCE = new IoTDBFilterRule();
private IoTDBFilterRule() {
super(LogicalFilter.class, Convention.NONE, IoTDBRel.CONVENTION, "IoTDBFilterRule");
}
public RelNode convert(RelNode rel) {
final LogicalFilter filter = (LogicalFilter) rel;
final RelTraitSet traitSet = filter.getTraitSet().replace(IoTDBRel.CONVENTION);
try {
return new IoTDBFilter(filter.getCluster(), traitSet,
convert(filter.getInput(), IoTDBRel.CONVENTION), filter.getCondition());
} catch (LogicalOptimizeException e) {
throw new AssertionError(e.getMessage());
}
}
}
抱歉,我发现了错误。这是过滤器的 copy
功能。
在VolcanoPlanner中,它选择最便宜的节点作为输入,需要复制一个新节点,
copy
函数应该是这样的
public Filter copy(RelTraitSet traitSet, RelNode input, RexNode condition){
return new Filter(getCluster(), traitSet, input, condition);
}
但是忘记改参数名了,结果是这样的:
public Filter copy(RelTraitSet traitSet, RelNode relNode, RexNode rexNode)
并且在执行复制函数时,它访问过滤器的原点输入作为输入参数,而不是函数定义中的 RelNode。
费了我很多时间才找到这个,请不要像我一样。