首页 > 解决方案 > 使用 RelBuilder 构建 RelNode 时,有什么方法可以删除特定规则?

问题描述

我正在使用 RelBuilder 构建一个 RelNode。

FrameworkConfig frameworkConfig = config().build();
 final RelBuilder builder = RelBuilder.create(frameworkConfig);
  RelNode root =
                 builder.scan("ITEM", "TEST")
                 .filter(
                         builder.equals(builder.field("ITEM_ID"), builder.literal("AM_TestItem_21Aug17_0614")))
                 .filter(
                        builder.equals(builder.field("OBJECT_TYPE"), builder.literal("Item")))
                 .build();

 PreparedStatement preparedStatement = RelRunners.run(root)
 preparedStatement.executeQuery()
    public static Frameworks.ConfigBuilder config() {
        CalciteSchema rootSchema1 = CalciteSchema.createRootSchema(true);
        rootSchema1 = rootSchema1.add("ITEM", new MySchema());
        // MySchema consists of Map of MyFilterableTable which extends AbstractTable and implements FilterableTable
        return Frameworks.newConfigBuilder().defaultSchema(rootSchema1.plus());
    }

MyFilterableTable 中的 scan 方法 public Enumerable<Object[]> scan(DataContext root, List<RexNode> filters) 将合并的过滤器字符串作为 [AND(=($0, 'AM_TestItem_21Aug17_0614'), =($3, 'Item'))]

我想要这些过滤器的单独条目,而不是合并一个。我希望计划者忽略 FilterMergeRule。

有没有办法做到这一点?

标签: javaapache-calcite

解决方案


使用 API 时没有简单的方法可以选择性地启用/禁用规则RelBuilder,这是正常的,因为此 API 仅用于创建计划。

此外,依赖过滤器不会被合并这一事实并不是一个好主意,因为将来FilterMergeRule当有两个相邻的过滤器运算符时,很有可能通过 RelBuilder 完成当前完成的合并。

不过,在扫描操作中,您可以调用RelOptUtil#conjunctions将过滤器拆分为单独的连词的方法,如果我很好地理解您的用例,这或多或少是您想要获得的。


推荐阅读