1
final RelBuilder builder = RelBuilder.create(config().build());
    RelNode root =
        builder.scan("EMP")
            .as("e")
            .scan("EMP")
            .as("m")
            .scan("DEPT")
            .join(JoinRelType.INNER)
            .join(JoinRelType.INNER)
            .filter(
                builder.equals(builder.field("e", "DEPTNO"),
                    builder.field("DEPT", "DEPTNO")),
                builder.equals(builder.field("m", "EMPNO"),
                    builder.field("e", "MGR")))
            .build();
    final String expected = ""
        + "LogicalFilter(condition=[AND(=($7, $16), =($8, $3))])\n"
        + "  LogicalJoin(condition=[true], joinType=[inner])\n"
        + "    LogicalTableScan(table=[[scott, EMP]])\n"
        + "    LogicalJoin(condition=[true], joinType=[inner])\n"
        + "      LogicalTableScan(table=[[scott, EMP]])\n"
        + "      LogicalTableScan(table=[[scott, DEPT]])\n";
    assertThat(str(root), is(expected));

上面的代码来自 RelBuilderTest.java 。为什么calcite会生成LogicalJoin(condition=[true], joinType=[inner])Node?当我使用RelToSqlConverter将 RelNode 转换为 SQL 时,遇到关于filter 'condition=[true]'

ava.lang.AssertionError: Internal error: While invoking method 'public org.apache.calcite.rel.rel2sql.SqlImplementor$Result org.apache.calcite.rel.rel2sql.RelToSqlConverter.visit(org.apache.calcite.rel.core.Filter)
at org.apache.calcite.util.Util.newInternal(Util.java:792)
at org.apache.calcite.util.ReflectUtil$2.invoke(ReflectUtil.java:535)
at org.apache.calcite.rel.rel2sql.RelToSqlConverter.dispatch(RelToSqlConverter.java:80

为什么会这样?

4

1 回答 1

1

RelBuilder正在做被告知的事情:无条件地建立一个连接。这类似于您可能编写的方式

SELECT ...
FROM Emp, Dept

然后在WHERE子句中指定连接条件:

WHERE Emp.deptno = Dept.deptno

RelBuilder不尝试进行优化(除了一些微优化,例如删除琐碎Project的 s)。折叠Filter到 上Join是 的工作FilterIntoJoinRule,并且将在查询优化阶段适时发生。

中的错误RelToSqlConverter是一个已知问题,将在下一个版本 (1.13.0) 中修复。

于 2017-06-05T20:57:27.760 回答