MySQL解析器源码分析--对select语句中子查询处理逻辑的分析(二)

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
云数据库 RDS MySQL,高可用系列 2核4GB
简介:

(接上文)

下面以一个简单的SQL作为例子来讲解。

例如: Select * from tt where tt.id in (select id from tt1) union select * from tt1;

SQL在经过解析后的类间关系如下图:


 

 

MySQL解析器相关处理逻辑

 

MySQL解析器在分析到SQL存在union或者select子句,from子句,where子句中的subselect时,都会调用mysql_new_select函数维护上述所讲的数据结构,区别是union在调用mysql_new_select时传第二个参数move_down=0;subselect在调用mysql_new_select时传第二个参数move_down=1。

 

mysql_new_select函数具体解释如下:

 

Code:
bool mysql_new_select(LEX *lex, bool move_down)
{
      SELECT_LEX *select_lex;
      THD *thd= lex->thd;
      DBUG_ENTER("mysql_new_select");

//为子查询新建一个SELECT_LEX即st_select_lex,这个st_select_lex可能对应遇到的select子句,from子句,

//where子句中的subselect或者union关系中的select子句;

if (!(select_lex= new (thd->mem_root) SELECT_LEX())) DBUG_RETURN(1); select_lex->select_number= ++thd->select_number; select_lex->parent_lex= lex; /* Used in init_query. */ select_lex->init_query(); select_lex->init_select(); lex->nest_level++; if (lex->nest_level > (int) MAX_SELECT_NESTING) { my_error(ER_TOO_HIGH_LEVEL_OF_NESTING_FOR_SELECT,MYF(0),MAX_SELECT_NESTING); DBUG_RETURN(1); } select_lex->nest_level= lex->nest_level; if (thd->stmt_arena->is_stmt_prepare()) select_lex->uncacheable|= UNCACHEABLE_PREPARE; //如果move_down=1,即是为select子句,from子句,where子句中的subselect创建相应数据结构时 if (move_down) { SELECT_LEX_UNIT *unit; lex->subqueries= TRUE; //新建一个SELECT_LEX_UNIT即st_select_lex_unit if (!(unit= new (thd->mem_root) SELECT_LEX_UNIT())) DBUG_RETURN(1); unit->init_query(); unit->init_select(); unit->thd= thd; //将此SELECT_LEX_UNIT挂在上一级select语句对应SELECT_LEX的下,即此SELECT_LEX的slave指针指向此SELECT_LEX_UNIT unit->include_down(lex->current_select); unit->link_next= 0; unit->link_prev= 0; unit->return_to= lex->current_select;

//同时将这个subselect对应的SELECT_LEX挂在刚建的这个SELECT_LEX_UNIT下,这里MySQL对于select子句,from子句,where子句

//中可能出现的subselect,都会先新建一个SELECT_LEX_UNIT挂在上一级select语句对应的SELECT_LEX下,

//同时建一个subselect对应的SELECT_LEX挂在SELECT_LEX_UNIT下。

//这样如果这个subselect的右边又出现了一个subselect和它进行union操作,可以将右边的这个subselect对应的

//SELECT_LEX放在上一级的SELECT_LEX_UNIT表达这个union关系。

select_lex->include_down(unit); select_lex->context.outer_context= &select_lex->outer_select()->context; } //如果move_down=0;意味着对应处理的是union关系 else { if (lex->current_select->order_list.first && !lex->current_select->braces) { my_error(ER_WRONG_USAGE, MYF(0), "UNION", "ORDER BY"); DBUG_RETURN(1); }

//将要处理这个新的参与union中的select子句对应的SELECT_LEX加入union链表中,union操作符左边这个select子句对应的

//SELECT_LEX已经在这个链表中

select_lex->include_neighbour(lex->current_select); SELECT_LEX_UNIT *unit= select_lex->master_unit(); if (!unit->fake_select_lex && unit->add_fake_select_lex(lex->thd)) DBUG_RETURN(1); select_lex->context.outer_context= unit->first_select()->context.outer_context; } select_lex->master_unit()->global_parameters= select_lex; select_lex->include_global((st_select_lex_node**)&lex->all_selects_list); lex->current_select= select_lex; select_lex->context.resolve_in_select_list= TRUE; DBUG_RETURN(0); }










本文转自百度技术51CTO博客,原文链接:http://blog.51cto.com/baidutech/748849,如需转载请自行联系原作者

相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助     相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
1天前
|
SQL 关系型数据库 MySQL
MySQL查询(万字超详细版)
本文详细介绍了数据库中的单表和多表查询方法。首先,单表查询包括全列查询、指定列查询及去重查询,其中应避免使用`*`以提高效率。接着,文章讲解了排序查询,包括升序和降序,并展示了如何通过多个字段进行排序。在多表查询部分,本文解释了内连接、外连接(左外连接和右外连接)以及自连接的概念和用法,提供了丰富的代码示例
16 1
MySQL查询(万字超详细版)
|
13天前
|
自然语言处理 关系型数据库 MySQL
MySQL MATCH 匹配中文 无法查询的问题如何处理?
【8月更文挑战第29天】MySQL MATCH 匹配中文 无法查询的问题如何处理?
43 6
|
12天前
|
图形学 开发者 UED
Unity游戏开发必备技巧:深度解析事件系统运用之道,从生命周期回调到自定义事件,打造高效逻辑与流畅交互的全方位指南
【8月更文挑战第31天】在游戏开发中,事件系统是连接游戏逻辑与用户交互的关键。Unity提供了多种机制处理事件,如MonoBehaviour生命周期回调、事件系统组件及自定义事件。本文介绍如何有效利用这些机制,包括创建自定义事件和使用Unity内置事件系统提升游戏体验。通过合理安排代码执行时机,如在Awake、Start等方法中初始化组件,以及使用委托和事件处理复杂逻辑,可以使游戏更加高效且逻辑清晰。掌握这些技巧有助于开发者更好地应对游戏开发挑战。
30 0
|
12天前
|
存储 关系型数据库 MySQL
MySQL 中的事务存储引擎深入解析
【8月更文挑战第31天】
11 0
|
12天前
|
存储 关系型数据库 MySQL
MySQL 中的 BLOB 数据类型深入解析
【8月更文挑战第31天】
61 0
|
12天前
|
存储 关系型数据库 MySQL
|
12天前
|
存储 缓存 关系型数据库
|
12天前
|
存储 关系型数据库 MySQL
深入解析 MySQL 中的扩展
【8月更文挑战第31天】
11 0
|
12天前
|
关系型数据库 MySQL 数据管理
深入解析 MySQL 中的关系类型
【8月更文挑战第31天】
13 0
|
12天前
|
SQL 关系型数据库 MySQL

热门文章

最新文章

推荐镜像

更多