数据中台,数据仓库在大数据的发展中占着重要的占比,二者两者都离不开血缘关系的构建,解析SQL构建血缘关系
我们可以借助工具查询最外层表的个数,一般的来源都是一个或多个,如果 是Union关系,那么就是0个,这样来处理Union的关系
TJoinList joins = stmt.getJoins();
if (joins.size() >= 1) {
// TODO 处理非Union的逻辑关系
} else {
// Union的逻辑可以拆分为 left和right
TSelectSqlStatement leftStmt = stmt.getLeftStmt();
if (Func.notNull(leftStmt)) {
parseStatement(leftStmt, null, pojoList, targetTable);
}
TSelectSqlStatement rightStmt = stmt.getRightStmt();
if (Func.notNull(rightStmt)) {
parseStatement(rightStmt, null, pojoList, targetTable);
}
}
如果最外层的SQL包子查询(临时表),那么就需要把子查询视为一个整体,先构建目标表到临时表之间的血缘关系。
借助工具,我们可以判断表类型,如果表类型是subquery,那么可以明确知道是子查询,那么就可以将其视为一个 新的表,递归处理
if (table.getTableType() == ETableSource.subquery) {
TSelectSqlStatement statement = table.getSubquery();
if (Func.notNull(statement)) {
parseStatement(statement, null, pojoList, table.getAliasName());
}
}
借助工具我们可以获取到所查询(操作)的字段,字段的那些大致分为三类,普通字段(可以直接使用) ,case when语句,Hive函数
switch (ExpressionType) {
case case_t:
// TODO case when查理
break;
case function_t:
// TODO 函数处理,cast比较特殊
break;
case arithmetic_plus_t:
case parenthesis_t:
case arithmetic_modulo_t:
case logical_and_t:
case arithmetic_times_t:
case arithmetic_divide_t:
case simple_comparison_t:
case array_access_expr_t:
// TODO 以上存在多对一 , 那么需要把两个字段分开,分别获取 每个字段的信息
break;
case simple_object_name_t:
// TODO 直接获取字段的信息
break;
default:
break;
}
附上血缘图Json
{
"edges": [
{
"from": {
"column": "name",
"tbName": "data2"
},
"to": {
"column": "name",
"tbName": "middle1"
}
},
{
...
}
],
"nodes": [
{
"id": "data1",
"name": "data1",
"type": "Origin",
"columns": [{
"name": "age"
}, {
"name": "name"
}, {
"name": "class"
}],
"top": 135,
"left": 10
},{
...
}
]
}
以上是解析HQL的思路,更多的是借助工具,如果有需要可以下面留言