LinkedIn Coral SQL 翻译实现原理

总体流程

以 Hive SQL 翻译成 Trino SQL 为例:

1
2
3
4
5
6
7
Hive SQL -> Calcite RelNode
解析成抽象语法树 AST(比如通过 hive 的 antlr 语法解析)
遍历节点转换为 SqlNode
SqlNode 转换为 Calcite RelNode(Coral IR)
Calcite RelNode -> Trino SQL
RelNode -> SqlNode
SqlNode -> TrinoSQL

详细流程

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
1.Hive SQL -> Calcite RelNode
创建 HiveToRelConverter
1.父类 ToRelConverter 构造方法
创建 SchemaPlus
创建 FrameworkConfig
创建 SqlRexConvertletTable
2.构造方法
创建 StaticHiveFunctionRegistry
创建 HiveFunctionResolver
创建 HiveSqlValidator
创建 ParseTreeBuilder
1.Hive SQL方言语法解析 -> 抽象语法树
parseTreeBuilder.process
CoralParseDriver#parse
进行sql解析,返回 hive ASTNode root 结构
processAST
visit 访问语法树
2.遍历 ASTNode visit 访问转换为 calcite SqlNode 结构
1.通过 visit 将 ast 转换为 hive sqlNode
ParseTreeBuilder#processAST
ParseTreeBuilder#visitQueryNode 访问创建 calcite SqlSelect 对象
visitSelect
visitFunction 函数处理
visitFunctionInternal
HiveFunctionResolver#tryResolve 处理函数名
通过 StaticHiveFunctionRegistry 查找对应的函数
2.hive sqlNode -> Coral Sql Node
sqlNode accept HiveSqlNodeToCoralSqlNodeConverter visit
这里就一个 ShiftArrayIndexTransformer 转换
将 hive 的数组下标进行调整
3.转化 SqlNode 到 RelNode
ToRelConverter.toRel
1.创建 sqlNode -> rel转换器
org.apache.calcite.sql2rel.SqlToRelConverter
2.执行 sqlNode -> RelNode 转换
validator#validate
HiveSqlToRelConverter#convertQuery 主要通过下面calcite里的方法进行转换,重写了部分方法
SqlToRelConverter#convertQueryRecursive
2.Calcite RelNode -> trino SQL
4.RelNode -> Trino SqlNode
将关系代数 转换成 Trino 的 SqlNode 语法树
1.创建 relNode -> sqlNode 转换器
org.apache.calcite.rel.rel2sql.RelToSqlConverter
2.执行 relNode -> sqlNode 转换
RelToTrinoConverter#convert
1.convertToSqlNode
将 relNode 转换成 trino sqlNode
2.DataTypeDerivedSqlCallConverter visit
处理数据类型的转换
里面定义很多 SqlCallTransformer 函数转换
3.CoralToTrinoSqlCallConverter visit 函数转换
构造方法里创建了很多 SqlCallTransformers
比如 CoralRegistryOperatorRenameSqlCallTransformer("nvl", 2, "coalesce")
将 nvl 函数转换成 coalesce 函数
SqlCallTransformer#apply
condition
判断是否满足条件
transform
进行sql翻译
OperatorRenameSqlCallTransformer
5.SqlNode -> trinoSQL
TrinoSqlRewriter#toSqlString
通过 sqlNode 写出翻译后的 sql

参考

coral github