如何在方解石中将项目、过滤器、聚合下推到 TableScan
How to push down project, filter, aggregation to TableScan in Calcite
我正在使用Apache Calcite 实现分布式OLAP 系统,数据源是RDBMS。所以我想把RelNode
树中的project/filter/aggregation下推到MyTableScan extends TableScan
。在MyTableScan
中,一个RelBuilder
得到推入RelNode
。最后,RelBuilder
生成对源数据库的Query。同时,原RelNode
树中的project/filter/aggregation需要移动或修改。
据我所知,Calcite 不支持此功能。
Current limitations: The JDBC adapter currently only pushes down table scan operations; all other processing (filtering, joins, aggregations and so forth) occurs within Calcite. Our goal is to push down as much processing as possible to the source system, translating syntax, data types and built-in functions as we go. If a Calcite query is based on tables from a single JDBC database, in principle the whole query should go to that database. If tables are from multiple JDBC sources, or a mixture of JDBC and non-JDBC, Calcite will use the most efficient distributed query approach that it can.
在我看来,RelOptRule
可能是一个不错的选择。不幸的是,当我创建新的RelOptRule
时,我不能轻易找到父节点来删除一个节点。
RelOptRule
是个不错的选择?任何人有实现此功能的好主意吗?
谢谢。
创建一个新的 RelOptRule
是正确的方法。请注意,您不应该尝试直接删除规则内的任何节点。相反,您匹配包含要替换的节点的子树(例如,TableScan
顶部的 Filter
)。然后用下推过滤器的等效节点替换整个子树。
这通常是通过创建符合特定适配器调用约定的相关操作的子类来处理的。例如,在 Cassandra 适配器中,有一个 CassandraFilterRule
匹配 CassandraTableScan
之上的 LogicalFilter
。 convert
函数然后构造一个 CassandraFilter
实例。 CassandraFilter
实例设置必要的信息,以便在实际发出查询时,过滤器可用。
浏览一些 Cassandra、MongoDB 或 Elasticsearch 适配器的代码可能会有所帮助,因为它们比较简单。我还建议将其添加到邮件列表中,因为您可能会在那里获得更详细的建议。
我创建了一些 RelOptRule
来下推 Project/Filter/Aggregate RelNode 上层 TableScan。也许对其他人有帮助。
RelOptRule
用于定义一些规则来匹配整个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
方法。该方法只有transformTo
tableScan
。结果就是把Filter->TableScan
换成了TableScan
,整个RelNode如下:
Project
|
TableScan
注意新RelNode的RelDataType
必须等于匹配的子树。
方解石支持一些规则使用,例如FilterJoinRule
、FilterTableScanRule
等。
我正在使用Apache Calcite 实现分布式OLAP 系统,数据源是RDBMS。所以我想把RelNode
树中的project/filter/aggregation下推到MyTableScan extends TableScan
。在MyTableScan
中,一个RelBuilder
得到推入RelNode
。最后,RelBuilder
生成对源数据库的Query。同时,原RelNode
树中的project/filter/aggregation需要移动或修改。
据我所知,Calcite 不支持此功能。
Current limitations: The JDBC adapter currently only pushes down table scan operations; all other processing (filtering, joins, aggregations and so forth) occurs within Calcite. Our goal is to push down as much processing as possible to the source system, translating syntax, data types and built-in functions as we go. If a Calcite query is based on tables from a single JDBC database, in principle the whole query should go to that database. If tables are from multiple JDBC sources, or a mixture of JDBC and non-JDBC, Calcite will use the most efficient distributed query approach that it can.
在我看来,RelOptRule
可能是一个不错的选择。不幸的是,当我创建新的RelOptRule
时,我不能轻易找到父节点来删除一个节点。
RelOptRule
是个不错的选择?任何人有实现此功能的好主意吗?
谢谢。
创建一个新的 RelOptRule
是正确的方法。请注意,您不应该尝试直接删除规则内的任何节点。相反,您匹配包含要替换的节点的子树(例如,TableScan
顶部的 Filter
)。然后用下推过滤器的等效节点替换整个子树。
这通常是通过创建符合特定适配器调用约定的相关操作的子类来处理的。例如,在 Cassandra 适配器中,有一个 CassandraFilterRule
匹配 CassandraTableScan
之上的 LogicalFilter
。 convert
函数然后构造一个 CassandraFilter
实例。 CassandraFilter
实例设置必要的信息,以便在实际发出查询时,过滤器可用。
浏览一些 Cassandra、MongoDB 或 Elasticsearch 适配器的代码可能会有所帮助,因为它们比较简单。我还建议将其添加到邮件列表中,因为您可能会在那里获得更详细的建议。
我创建了一些 RelOptRule
来下推 Project/Filter/Aggregate RelNode 上层 TableScan。也许对其他人有帮助。
RelOptRule
用于定义一些规则来匹配整个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
方法。该方法只有transformTo
tableScan
。结果就是把Filter->TableScan
换成了TableScan
,整个RelNode如下:
Project
|
TableScan
注意新RelNode的RelDataType
必须等于匹配的子树。
方解石支持一些规则使用,例如FilterJoinRule
、FilterTableScanRule
等。