先看0.7.1的执行过程:
hive> select * from table02 where id=500000;
对于这样的一个查询,Hive从CliDriver这个类的main函数开始:
CliDriver.main(String[] args)
CliSessionState ss=new CliSessionState(new HiveConf(SessionState.class));
SessionState.start(ss);
CliDriver cli=new CliDriver();
废话不多说来到了主要的循环:
while((line=reader.readLine(curPrompt +"> "))!=null){
处理每一行数据,当然还包括一些一个命令分成多行的处理,不多说。
ret=cli.processLine(line String);
processCmd(oneLine);//可能一个line包含多个“;”,需要分开处理
一些特别的命令单独处理,像exit,source等。。。
CommandProcessor proc = CommandProcessorFactory.get(tokens[0],(HiveConf)conf);
这里set dfs add delete 会返回相应的处理器,其余的返回new Driver()
if proc instance of Driver
ret=proc.run(cmd).getResponseCode();
Driver.compile(cmd);
Driver.execute();
轮询compile出来的每一个task,Driver.launchTask(tsk,queryId,noName,running,jobname,jobs.ctx);
用TaskRunner包装tsk,tskRun.runSequential();
tsk.executeTask();
tsk.execute(drivercontext);调用相应的子类的execute方法。{
举两个例子,
如果是show tables; 则是DDLTask,一直判断到ShowTableDesc showTbls= work.getShowTblsDesc();
if(showTbls !=null) return showTables(db,showTbls);
如果是上面那个查询;则是MapreduceTask,最后会来到这么一句话:
executor=Runtime.getRuntime().exec(cmdLine,env,new File(workDir));//workDir是/home/allen/Desktop/hive-0.7.1
将executor所在进程的输出打印转移到本线程中来。
int exitVal=executor.waitFor(); //等待执行。 至于cmdLine是什么样,见前一篇文章。
返回retValue;
}
返回retValue;
返回retValue;
从tskRun返回
从Driver.execute()返回成功值
return new CommandProcessResponse(retValue);
从proc.getResults(res) 打印query 结果
计算时间,打印出来
else 执行命令,set dfs等
return retValue;
CommandProcessorFactory.clean()
返回返回值
终于回到了while循环体内。
}
main函数体。
Driver.compile(cmd); 就是根据hql语句做优化,生成plan.xml的地方。以后要重点分析下。
现在看下0.8.1有什么改变
CliDriver.main(String[] args){
int ret=run(args);// while循环没有放到main函数里面,为什么要这样
System.exit(ret);
}
看run(args){
CliSessionState ss =new CliSessionState(new HiveConf(SessionState.class));//上来这里就报找不到bulltin class{
调用了CliSessionState(hiveconf)构造函数{
super(conf);//super就是SessionState{
Class<?> pluginClass =Utilities.getBuiltinUtilsClass();
Url jarLocation=pluginClass.getProtectionDomain().getCodeSource().getLocation(); 这里返回的是/hive-0.8.1/eclipse-out/
add_buildin_resource(ResourceType.JAR,jarLocation.toString());
FunctionRegistry.registerFunctionsFromPluginJar(jarLocation,pluginClass.getClassLoader()); //这里报异常,解决方法:将src/builtins/ 从build path 的src中删除,搞定!!!
}
}
}
SessionState.start(ss);
CliDriver cli = new CliDriver();
while(读取命令行){
ret=cli.processLine(line,true);
for(";"分割){
ret = processCmd(command);{
CommandProcessor proc = CommandProcessorFactory.get(token[0],conf);
ret = processLocalCmd(cmd,proc,ss);{
还是判断是否instanceof Driver{
计时;
ret= qp.run(command).getResponseCode();{
int ret = compile (command);{//这里报空指针,Debug了半天,是0.7.1生成的metastore直接给0.8.1用不支持的缘故
ParseDriver pd = new ParseDriver();
ASTNode tree =pd.parse(command,ctx);
}
ret=execute();{//Driver.execute()
对每一个tasks,launchTask(tsk,queryId,noName,running,jobname,jobs,driverCxt);
下面和0.7.1一样。。。
}
}
}
}
}
}
}
}