HQL的解析过程主要在Driver中的compile方法,这一些主要看这个方法中的代码。

1. compile中的主要内容

public int compile(String command, boolean resetTaskIds, boolean deferClose) {

..........

// 对sql语句进行处理(敏感信息、变量替换等)

String queryStr = command;

queryStr = HookUtils.redactLogString(conf, command); // 处理敏感信息(这里应该是可以自定义扩展的)

............

// Step1. 获取抽象语法树

ASTNode tree = ParseUtils.parse(command, ctx);

.............

// Step2. 进行语义分析

BaseSemanticAnalyzer sem = SemanticAnalyzerFactory.get(queryState, tree);

sem.analyze(tree, ctx);

sem.validate();

// Step3. 生成执行计划

schema = getSchema(sem, conf);

plan = new QueryPlan(queryStr, sem, perfLogger.getStartTime(PerfLogger.DRIVER_RUN), queryId, queryState.getHiveOperation(), schema);

.............

return 0;

}

compile中主要有三大部分内容:

根据SQL生成抽象语法树

进行语义分析

执行计划的生成

2. 获取抽象语法树

主要是通过ParseUtils中的parse方法来生成语法树,最后转向ParseDriver中的parse方法,代码如下:

public ASTNode parse(String command, Context ctx, String viewFullyQualifiedName) {

.............

// 创建词法规则

HiveLexerX lexer = new HiveLexerX(new ANTLRNoCaseStringStream(command));

TokenRewriteStream tokens = new TokenRewriteStream(lexer);

// 创建语法分析器

HiveParser parser = new HiveParser(tokens);

r = parser.statement();

ASTNode tree = (ASTNode) r.getTree();

.............

return tree;

}

Hive主要是通过用ANTLR语法定义的词法和文法文件来进行解析,最后生成抽象语法树。

3. 进行语义分析

语义分析主要通过 BaseSemanticAnalyzer 实现类中的 analyze 方法进行。

不同的sql语句会用不同的 BaseSemanticAnalyzer实现类来进行分析,主要有以下语义分析器:

3.1 语义分析器

语法

语义分析器

explain .......

ExplainSemanticAnalyzer

rewirte ..... ??

ExplainSQRewriteSemanticAnalyzer

load ...

LoadSemanticAnalyzer

export ...

ExportSemanticAnalyzer

import ...

ImportSemanticAnalyzer

repl dump ... / repl load ... / repl status ... ??

ReplicationSemanticAnalyzer

alter table .../ alter view ...

DDLSemanticAnalyzer

create database .../ drop database .../ use databaseName / drop table .../ drop view .../ drop materialized view .../ desc database .../ desc table .../ desc function .../ msck ...??/ rebuild ...??/show databases... / show tables.../ show columns.../ show create .... / show functions .../ show partitions .../ show ....../ abort transcations .../ lock .../ grant ... / revoke ... / set role ...

DDLSemanticAnalyzer

create function ... / drop function ... / reload function ...

FunctionSemanticAnalyzer

analyze ...

ColumnStatsSemanticAnalyzer

create macro.../ drop macro... (宏)

MacroSemanticAnalyzer

update table.../ delete from ... / merge ...

UpdateDeleteSemanticAnalyzer

其他语句

如果参数 hive.cbo.enable 被置为 true(默认情况下是true),则创建 CalcitePlanner对象,否则创建SemanticAnalyzer对象。CalcitePlanner继承了SemanticAnalyzer

从上面对应关系看来,我们常写的查询语句主要是通过 SemanticAnalyzer 中的 analyze 方法解析的。

3.2 SemanticAnalyzer语义分析器中的analyze方法

主要看其中的analyze方法,anlyze最终转向的是各个语义分析器中的 analyzeInternal 方法,SemanticAnalyzer中的analyzeInternal 代码如下:

// PlannerContext 是SemanticAnalyzer中的一个静态类,

