基于Hql的表级数据血缘

预备知识
  • 表级数据血缘:数据表的派生关系。
  • Hql: hive sql
  • 通过hive的hql parser在AST(抽象语法树)层级操作
  • 如果需要做字段血缘,在AST级别是可以完成的,不过需要熟悉大量的hql语法规则和其在ast中的实际表示。
  • 耳闻hive的ast并不好,也许是积重难返吧,新语法规则的引入必然要和旧的规则做妥协。可以换用spark sql的parser或者presto的parser。
参考
  • hql的编译过程
  • 从Hive到Antlr,再到DFA
  • AST抽象语法树
数据血缘
  • 分析过程:
    • 查看hql的官方文档,结合应用实例,分析确定存在血缘关系的hql有2种:
      • Create Table As Select (CTAS)
      • Inserting data into Hive Tables from queries
    • 了解基本的AST结构,分析上边2种hql的AST结构,从中抽取原表和目标表的对应关系。
  • hql获取:一种方式是通过hive hook的方式从hive server端获取。
  • 结论:搞清ast的结构,结果还是很清晰和简单的。

Create Table As Select (CTAS)

  • 前置条件:create hql中除了destination table,其他所有出现的表都是source table。
  • comman AST:
    • 所有的db_name.tb_name都存储在TOK_TABNAME节点下。
    • 将子查询的from子句展开后,每个表生成一个TOK_TABREF节点。
TOK_CREATETABLE:TOK_TABNAMEdb_nametb_nameTOK_LIKETABLE:-> [create like 可以从这入手]TOK_QUERY:TOK_FROM:{...}TOK_INSERT{...}
  • pscode:
{AST = createAST From (sql : String);root = getRootToken From (AST : Tree);desc_table = getdest_table From  childWithName(root.childs,'TOK_TABNAME')query_sql = getQuerySql From childWithName(nodes = root.childs,'TOK_QUERY')->{nodes.foreach(c -> return getsql(c) if c is subquery else childWithName(nodes = c.childs,'TOK_QUERY'))}AST = createAST From (query_sql : String);source_tatbles : List = getSrcTb From (nodes = AST.root.childs,'TOK_TABREF'))") ->{nodes.foreach(c -> return getTb(c) if c is 'TOK_TABREF' || c == null else childWithName(nodes = c.childs,'TOK_TABREF'))}
}

select hql

  • select语句并不存在血缘关系,但是它是有血缘关系的hql的ast的子树。
  • common AST
TOK_QUERYTOK_FROMTOK_TABREFTOK_TABNAMEloangjj_basicTOK_INSERTTOK_DESTINATIONTOK_DIRTOK_TMP_FILETOK_SELECTTOK_SELEXPRTOK_TABLE_OR_COLidTOK_SELEXPRTOK_TABLE_OR_COLnameTOK_SELEXPRTOK_TABLE_OR_COLgender

Inserting data into Hive Tables from queries

  • insert语句的语法树是一致的形式。
  • 把单表插入和动态分区插入看作多表插入一种特殊形式,统一处理。
  • think single table insert as an special situation of multi table inserts
  • common AST:
from test1  insert into table test2  partition (age)  select name,address,school,age  insert overwrite table test3  select name,address  where age>24;  TOK_QUERYTOK_FROMTOK_TABREFTOK_TABNAMEtestTOK_INSERTTOK_INSERT_INTOTOK_TABTOK_TABNAMEtest2TOK_PARTSPECTOK_PARTVALageTOK_SELECTTOK_SELEXPRTOK_TABLE_OR_COLnameTOK_SELEXPRTOK_TABLE_OR_COLaddressTOK_SELEXPRTOK_TABLE_OR_COLschoolTOK_SELEXPRTOK_TABLE_OR_COLageTOK_INSERTTOK_DESTINATIONTOK_TABTOK_TABNAMEtest3TOK_SELECTTOK_SELEXPRTOK_TABLE_OR_COLnameTOK_SELEXPRTOK_TABLE_OR_COLaddressTOK_WHERE>TOK_TABLE_OR_COLage24
  • pscode:
    source_table[] = all TOK_TABREF in TOK_QUERYdesc_table[]   = all TOK_TAB in all TOK_INSERT


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部