在阅读SparkSql源码过程中,可能会遇到的小迷惑
resolved主要用来标记当前 LogicalPlan 是否为经过了解析。
代码语言:javascript复制//当前logicalplan中的所有的expressions都被解析了,并且该logicalplan的子节点也被解析,刚当前的logicalplan的resolved会返回true
lazy val resolved: Boolean = expressions.forall(_.resolved) && childrenResolved
logicalplan分unresolved logical plan和resolved logical plan,resolved可以被子类重写。
看两个案例
UnresolvedRelation
UnresolvedRelation 是由ASTTree直接生成的unresolved logical plan的节点,还未被解析,所以resolved被赋值为false
Aggregate
Aggregate 有"两重身份",不像 UnresolvedRelation 一定是未解析的。Aggregate即可以unresolved也可resolved。
具体它有没有被解析,主要依靠重写的resolved变量来决定:
1、确认所有expressions都被解析
2、确认当前节点的所有子节点都被解析
3、不能含有window函数。为什么不能含有window函数呢?把sparksql整体的代码看一遍后,就很清楚啦,在生成resolved logical plan阶段,有一个ExtractWindowExpressions的规则,这个规则专门负责把window函数抽取为window节点。
ExtractWindowExpressions的apply方法如下:
看具体的执行计划也很清晰
Sql:
代码语言:javascript复制SELECT A,B, COUNT(1) AS CNT,row_number() over(partition by A order by B desc) as rn FROM TESTDATA2 WHERE A>2 GROUP BY A,B