// 如果参数hive.cbo.enable为false,这里 plannerCtx 是新建的 PlannerContext 的对象

// 如果参数hive.cbo.enable为true,这里 plannerCtx 是 PreCboCtx 对象,PreCboCtx继承了PlannerContext

void analyzeInternal(ASTNode ast, PlannerContext plannerCtx) throws SemanticException {

...........

// step1. 从抽象语法树生成 resolved parse tree

genResolvedParseTree(ast, plannerCtx)

...........

// step2. 从 resolved parse tree 生成 op tree

Operator sinkOp = genOPTree(ast, plannerCtx);

...........

// step3. 推断结果集表结构

resultSchema = convertRowSchemaToViewSchema(opParseCtx.get(sinkOp).getRowResolver());

或者

resultSchema = convertRowSchemaToResultSetSchema(opParseCtx.get(sinkOp).getRowResolver(), HiveConf.getBoolVar(conf, HiveConf.ConfVars.HIVE_RESULTSET_USE_UNIQUE_COLUMN_NAMES));

............

// step4. 为优化器和物理编译器生成上下文

ParseContext pCtx = new ParseContext(queryState, opToPartPruner, opToPartList, topOps,

new HashSet(joinContext.keySet()),

new HashSet(smbMapJoinContext.keySet()),

loadTableWork, loadFileWork, columnStatsAutoGatherContexts, ctx, idToTableNameMap, destTableId, uCtx,

listMapJoinOpsNoReducer, prunedPartitions, tabNameToTabObject, opToSamplePruner,

globalLimitCtx, nameToSplitSample, inputs, rootTasks, opToPartToSkewedPruner,

viewAliasToInput, reduceSinkOperatorsAddedByEnforceBucketingSorting,

analyzeRewrite, tableDesc, createVwDesc, queryProperties, viewProjectToTableSchema, acidFileSinks);

...........

// step5. 执行逻辑优化

Optimizer optm = new Optimizer();

optm.setPctx(pCtx);

optm.initialize(conf);

pCtx = optm.optimize();

FetchTask origFetchTask = pCtx.getFetchTask();

.............

// step6.优化物理执行树 & 翻译成目标执行引擎

TaskCompiler compiler = TaskCompilerFactory.getCompiler(conf, pCtx);

compiler.init(queryState, console, db);

compiler.compile(pCtx, rootTasks, inputs, outputs);

fetchTask = pCtx.getFetchTask();

...............

return;

}

从以上代码中可以看出语义分析中主要包括以下几部分:

从抽象语法树生成 resolved parse tree

从 resolved parse tree 生成 op tree

推断结果集表结构

为优化器和物理编译器生成上下文

执行逻辑优化

优化物理执行树 & 翻译成目标执行引擎

4. 小结

这一节主要看了一下HQL解析中抽象语法树的生成和语义分析器中的analyze方法都做了什么,后面开始分析从抽象语法树 到 执行计划的过程中都做了什么。

