【问题标题】:How to push down project, filter, aggregation to TableScan in Calcite如何在 Calcite 中将项目、过滤器、聚合下推到 TableScan
【发布时间】:2018-06-13 19:21:13
【问题描述】:

我正在使用 Apache Calcite 来实现一个分布式 OLAP 系统,它的数据源是 RDBMS。所以我想将RelNode树中的项目/过滤器/聚合下推到MyTableScan extends TableScan。在MyTableScan 中,一个RelBuilder 得到推送的RelNode。最后,RelBuilder 生成对源数据库的查询。同时,应移动或修改原RelNode树中的项目/过滤器/聚合。

据我所知,Calcite 不支持此功能。

当前限制:JDBC适配器目前只下推表扫描操作;所有其他处理(过滤、连接、聚合等)都在 Calcite 中进行。我们的目标是将尽可能多的处理下推到源系统,同时翻译语法、数据类型和内置函数。如果 Calcite 查询基于来自单个 JDBC 数据库的表,则原则上整个查询都应该转到该数据库。如果表来自多个 JDBC 源,或者是 JDBC 和非 JDBC 的混合,Calcite 将使用它可以使用的最有效的分布式查询方法。

在我看来,RelOptRule 可能是一个不错的选择。不幸的是,当我创建新的RelOptRule 时,我无法轻松找到父节点来删除节点。

RelOptRule是个不错的选择吗?任何人都有实现此功能的好主意?

谢谢。

【问题讨论】:

    标签: java database apache-calcite


    【解决方案1】:

    创建一个新的RelOptRule 是可行的方法。请注意,您不应该尝试直接删除规则内的任何节点。相反,您匹配包含要替换的节点的子树(例如,TableScan 顶部的 Filter)。然后用下推过滤器的等效节点替换整个子树。

    这通常通过创建符合特定适配器调用约定的相关操作的子类来处理。例如,在 Cassandra 适配器中,有一个 CassandraFilterRule 匹配 LogicalFilterCassandraTableScan 之上。然后convert 函数构造一个CassandraFilter 实例。 CassandraFilter 实例设置必要的信息,以便在实际发出查询时,过滤器可用。

    浏览 Cassandra、MongoDB 或 Elasticsearch 适配器的一些代码可能会有所帮助,因为它们更简单。我还建议将其带到邮件列表中,因为您可能会在那里获得更详细的建议。

    【讨论】:

    • convert 函数是我想要的,我在一些规则中找到了它。
    【解决方案2】:

    我创建了一些RelOptRule 来下推 Project/Filter/Aggregate RelNode 上 TableScan。也许对其他人有帮助。

    RelOptRule 用于定义一些 Rules 来匹配整个 RelNode 中的子树。匹配时调用onMatch方法做某事。

    onMatch方法中,我们可以新建一个RelNode并调用transformTo方法替换匹配的子树。

    例如:

    Project
      |
    Filter
      |
    TableScan
    

    PushDownFilter规则如下:

      public class PushDownFilter extends RelOptRule {
    
      public PushDownFilter(RelOptRuleOperand operand, String description) {
        super(operand, "Push_down_rule:" + description);
      }
    
      public static final PushDownFilter INSTANCE =
          new PushDownFilter(
              operand(
                  Filter.class,
                  operand(TableScan.class, none())),
              "filter_tableScan");
    
      @Override
      public void onMatch(RelOptRuleCall call) {
        LogicalFilter filter = (LogicalFilter) call.rels[0];
        TableScan tableScan = (TableScan) call.rels[1];
        // push down filter
        call.transformTo(tableScan);
      }
    }
    

    此规则将匹配Filter->TableScan 子树,然后调用onMatch 方法。该方法只有transformTotableScan。结果就是把Filter->TableScan换成了TableScan,整个RelNode如下:

    Project
      |
    TableScan
    

    注意新RelNode的RelDataType必须等于匹配的子树

    方解石支持一些规则使用,例如FilterJoinRuleFilterTableScanRule等。

    【讨论】:

    • 我们应该向call.transformTo(<<here>>) 提供一些额外的输入信息。看来 TableScan 应该以某种方式进行修改,以便同时推送额外的过滤器属性,对吧?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-08-04
    • 2017-07-18
    • 1970-01-01
    • 2019-04-12
    相关资源
    最近更新 更多