spark sql parse 过程
2020-04-19 本文已影响0人
莱布尼茨不会求导
-
spark sql parse 引擎
- ANTLR(ANother Tool for Language Recognition),kudu、presto、hive 都是用 ANTLR 解析 sql 语句。
- ANTLR 提供了两种机制来访问生成的语法树:Listener 和 Visitor, spark sql 使用的是 Visitor 模式,具体实现类为: SqlBaseVisitor, Hive 好像使用的是 Listener 模式
-
antlr4 的使用需要定义一个语法文件,spark sql 的语法文件的路径在
image.png-
antlr 会根据上面定义的 sqlBase.g4 生成语法解析(SqlBaseParser) 和词法解析器(SqlBaseLexer)
image.png
-
-
spark sql 的解析是 SparkSqlParser 完成的
SparkSqlParse 继承自 AbstractSqlParser 抽象类,抽象类中提供了一个 parsePlan 方法执行具体的解析过程
/**
* Creates LogicalPlan for a given SQL string.
* */
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 new ParseException(Option(sqlText), "Unsupported SQL statement", position, position)
}
}
- 上述 parsePlan 的方法入参是 String 类型的 sqlText,方法返回值为 LogicalPlan, 这个方法的调用完成了输入 sql 语句到 logicalPlan 的转化
- 调用 astBuilder.visitSingleStatement 使用 ANTLR 的 Vistor 模式遍历 Tree,将antlr里面的节点都替换成 catalyst 里面的类型,所有的类型都继承抽象类 TreeNode,TreeNode又有子节点children: Seq[BaseType],组织成了树的结构。
-
spark sql parse 解析案例
-
输入 sql: SELECT name,age FROM people WHERE age > 10 group by 1,2
-
经过 parsePlan 解析出来的 Logical plan,输出如下:
== Parsed Logical Plan == 'Aggregate [1, 2], ['name, 'age] +- 'Filter ('age > 10) +- 'UnresolvedRelation `people`
-
通过设置断点可以看到
image.png
解析出来的 logical plan 的 schema 还没有形成
-