/** Spark SQL源码分析系列文章*/
前面几篇文章讲解了Spark SQL的核心执行流程和Spark SQL的Catalyst框架的Sql Parser是怎样接受用户输入sql,经过解析生成Unresolved Logical Plan的。我们记得Spark SQL的执行流程中另一个核心的组件式Analyzer,本文将会介绍Analyzer在Spark SQL里起到了什么作用。
Analyzer位于Catalyst的analysis package下,主要职责是将Sql Parser 未能Resolved的Logical Plan 给Resolved掉。
一、Analyzer构造
Analyzer会使用Catalog和FunctionRegistry将UnresolvedAttribute和UnresolvedRelation转换为catalyst里全类型的对象。
Analyzer里面有fixedPoint对象,一个Seq[Batch].
-
class Analyzer(catalog: Catalog, registry: FunctionRegistry, caseSensitive: Boolean)
-
extends RuleExecutor[LogicalPlan] with HiveTypeCoercion {
-
// TODO: pass this in as a parameter.
-
val fixedPoint = FixedPoint(100)
-
val batches: Seq[Batch] = Seq(
-
Batch("MultiInstanceRelations", Once,
-
NewRelationInstances),
-
Batch("CaseInsensitiveAttributeReferences", Once,
-
(if (caseSensitive) Nil else LowercaseAttributeReferences :: Nil) : _*),
-
Batch("Resolution", fixedPoint,
-
ResolveReferences ::
-
ResolveRelations ::
-
NewRelationInstances ::
-
ImplicitGenerate ::
-
StarExpansion ::
-
ResolveFunctions ::
-
GlobalAggregates ::
-
typeCoercionRules :_*),
-
Batch("AnalysisOperators", fixedPoint,
-
EliminateAnalysisOperators)
-
)
Analyzer里的一些对象解释:
FixedPoint:相当于迭代次数的上限。
-
/** A strategy that runs until fix point or maxIterations times, whichever comes first. */
-
case class FixedPoint(maxIterations: Int) extends Strategy
Batch: 批次,这个对象是由一系列Rule组成的,采用一个策略(策略其实是迭代几次的别名吧,eg:Once)
-
/** A batch of rules. */,
-
protected case class Batch(name: String, strategy: Strategy, rules: Rule[TreeType]*)
Rule:理解为一种规则,这种规则会应用到Logical Plan 从而将UnResolved 转变为Resolved
-
abstract class Rule[TreeType <: TreeNode[_]] extends Logging {
-
/** Name for this rule, automatically inferred based on class name. */
-
val ruleName: String = {
-
val className = getClass.getName
-
if (className endsWith "$") className.dropRight(1) else className
-
}
-
def apply(plan: TreeType): TreeType
-
}
Strategy:最大的执行次数,如果执行次数在最大迭代次数之前就达到了fix point,策略就会停止,不再应用了。
-
/**
-
* An execution strategy for rules that indicates the maximum number of executions. If the
-
* execution reaches fix point (i.e. converge) before maxIterations, it will stop.
-
*/
-
abstract class Strategy { def maxIterations: Int }
Analyzer解析主要是根据这些Batch里面定义的策略和Rule来对Unresolved的逻辑计划进行解析的。
这里Analyzer类本身并没有定义执行的方法,而是要从它的父类RuleExecutor[LogicalPlan]寻找,Analyzer也实现了HiveTypeCosercion,这个类是参考Hive的类型自动兼容转换的原理。如图:
RuleExecutor:执行Rule的执行环境,它会将包含了一系列的Rule的Batch进行执行,这个过程都是串行的。
具体的执行方法定义在apply里:
可以看到这里是一个while循环,每个batch下的rules都对当前的plan进行作用,这个过程是迭代的,直到达到Fix Point或者最大迭代次数。
-
def apply(plan: TreeType): TreeType = {
-
var curPlan = plan