MySQL 源码|55 - 语法解析:基础查询语句(query_specification)

目录文档:MySQL 源码|源码剖析文档目录

源码位置(版本 = MySQL 8.0.37):sql/sql_yacc.yy

前置文档:


在此之前,我们已经梳理了 query_specification 规则中涉及的 ORDER BY 子句、GROUP BY 子句、FROM 子句、JOIN 子句、INFO 子句和 WINDOW 子句,现在,我们来梳理 query_specification 规则。

本节涉及相关关系如下图所示:其中绿色节点为本章节梳理,蓝色节点为之前章节已梳理,红色节点为后续章节梳理。

在这里插入图片描述

query_specification 规则

query_specification 规则用于匹配基础查询语句,标准语法如下:

SELECT
    [ALL | DISTINCT | DISTINCTROW ]
    [HIGH_PRIORITY]
    [STRAIGHT_JOIN]
    [SQL_SMALL_RESULT] [SQL_BIG_RESULT] [SQL_BUFFER_RESULT]
    [SQL_NO_CACHE] [SQL_CALC_FOUND_ROWS]
    select_expr [, select_expr] ...
    [into_option]
    [FROM table_references
      [PARTITION partition_list]]
    [WHERE where_condition]
    [GROUP BY {col_name | expr | position}, ... [WITH ROLLUP]]
    [HAVING where_condition]
    [WINDOW window_name AS (window_spec)
        [, window_name AS (window_spec)] ...]

这里不包含 ORDER BY 子句和 LIMIT 子句,是因为 MySQL 的查询树结构中,ORDER BY 子句和 LIMIT 子句的逻辑保存在 Query_block 之中,而这个规则解析的应该是不包含这部分的核心查询逻辑。这个逻辑我们会在后续继续梳理。

Bison 语法如下:

query_specification:
          SELECT_SYM
          select_options
          select_item_list
          into_clause
          opt_from_clause
          opt_where_clause
          opt_group_clause
          opt_having_clause
          opt_window_clause
          opt_qualify_clause
          {
            $$= NEW_PTN PT_query_specification(
                                      @$,
                                      $1,  // SELECT_SYM
                                      $2,  // select_options
                                      $3,  // select_item_list
                                      $4,  // into_clause
                                      $5,  // from
                                      $6,  // where
                                      $7,  // group
                                      $8,  // having
                                      $9,  // windows
                                      $10, // qualify
                                      @5.raw.is_empty()); // implicit FROM
          }
        | SELECT_SYM
          select_options
          select_item_list
          opt_from_clause
          opt_where_clause
          opt_group_clause
          opt_having_clause
          opt_window_clause
          opt_qualify_clause
          {
            $$= NEW_PTN PT_query_specification(
                                      @$,
                                      $1,  // SELECT_SYM
                                      $2,  // select_options
                                      $3,  // select_item_list
                                      nullptr,// no INTO clause
                                      $4,  // from
                                      $5,  // where
                                      $6,  // group
                                      $7,  // having
                                      $8,  // windows
                                      $9,  // qualify
                                      @4.raw.is_empty()); // implicit FROM
          }
        ;
  • select_options 规则用于匹配可选的查询选项
  • select_item_list 规则用于匹配查询的字段信息
  • into_clause 规则用于匹配 INTO 子句
  • opt_from_clause 规则用于匹配可选的 FROM 子句
  • opt_where_clause 规则用于匹配可选的 WHERE 子句
  • opt_group_clause 规则用于匹配可选的 GROUP BY 子句
  • opt_having_clause 规则用于匹配可选的 HAVING 子句
  • opt_window_clause 规则用于匹配可选的 WINDOW 子句
  • opt_qualify_clause 规则用于匹配可选的 QUALIFY 子句
select_options 规则

select_options 规则用于匹配可选的查询选项,对应标准语法如下:

    [ALL | DISTINCT | DISTINCTROW ]
    [HIGH_PRIORITY]
    [STRAIGHT_JOIN]
    [SQL_SMALL_RESULT] [SQL_BIG_RESULT] [SQL_BUFFER_RESULT]
    [SQL_NO_CACHE] [SQL_CALC_FOUND_ROWS]

select_options 规则有不匹配和匹配 select_option_list 规则匹配结果两种备选方案,Bison 语法如下:

select_options:
          %empty
          {
            $$.query_spec_options= 0;
          }
        | select_option_list
        ;
select_option_list 规则

select_option_list 规则用于匹配大于等于一个、用空格分隔的查询选项,Bison 语法如下:

select_option_list:
          select_option_list select_option
          {
            if ($$.merge($1, $2))
              MYSQL_YYABORT;
          }
        | select_option
        ;
select_option 规则

select_option 规则用于匹配单个查询选项,标准语法如下:

ALL | DISTINCT | DISTINCTROW | HIGH_PRIORITY | STRAIGHT_JOIN | SQL_SMALL_RESULT | SQL_BIG_RESULT | SQL_BUFFER_RESULT | SQL_NO_CACHE | SQL_CALC_FOUND_ROWS

