-
spark sql parse 引擎
- ANTLR(ANother Tool for Language Recognition)绞愚,kudu眠寿、presto、hive 都是用 ANTLR 解析 sql 語句锌半。
- ANTLR 提供了兩種機(jī)制來訪問生成的語法樹:Listener 和 Visitor, spark sql 使用的是 Visitor 模式搂抒,具體實(shí)現(xiàn)類為: SqlBaseVisitor, Hive 好像使用的是 Listener 模式
-
antlr4 的使用需要定義一個(gè)語法文件弥臼,spark sql 的語法文件的路徑在
image.png-
antlr 會(huì)根據(jù)上面定義的 sqlBase.g4 生成語法解析(SqlBaseParser) 和詞法解析器(SqlBaseLexer)
image.png
-
spark sql 的解析是 SparkSqlParser 完成的
SparkSqlParse 繼承自 AbstractSqlParser 抽象類,抽象類中提供了一個(gè) parsePlan 方法執(zhí)行具體的解析過程
/**
* 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 的方法入?yún)⑹?String 類型的 sqlText宴咧,方法返回值為 LogicalPlan, 這個(gè)方法的調(diào)用完成了輸入 sql 語句到 logicalPlan 的轉(zhuǎn)化
- 調(diào)用 astBuilder.visitSingleStatement 使用 ANTLR 的 Vistor 模式遍歷 Tree,將antlr里面的節(jié)點(diǎn)都替換成 catalyst 里面的類型径缅,所有的類型都繼承抽象類 TreeNode掺栅,TreeNode又有子節(jié)點(diǎn)children: Seq[BaseType]烙肺,組織成了樹的結(jié)構(gòu)。
-
spark sql parse 解析案例
輸入 sql: SELECT name,age FROM people WHERE age > 10 group by 1,2
-
經(jīng)過 parsePlan 解析出來的 Logical plan氧卧,輸出如下:
== Parsed Logical Plan == 'Aggregate [1, 2], ['name, 'age] +- 'Filter ('age > 10) +- 'UnresolvedRelation `people`
-
通過設(shè)置斷點(diǎn)可以看到
image.png
解析出來的 logical plan 的 schema 還沒有形成