1. Calcite中主要数据结构转化流程
如图所示,SQL在Calcite中会经历以上流程,最终会生成优化过后的RelNode, 下面就以图中的各个点数据结构进行说明
2. SQL到SqlNode
通过Parser, 可以将Sql转化成SqlNode, 什么是SqlNode? SqlNode是Calcite中用于表达关系运算的中间数据结构,这么说可能有些抽象,可以看下图:
便于解释
select id, cast(score as int), 'hello' from T where id < ?
以上SQL中,
- id, score, T 等为SqlIdentifier
- cast()为SqlCall
- int 为SqlDataTypeSpec
- 'hello' 为SqlLiteral
- '?' 为SqlDynamicParam
进一步看
在Calcite中,所有的操作都是一个SqlCall, 如查询是一个SqlSelect, 删除是一个SqlDelete等,对应的查询条件等为SqlCall中的参数, 如代码所示
public class SqlSelect extends SqlCall {
public static final int FROM_OPERAND = 2;
public static final int WHERE_OPERAND = 3;
public static final int HAVING_OPERAND = 5;
SqlNodeList keywordList;
SqlNodeList selectList;
SqlNode from;
SqlNode where;
SqlNodeList groupBy;
SqlNode having;
SqlNodeList windowDecls;
SqlNodeList orderBy;
SqlNode offset;
SqlNode fetch;
3. SqlNode 到SqlNode
此过程主要是根据定义的scheam, table, columns 来验证SqlNode是否合法。由于此过程中没有设计数据结构转化,先略过,后面会有文章专们针对validator进行说明
4. SqlNode到RelNode
此过程中SqlToRelConverter会将SqlNode转化成RelNode, 这其中主要涉及了以下几个数据结构
1. RelNode
关系表达式, 主要有TableScan, Project, Sort, Join等。如果SQL为查询的话,所有关系达式都可以在SqlSelect中找到, 如 where和having 对应的Filter, selectList对应Project, orderBy、offset、fetch 对应着Sort, From 对应着TableScan/Join等等, 示便Sql最后会生成如下RelNode树
LogicalProject
LogicalFilter
LogicalTableScan
2. RexNode
行表达式, 如RexLiteral(常量), RexCall(函数), RexInputRef(输入引用)等, 还是这一句SQL select id, cast(score as int), 'hello' from T where id < ?
, 其中id 为RexInputRef
, cast为RexCall
, 'hello' 为RexLiteral
等
3. Traits
转化特征,存在于RelNode中,目前有三种Traits: Convention
、RelCollation
、 RelDistribution
。 Convention
指的是改关系表达式所遵循的规范,如SparkConvention、PigConvention, 同一个关系表达式的所有输入必须含有相同的Convention. 可以通过ConverterRule将一个Convention转化成另一个Convention. RelCollation
指的是该关系表达式所定义数据的排序,比如说LogicalSort 中如果RelCollation标识数据如果已经是排序好了,可以消除LogicalSort
. RelDistribution
标识数据的分布特点。
4. Rule
转化规则,可以将一个RelNode 转化另一种RelNode, 目前Calcite主要有两种Rule.
4.1 直接继承RelOptRule。 这种类型的Rule主要作用是将一个关系表达式转化成等价的另一种表达式
4.2 继承ConverterRule.将RelNode的Convention转化成另一种Convention
5. Planners
优化器。主要有两种HepPlanner
和VolcanoPlanner
分别对应着RBO和CBO优化器
3. Optimizer 将RelNode 转化成另一种RelNode
此过程是利用Planner进行RBO和CBO优化,请参考后面关于RBO和CBO的介绍
总结
Calcite 执行计划生成主要的数据结构在SqlNode和RelNode中,特别是RelNode, 其包含了许多为后面优化设置的数据结构如trait。
SqlNode 生成逻辑在Parser中,具体逻辑请参考Calcite中定制自已SQL解析器
RelNode 主要是通过调用SqlToRelConverter生成,后面会用篇幅详细介绍这一过程
Calcite 中还有许多相关数据结构,读者如果感兴趣,请自行阅读原码