HiveSQL注释问题排查

现象:

--CREATE EXTERNAL TABLE ads_meta_dev.ads_meta_flow_aa_index_pd
set hive.merge.tezfiles = true;

这条SQL用beeline查询没问题

beeline -u 'jdbc:hive2://hive-adhoc:10000/default?mapreduce.job.queuename=tc_infra_tsn_dev;auth=noSasl' -n tc_warehouse -p hive_PY8fJ70p --hiveconf hive.stats.autogather=false --hiveconf hive.strict.checks.large.query=false --hiveconf hive.mapred.mode=nostrict -e "--CREATE EXTERNAL TABLE ads_meta_dev.ads_meta_flow_aa_index_pd \n set hive.merge.tezfiles = true;"
 
echo '--CREATE EXTERNAL TABLE ads_meta_dev.ads_meta_flow_aa_index_pd \n set hive.merge.tezfiles = true;' > /tmp/test.sql
beeline -u 'jdbc:hive2://hive-adhoc:10000/default?mapreduce.job.queuename=tc_infra_tsn_dev;auth=noSasl' -n tc_warehouse -p hive_PY8fJ70p --hiveconf hive.stats.autogather=false --hiveconf hive.strict.checks.large.query=false --hiveconf hive.mapred.mode=nostrict -f /tmp/test.sql

但是在即席查询平台就会报错

平台把异常做了封装,看不到具体的堆栈日志

所以用正式环境的hive源码编译在本地搭建hiveserver服务,复现问题

hiveserver日志

只看堆栈日志也看不出啥问题,很正常的一条sql为啥用HiveStatement方式查询回报错?

即席查询执行SQL的方式

debug跟踪下代码

从哪个地方入手?看堆栈信息报错的地方是 PareserDriver.parse 方法,在这个地方打上断点

再往下就是parse解析器,应该不会是解析器的问题

但是set命令为啥会走到 解析 SQL的 ParseDriver 呢?应该是前面就出问题了

往上翻堆栈

发现 这个地方的 operation (ExecuteStatementOperation) 是个抽象类

而实现是 HiveCommandOperation 和 SQLOperation

更加印证了之前的猜想,set 语句应该是 command命令,应该用 HiveCommandOperation,但是现在却是用的 SQLOperation

看operation具体是怎么生成的

具体逻辑在 CommandProcessorFactory.getForHiveCommand(tokens, parentSession.getHiveConf()) 这个方法的参数 tokens 是将 SQL 按空格分割成的数组,依据tokens数组的第一个字符串是不是特殊命令来判断是不是command命令

这条SQL分割出来的结果是

["--CREATE", "EXTERNAL", "TABLE", "ads_meta_dev.ads_meta_flow_aa_index_pd", "set", "hive.merge.tezfiles", "=", "true"],返回的是 SQLOperation,所以用到了ParseDriver

感觉是 Hive 的一个bug

看Hive的高版本有没有修复这个问题

翻到 ExecuteStatementOperation 这个文件的修改历史,果然找到一个patch HIVE-16935 修复了这个问题,但是在3.0.0版本才上线

只是加了一行处理 HiveStringUtils.removeComments(statement) 就是把SQL的注释都去掉

在公司hive-2.1.1的源码加上这段逻辑,在本地重新编译打包,运行同样的SQL没有再报错

但是要改线上的hive要重启服务,影响比较大,把HiveStringUtils类复制放到zue上,在下发查询的时候处理SQL,同样也能解决问题

打赏一个呗

取消

感谢您的支持,我会继续努力的!

扫码支持
扫码支持
扫码打赏,你说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