MYSQL服务器接收SQL格式的查询,首先要对sql进行解析,内部将文本格式转换为二进制结构,这个转换就是解析器,解析的目的是为了让优化器更好的处理指令,以便以最优的路径,最少的耗时返回我们想要的结果。
sql解析器的构成:
1、词法分析(Lexical scanner):作用是将整个查询分解为多个元素。
2、语法规则(Grammar rule module):寻找sql语法规则组合,产生一个序列,执行这些规则相关的代码。
1 and 2 产生一棵解析树,提供给优化器使用。
mysql解析器的特殊性在于它直接转换为程序内存中的内部解析的C/C++结构,而一般的解析器是将文本表达式转换为字节代码。
1. 源码解读解析器
MySQL语法解析封装在函数MYSQLparser中,包含两个模块:词法分析(Lexical scanner)和语法规则(Grammar rule module)。词法分析将整个SQL语句打碎成一个个单词(Token),而语法规则模块则根据MySQL定义的语法规则生成对应的数据结构,并存储在对象THD->LEX结构当中。最后优化器,根据这里的数据,生成执行计划,再调用存储引擎接口执行。词法分析和语法规则模块有两个较成熟的开源工具Flex和Bison分别用来解决这两个问题。MySQL出于性能和灵活考虑,选择了自行完成词法解析部分,语法规则部分使用Bison。词法解析和Bison沟通的核心函数是由词法解析器提供的函数接口yylex(),在Bison中,必要的时候调用yylex()获得词法解析的数据,完成自己的语法解析。Bison的入口为yyparse(),在MySQL中定义为MYSQLParse。
1.1. 解析示意

Bison在做语法解析后,会将解析结果(解析树/AST)存储在THD::LEX中,通过存储WHERE的数据结构来查看语法解析的结果。

1.2. 解析树的ITEM对象
在MYSQL中,有以下ITEM大类型:
FIELD_ITEM, FUNC_ITEM,
SUM_FUNC_ITEM,
STRING_ITEM,
INT_ITEM,
REAL_ITEM,
NULL_ITEM,
VARBIN_ITEM,
COPY_STR_ITEM,
FIELD_AVG_ITEM,
DEFAULT_VALUE_ITEM,
PROC_ITEM,COND_ITEM,
REF_ITEM,
FIELD_STD_ITEM,
FIELD_VARIANCE_ITEM,
INSERT_VALUE_ITEM,
SUBSELECT_ITEM,
ROW_ITEM,
CACHE_ITEM,
TYPE_HOLDER,
PARAM_ITEM
其中许多ITEM还有小类,如Item_func有如下小类型:
UNKNOWN_FUNC,
EQ_FUNC,
EQUAL_FUNC,
NE_FUNC,
LT_FUNC,
LE_FUNC,
GE_FUNC,
GT_FUNC,FT_FUNC,
LIKE_FUNC,
NOTLIKE_FUNC,
ISNULL_FUNC,
ISNOTNULL_FUNC,
COND_AND_FUNC,
COND_OR_FUNC,
COND_XOR_FUNC,
BETWEEN, IN_FUNC,
INTERVAL_FUNC,
ISNOTNULLTEST_FUNC,
SP_EQUALS_FUNC,
SP_DISJOINT_FUNC,
SP_INTERSECTS_FUNC,
SP_TOUCHES_FUNC,
SP_CROSSES_FUNC,
SP_WITHIN_FUNC,
SP_CONTAINS_FUNC,
SP_OVERLAPS_FUNC,
SP_STARTPOINT,
SP_ENDPOINT,
SP_EXTERIORRING,
SP_POINTN,
SP_GEOMETRYN,
SP_INTERIORRINGN,
NOT_FUNC,
NOT_ALL_FUNC,
NOW_FUNC,
VAR_VALUE_FUNC
1.3. ITEM语法树

1.4. FIELD 类型
enum enum_field_types {
MYSQL_TYPE_DECIMAL, MYSQL_TYPE_TINY,
MYSQL_TYPE_SHORT,MYSQL_TYPE_LONG,
MYSQL_TYPE_FLOAT,MYSQL_TYPE_DOUBLE,
MYSQL_TYPE_NULL,MYSQL_TYPE_TIMESTAMP,
MYSQL_TYPE_LONGLONG,MYSQL_TYPE_INT24,
MYSQL_TYPE_DATE, MYSQL_TYPE_TIME,
MYSQL_TYPE_DATETIME,MYSQL_TYPE_YEAR,
MYSQL_TYPE_NEWDATE,
MYSQL_TYPE_ENUM=247,
MYSQL_TYPE_SET=248,
MYSQL_TYPE_TINY_BLOB=249,
MYSQL_TYPE_MEDIUM_BLOB=250,
MYSQL_TYPE_LONG_BLOB=251,
MYSQL_TYPE_BLOB=252,
MYSQL_TYPE_VAR_STRING=253,
MYSQL_TYPE_STRING=254,
MYSQL_TYPE_GEOMETRY=255
};
1.5. FIELD和ITEM的关系
通过Item类中的tmp_table_field_from_field_type函数将一个Item类转化为一个Filed类返回,例如
Item_int ->Field_longlong
Item_real->Field_double
Item_string->Field_string
1.6. Bison语法中的WHERE

select_from ==> ---->from
join_table_list
where_clause
---->expr or expr
---->expr amd expr
---->……………………
---->simple_expr comp_op simple_expr
  group_clause having_clauseopt_order_clauseopt_limit_clause

where 要点:
where_clause:
/ empty / {}
| WHERE expr
{
THD->lex->current_select->where = $2
}

