01 简介
Apache Calcite 是一款开源SQL
解析工具, 可以将各种SQL
语句解析成抽象语法术AST(Abstract Syntax Tree)
, 之后通过操作AST
就可以把SQL
中所要表达的算法与关系体现在具体代码之中,将来会有越来越多的数据处理引擎采用Calcite作为SQL
解析工具。
如下图,阿里的blink
框架已经集成了Calcite
的源码:
官方地址:https://calcite.apache.org/
02 功能
Calcite解析SQL的步骤如下:
Calcite有以下主要功能:
- SQL 解析:Parser步骤中Calcite通过Java CC将SQL解析成未经校验的AST;
- SQL 校验:Validate步骤主要作用是校证Parser步骤中的AST是否合法,如验证SQL scheme、字段、函数等是否存在; SQL语句是否合法等. 此步完成之后就生成了RelNode树;
- 查询优化:Optimize步骤主要的作用优化RelNode树, 并将其转化成物理执行计划。主要涉及SQL规则优化如:基于规则优化(RBO)及基于代价(CBO)优化; Optimze 这一步原则上来说是可选的, 通过Validate后的RelNode树已经可以直接转化物理执行计划,但现代的SQL解析器基本上都包括有这一步,目的是优化SQL执行计划。此步得到的结果为物理执行计划。
- SQL 生成器
- 数据连接
Execute即执行阶段:此阶段主要做的是将物理执行计划转化成可在特定的平台执行的程序,如Hive与Flink都在在此阶段将物理执行计划CodeGen生成相应的可执行代码。
03 相关组件
Calcite主要有以下组件:
- Catelog: 主要定义SQL语义相关的元数据与命名空间。
- SQL parser: 主要是把SQL转化成AST.
- SQL validator: 通过Catalog来校证AST.
- Query optimizer: 将AST转化成物理执行计划、优化物理执行计划.
- SQL generator: 反向将物理执行计划转化成SQL语句.
3.1 Catalog
Catalog:主要定义被SQL访问的命名空间
主要包括以下几点:
- schema: 主要定义schema与表的集合,schame 并不是强制一定需要的,比如说有两张同名的表T1, T2,就需要schema要区分这两张表,如A.T1, B.T1;
- 表:对应关系数据库的表,代表一类数据,在calcite中由RelDataType定义;
- RelDataType: 代表表的数据定义,如表的数据列名称、类型等。
Schema:
public interface Schema { Table getTable(String name); Set<String> getTableNames(); Set<String> getFunctionNames(); Schema getSubSchema(String name); Set<String> getSubSchemaNames(); Expression getExpression(SchemaPlus parentSchema, String name); boolean isMutable();
Table:
public interface Table { RelDataType getRowType(RelDataTypeFactory typeFactory); Statistic getStatistic(); Schema.TableType getJdbcTableType(); }
其中RelDataType代表Row的数据类型, Statistic 用于统计表的相关数据、特别是在CBO用于计表计算表的代价。
一句Sql:
selcct id, name, cast(age as bigint) from A.INFO
- id, name则为data type field
- bigint为 data type
- A 为schema
- INFO 为表
3.2 SQL Parser
SQL Parser:由Java CC编写,将SQL转化成AST.
- Java CC: 指的是Java Compiler Compiler, 可以将一种特定域相关的语言转化成Java语言;
- 在Calcite中将标记(Token)表示为 SqlNode, 并且Sqlnode可以通过unparse方法反向转化成SQL。
例如SQL如下:
cast(id as float)
Java CC 可表示为:
<CAST> <LPAREN> e = Expression(ExprContext.ACCEPT_SUBQUERY) <AS> dt = DataType() {agrs.add(dt);} <RPAREN> ....
还有Query Optimizer这些内容,本文不再详述:
04 用法
具体的用法可以参考:
- mysql-protocol:https://github.com/yuqi1129/schema/tree/master/mysql-protocol
- calcite-test:https://github.com/yuqi1129/calcite-test
05 文末
本文主要讲解了Apache Calcite的功能、组件及用法,希望能帮助到大家,谢谢大家的阅读,本文完!