MySQL 源码|56 - 语法解析:WITH 子句

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

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

前置文档:


在继续梳理 SELECT 表达式、UPDATE 表达式和 DELETE 表达式之前,我们首先梳理 WITH 子句的规则。

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

在这里插入图片描述

opt_with_clause 规则

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

opt_with_clause:
          %empty { $$= nullptr; }
        | with_clause { $$= $1; }
        ;
with_clause 规则

with_clause 规则用于匹配 WITH 子句,对应的标准语法如下,详见 MySQL 参考手册 - 15.2.20 WITH (Common Table Expressions)

with_clause:
    WITH [RECURSIVE]
        cte_name [(col_name [, col_name] ...)] AS (subquery)
        [, cte_name [(col_name [, col_name] ...)] AS (subquery)] ...

with_clause 规则的 Bison 语法有如下两种备选方案,分别匹配包含和不包含 RECURSIVE 关键字的标准语法,Bison 语法如下:

with_clause:
          WITH with_list
          {
            $$= NEW_PTN PT_with_clause(@$, $2, false);
          }
        | WITH RECURSIVE_SYM with_list
          {
            $$= NEW_PTN PT_with_clause(@$, $3, true);
          }
        ;
with_list 规则

with_list 规则用于匹配 WITH 子句中的临时表的列表,对应的标准语法如下:

cte_name [(col_name [, col_name] ...)] AS (subquery)
[, cte_name [(col_name [, col_name] ...)] AS (subquery)] ...

with_list 规则的 Bison 语法通过如下两种备选方案,实现了匹配任意数量是否逗号分隔的 WITH 子句临时表,Bison 语法如下:

with_list:
          with_list ',' common_table_expr
          {
            if ($1->push_back($3))
              MYSQL_YYABORT;
            $$->m_pos = @$;
          }
        | common_table_expr
          {
            $$= NEW_PTN PT_with_list(@$, YYTHD->mem_root);
            if ($$ == nullptr || $$->push_back($1))
              MYSQL_YYABORT;    /* purecov: inspected */
          }
        ;
common_table_expr 规则

common_table_expr 规则用于匹配每一个 WITH 子句中的临时表,对应标准语法 cte_name [(col_name [, col_name] ...)] AS (subquery),只有依次匹配表名标识符(ident 规则)、表字段列表(opt_derived_column_list 规则)、AS 关键字和多行子查询(table_subquery 规则)这一种备选方案,Bison 语法如下:

common_table_expr:
          ident opt_derived_column_list AS table_subquery
          {
            LEX_STRING subq_text;
            subq_text.length= @4.cpp.length();
            subq_text.str= YYTHD->strmake(@4.cpp.start, subq_text.length);
            if (subq_text.str == nullptr)
              MYSQL_YYABORT;   /* purecov: inspected */
            uint subq_text_offset= @4.cpp.start - YYLIP->get_cpp_buf();
            $$= NEW_PTN PT_common_table_expr(@$, $1, subq_text, subq_text_offset,
                                             $4, &$2, YYTHD->mem_root);
            if ($$ == nullptr)
              MYSQL_YYABORT;   /* purecov: inspected */
          }
        ;
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

长行

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

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

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

打赏作者

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

抵扣说明:

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

余额充值