Java解析SQL生成语法树_04. Hive源码 — HQL解析(抽象语法树的生成和语义分析)相关推荐

  1. Java解析SQL生成语法树_Atitit.sql ast 表达式 语法树 语法 解析原理与实现 java php c#.net js python...

    Atitit.sql ast 表达式 语法树 语法 解析原理与实现java php c#.net js python 1.1.Sql语法树ast如下图锁死 2.SQL语句解析的思路和过程 2.1.le ...

  2. 抽象语法树手动生成--java实现

    本人博客内编译原理文章的配套资源jar包,包括词法分析,语法分析,中间代码生成,静态语义检查,代码解释执行以及抽象语法树的手动生成:https://download.csdn.net/download ...

  3. Java 集合系列(4): LinkedList源码深入解析1

    戳上面的蓝字关注我们哦! 精彩内容 精选java等全套视频教程 精选java电子图书 大数据视频教程精选 java项目练习精选 概要 前面,我们已经学习了ArrayList,并了解了fail-fast ...

  4. Java 集合系列(2): ArrayList源码深入解析和使用示例

    戳上面的蓝字关注我们哦! 精彩内容 精选java等全套视频教程 精选java电子图书 大数据视频教程精选 java项目练习精选 概要 上一章,我们学习了Collection的架构.这一章开始,我们对C ...

  5. Java 集合系列(4): LinkedList源码深入解析2

    戳上面的蓝字关注我们哦! 精彩内容 精选java等全套视频教程 精选java电子图书 大数据视频教程精选 java项目练习精选 第4部分 LinkedList遍历方式 LinkedList遍历方式 L ...

  6. python 抽象语法树_抽象语法树(Abstract Syntax Tree)

    一般来说,程序中的一段源代码在执行之前会经历下面三个步骤 1 分词/词法分析 这个过程会将由字符组成的字符串分解成有意义的代码快,这些代码块被称为词法单元.例如 var a = 4:会被分解成 var ...

  7. 淘宝数据库OceanBase SQL编译器部分 源码阅读--解析SQL语法树

    http://blog.csdn.net/qq910894904/article/details/28658421 OceanBase是阿里巴巴集团自主研发的可扩展的关系型数据库,实现了跨行跨表的事务 ...

  8. php ast 抽象语法树,AST抽象语法树的基本思想

    AST抽象语法树的基本思想 前言 AST概述 AST结构 AST解析 转换 生成 前言 在阅读java ORM框架spring data jpa的源码时,发现Hibernate(spring data ...

  9. Hive源码阅读--导读

    总述 Hive的执行流程大致分为两部分,即任务的提交与返回,命令的编译与执行. 前者在CliDriver类中流转,后者主要在Driver与ParseDriver类,核心编译在BaseSemanticA ...

最新文章

  1. 视频云王海华:关于移动短视频技术选型的那些事
  2. VoIP应用系统大盘点
  3. [云炬python3玩转机器学习] 5-7,8 多元线性回归正规解及其实现
  4. 泛微文档存放在服务器哪个地址,泛微OA根据文档的docid查询文档附件存放的路径...
  5. 机器学习week8 ex7 review
  6. 2017.10.11 Problem c 失败总结
  7. 百度DuerOS负责人景鲲晋升副总裁,继续向李彦宏汇报
  8. 计算机网络原理 谢希仁(第8版)第二章习题答案
  9. GIS三维可视化技术在输电领域的应用研讨
  10. 每日一记:2017.7.20
  11. Ant Design Vue 表格行内编辑!!!
  12. 自组织神经网络:自组织特征映射SOM网络
  13. 超详细面试准备(10分钟打遍所有初级后端开发面试)
  14. ubuntu18.0.4桌面死机问题
  15. 二进制整数奇偶互换c语言,奇偶
  16. mac电脑usb连接android手机,Android安卓设备连接Mac的方法
  17. 禅与摩托车维修艺术摘录
  18. uniapp vue 身份证号校验
  19. Java实现蓝桥杯模拟元音单词的验证
  20. 解决电脑浏览器打不开网页问题

热门文章

  1. 提示数据信息:汪琪玩Excel第二十七招
  2. 网银密码控件自动输入密码
  3. 关于华硕飞行堡垒安装Ubuntu时的 卡死 和 grub引导问题 的解决办法
  4. 使用ipset来批量控制iptables
  5. linux——signal信号 SIGHUP、SIGINT
  6. Linux安装MySQL 5.7
  7. 深入分析微信小程序带来的机遇
  8. 7.牛批了 Android 2022高级资深面试题 一线大厂和二线大厂面试真题精选 (大疆 附答案)第七套 30k+
  9. 鼎捷T100——利用自定义查询维护作业(azzi310)开发建立xg报表
  10. Linux桌面版操作系统的中文字体选择