- 由前文可知,真正执行sql的位置是ret = qp.run(cmd).getResponseCode();ctrl+鼠标左键进入run方法中,发现其中是一个抽象方法
按ctrl+H查看层级,进入Driver中,Driver中对run进行了实现;即真正的处理均在Driver中实现的,而run方法则是这个类的入口
可以发现run方法调用同名的方法,但输入参数多了一个alreadyComplied,该参数表示是否已经编译完成
@Override
public CommandProcessorResponse run(String command) {
return run(command, false);//第二个参数表示是否已经编译完成
}
public CommandProcessorResponse run(String command, boolean alreadyCompiled) {
// 这一句调用的runInternal是对sql的执行,下面都是对执行结果的校验
// 不管对不对,先执行,保证优先性
try {
runInternal(command, alreadyCompiled);
return createProcessorResponse(0);
} catch (CommandProcessorResponse cpr) {
}
}
- 可以看到上述run方法中最重要的是进入了runInternal方法中,注意上文中传入的第二个参数是false
进入runInternal方法中,根据alreadyCompiled=false我们可以找到程序该方法下一步调用的是compileInternal方法,先不着急进入该方法中,继续向下看,可以看到执行完compileInternal后会执行execute方法,即sql的解析、编辑、优化和最后的执行不是在一个方法中实现的
6.1在 compileInternal方法中把SQL编译为QueryPlan(解析、编译、优化)
6.2 在execute();中执行QueryPlan中的所有task
//编译和执行程序同级别在该方法中调用
private void runInternal(String command, boolean alreadyCompiled) throws CommandProcessorResponse {
if (!alreadyCompiled) {
// compile internal will automatically reset the perf logger
// 调用compileInternal方法把SQL编译为QueryPlan
compileInternal(command, true);//进行解析、编译、优化
// then we continue to use this perf logger
perfLogger = SessionState.getPerfLogger();
} else {
// reuse existing perf logger.
perfLogger = SessionState.getPerfLogger();
// Since we're reusing the compiled plan, we need to update its start time for current run
plan.setQueryStartTime(perfLogger.getStartTime(PerfLogger.DRIVER_RUN));
}
try {
// 调用execute执行QueryPlan中的所有task
execute();
} catch (CommandProcessorResponse cpr) {
rollback(cpr);
throw cpr;
}
}
- 我们先看sql的解析编译和优化过程,即 compileInternal
private void compileInternal(String command, boolean deferClose) throws CommandProcessorResponse {
try {
// Driver的run方法最终会执行compile()操作,Compiler作语法解析和语义分析。
// compile()是Driver最关键的方法,单个方法代码近300行。
compile(command, true, deferClose);
} catch (CommandProcessorResponse cpr) {
try {
releaseLocksAndCommitOrRollback(false);
} catch (LockException e) {
LOG.warn("Exception in releasing locks. " + org.apache.hadoop.util.StringUtils.stringifyException(e));
}
throw cpr;
} finally {
compileLock.unlock();
}
}



