Проблема при добавлении FilterRule в pu sh вниз фильтра в адаптере: RelSubset не может быть приведен к HepRelVertex - PullRequest
0 голосов
/ 07 января 2020

Я написал адаптер и добавил некоторые правила для предикатов pu sh.

Однако, когда я добавил FilterRule в фильтр down * pu sh, в тесте возникла проблема:

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$0(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)

Я попытался отладить эту проблему и обнаружил, что неправильный узел: введите описание изображения здесь

Набор в RelSubset был: введите описание изображения здесь

И ошибка произошла в функции 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());
      }
    }
  }

1 Ответ

0 голосов
/ 08 января 2020

Извините, я нашел ошибку. Это функция фильтра 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 в определении функции.

Это стоило мне много времени, чтобы найти это, пожалуйста, не делайте, как я.

...