Bison 语法的第二个备选方案 SQL_NO_CACHE_SYM 用于实现标准语法 SQL_NO_CACHE。Bison 语法如下:

select_option:
          query_spec_option
          {
            $$.query_spec_options= $1;
          }
        | SQL_NO_CACHE_SYM
          {
            push_deprecated_warn_no_replacement(YYTHD, "SQL_NO_CACHE");
            /* Ignored since MySQL 8.0. */
            $$.query_spec_options= 0;
          }
        ;
query_spec_option 规则

query_spec_option 规则用于匹配除 SQL_NO_CACHE 之外的其他单个查询选项,标准语法如下:

ALL | DISTINCT | DISTINCTROW | HIGH_PRIORITY | STRAIGHT_JOIN | SQL_SMALL_RESULT | SQL_BIG_RESULT | SQL_BUFFER_RESULT | SQL_CALC_FOUND_ROWS

Bison 语法中的每个备选方案,分别对应一个标准语法。Bison 语法如下:

query_spec_option:
          STRAIGHT_JOIN       { $$= SELECT_STRAIGHT_JOIN; }
        | HIGH_PRIORITY       { $$= SELECT_HIGH_PRIORITY; }
        | DISTINCT            { $$= SELECT_DISTINCT; }
        | SQL_SMALL_RESULT    { $$= SELECT_SMALL_RESULT; }
        | SQL_BIG_RESULT      { $$= SELECT_BIG_RESULT; }
        | SQL_BUFFER_RESULT   { $$= OPTION_BUFFER_RESULT; }
        | SQL_CALC_FOUND_ROWS {
            push_warning(YYTHD, Sql_condition::SL_WARNING,
                         ER_WARN_DEPRECATED_SYNTAX,
                         ER_THD(YYTHD, ER_WARN_DEPRECATED_SQL_CALC_FOUND_ROWS));
            $$= OPTION_FOUND_ROWS;
          }
        | ALL                 { $$= SELECT_ALL; }
        ;
select_item_list 规则

select_item_list 规则用于匹配逗号分隔的多个查询字段或通配符 *,Bison 语法如下:

select_item_list:
          select_item_list ',' select_item
          {
            if ($1 == nullptr || $1->push_back($3))
              MYSQL_YYABORT;
            $$= $1;
            $$->m_pos = @$;
          }
        | select_item
          {
            $$= NEW_PTN PT_select_item_list(@$);
            if ($$ == nullptr || $$->push_back($1))
              MYSQL_YYABORT;
          }
        | '*'
          {
            Item *item = NEW_PTN Item_asterisk(@$, nullptr, nullptr);
            $$ = NEW_PTN PT_select_item_list(@$);
            if ($$ == nullptr || item == nullptr || $$->push_back(item))
              MYSQL_YYABORT;
          }
        ;
select_item 规则

select_item 规则用于匹配单个查询字段,Bison 语法如下:

select_item:
          table_wild { $$= $1; }
        | expr select_alias
          {
            $$= NEW_PTN PTI_expr_with_alias(@$, $1, @1.cpp, to_lex_cstring($2));
          }
        ;
  • table_wild 规则用于匹配 ident.*ident.ident.* 的通配符名称
  • expr 规则用于匹配一般表达式
  • select_alias 规则用于匹配 AS 子句指定别名
table_wild 规则

table_wild 规则用于匹配 ident.*ident.ident.* 的通配符名称,Bison 语法如下:

table_wild:
          ident '.' '*'
          {
            $$ = NEW_PTN Item_asterisk(@$, nullptr, $1.str);
          }
        | ident '.' ident '.' '*'
          {
            if (check_and_convert_db_name(&$1, false) != Ident_name_check::OK)
              MYSQL_YYABORT;
            auto schema_name = YYCLIENT_NO_SCHEMA ? nullptr : $1.str;
            $$ = NEW_PTN Item_asterisk(@$, schema_name, $3.str);
          }
        ;
opt_where_clause 规则

opt_where_clause 规则用于匹配可选的 WHERE 子句,对应标准语法 [WHERE where_condition],Bison 语法如下:

opt_where_clause:
          %empty { $$ = nullptr; }
        | where_clause
        ;
where_clause 规则

where_clause 规则用于匹配 WHERE 子句,对应标准语法 WHERE where_condition,Bison 语法如下:

where_clause:
          WHERE expr    { $$ = NEW_PTN PTI_where(@2, $2); }
        ;
opt_having_clause 规则

opt_having_clause 规则用于匹配可选的 HAVING 子句,对应标准语法 [HAVING where_condition],Bison 语法如下:

opt_having_clause:
          %empty { $$= nullptr; }
        | HAVING expr
          {
            $$= new PTI_having(@$, $2);
          }
        ;
opt_qualify_clause 规则

opt_qualify_clause 规则用于匹配可选的 QUALIFY_CLAUSE 子句,Bison 语法如下:

opt_qualify_clause:
           %empty { $$= nullptr; }
        | QUALIFY_SYM expr
          {
            $$= new PTI_qualify(@$, $2);
          }
        ;
  • 17
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

长行

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值