之前已经对spark core做了较为深入的解读,在如今SQL大行其道的背景下,spark中的SQL不仅在离线batch处理中使用广泛,structured streamming的实现也严重依赖spark SQL。因此,接下来,会对spark SQL做一个较为深入的了解。

本文首先介绍一下spark sql的整体流程,然后对这个流程之中涉及到的第一个步骤:SQL语法解析部分做一下较为深入的分析。

1,spark sql概述

首先截取一张任何介绍spark sql实现都会出现的图(如下)。

总体执行流程如下:从提供的输入API(SQL,Dataset, dataframe)开始,依次经过unresolved逻辑计划,解析的逻辑计划,优化的逻辑计划,物理计划,然后根据cost based优化,选取一条物理计划进行执行。从unresolved logical plan开始, sql的查询是通过抽象语法树(AST)来表示的,所以以后各个操作都是对AST进行的等价转换操作。 针对以上过程作如下几点说明:

1,编程接口:通过像df.groupBy("age")这样的Dataset接口构造查询过程,抽象语法树(AST)会自动建立。而通过“SELECT name, count(age) FROM people where age > 21 group by name” 这样的sql语句进行查询时,需要增加一个步骤是,需要将SQL解析成AST(spark 2.2中目前是借助于antlr4来做的,具体见后面分析)。

2,经过步骤1后,我们可以得到unresolved logical plan,此时像以上sql中的name,count(age),people都是unresolved attribute,relation等,他们是AST树TreeNode的一中类型,但是他们是不能被计算的(实现了Unevaluable接口)。

3,unresolved logical plan通过Analyzer模块定义的一系列规则,将步骤2中的unresolved的attribute,relation借助catalog去解析,如将之前提到的unresolved attribute转换成resolved attribute。此时,如果sql中某个表不存在或者列和表不对应,在此阶段便可以发现。Analyzer定义一系列部分规则如下:

4,解析成resolved logical plan以后,通过一系列优化规则会将resolved logical plan的AST转化成optimized logical plan的AST。这些优化包括基于规则和代价的优化,比如谓词下推,列值裁剪等。

5,AST到了optimized logical plan以后,利用如下的策略将逻辑计划转化成物理计划,物理计划是可以执行的计划。当有相关的action操作时,物理计划便可以执行。

2,SQL Parser的具体实现

在上节步骤1中提到,如果使用选择使用SQL进行查询,首先需要将SQL解析成spark中的抽象语法树(AST)。在spark中是借助开源的antlr4库来解析的。Spark SQL的语法规则文件是:SqlBase.g4。该文件以及生成的相关文件截图如下。

在生成的文件中SqlBaseBaseListener和SqlBaseBaseVistor分别代表两种遍历AST的方法,在spark中主要用了visitor模式。

接下来,将看一下spark中,当使用spark.sql("select *** from ...")时,sql怎么解析成spark内部的AST的?

1,用户调用的spark.sql的入口是sparkSession中sql函数,该函数最终返回DataFrame(DataSet[Row]),sql的解析的过程主要是在

sessionState.sqlParser.parsePlan(sqlText)中发生的。
def sql(sqlText: String): DataFrame = {
Dataset.ofRows(self, sessionState.sqlParser.parsePlan(sqlText))
}
2,调用到parsePlan,将调用parse函数,传入的两个参数分为:sql语句,sqlBaseParse到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 new ParseException(Option(sqlText), "Unsupported SQL statement", position, position)
}
}

3,在parse函数中,首先构造SqlBaseLexer词法分析器,接着构造Token流,最终SqlBaseParser对象,然后一次尝试用不同的模式去进行解析。最终将执行parsePlan中传入的函数。

4,在步骤2中,astBuilder是SparkSqlAstBuilder的实例,在将Antlr中的匹配树转换成unresolved logical plan中,它起着桥梁作用。

astBuilder.visitSingleStatement使用visitor模式,开始匹配SqlBase.g4中sql的入口匹配规则:
singleStatement
: statement EOF
;

递归的遍历statement,以及其后的各个节点。在匹配过程中,碰到叶子节点,就将构造Logical Plan中对应的TreeNode。如当匹配到

singleTableIdentifier
: tableIdentifier EOF
;

规则时(单表的标识符)。即调用的函数如下:

override def visitSingleTableIdentifier(
ctx: SingleTableIdentifierContext): TableIdentifier = withOrigin(ctx) {
visitTableIdentifier(ctx.tableIdentifier)
}

可以看到将递归遍历对应的tableIdentifier,tableIdentifier的定义和遍历规则如下:

tableIdentifier
: (db=identifier '.')? table=identifier
;
override def visitTableIdentifier(
ctx: TableIdentifierContext): TableIdentifier = withOrigin(ctx) {
TableIdentifier(ctx.table.getText, Option(ctx.db).map(_.getText))
}

可以看到当匹配到tableIdentifier,将直接生成TableIdentifier对象,而该对象是TreeNode的一种。经过类似以上的过程,匹配结束后整个spark内部的抽象语法树也就建立起来了。

3,小结

本文主要介绍spark catalyst的总体执行情况,以及sql parse的具体实现细节。接下来,计划还将对Analyzer,Optimization,以及执行的过程做更深入的分析。

