2017-06-05 24 views
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。爲什麼方解石生成LogicalJoin(condition=[true], joinType=[inner])節點?當我使用RelToSqlConverter到RelNode到SQL轉換,它遇到有關filter 'condition=[true]'加入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 

爲什麼會發生這種情況的錯誤?

回答

1

RelBuilder正在做的事情是:建立一個沒有條件的連接。這類似於你怎麼可能寫

SELECT ... 
FROM Emp, Dept 

後來指定WHERE子句中的連接條件:

WHERE Emp.deptno = Dept.deptno 

RelBuilder不會嘗試從幾個微優化,例如進行優化(除刪除普通的Project s)。將Filter摺疊到Join的作業是FilterIntoJoinRule,並且將在查詢優化階段恰當地發生。

RelToSqlConverter中的錯誤是known issue,將在下一版本(1.13.0)中修復。