hive遍历_Hive解析流程-抽象语法树生成
HiveQL解析流程:
- Hive根据Antlr定义的词法、语法规则完成词法、语法分析将HQL解析为AST Tree;
- 遍历AST Tree,抽象出查询的基本组成单元Query Block;
- 遍历Query Block解析为操作树Operator Tree(即,逻辑执行计划);
- 逻辑优化器进行操作树变换,合并多余的ReduceSinkOperator,减少shuffle;
- 遍历Operator Tree,将操作树翻译为对应的MapReduce任务;
- 物理优化器进行MapReduce任务变换,生成最终的执行计划。
1、前言
Hive通过antlr3定义HiveQL语言。ANTLR是一个基于LL(*)算法实现的语言识别器,定义词法文件、语法文件,通过 antlr 可以构造出相应的词法分析器 (Lexer)、语法分析器 (Parser) 和树分析器 (Tree Parser)。
词法分析器(Lexer):校验输入字符的合法性,将无含义的字符流翻译为有意义的单词(token),识别关键字,生成token流。
语法分析器(Parser):语法分析器将获取到的token流组织,按照语法规则进行重写生成抽象语法树。
树分析器(TreeParser):对语法分析生成的抽象语法树遍历,进行语法树的分析工作。
2、词法、语法文件
Hive中通过antlr3定义的词法文件、语法文件存放在Hive源码src/org/apache/hadoop/hive/ql/parse/ 目录中,以.g后缀结尾,其中包含了5个文件。
HiveLexer.g :定义Hive关键字,及组成词组的合法字符
SelectClauseParser.g :定义select语句的语法规则
FromClauseParser.g :定义from语句的语法规则
IdentifiersParser.g :定义函数、group等的语法规则
HiveParser.g:定义语法规则文件,引入了其他语法规则文件
词法文件
HiveLexer.g是Hive的词法文件,其中定义了Hive所有的关键字、保留字以及可以被Hive识别的合法字符,不在其中定义的字符,将被Hive认为是非法字符输入。词法规则示例:
KW_SELECT
语法文件
语法文件中定义了HiveQL的语法规则,用户写的HiveQL将会按照在语法文件中定义的语法规则进行重写,将HiveQL转换为抽象语法树。
Hive的查询语句由以下几个部分构成:
- Select语句:查询映射部分;
- From语句:描述查询的数据源,数据源主要包括表、子查询语句、join语句等;
- Body语句:查询语句的主体部分,包括group by,distribute by,order by,sort by,limit,having,where,clusterby等。
语法文件中 atomSelectStatement 部分是查询语句的基本结构,如下:
atomSelectStatement:s=selectClausef=fromClause?w=whereClause?g=groupByClause?h=havingClause?win=window_clause?-> ^(TOK_QUERY $f? ^(TOK_INSERT ^(TOK_DESTINATION ^(TOK_DIR TOK_TMP_FILE))$s $w? $g? $h? $win?))|LPAREN! selectStatement RPAREN!;
语法文件中,将输入的HiveQL按照语法规则进行重写,生成如下结构语法树:
语法树由from 和 TOK_INSERT 两部分组成。from 代表了 from子句的语法树;TOK_INSERT 子树是查询的主体部分,包含了查询结果目的数据源TOK_DESTINATION子树、select子句语法树、body子句(where, group,having等)语法树。
以上是Hive查询语句的语法树主体结构,所有的查询语句都会转换成这样结构的语法树,不同的是from、select等子树的不同,子树的生成同样也是根据语法文件中定义的语法规则,对各个子句进行重写,生成对应的语法树子树,拼接到语法树的主体结构上,最终生成HiveQL对应的完整抽象语法树。
3、 词法、语法解析
词法、语法解析入口
Driver类
run(cmd)
-runInternal(cmd,compiled)
--compileInternal(cmd)
---compile(cmd)* 开始进行词法、语法解析
ParseUtiles工具类
----parse(cmd)ParseDriver解析驱动类
-----parse(cmd)
------1.HiveLexerX 词法解析
------2.HiveParser 语法解析
------3.parser.statement().getTree() 生成AST Tree
解析流程
HiveLexerX,HiveParser都是由Antlr词法、语法文件编译后自动生成的词法、语法解析类。
- HiveLexerX解析类进行字符流->Token流的转换,其进行HQL词法识别;
- HiveParser解析类进行字符流->Token流的转换,其进行HQL语法识别,语法识别会对原语进行翻译,并通过一些标识符标示一些特定的语法(如,TOK_QUERY标示一个查询块);
示例HiveQL:
SELECT
基于示例HQL,生成的AST Tree如下:
TOK_QUERYTOK_FROMTOK_LEFTOUTERJOINTOK_TABREFTOK_TABNAMEtempt1t1TOK_TABREFTOK_TABNAMEtempt2t2and=.TOK_TABLE_OR_COLt1id.TOK_TABLE_OR_COLt2id=.TOK_TABLE_OR_COLt2name'aa'TOK_INSERTTOK_DESTINATIONTOK_DIRTOK_TMP_FILETOK_SELECTTOK_SELEXPR.TOK_TABLE_OR_COLt1idTOK_SELEXPR.TOK_TABLE_OR_COLt1nameTOK_SELEXPR.TOK_TABLE_OR_COLt2namename_t2TOK_WHERE=.TOK_TABLE_OR_COLt1name'a'
详细对比HQL原语和AST Tree来看,解析过程对每个表生成一个TOK_TABREF节点,对from关键字生成一个TOK_FROM节点,对查询的每个字段生成一个TOK_SELEXPR节点,每个使用到的属性列生成一个TOK_TABLE_OR_COL节点,where关键字对应生成TOK_WHERE节点,其他节点类似可以一一对应到HQL原语上。
hive遍历_Hive解析流程-抽象语法树生成相关推荐
- hive查询where join_Hive解析流程-抽象语法树生成
HiveQL解析流程: Hive根据Antlr定义的词法.语法规则完成词法.语法分析将HQL解析为AST Tree: 遍历AST Tree,抽象出查询的基本组成单元Query Block: 遍历Que ...
- Java解析SQL生成语法树_04. Hive源码 — HQL解析(抽象语法树的生成和语义分析)
HQL的解析过程主要在Driver中的compile方法,这一些主要看这个方法中的代码. 1. compile中的主要内容 public int compile(String command, boo ...
- AST(抽象语法树)超详细
自己研究的东西会用到AST,就自己通过查阅资料,整理一下. 本文目录 第一部分:AST的作用 第二部分:AST的流程 第三部分: Eclipse AST的获取与访问 第一部分:AST的作用 首先来一个 ...
- AST抽象语法树的基本思想
AST抽象语法树的基本思想 前言 AST概述 AST结构 AST解析 转换 生成 前言 在阅读java ORM框架spring data jpa的源码时,发现Hibernate(spring data ...
- 抽象语法树在 JavaScript 中的应用
抽象语法树是什么 在计算机科学中,抽象语法树(abstract syntax tree 或者缩写为 AST),或者语法树(syntax tree),是源代码的抽象语法结构的树状表现形式,这里特指编程语 ...
- php ast 抽象语法树,AST抽象语法树的基本思想
AST抽象语法树的基本思想 前言 AST概述 AST结构 AST解析 转换 生成 前言 在阅读java ORM框架spring data jpa的源码时,发现Hibernate(spring data ...
- ast抽象语法树_新抽象语法树(AST)给 PHP7 带来的变化
本文大部分内容参照 AST 的 RFC 文档而成:https://wiki.php.net/rfc/abstract_syntax_tree,为了易于理解从源文档中节选部分进行介绍. 我的官方群点击此 ...
- java抽象语法树_抽象语法树AST的全面解析(一)
Javac编译概述 将.java源文件编译成.class文件,这一步大致可以分为3个过程: 1.把所有的源文件解析成语法树,输入到编译器的符号表: 2.注解处理器的注解处理过程: 3.分析语法树并生成 ...
- 应用ast抽象语法树修改js函数
原理:AST抽象语法树 目标:在每一个函数里面插入一个console.log()把函数传入的全部参数输出出来 关于:本文章是在基于我的个人理解且怕忘记知识所记录下来的给自己看并且分享自己的一个心得,文 ...
最新文章
- 技术图文:如何利用 Python 做一个简单的定时器类?
- PHP Memcached + APC + 文件缓存封装
- QT的QMultiMap类的使用
- 素数与线性筛选法初级版
- CMD下查询Mysql中文乱码的解决方法
- MonoRail - 简介 [基础知识篇]
- mysql何时会走索引
- mysql内置时间函数大全_MySQL 的时间函数 大全
- webservice传递特殊字符时的解决的方法
- 被隐藏的或许才是金子
- python elasticsearch模块_Python3 操作 elasticsearch
- iPhone手机获取uuid 方法
- linux下iptables详解
- 换工作,看机会的,戳进来!
- python实现QQ登陆验证码数据采集
- 非正态独立小样本统计检验方法的选择
- android 打开微信客户端,Android中接入微信客户端心得
- IIC总线最多能接几个设备
- 2023年核桃仁行业产业布局:全球核桃仁产量稳步增长
- 64位系统编译32位程序报错
热门文章
- 从0开始配置Win环境下VScode (VScode For C/C++)
- 使用C#打造通用的数据库连接类
- 计算机信息安全与信息伦理课件,信息安全实验室
- android setflag找不到_Android面试题4–Activity之Intent的Flag
- leetcode题解66-加一
- POJ 1639 Picnic Planning:最小度限制生成树
- Codeforces 343D Water Tree(DFS序 + 线段树)
- oracle中的数据读取与查找
- [导入] 用java把页面日期控件写出来
- 弄了个Gmail,觉得不适合我