加入 condition=true 的计划节点遇到错误
Join plan node with condition=true encounter an error
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(=(, ), =(, ))])\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。方解石为什么会生成LogicalJoin(condition=[true], joinType=[inner])
节点?当我使用 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.invoke(ReflectUtil.java:535)
at org.apache.calcite.rel.rel2sql.RelToSqlConverter.dispatch(RelToSqlConverter.java:80
为什么会这样?
RelBuilder
正在按照指示进行操作:构建无条件连接。这类似于你如何写
SELECT ...
FROM Emp, Dept
之后在WHERE
子句中指定连接条件:
WHERE Emp.deptno = Dept.deptno
RelBuilder
不会尝试进行优化(除了一些微优化,例如删除琐碎的 Project
s)。将 Filter
折叠到 Join
是 FilterIntoJoinRule
的工作,并且会在查询优化阶段适时发生。
RelToSqlConverter
中的错误是 known issue,将在下一版本 (1.13.0) 中修复。
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(=(, ), =(, ))])\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。方解石为什么会生成LogicalJoin(condition=[true], joinType=[inner])
节点?当我使用 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.invoke(ReflectUtil.java:535)
at org.apache.calcite.rel.rel2sql.RelToSqlConverter.dispatch(RelToSqlConverter.java:80
为什么会这样?
RelBuilder
正在按照指示进行操作:构建无条件连接。这类似于你如何写
SELECT ...
FROM Emp, Dept
之后在WHERE
子句中指定连接条件:
WHERE Emp.deptno = Dept.deptno
RelBuilder
不会尝试进行优化(除了一些微优化,例如删除琐碎的 Project
s)。将 Filter
折叠到 Join
是 FilterIntoJoinRule
的工作,并且会在查询优化阶段适时发生。
RelToSqlConverter
中的错误是 known issue,将在下一版本 (1.13.0) 中修复。