上一篇已经初始化完成sparkSession,以及各种初始化的类,从这篇开始我们着重说catalyst的整体流程。
第一个流程是sql语句经过语法和词法分析解析成Unresolved Logical Plan。

SparkSession.sql()

从上一篇我们知道sqlParser=SparkSqlParser, SparkSqlParser是spark解析sql预发成LogicalPlan的核心类。 SparkSqlParser继承了抽象类AbstractSqlParser。

最终调用的是AbstractSqlParser.parsePlan()

在线sparksql编译器 sparksql源码解析_执行计划

在线sparksql编译器 sparksql源码解析_sql_02


astBuilder的初始化是在SparkSqlParser中,继承关系如下

astBuilder = SparkSqlAstBuilder -> AstBuilder-> SqlBaseBaseVisitor,

在线sparksql编译器 sparksql源码解析_big data_03


在这个地方spark使用了Antlr4进行语法和词法的解析。

SqlBase.g4

SqlBase.g4文件是Antlr4的基础文件,
路径:sql/catalyst/src/main/antlr4/org/apache/spark/sql/catalyst/parser/SqlBase.g4
下图就是一些常用的查询语法,想要深入的了解源码中的执行内容,就需要对SqlBase.g4文件有一定的了解,这个对后续自定义一些语法有很大的帮助。
比如我们常用的:

  • relation 一般指查询的hive表,文件等
  • namedExpression 变量
  • valueExpression 变量的值


    下面就是我用idea的插件运行了一个sql.

SqlBase.g4在编译执行之后会创建一些执行文件,spark会继承这些文件做自定义的操作。比如AstBuilder 继承SqlBaseBaseVisitor.

在线sparksql编译器 sparksql源码解析_在线sparksql编译器_04


以SqlBaseBaseVisitor为例,其实就是以SqlBase.g4中按照语法来生成的,spark只需继承重写部分函数即可。

在线sparksql编译器 sparksql源码解析_big data_05

SparkSqlParser

回到ParseDriver的parsePlan(), 我们可以知道,astBuilder = SparkSqlParser

在线sparksql编译器 sparksql源码解析_spark_06


在线sparksql编译器 sparksql源码解析_sql_07


下图中通过解析整个语法树,sql转换成逻辑执行计划,当前生成的逻辑执行计划还是Unresolved Logical Plan。

在线sparksql编译器 sparksql源码解析_在线sparksql编译器_08


在线sparksql编译器 sparksql源码解析_sql_09

Tree

Tree是Catalyst执行计划表示的数据结构。LogicalPlans,Expressions和Pysical Operators都可以使用Tree来表示。Tree具备一些Scala Collection的操作能力和树遍历能力。
Tree有三种

  • UnaryNode:一元节点,即只有一个子节点 ag: Project
  • BinaryNode:二元节点,即有左右子节点的二叉节点 ag : Join
  • LeafNode:叶子节点,没有子节点的节点 ag: HiveTableRelation
    Tree有两个子类继承体系,即QueryPlan和Expression

QueryPlan下面的两个子类分别是LogicalPlan(逻辑执行计划)和SparkPlan(物理执行计划)

Expression是表达式体系,是指不需要执行引擎计算,而可以直接计算或处理的节点

在线sparksql编译器 sparksql源码解析_sql_10

以AstBuilder.visitQuerySpecification为例

在线sparksql编译器 sparksql源码解析_big data_11


在线sparksql编译器 sparksql源码解析_spark_12


在线sparksql编译器 sparksql源码解析_big data_13

这个地方就可以理解SparkSqlParser 是怎么把Tree的节点转换成LogicalPlan.

我以一个sql为例来看一下它具体的执行计划

select count(org_id), bu_cd  from dim_org group by bu_cd limit 1024

在线sparksql编译器 sparksql源码解析_在线sparksql编译器_14