expr:
...
| expr and expr
{
$$ = new (YYTHD->mem_root) Item_cond_and($1, $3)
}
|ident comp_op NUM /简化版/
{
$$ = new Item_func_ge(a, b); /简化版/
}

通过解析就能生成where的语法树。
Where解析树的分支:如图

1.7. 总结
解析器的最终执行结果就是解析树,sql语法的复杂性要求具有同样复杂程度的结构,通过这种结构有效存储用于执行每个可能使用到的sql语句所需的信息。
解析树中重要的两个对象【enum_sql_command和select_lex】, sql_command显示sql类型,execute_command则指导调用相关函数。通过内核级别的调用,最终生成解析树,提供给优化器,最终完成我们的操作指令。

2. 参考资料
[1]OReilly Understanding MySQL Internals
[2]MySQL内核:InnoDB存储引擎
[3]OReilly
[4]《lex与yacc》(第二版)
[5]《flex与bison》(第二版)
[6]Bison操作手册: http://www.gnu.org/software/bison/manual/bison.html

本文由京东商城数据库技术部郭光欣提供。

MySQL内核源码解读-SQL解析之解析器浅析相关推荐

  1. PTMs:QLoRA技巧之源码解读(qlora.py文件)—解析命令与加载参数→数据预处理→模型训练+评估+推理

    PTMs:QLoRA技巧之源码解读(qlora.py文件)-解析命令与加载参数→数据预处理→模型训练+评估+推理 目录 QLoRA技巧之源码解读(qlora.py文件)-解析命令与加载参数→数据预处理 ...

  2. 【Android】OkHttp源码解读逐字稿(1)-拦截器

    目录 0.前言 1.OkHttp的简单使用 2.浅析开始 拦截器 链式调用流程示意图 第 0 个拦截器 第一个 拦截器 RetryAndFollowUpInterceptor 第二个拦截器 Bridg ...

  3. mysql的源码解读(1):mysql的目录结构详解

    一.mysql的简介 二.mysql的编译包安装目录结构详解 1)编译包解压之后的目录结构 mysql-5.6.39├── bin # 存放的是服务器和客户端的程序(命令)├── COPYING # ...

  4. spring beans源码解读之--bean definiton解析器

    spring提供了有两种方式的bean definition解析器:PropertiesBeanDefinitionReader和XmLBeanDefinitionReader即属性文件格式的bean ...

  5. mysql源码如何解析where字句_用mysql源码进行SQL解析

    用mysql源码进行SQL解析 Mysql是通过yacc进行SQL语句解析的,这里介绍一下如何使用mysql的源码进行SQL语句解析.由于Mysql的源代码注释比较少,而且缺少资料,所有些地方研究不够 ...

  6. ClickHouse 源码阅读 —— SQL的前世今生

    注:以下分析基于开源 v19.15.2.2-stable 版本进行,社区最新版本代码改动较大,但是总体思路是不变的. 用户提交一条查询SQL背后发生了什么? 在传统关系型数据库中,SQL处理器的组件主 ...

  7. 【Android】OkHttp源码解读逐字稿(2)-OkHttpClient

    目录 0.前言 1.各个属性浅析 01.dispatcher 02.connectionPool 03.interceptors&networkInterceptors 04.eventLis ...

  8. mysql8.0源代码解析_源码解读:MySQL 8.0 InnoDB无锁化设计的日志系统

    原标题:源码解读:MySQL 8.0 InnoDB无锁化设计的日志系统 作者介绍 张永翔,现任网易云RDS开发,持续关注MySQL及数据库运维领域,擅长MySQL运维,知乎ID:雁南归. MySQL ...

  9. Linux内核网络协议栈:udp数据包发送(源码解读)

    <监视和调整Linux网络协议栈:接收数据> <监控和调整Linux网络协议栈的图解指南:接收数据> <Linux网络 - 数据包的接收过程> <Linux网 ...

最新文章

  1. 8个无敌好用国产APP推荐:(办公类、学习类、生活类)
  2. axis1 web Service 环境部署
  3. 测试在MicroPython中对于main.py进行修改
  4. linux下configure命令详解
  5. c语言 python-C语言和python的区别
  6. git 拉新项目_git上拉取项目
  7. Git之回退已经提交到远程仓库的代码(已经push的代码)
  8. [Oracle]使用非滚动游标
  9. Selenium系列文章汇总
  10. cp无法创建普通文件权限不够_MAC从管理员变成了普通用户怎么办?
  11. sublime快速打开终端terminal
  12. docker-compose 布署应用nginx中的react应用获取环境变量
  13. js实现斗地主计分器
  14. ThinkpadT420加装上网卡
  15. Quasi_Newton
  16. vue项目,引入插件element ui 样式不生效
  17. SpringBoot入门系列(二)如何返回统一的Json数据格式
  18. c语言程序设计试题1253,2017年1月试卷号1253C语言程序设计A.pdf
  19. 微信小程序foreach遍历_微信小程序wx:for和wx:for-item的用法
  20. HDF5 学习总结1

热门文章

  1. arm linux考勤,定稿毕业论文_基于ARM与Linux的员工刷卡考勤系统喜欢就下吧(范文1)...
  2. dropout与lstm的结合使用
  3. phpcms调用栏目描述_phpcms标签整理_当前栏目调用
  4. linux打开vivado_ubuntu启动vivado UBUNTU 16.04安装VIVADO成功启动SDK - Linux - 服务器之家...
  5. 决策树 prepruning_数据挖掘入门系列教程(三点五)之决策树
  6. lxml 和 XPah (爬虫)
  7. FIO工具测试延迟、带宽、IOPS
  8. (一)网络与信息安全概论入门阶段笔记
  9. linux搭建Nexus初次体验
  10. Vue中绑定值与字符串拼接以及结合三目表达式实现是否为空判定的使用