Catalyst揭秘 Day3

sqlParser解析

今天我们会进入catalyst引擎的第一个模块sqlparser,它是catalyst的前置模块。

树形结构

从昨天的介绍我们可以看到sqlParser会返回一个logicalPlan,它是TreeNode的子类。

TreeNode,作为一个树形抽象类,SQL语法的解析的时候,所有的元素都是TreeNode,可能是叶子节点,也可能是树枝节点,可能有0个或多个子节点,其方法都是对树的操作。

通过SQLParser,会把我们的sql语句变成一颗树,针对这个树,我们有一系列的数据类型,并且运用一系列的规则,对这个树进行解析、优化。所以第一个问题,就是怎么生成这个树,这个就是SQLParser的价值。

解析入口

sqlparse完成的步骤就是怎么把一个sql变成树状结构。

我们进入源码,从sql方法开始,会调用parseSql方法。

其最终是会调用ParserDialect的parse方法。

再进一步,会调用AbstractSparkSQLParser的parse方法来实现,这个方法非常的关键,使用的是个模板模式。

这里面会用到lexical词法解析。

首先我们看到,在构造时,会使用反射的方式来找到所有保留的关键字。

并在词法解析器初始化时,会进行添加。

AbstractSparkSQLParser的parse方法是关键,我们来详细解析一下。
这里有三个关键部分,phrase方法,start方法和Scanner对象。

解析方法1:循环遍历

首先看一下phrase方法,这是一个总控方法,会构造一个解析器,内部这是个循环器,循环读取字符串中的数据,进行解析生成短语。注意下,方法核心就是调用一句p(in),其中p是start方法,而in是Scanner对象。

解析方法2:分词

再看下Scanner对象,其主要作用是对字符串进行分词,其中核心是whitespace和token方法。
Success封装了我们当前的解析结果和没有解析的结果,对分词功能来说,未解析部分是我们需要的。

whitespace中定义了对于分割词的规则。

token中定义了合法字符的校验。

这里的表达是比较复杂,我们简单看一下。

关键字都会被定义为Keyword类型,这里有两个隐式转换。

首先是对Keyword进行转换,会对字符进行格式化normalize。

下面是更关键,会对输入字符进行隐式转换,构建Parser,默认是于输入字符进行==等式判断。

acceptIf方法内部会调用输入对象而first方法进行判断,并返回Success或Failure对象。

解析方法3:生成语法树

最后让我们看下start方法,这个方法就是对分词的结果进行匹配,并生成TreeNode。

这里使用到了非常强大的模式匹配,将select语句的各个部分解析出来,并形成了一个logicalPlan。

至此,sqlParse的过程完成。总而而言,对输入字符会进行两轮处理,第一轮是通过Scanner进行分词处理,第二轮是根据语法规则,将各个语句部分生成TreeNode。

小结

整个Spark中,有几个数据结构,RDD、broadcast、accumulator,各个子框架都需要用RDD来存储数据。

我们传递了两个观点:
1.无论是哪个子框架,最终肯定是被rdd来存储的,一般只不过是在构建时会使用一个新的数据结构,比如sparksql是用树的方式来构建。
2.上面的算法调度执行引擎等一般都是依赖spark core,并加入自己基于这个数据结构领域框架需要的特色。

欲知后事如何,且听下回分解!

DT大数据每天晚上20:00YY频道现场授课频道68917580

