数据库
首页 > 数据库> > MySQL 8.0 QueryResolver 源码笔记

MySQL 8.0 QueryResolver 源码笔记

作者:互联网

MySQL 8.0 QueryResolver 源码笔记

前言

核心逻辑在SELECT_LEX::prepare()中,按照源码注释,其包括的大致内容如下:

/**
  Prepare query block for optimization.

  Resolve table and column information.
  Resolve all expressions (item trees), ie WHERE clause, join conditions,
  GROUP BY clause, HAVING clause, ORDER BY clause, LIMIT clause.
  Prepare all subqueries recursively as part of resolving the expressions.
  Apply permanent transformations to the abstract syntax tree, such as
  semi-join transformation, derived table transformation, elimination of
  constant values and redundant clauses (e.g ORDER BY, GROUP BY).
**/

通俗地讲,Resolver可以分为两部分:Semantic check和Rewriter。

Semantic check

这个概念来自于Oracle,主要负责将field、db甚至host等资源信息去和真实数据库内的对象去做绑定。举个例子,Parser是不关心field是否真实存在的,只要符合格式,随便写个字符串它都会语法解析成Item_field对象;而Semantic check步骤正是去结合数据库元信息去检查字段、表名、数据库名等是否合法真实存在。

需注意的是,基本的用户SELECT权限检查在MySQL的实现中放在了 precheck() 函数中,列权限检查放在了 SELECT_LEX::prepare() 的 setup_fields() 函数中。即,对于MySQL的实现,Semantic check仅是个逻辑上的流程概念。在一些其他数据库的实现中,可能会更直观地看到SemanticChecker这样的逻辑或者插件函数。

Table和Fields的绑定(逻辑分散在Sql_cmd_dml::prepare/SELECT_LEX::prepare等地方):

  1. Parser时会找到所有的表,在Sql_cmd_dml::prepare阶段会按照表名和当前session所在的database(如果显式指定了则以用户指定的为准)去执行 open tables,如果表不合法则打开失败。

  2. Item_field绑定Field的核心是set_field(Field*)函数。而 set_field 的主要调用逻辑都是 fix_field()。fix_field 的注释较为缺乏,实际用途是根据不同的resolution结果去绑定一个Item_field到物理或生成的Field上。fix_field会在多个地方被调用的原因是在 SQL Rewrite 的过程中,列发生变化,比如derive table优化或subquery优化,生成表的列优化为物理表的列等。这部分逻辑非常分散且复杂

Rewriter

剩下的 Resolve all expressions 、subquery、消除常量或冗余语句等都属于Rewriter过程,在很多MySQL分析中还是会把其称作Resolver。

TABLE
SELECT fields
WHERE conds/ Join conds

. setup_having : having_cond->fix_fields() 。having没有专门的函数括起

GROUPBY / ORDERBY

Subquery

Others

标签:8.0,join,setup,derived,field,subquery,源码,table,QueryResolver
来源: https://www.cnblogs.com/lhfcws/p/14879906.html