hive中sql解析出对应表和字段的调查

---恢复内容开始---

1.阿里的druid中的sql parser有各种关系数据库sql的解析,但hive的不支持。

druid初期的版本中是包含hive的,将以前版本中的hive dialect对应的内容放入,测试,发现有些语句不支持,如:
show create table xxx;
show tables;
普通的select语句是可以解析的,如:
sql:select STATIS_DATE, INTFC_TP, TRMNL_TP_ID, APP_VERSION, CLNT_CHNL, BRAND_CATE_ID, BRAND_CATE_NM, BRAND_ID, BRAND_NM, CATENTRY_GROUP_ID, CATENTRY_GROUP_NM, GDS_ID, CATENTRY_ID, CATENTRY_NM, UV_QTY, PV_QTY, 0 NEW_UV_QTY, SEARCH_CNT, SHOPNG_CART_PV_QTY, PAGE_DRTN, 0 EXIT_QTY, ORDER_PAY_QTY, ORDER_PAY_AMNT, ORDER_PAY_SALE_QTY, ORDER_DLVRY_PAY_QTY, ORDER_DLVRY_PAY_AMNT, ORDER_DLVRY_PAY_SALE_QTY, ETL_TIME from mobdss.tdm_trmnl_cate_stat_d t where t.statis_date >= regexp_replace(date_sub(from_unixtime(to_unix_timestamp('20150505', 'yyyyMMdd'), 'yyyy-MM-dd'), 6), '-', '') and t.statis_date <= 20150505
结果:{mobdss.tdm_trmnl_cate_stat_d=Select}
[mobdss.tdm_trmnl_cate_stat_d.STATIS_DATE, mobdss.tdm_trmnl_cate_stat_d.INTFC_TP, mobdss.tdm_trmnl_cate_stat_d.TRMNL_TP_ID, mobdss.tdm_trmnl_cate_stat_d.APP_VERSION, mobdss.tdm_trmnl_cate_stat_d.CLNT_CHNL, mobdss.tdm_trmnl_cate_stat_d.BRAND_CATE_ID, mobdss.tdm_trmnl_cate_stat_d.BRAND_CATE_NM, mobdss.tdm_trmnl_cate_stat_d.BRAND_ID, mobdss.tdm_trmnl_cate_stat_d.BRAND_NM, mobdss.tdm_trmnl_cate_stat_d.CATENTRY_GROUP_ID, mobdss.tdm_trmnl_cate_stat_d.CATENTRY_GROUP_NM, mobdss.tdm_trmnl_cate_stat_d.GDS_ID, mobdss.tdm_trmnl_cate_stat_d.CATENTRY_ID, mobdss.tdm_trmnl_cate_stat_d.CATENTRY_NM, mobdss.tdm_trmnl_cate_stat_d.UV_QTY, mobdss.tdm_trmnl_cate_stat_d.PV_QTY, mobdss.tdm_trmnl_cate_stat_d.SEARCH_CNT, mobdss.tdm_trmnl_cate_stat_d.SHOPNG_CART_PV_QTY, mobdss.tdm_trmnl_cate_stat_d.PAGE_DRTN, mobdss.tdm_trmnl_cate_stat_d.ORDER_PAY_QTY, mobdss.tdm_trmnl_cate_stat_d.ORDER_PAY_AMNT, mobdss.tdm_trmnl_cate_stat_d.ORDER_PAY_SALE_QTY, mobdss.tdm_trmnl_cate_stat_d.ORDER_DLVRY_PAY_QTY, mobdss.tdm_trmnl_cate_stat_d.ORDER_DLVRY_PAY_AMNT, mobdss.tdm_trmnl_cate_stat_d.ORDER_DLVRY_PAY_SALE_QTY, mobdss.tdm_trmnl_cate_stat_d.ETL_TIME]


2.General sql parser中有hive sql的对应解析,但是商业版且自己不可控,不打算用。
参照:http://107.170.101.241:8080/getTableColumn/

3.antlr的使用,文法文件,语法文件定义,然后运行解析生成AST。
参照:http://www.ibm.com/developerworks/cn/java/j-lo-antlr/,定义了一个基本的+-运算的Expr.g。
自定义hive文法文件去解析几乎不可能实现。
到hive中的文发文件进行解析,不如直接通过调用hive的parse方法,拿到语法树。


4.从hive的ParseDriver中获取语法树,直接解析得到table和column,但没有可用的visitor进行遍历语法树进行获取。
遍历ast,通过hive既有的方法或者自定义遍历器得到对应的解析

Hive的ParseDriver类中,通过antlr生成的语法树AST。
例子:Select name,ip from zpc where age > 10 and area in (select area from city)

(TOK_QUERY 
(TOK_FROM 
(TOK_TABREF 
(TOK_TABNAME zpc)
)
) 
(TOK_INSERT 
(TOK_DESTINATION (TOK_DIR TOK_TMP_FILE)) 
(TOK_SELECT 
(TOK_SELEXPR (TOK_TABLE_OR_COL name)) (TOK_SELEXPR (TOK_TABLE_OR_COL ip))
) 
(TOK_WHERE 
(and 
(> (TOK_TABLE_OR_COL age) 10) 
(TOK_SUBQUERY_EXPR (TOK_SUBQUERY_OP in) 
(TOK_QUERY 
(TOK_FROM 
(TOK_TABREF 
(TOK_TABNAME city)
)
) 
(TOK_INSERT 
(TOK_DESTINATION (TOK_DIR TOK_TMP_FILE)) 
(TOK_SELECT 
(TOK_SELEXPR (TOK_TABLE_OR_COL area))
)
)
) 
(TOK_TABLE_OR_COL area)
)
)
)
)
)

注:1.TOK_INSERT个节点是在语法改写中特意 增加了的一个节点。原因是Hive中所有查询的数据均会保存在HDFS临时的文件中,无论是中间的子查询还是查询最终的结果,Insert语句最终会将数 据写入表所在的HDFS目录下。
2.每个表生成一个TOK_TABREF节点。

目标:可以遍历AST,获取到table和table对应的列名。
另外可以从mysql中获取table的列及类型对应信息。(调用desc table即可)。
调用hive树的遍历:((SemanticAnalyzer) sem).doPhase1(ast, qb, null);
QBParseInfo info = qb.getParseInfo();
QBParseInfo中可以获取表名,分区名,列名,别名等信息。
判断QB的属性和方法后,觉得QB中的信息并不是想要的信息。

结论:自定义遍历器,来遍历AST树中的表名。遍历器的实现其实也很简单,深度遍历,判断对应的token节点获取相应的值。

 

---恢复内容结束---

posted on 2015-06-17 20:43  在大地画满窗子  阅读(6408)  评论(0编辑  收藏  举报