hive变量传递的源码实现
用过hive的人都知道,可以通过在cli向hive传递参数,变量等,这里其实是通过下面两个类实现的。
org.apache.hadoop.hive.ql.processors.SetProcessor类
org.apache.hadoop.hive.ql.parse.VariableSubstitution类
其中SetProcessor类定义了对set 命令的处理,VariableSubstitution类负责把变量值进行转换。
VariableSubstitution用来实现在解析hive命令时把特殊字符进行转换,如果是以!开头的shell命令的话,直接在 CliDriver类的 processCmd方法中做转换
else if (cmd_trimmed.startsWith("!")) {String shell_cmd = cmd_trimmed.substring(1);shell_cmd = new VariableSubstitution().substitute(ss.getConf(), shell_cmd);
其他的命令会在具体的CommandProcessor 实现类中做转换。关于CommandProcessor 类这里简单说下,后面会相信分析:
CommandProcessor 的调用是在在CliDriver类的processLocalCmd 方法中发生的。
int processLocalCmd (String cmd, CommandProcessor proc, CliSessionState ss)
这里传入一个CommandProcessor 的实例,函数中会判断具体的实现类。如果实现类是Driver类(即执行的命令是sql),会调用Driver的run方法。
if (proc instanceof Driver) {Driver qp = (Driver) proc;
.....ret = qp.run(cmd).getResponseCode();
如果是其他实现类(即执行的命令是set/add/compile等),会调用对应实现类(commandprocessor相关类)的run方法。
下面分析下VariableSubstitution的具体实现:
VariableSubstitution类有两个控制参数
hive.variable.substitute 控制是否打开Substitution功能,默认是true
hive.variable.substitute.depth ,控制可以匹配到几层,默认是40
主要有getSubstitute和substitute方法。
方法的调用顺序是
substitute----->getSubstitute
其中substitute 方法如下:
public String substitute ( HiveConf conf, String expr) {
if (conf.getBoolVar( ConfVars.HIVEVARIABLESUBSTITUTE)){ //判断hive.variable.substitute是否设置truel4j.debug( "Substitution is on: "+expr);} else {return expr;}if (expr == null) {return null;}Matcher match = varPat.matcher( "");String eval = expr;for(int s=0;s<conf.getIntVar( ConfVars.HIVEVARIABLESUBSTITUTEDEPTH); s++) {match.reset(eval);if (!match.find()) { //判断输入的命令是否匹配"\\$\\{[^\\}\\$\u0020]+\\}",如果不匹配直接返回return eval;}String var = match.group();var = var.substring(2, var.length()-1); // remove ${ .. }String val = getSubstitute(conf, var);if (val == null) {l4j.debug("Interpolation result: " +eval);return eval; // return literal, no substitution found}// substituteeval = eval.substring(0, match.start())+val+eval.substring(match.end()); //完成替换}throw new IllegalStateException("Variable substitution depth too large: "+ conf.getIntVar(ConfVars.HIVEVARIABLESUBSTITUTEDEPTH) + " " + expr);}
其中getSubstitute会调用SetProcessor类,来解析命令。
比如,以hiveconf:开头的命令会经过如下的处理:
if (var.startsWith( SetProcessor.HIVECONF_PREFIX)){val = conf.get(var.substring( SetProcessor.HIVECONF_PREFIX.length()));}
但是对于使用命名空间如hiveconf,system,env的,前缀则不可少,hivevar可以不需要前缀。
if (val == null){if(var.startsWith( SetProcessor.HIVEVAR_PREFIX)){ //这里HIVEVAR_PREFIX的值是hivevar:val = SessionState.get().getHiveVariables().get(var.substring( SetProcessor.HIVEVAR_PREFIX.length()));} else {val = SessionState.get().getHiveVariables().get(var);}}
这里有个例子:
set system:testdate=20140816;
select * from chinacache_log where dt >= '${system:testdate}' limit 5;
1)第一个set命令在经过processLocalCmd 方法处理之后,传入substitute的expr是20140816 (取=号之后的数据)
因为不能匹配到正则,直接回返回。
String eval = expr;
.....if (!match.find()) { return eval;}
2)第2条sql
select * from xxxx where f1>='${system:testdate}'
由Driver处理后,传入的expr是
select * from peter001 where f1>='${system:testdate}'
由match.group()匹配到${system:testdate},然后通过
var.substring(2, var.length()-1)
去除掉${},并调用getSubstitute获取设置的变量值,并最终生成一个有效的sql。
最终由
eval.substring(0, match.start())+val+eval.substring(match.end())
返回的值是
select * from peter001 where f1>='20140816'
完成了变量的替换。
转载于:https://blog.51cto.com/caiguangguang/1541758
hive变量传递的源码实现相关推荐
- react中context到底是如何传递的-源码分析
react中使用context 基本要求就是 父组件中声明Parent.prototype.getChildContext 父组件中声明Parent.childContextType 子组件声明 Ch ...
- Flutter路由管理和页面参数的传递(源码分析)
前言 上一篇 Flutter路由管理和页面参数的传递(获取&返回) 文章中我们讲述了这么用代码实现 Flutter 中页面参数的传递,这一篇我们用源码分析一下 Navigator 为什么可以进 ...
- hive 强转为string_String 源码浅析————终结篇
写在前面 说说这几天看源码的感受吧,其实 jdk 中的源码设计是最值得进阶学习的地方.我们在对 api 较为熟悉之后,完全可以去尝试阅读一些 jdk 源码,打开 jdk 源码后,如果你英文能力稍微过得 ...
- 关于互斥锁,条件变量的内核源码解析
一.解决问题和适用范围 主要是用来等待一个条件,这个条件可能需要另一个线程来满足这个条件.这个和我们平常适用的pthread_mutex_lock的最大不同在于后者保护的一般是一个代码段(也就是关键区 ...
- 二位数组的随机生成,遍历,求和,反转。和两个变量的^反转 源码
import java.util.Random;/*** derf*/ public class Operate {public static void main(String[] args) {in ...
- Hive学习(一)窗口函数源码阅读
Hive学习(一)窗口函数源码阅读 背景 窗口函数执行逻辑 代码流转图 源码阅读分析 PTFOperator PTFInvocation PTFPartition TableFunctionEvalu ...
- nginx源码分析之变量
nginx中的变量在nginx中的使用非常的多,正因为变量的存在,使得nginx在配置上变得非常灵活. 我们知道,在nginx的配置文件中,配合变量,我们可以动态的得到我们想要的值.最常见的使用是,我 ...
- Hive源码阅读之路
Hive源码阅读(1)阅读环境搭建 前言:让学习成为一种习惯 环境准备 Hive源码下载 Hive源码目录 hive三个最重要的组件: 其他组件 hive辅助组件 编译源码 配置Hive本地调试 配置 ...
- uboot源码——环境变量
以下内容源于朱有鹏嵌入式课程的学习,如有侵权,请告知删除. 参考资料:http://www.cnblogs.com/biaohc/p/6398515.html. 一.uboot的环境变量基础 1.环境 ...
- HashMap、ConcurrentHashMap源码解读(JDK7/8)
下载地址(已将图片传到云端,md文件方便浏览更改):https://download.csdn.net/download/hancoder/12318377 推荐视频地址: https://www.b ...
最新文章
- IIS初始化(预加载),解决第一次访问慢,程序池被回收问题
- go语言定义二维数组
- 光流 | 由粗到精的稠密光流算法
- zabbix监控搭建
- 5-(基础入门篇)学会刷Wi-Fi模块固件(刷LUA版本固件)
- pyecharts geo_pyechartstableau可视化分析案例+分析思路
- 延迟分析中的案例研究:锁定与同步
- 【机器学习】opencv-人脸识别
- torch学习笔记--tensor介绍2,对tensor的结构
- c语言加速度积分得到速度_自编微积分教材-第一章 微积分漫谈(1)
- 二维数组名作为实参或者形参
- 阿里巴巴证实全资收购协作软件平台 Teambition
- Xcode 4.2 中的Automatic Reference Counting (ARC)
- JAVA如何选中一行上移_js操作table中tr的顺序实现上移下移一行的效果
- xlsxwriter去掉网格线_(原创)xlsxwriter,python excel 写入数据\图表等操作_图表操作(二)...
- 《现代信息检索导论》课程梳理
- 天线的极化与圆极化天线
- 用python画小仓鼠代码,用python画小仓鼠教程
- 【计算机操作系统】新兴操作系统
- html 获取浏览器语言,js之获取浏览器语言
热门文章
- KVM 介绍(2):CPU 和内存虚拟化
- Camera 初始化(Open)一(FrameWork - Hal)
- freeswitch的dialplan中condition变量
- Linux虚拟文件系统之文件打开(sys_open())
- android AES对称加密算法使用实例
- 上传附件点击事件_支持高拍仪扫描凭证附件的出纳记账软件
- Bellman-ford算法、SPFA算法、SPFA判断负环(附例题)
- 同余方程-NOIP2012TGD2T1
- 51nod1433--简单数学
- baum welch java_Baum Welch估计HMM参数实例