Spark SQL catalyst概述和SQL Parser的具体实现的更多相关文章

  1. Oracle-05-SQL语句概述、分类&SQL*PLUS概述(初识insert,desc,list,r,del,a,c,n等命令)

    一.SQL语句概述 (1)SQL全程是"结构化查询语言(Structured Query Language)". SQL是大多数主流数据库系统採用的标准查询语言. (2)SQL语句 ...

  2. 第八篇:Spark SQL Catalyst源码分析之UDF

    /** Spark SQL源码分析系列文章*/ 在SQL的世界里,除了官方提供的常用的处理函数之外,一般都会提供可扩展的对外自定义函数接口,这已经成为一种事实的标准. 在前面Spark SQL源码分析 ...

  3. 第三篇:Spark SQL Catalyst源码分析之Analyzer

    /** Spark SQL源码分析系列文章*/ 前面几篇文章讲解了Spark SQL的核心执行流程和Spark SQL的Catalyst框架的Sql Parser是怎样接受用户输入sql,经过解析生成 ...

  4. 第二篇:Spark SQL Catalyst源码分析之SqlParser

    /** Spark SQL源码分析系列文章*/ Spark SQL的核心执行流程我们已经分析完毕,可以参见Spark SQL核心执行流程,下面我们来分析执行流程中各个核心组件的工作职责. 本文先从入口 ...

  5. Spark SQL Catalyst源代码分析之UDF

    /** Spark SQL源代码分析系列文章*/ 在SQL的世界里,除了官方提供的经常使用的处理函数之外.一般都会提供可扩展的对外自己定义函数接口,这已经成为一种事实的标准. 在前面Spark SQL ...

  6. Spark SQL Catalyst源代码分析之Analyzer

    /** Spark SQL源代码分析系列文章*/ 前面几篇文章解说了Spark SQL的核心运行流程和Spark SQL的Catalyst框架的Sql Parser是如何接受用户输入sql,经过解析生 ...

  7. Spark SQL Catalyst源代码分析之TreeNode Library

    /** Spark SQL源代码分析系列文章*/ 前几篇文章介绍了Spark SQL的Catalyst的核心执行流程.SqlParser,和Analyzer,本来打算直接写Optimizer的,可是发 ...

  8. Spark SQL Catalyst源代码分析Optimizer

    /** Spark SQL源代码分析系列*/ 前几篇文章介绍了Spark SQL的Catalyst的核心运行流程.SqlParser,和Analyzer 以及核心类库TreeNode,本文将具体解说S ...

  9. Spark SQL / Catalyst 内部原理 与 RBO

    原创文章,转载请务必将下面这段话置于文章开头处. 本文转发自技术世界,原文链接 http://www.jasongj.com/spark/rbo/ 本文所述内容均基于 2018年9月10日 Spark ...

随机推荐

  1. Principle of least astonishment

    Principle of least astonishment - Wikipedia https://en.wikipedia.org/wiki/Principle_of_least_astonis ...

  2. 解决pyspark-linux-windowsIDE JAVA_HOME not set

    对 os.environ 赋值 ssh://root@192.168.2.51:22/usr/bin/python -u /home/data/tmp_test/trunk/personas/tmp_ ...

  3. inherited在消息中的作用(编译器根据inherited所在的函数,直接转换成对祖先类同名动态函数的调用,或者转换成对DefaultHandler的调用)

    好奇一下.看来Object Pascal确实与Windows深入结合了. unit Unit1; interface uses Windows, Messages, SysUtils, Variant ...

  4. Mac JDK 多版本共存

    1.    安装各JDK版本,安装后通过Java -version检测是否安装好    2.    打开~/.bash_profile,没有的话创建    vim ~/.bash_profile   ...

  5. Delphi通过POST传递参数给PHP

    Delphi代码 ******************************************************************************************* ...

  6. 常用bluetooth协议

    HFP: HFP(Hands-free Profile),让蓝牙设备可以控制电话,如接听.挂断.拒接.语音拨号等,拒接.语音拨号要视蓝牙耳机及电话是否支持. HSP: HSP 描述了 Bluetoot ...

  7. MYSQL初级学习笔记七:MySQL中使用正则表达式!(视频序号:初级_44)

    知识点九:MySQL中使用正则表达式(44) (1):REGEXP‘匹配方式’: (2):常用匹配方式: 模式字符 ^ 匹配字符开始的部分 $ 匹配字符串结尾的部分 . 代表字符串中的任意一个字符,包 ...

  8. JavaScript SHA-1

    1. [文件] webtoolkit.sha1.js ~ 4KB     /****  Secure Hash Algorithm (SHA1)*  http://www.huiyi8.com/css ...

  9. BlueSea笔记<1>--Cricket初探

    最近在看Cricket这个实现了Actor模式的F#开源框架,对其工作方式作了一番探究.首先来看一段简单的例子代码: type Say = | Hello let greeter = actor { ...

  10. 分段控制器--UISegmentedControl 基本用法

    http://blog.csdn.net/heng615975867/article/details/43527295 http://blog.csdn.net/gf771115/article/de ...