首页 > 解决方案 > 为什么 Apache Calcite RelOptRule 跳过过滤条件子查询?

问题描述

例如,我们有下一个 Rel 树(条件中有子查询)

LogicalProject(id=[$0], varchar_col=[$1], link_col=[$2])
  LogicalFilter(condition=[IN($0, {
        LogicalSort(fetch=[1])
          LogicalProject(id=[$0])
            LogicalTableScan(table=[[db, table2]])
        })])
    LogicalTableScan(table=[[db, table1]])

它是由以下内容创建的:

SELECT * FROM db.table1 as b where b.id IN (select c.id from db.table2 as c limit 1)

如果我实现仅查找 TableScan 的 RelOptRule,它将只找到一个与table1一起操作的

new TestRule(RelOptRule.operand(LogicalTableScan.class, RelOptRule.any()), "test")

那是一个错误吗?RelShuttle 中发生了常见行为,它会相应地跳过 RelNode

标签: javaapache-calcite

解决方案


这不是一个错误。按照设计,方解石规则仅匹配调用中的 RelNodes。过滤条件将是 RexCall,并且规则不适用于它。您可能需要在 Filter 上创建一个新规则并检查输入 Rex Expr 是否是 RelNode 调用(或任何其他检查),然后将此规则应用于该规则并进行转换。更容易的是首先将 In 分解为 Join 然后应用您的规则


推荐阅读