使用Hive内置的解析器构建血缘关系

背景

最近在做数据血缘关系相关的工作,最初级的版本我们是通过执行计划分析出表到表的计算关系。有同事在看了之后提出,希望能给一个字段到字段的计算关系出来,所以我们做了一些尝试,到今天为止算是有一个大概的东西出来。仓库组的HiveQL一般情况下是写好后,定时调度SparkSQL来执行的。这些HiveQL格式都差不多的样子

insert overwrite table name partition(partition info) select columninfo from table or sql

所以我想,针对这类的HiveQL,我们用Hive的解析器得到语法树,然后遍历语法树得到字段与字段的计算关系。

解析器

Hive的解析器是基于Antlr4的,把SQL扔给这个解析器返回的就是ASTNode为根节点的一棵树,我们写好遍历器,就可以把要解析的东西拿出来了。鉴于我们要的是表和表的依赖关系,以及字段之间的依赖关系,所以关于Where,Group by,Order by等等不影响结果的部分都不做介绍,只把关注点集中在Select From Join Union上。每个人做的时候应该有自己的想法,按照自己想法做,避免被我的思维方式带到沟里,所以代码是不会贴的,只是把HiveQL解析出的语法树关键点的特征罗列一下。

语法树特征

我用几种SQL的片段来做例子,把解析到的结果用echarts的树图展现出来,方便理解。所有的HiveQL解析出的语法树根节点都是EMPTY节点,每个查询语句最后解析出的都是EMPTY节点下的一个TOK_QUERY节点,不再冗述。

带*的查询

语句

insert overwrite table dest_table partition(dt='{0}') select * from db_name.table_name;

解析结果

带星的查询

结果分析

首先,我们可以看到,根节点是一个空节点,然后空节点下面试TOK_QUERY节点。此节点分成了两部分:TOK_INSERT 结果集子节点和TOK_FROM数据来源子节点。
TOK_INSERT:中有两个子节点TOK_DETINATION表示数据要写到哪里去,TOK_SELECT表示选处的结果集中每个字段是如何计算得到的。注意TOK_SELECT下面的TOK_SELEXPR表示的是每个字段,TOK_SELEXPR下面才是这个字段的结果过程,本例中结果集的 * 用一个TOK_ALLCOLREF节点表示。
TOK_FROM: 节点表示的是表或者子SQL是如何关联或Union的。在这个例子里,我们看到的信息还不多,制之后TOK_FROM下面可以有TOK_TABREF这个类型(它表示一张具体的数据表)

多表关联

语句

insert overwrite table dest_table partition(dt='{0}') 
    select * from db_name.table_name_1 t1
                 join db_name.table_name_2 t2 on t1.a = t2.a
                 join db_name.table_name_3 t3 on t2.b = t3.b

解析结果

多表关联

结果分析

这个例子我们不关心结果集部分,只看多表关联。TOK_FROM节点下,是一个TOK_JOIN节点,表示数据来自两个源(有可能是子查询,有可能是表)的关联。TOK_JOIN下面是一个TOK_JOIN,一个TOK_TABREF和一个EQUAL,表示当前TOK_JOIN是由另外两表关联后,再与第三表关联得到的。EQUAL就是关联条件。看到这里,我们也就明白了,尽管我们写了多个表的join,但是HiveQL解析器会把数据表选择两个做一次关联,然后再去关联第三个……以此类推。

多种字段计算

语句


insert overwrite table dest_table partition(dt='{0}') 
select 
    t1.a as t1a , 
    func(t2.a) as t2a ,  --假装我是UDF好了
    case t3.a when 1 then 100 when 2 then 200 else 300 end as t3a_1,
    case when t3.a > 100 then 1 when t3.a < 100 then -1 else 0 end as t3a_2,
    (t1.a  + 2) * t3.a as expr
from db_name.table_name_1 t1 
        join db_name.table_name_2 t2 on t1.a = t2.a
        join db_name.table_name_3 t3 on t2.b = t3.b;

解析结果

多字段计算

结果分析

需要特殊注意的一点是两种不同的case when语句形式得到的节点略有不同

带Union的

语句

insert overwrite table dest_table partition(dt='{0}') 
select * from (
  select a from table_a 
  union all 
  select a from table_b  
  union all 
  select a from table_c
) t;

解析结果

UNION语句

结果分析

UNION也是先两个表UNION,然后再UNION第三个表得到结果的。

总结

看到这里,估计大家对AST树的内部构造有一个大致的了解了,那么后续的工作中可以根据自己的需求,来做相关的解析逻辑。我自己写了一个AST树的遍历工具,然后把树的结构按照echarts里的树图组织一下输出出来,遇到问题的时候就把这个输出的结果贴到echarts的demo页面里,看看解析结果和我解析代码是否有不一致的情况,对分析AST树还是很有帮助的。

子查询的情况没有介绍,其实都差不多,各位可以自行尝试一下

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,530评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 86,403评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,120评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,770评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,758评论 5 367
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,649评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,021评论 3 398
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,675评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,931评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,659评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,751评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,410评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,004评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,969评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,203评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,042评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,493评论 2 343

推荐阅读更多精彩内容