2021SC@SDUSC
目录
在上一篇博客里其实已经提到有关processLocalCmd这个方法的一些内容了。这里还会按照逻辑来从这个方法的开头开始讲,会有重复。
从调用开始
我们先回到processCmd
这个方法的最后
我要在继续推进processLocalCmd
方法之前再确认一下这三个变量。
cmd
:单条完整HQL指令字符串
proc
:这是一个CommandProcessor
对象,他具体的内容取决于这个命令是否是“非HQL语句”,如果是划定的一系列“非HQL语句”中的一员,那么这个对象将会是某一种特殊的对象;如果不是“非HQL语句”(且不是个空语句),那么就会返回Driver
类或ReExecDriver
类对象。我们在上一篇博客中已经发现后者的很多方法其实是调用了前者的同名方法,故结合以上几种情况,我们目前先认为proc
大概率是一个Driver
类对象或者最终要调用Driver
类的方法。
ss
:会话相关对象(注释说的)
接下来,我们走进这个方法吧
processLocalCmd的核心:qp.run(cmd)
不同的情况
首先,这个方法的执行也是分情况的。
第一处是检测proc
是否为null
。根据processCmd
中获取proc
的方法来看,proc
只有在语句为空的时候才会是null
。为null
的时候这个方法直接返回ret
,也就是0.
如果proc
不为null
就会进行第二次判断。这一次是判断它是不是IDriver
,此时这条指令应该是一个普通的HQL(这里可以参见本文第一小节)。那么另一个分支中对应的就是所谓的“非HQL”了。我们先着重注意第一种情况。
被计时的方法
我们可以看到这里有一个start
和end
,他们都是取时间的,他们在给一部分代码计时。而在HQL命令行执行命令后显示的内容中,就有记录这个任务执行时长的部分。而这块中,qp.run(cmd).getResponseCode()
就是显而易见的核心了。
Driver
和ReExecDriver
都实现了接口IDriver
,IDriver
中定义了run(String cmd)
的方法。我们之前说过,无论是哪一种IDriver,最后总是在调用Driver
的方法。所以我们下一步就去看Driver
的实现就好了。
重重调用
run(String cmd)
仍然有几层调用,我们来看看
run(String cmd)
调用run(String cmd,boolean alreadyComplied)
。然后,这个主要的run
,实际的工作代码其实就一行,它调用了一个方法。剩下的内容还很多,但是全都是异常处理(其实异常处理部分的代码有注释)。我们先跳过,直接看核心方法runInternal
runInternal
编译入口compileInternal
首先是一些对状态的操作
然后我们就看到了这个!compileInternal
这个方法正式开始对HQL语句进行编译。
前面的部分,那些对象都是用于性能度量的,我们看compile
核心编译方法compile之前
这里遇到了一个问题。compileInternal
这个方法被调用了两次
它们有条件,第一次就是看你有没有编译过,但是第二次调用这个方法的外部条件isValidTxnListState()
涉及了很多东西,而且其涉及的txn
和ctx
这两个变量都在compile
方法中经过了很多的更改,这甚至涉及了我所管辖的范围之外的内容。我会尝试进行交流,尽量去弄懂它的意义。如果实在困难(我们的进度可能并不相同),我会先去解读compile
方法本身