Spark SQL Catalyst源码分析之SqlParser

  /** Spark SQL源码分析系列文章*/

    Spark SQL的核心执行流程我们已经分析完毕,可以参见Spark SQL核心执行流程,下面我们来分析执行流程中各个核心组件的工作职责。

    本文先从入口开始分析,即如何解析SQL文本生成逻辑计划的,主要设计的核心组件式SqlParser是一个SQL语言的解析器,用scala实现的Parser将解析的结果封装为Catalyst TreeNode ,关于Catalyst这个框架后续文章会介绍。

一、SQL Parser入口

    Sql Parser 其实是封装了scala.util.parsing.combinator下的诸多Parser,并结合Parser下的一些解析方法,构成了Catalyst的组件UnResolved Logical Plan。

    先来看流程图:

     

     一段SQL会经过SQL Parser解析生成UnResolved Logical Plan(包含UnresolvedRelation、 UnresolvedFunction、 UnresolvedAttribute)。

    在源代码里是:  

 

 
  1. def sql(sqlText: String): SchemaRDD = new SchemaRDD(this, parseSql(sqlText))//sql("select name,value from temp_shengli") 实例化一个SchemaRDD

  2.  
  3. protected[sql] def parseSql(sql: String): LogicalPlan = parser(sql) //实例化SqlParser

  4.  
  5. class SqlParser extends StandardTokenParsers with PackratParsers {

  6.  
  7. def apply(input: String): LogicalPlan = { //传入sql语句调用apply方法,input参数即sql语句

  8. // Special-case out set commands since the value fields can be

  9. // complex to handle without RegexParsers. Also this approach

  10. // is clearer for the several possible cases of set commands.

  11. if (input.trim.toLowerCase.startsWith("set")) {

  12. input.trim.drop(3).split("=", 2).map(_.trim) match {

  13. case Array("") => // "set"

  14. SetCommand(None, None)

  15. case Array(key) => // "set key"

  16. SetCommand(Some(key), None)

  17. case Array(key, value) => // "set key=value"

  18. SetCommand(Some(key), Some(value))

  19. }

  20. } else {

  21. phrase(query)(new lexical.Scanner(input)) match {

  22. case Success(r, x) => r

  23. case x => sys.error(x.toString)

  24. }

  25. }

  26. }

 

    1.  当我们调用sql("select name,value from temp_shengli")时,实际上是new了一个SchemaRDD

    2. new SchemaRDD时,构造方法调用parseSql方法,parseSql方法实例化了一个SqlParser,这个Parser初始化调用其apply方法。

    3. apply方法分支:

         3.1 如果sql命令是set开头的就调用SetCommand,这个类似Hive里的参数设定,SetCommand其实是一个Catalyst里TreeNode之LeafNode,也是继承自LogicalPlan,关于Catalyst的TreeNode库这个暂不详细介绍,后面会有文章来详细讲解。

         3.2 关键是else语句块里,才是SqlParser解析SQL的核心代码:

 
  1. phrase(query)(new lexical.Scanner(input)) match {

  2. case Success(r, x) => r

  3. case x => sys.error(x.toString)

  4. }

        可能 phrase方法大家很陌生,不知道是干什么的,那么我们首先看一下SqlParser的类图:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值