【MySQL·8.0·源码】MySQL 语法树基础知识

发布时间:2023年12月18日

基础

我们都知道 SQL 语句经过词法分析器时,识别扫描输入的 SQL 语句,将关键词、标识符、常量等分解转换成独立的 tokens,进一步在语法分析阶段根据语法规则检查 tokens 序列的结构并不断 shift 、reduce 构建成 SQL 语法解析树。

在 MySQL 中,撇去解析树构建过程中的结构,最终生成语法树最重要的两个结构就是 Query_expressionQuery_block

Query_expression 对应 <query expression> 用于描述查询表达式

(SELECT column1 FROM table1 WHERE condition1)
UNION
(SELECT column2 FROM table2 WHERE condition2);

Query_block 则对应 <query specification> 用以描述查询规范或定义,表示一个 SELECT 主体部分,通常包括查询的各个组成部分,例如要选择的列、查询的表、过滤条件等。

SELECT
  [DISTINCT | ALL] select_list
FROM
  table_reference
[WHERE
  search_condition]
[GROUP BY
  grouping_column_reference,...]
[HAVING
  search_condition]
[ORDER BY
  order_column_reference [ASC | DESC],...];

SQL 表达式可能是一条简单的 SELECT
select * from t1;

也可能是多条 SELECT 的代数运算,例如: UNIONINTERSET 或者 EXCEPT 运算。
select * from t1 union select * from t2 union select * from t3 order by 1;

所以 Query_expression 的数据结构中主要维护的是表达式或者语句之间关系

class Query_expression {
  Query_expression *next;
  Query_expression **prev;
  Query_block *master;
  Query_block *slave;
}

Query_block 代表的是某条具体的 SQL,所以SELECT 语句中的所有 Clause 都在 Query_block

  • <select list>
  • <table expression><from clause><table reference>
  • <where clause>
  • <group by clause>
  • <having clause>
  • <order by clause>
  • <rollup clause>
class Query_block : public Query_term
    mem_root_deque<Item*> fields;
    SQL_I_List<Table_ref> m_table_list;
    Item *m_where_cond;
    Item *m_having_cond;
    SQL_I_List<ORDER> order_list;
    SQL_I_List<ORDER> group_list;
    Item *select_limit;
    Item *offset_limit;
    Prealloced_array<Item_rollup_group_item*, 4> rollup_group_items;
    Prealloced_array<Item_rollup_sum_switcher*, 4> rollup_sums;
    LEX *parent_lex;
    Query_block *next;
    Query_expression *master;
    Query_expression *slave;
    Query_block *link_next;
    Query_block **link_prev;
    Query_result *m_query_result;
}

一些常见 SQL 语法树中 Query_expressionQuery_bloack 之间的关系可以阅读【MySQL·8.0·源码】MySQL 语法树结构

Item

从上面的 Query_block 中的各个子句上看到大量的 Item 结构
MySQL 源码使用一个 Item 基类来表示在关系查询中出现的任意类型的 expression (表达式)

  • 从类的继承关系角度来看,下面一些常见的继承 Item 的子类

    class Item
    	+--Item_row
    	+--Item_basic_constant
         +--Item_num
            +--Item_int
            +--Item_decimal
            +--Item_float
         +--Item_null
         +--Item_string
         +--Item_json
         +--..
    	+--Item_ident
         +--Item_field
         +--Item_ref
    	+--Item_param
    	+--Item_result_field
         +--Item_subselect
            +--Item_singlerow_subselect
            +--Item_exists_subselect
         +--Item_func
            +--Item_str_func
            +--Item_sum
            +--Item_timeval_func
            +--...
      +--...
    
  • 从 SQL 语句各表达式的角度来看

    • lieral(constant)values 字面值、常量值
    • <column references> 列引用
    • <variable references> 变量引用
    • 表达式
      • <predicates> 谓词表达式
        • <comparison predicate> 比较谓词
        • <between predicate>
        • <in predicate>
        • <like predicate>
        • <exists predicate>
        • <match predicate>
      • <numeric value function><string value function>算术和字符串函数
      • <row value expressiion>行对象
      • <mathod reference>函数引用
      • <subquery>子查询

常见表达式对应的 Item

  • <select list>

     class Query_block : public Query_term
        mem_root_deque<Item*> fields;
    

    Q1:

    select c1,c2,c3 from t1;
    

    在这里插入图片描述

    Q2:

    select c1+3, "joy", max(c2) from t1;
    

    在这里插入图片描述

  • <where clause>

    select * from t1 where c1 > 20 and c1 <= 30 or c1 + c2 > c3;
    

    在这里插入图片描述

  • <group by clause>

    SELECT c1, c2, COUNT(*) AS count_rows
    FROM t1
    GROUP BY c1, c2;
    

    在这里插入图片描述

  • <rollup clause>

    select * from t1 group by c1 with rollup;
    

    在这里插入图片描述

  • <having clause>

    select c1, sum(c2) as total from t1 group by c1 having total < 5;
    

    在这里插入图片描述

  • <order by clause>

    select * from t1 order by c1, c2 desc;
    

    在这里插入图片描述

  • <subquery>

select * from t1 where c1 in (select c2 from t2);

在这里插入图片描述

SELECT *
FROM t1
WHERE EXISTS (SELECT 1 FROM t2 WHERE t1.c1 = t2.c2);

在这里插入图片描述

文章来源:https://blog.csdn.net/u010502974/article/details/135060561
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。