Spark SQL的解析层是Spark SQL执行流程的第一个环节。解析层的目标就是将SQL转成 AST(抽象语法树)。
Spark 从 2.0版本开始就使用 ANTLR ( Another Tool for Language Recognition) 进行词法和语法解析。Spark 使用 ANTLR 将 SQL转化成 AST,这个 AST 通常称为 Unresolved Logical Plan(这个称呼来源于 Spark SQL 的原始论文,源码中一般称为 Parsed Logical Plan)。
ANTLR文件SQLBaseLexer.g4的内容大概如下:
lexer grammar SQLBaseLexer;
@members{
// 变量和函数定义
}
// Token 定义
ANTLR文件SQLBaseParser.g4的内容大概如下:
lexer grammar SQLBaseParser;
option { tokenVocab = SQLBaseLexer; }
@members{
// 变量和函数定义
}
// 语法定义
SqlBaseParser相关接口和类如下:
- ParseTreeVisitor 定义了语法树的层级结构。
- AbstractParseTreeVisitor 本身是抽象类,实现了 ParseTreeVisitor 定义的语法树层级结构。
- SqlBaseParserg4 文件,生成了对应的访问入口。例如:生成了visitQuery、 visitSingleStatement.visitStatementDefault、 visitQueryOrganization 等接囗。
- SqlBaseParserBaseVisitor 通过继承AbstractParseTreeVisitor 并实现SqlBaseParserVisitor,将 SQL 语法与语法树的层级结构编织到一起。
- SqlBaseParser 相当于 ANTLR4 语法解析的入口,中间通过操作 SqlBaseParserVisitor 来进行语法解析。
解析层的入口在 ParseDriver.scala
/** 为给定的 SQL 字符串创建一个 LogicalPlan */
override def parsePlan(sqlText: String): LogicalPlan = parse(sqlText) { parser =>
astBuilder.visitSingleStatement(parser.singleStatement()) match {
case plan: LogicalPlan => plan
case _ =>
val position = Origin(None, None)
throw QueryParsingErrors.sqlStatementUnsupportedError(sqlText, position)
}
}
上述代码包含 4 个流程阶段:parse、生成解析树、生成 AST、结果处理。
后续会结合代码对流程进行进一步介绍。
参考:
《Apache Spark SQL 解析层优化》- 耿嘉安