Catalyst揭秘 Day3 sqlParser解析的更多相关文章

  1. Catalyst揭秘 Day4 analyzer解析

    Catalyst揭秘 Day4 analyzer解析 今天继续解析catalyst,主要讲一下analyzer,在sql语句的处理流程中,analyzer是在sqlparse的基础上,把unresol ...

  2. Catalyst揭秘 Day5 optimizer解析

    Catalyst揭秘 Day5 optimizer解析 Optimizer是目前为止中catalyst中最重要的部分.主要作用是把analyzed logicalPlan变成optimized Log ...

  3. Catalyst揭秘 Day6 Physical plan解析

    Catalyst揭秘 Day6 Physical plan解析 物理计划是Spark和Sparksql相对比而言的,因为SparkSql是在Spark core上的一个抽象,物理化就是变成RDD,是S ...

  4. Catalyst揭秘 Day1 Catalyst本地解析

    Catalyst揭秘 Day1 Catalyst本地解析 今天开始讲下Catalyst,这是我们必须精通的内容之一: 在Spark2.x中,主要会以Dataframe和DataSet为api,无论是D ...

  5. Catalyst揭秘 Day2 Catalyst源码初探

    Catalyst揭秘 Day2 Catalyst源码初探 这节课从源码角度来讲catalyst. 首先有一个观点要澄清,就是技术不是越底层就越是性能和效率更高.因为除了指令执行性能以外,更重要的是架构 ...

  6. Catalyst揭秘 Day8 Final 外部数据源和缓存系统

    Catalyst揭秘 Day8 Final 外部数据源和缓存系统 今天是Catalyst部分的收官,主要讲一些杂项内容. 外部数据源处理 什么叫外部数据源,是SparkSql自己支持的一些文件格式,以 ...

  7. Catalyst揭秘 Day7 SQL转为RDD的具体实现

    Catalyst揭秘 Day7 SQL转为RDD的具体实现 从技术角度,越底层和硬件偶尔越高,可动弹的空间越小,而越高层,可动用的智慧是更多.Catalyst就是个高层的智慧. Catalyst已经逐 ...

  8. Spark Tungsten揭秘 Day3 内存分配和管理内幕

    Spark Tungsten揭秘 Day3 内存分配和管理内幕 恭喜Spark2.0发布,今天会看一下2.0的源码. 今天会讲下Tungsten内存分配和管理的内幕.Tungsten想要工作,要有数据 ...

  9. Kakfa揭秘 Day3 Kafka源码概述

    Kakfa揭秘 Day3 Kafka源码概述 今天开始进入Kafka的源码,本次学习基于最新的0.10.0版本进行.由于之前在学习Spark过程中积累了很多的经验和思想,这些在kafka上是通用的. ...

随机推荐

  1. Android(java)学习笔记72:线程的状态转换图以及常见执行情况

    1. 线程的状态转换图以及常见执行情况: 2. 线程状态类型: (1)新建状态(New):新创建了一个线程对象.(2)就绪状态(Runnable):线程对象创建后,其他线程调用了该对象的start() ...

  2. c语言实现:4和7幸运数字的题

    #include <stdio.h> #include <math.h> #include <vector> using namespace std; int ma ...

  3. [改善Java代码]适时选择不同的线程池来实现

    Java的线程池实现从最根本上来说只有两个:ThreadPoolExecutor类和ScheduledThreadPoolExecutor类,这两个类还是父子关系,但是Java为了简化并行计算,还提供 ...

  4. 关于Linux系统和Windows系统中文件夹的命名规范

    Windows系统中. 1.在创建文件夹的时候不能以"."开头(但是文件以多个点开头并且还有其他合法字符的话就是合法的) 但是在windows系统中确实见过以一个点".& ...

  5. Linux时间函数

    一.时间编程 1.核心理论 (1).时间类型 2.函数学习 (1).获取日历时间 函数名:time 函数原型:time_t time(time_t *t) 函数功能:获取当前日历时间 所属头文件:&l ...

  6. Android Studio 快捷方式

    Alt+回车 导入包,自动修正 Ctrl+N 查找类 Ctrl+Shift+N 查找文件 Ctrl+Alt+L 格式化代码 Ctrl+Alt+O 优化导入的类和包 Alt+Insert 生成代码(如g ...

  7. 160多个android开源代码汇总

    第一部分 个性化控件(View) 主要介绍那些不错个性化的View,包括ListView.ActionBar.Menu.ViewPager.Gallery.GridView.ImageView.Pro ...

  8. CSS有用的代码片段

    1.垂直对齐 .vc{ position:relative; top:50%; -webkit-transform:translateY(-50%); -o-transform:translateY( ...

  9. Contoso 大学 - 5 – 读取关联数据

    原文 Contoso 大学 - 5 – 读取关联数据 By Tom Dykstra, Tom Dykstra is a Senior Programming Writer on Microsoft's ...

  10. self指向函数地址 动态调用函数的简单例子

    #import <Foundation/Foundation.h> @interface Person : NSObject - (void)test1; - (void)test2:(N ...