源:http://caiguangguang.blog.51cto.com/1652935/1541758
hive 可以通过在cli向hive传递参数,变量等,其实是通过下面两个类实现
1、org.apache.hadoop.hive.ql.processors.SetProcessor类
2、org.apache.hadoop.hive.ql.parse.VariableSubstitution类
其中,SetProcessor类定义了对set命令的处理,VariableSubstitution类负责把变量值进行转换
VaruableSublititution用来实现在解析hive命令时把特殊字符进行转换,如果是以!开头的shell命令的话,直接在CliDriver类的processCmd方法中做转换
1
2
3
|
else
if
(cmd_trimmed.startsWith(
"!"
)) {
String shell_cmd = cmd_trimmed.substring(
1
);
shell_cmd =
new
VariableSubstitution().substitute(ss.getConf(), shell_cmd);
|
CommandProcessor的调用是在CliDriver类的processLocalCmd方法中发生的
int
processLocalCmd (String cmd, CommandProcessor proc, CliSessionState ss)
1
2
3
4
|
if
(proc
instanceof
Driver) {
Driver qp = (Driver) proc;
.....
ret = qp.run(cmd).getResponseCode();
|
VariableSubtitution的具体实现:
VariableSutitution类有两个控制参数
1
2
|
hive.variable.substitute 控制是否打开Substitution功能,默认是
true
hive.variable.substitute.depth ,控制可以匹配到几层,默认是
40
|
方法的调用顺序是
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
|
public
String substitute ( HiveConf conf, String expr) {
if
(conf.getBoolVar( ConfVars.HIVEVARIABLESUBSTITUTE)){
//判断hive.variable.substitute是否设置true
l4j.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
}
// substitute
eval = eval.substring(
0
, match.start())+val+eval.substring(match.end());
//完成替换
}
throw
new
IllegalStateException(
"Variable substitution depth too large: "
+ conf.getIntVar(ConfVars.HIVEVARIABLESUBSTITUTEDEPTH) +
" "
+ expr);
}
|
比如,以hiveconf:开头的命令会经过如下的处理;
1
2
3
|
if
(var.startsWith( SetProcessor.HIVECONF_PREFIX)){
val = conf.get(var.substring( SetProcessor.HIVECONF_PREFIX.length()));
}
|
1
2
3
4
5
6
7
|
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);
}
}
|
1
2
|
set system:testdate=
20140816
;
select * from chinacache_log where dt >=
'${system:testdate}'
limit
5
;
|
1
2
3
4
5
|
String eval = expr;
.....
if
(!match.find()) {
return
eval;
}
|
1
|
select * from xxxx where f1>=
'${system:testdate}'
|
1
|
select * from peter001 where f1>=
'${system:testdate}'
|
1
|
var.substring(
2
, var.length()-
1
)
|
1
|
eval.substring(
0
, match.start())+val+eval.substring(match.end())
|
1
|
select * from peter001 where f1>=
'20140816'
|