Apache Calcite是一款基础SQL处理框架,该框架提供SQL解析优化等功能,并被广泛运用于Apache Hive,Drill,Flink等项目中。
Apache Calcite架构
Apache Calcite整体架构如下图所示
Calcite SQL处理流程
calcite SQL处理过程分为如下5个过程:
- Parse: calcite使用JavaCC来进行SQL解析生成AST
- Validate:验证SQL的正确性并根据元数据验证SQL中涉及到的column,table是否有效
- Convert:将AST转化成RelNode Tree,也就是转化成逻辑执行计划
- Optimize:对逻辑执行计划进行优化,例如谓词下位,列裁剪等,生成优化后的RelNode Tree
- Execute:生成物理执行计划,执行物理执行计划
在这里我们主要对Validate,Convert,Optimize进行源码分析,首先我们来看一下calcite validate的处理流程
validate过程
我们在SqlValidatorTest.java文件中添加如下代码,通过举例进行说明
// SqlValidatorTest.java
@Test public void testWhereJoinOrderGroupByHaving() {
sql("SELECT COUNT(empno), name FROM EMP AS e JOIN DEPT AS d ON e.deptno = d.deptno WHERE comm > 1 GROUP BY name HAVING SUM(sal) > 30 ORDER BY name LIMIT 10 OFFSET 3").ok();
}
DATABASE SALES
|
|----Table EMP
EMPNO(INT) ENAME(VARCHAR(20)) JOB(VARCHAR(10)) MGR(INT) HIREDATE(TIMESTAMP) SAL(INT) COMM(INT) DEPTNO(INT) SLACKER(BOOLEAN)
|----Table DEPT
DEPTNO(INT) NAME(VARCHAR(10)
calcite validate主要完成以下工作:
- 通过元数据验证SQL中用到的database,table,field是否存在
- 验证SQL是否有效
- Rewrite sqlNode,将sqlNode的name转化为full qualified name,例上述SQL在经过validate后变为
SELECT COUNT(`EMPNO`), `NAME`
FROM `EMP` AS `E`
INNER JOIN `DEPT` AS `D` ON `E`.`DEPTNO` = `D`.`DEPTNO`
WHERE `E`.`COMM` > 1
GROUP BY `D`.`NAME`
HAVING SUM(`E`.`SAL`) > 30
ORDER BY `NAME`
OFFSET 3 ROWS
FETCH NEXT 10 ROWS ONLY
validate源码如下所示:
//SqlValidatorImpl.java
public SqlNode validate(SqlNode topNode) {
SqlValidatorScope scope