Calcite中主要数据结构转化流程
如图所示,SQL在Calcite中会经历以上流程,最终会生成优化过后的RelNode, 下面就以图中的各个点数据结构进行说明
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
SqlNode 到SqlNode
此过程主要是根据定义的scheam, table, columns 来验证SqlNode是否合法。由于此过程中没有设计数据结构转化
SqlNode到RelNode
此过程中SqlToRelConverter会将SqlNode转化成RelNode, 这其中主要涉及了以下几个数据结构
RelOptNode
RelOptNode
接口, 它代表的是能被 planner 操作的 expression node
getId()
: 表达式唯一数字 ID (进程启动后维度)getDigest()
: 简洁的描述关系表达式定义唯一性(不会包含当前算子ID但会包含子算子ID)getDescription/toString
: 通常是rel#{id}:{digest}
但多带 ID 信息getTraitSet()
: 获取关系表达式的 traits, 这个马上后面会介绍.getInput()
: 获取当前关系表达式的 input 表达式们getCluster()
: 获取当前关系表达式所属的 clusterRelNode
关系表达式, 主要有TableScan, Project, Sort, Join等。如果SQL为查询的话,所有关系达式都可以在SqlSelect中找到, 如 where和having 对应的Filter, selectList对应Project, orderBy、offset、fetch 对应着Sort, From 对应着TableScan/Join等等, 示便Sql最后会生成如下RelNode树
LogicalProject LogicalFilter LogicalTableScan
RexNode
行表达式, 如RexLiteral(常量), RexCall(函数), RexInputRef(输入引用)等, 还是这一句SQL
select id, cast(score as int), 'hello' from T where id < ?
, 其中id 为RexInputRef
, cast为RexCall
, ‘hello’ 为RexLiteral
等Traits
转化特征,存在于RelNode中,目前有三种Traits:
Convention
、RelCollation
、RelDistribution
。Convention
指的是改关系表达式所遵循的规范,如SparkConvention、PigConvention, 同一个关系表达式的所有输入必须含有相同的Convention. 可以通过ConverterRule将一个Convention转化成另一个Convention.RelCollation
指的是该关系表达式所定义数据的排序,比如说LogicalSort 中如果RelCollation标识数据如果已经是排序好了,可以消除LogicalSort
.RelDistribution
标识数据的分布特点Rule
转化规则,可以将一个RelNode 转化另一种RelNode, 目前Calcite主要有两种Rule.
直接继承RelOptRule。 这种类型的Rule主要作用是将一个关系表达式转化成等价的另一种表达式
- 继承ConverterRule.将RelNode的Convention转化成另一种Convention
Planners
优化器。主要有两种HepPlanner
和VolcanoPlanner
分别对应着RBO和CBO优化器Optimizer 将RelNode 转化成另一种RelNode
此过程是利用Planner进行RBO和CBO优化