目录文档:MySQL 源码|源码剖析文档目录
源码位置(版本 = MySQL 8.0.37):sql/sql_yacc.yy
前置文档:
在此之前,我们已经梳理的规则关系如下图所示。
下面我们梳理在 simple_expr
中使用的 row_subquery
规则和 table_subquery
规则,这两个规则用于处理单行子查询和多行子查询。涉及为子查询的规则如下图所示:其中绿色节点为本章节梳理,蓝色节点为之前章节已梳理,红色节点为后续章节梳理。
row_subquery
规则
row_subquery
规则用于匹配单行子查询,只有匹配 subquery
规则匹配结果这一种备选方案,Bison 语法如下:
row_subquery:
subquery
;
table_subquery
规则
table_subquery
规则用于匹配多行子查询,只有匹配 subquery
规则匹配结果这一种备选方案,Bison 语法如下:
table_subquery:
subquery
;
subquery
规则
subquery
规则用于匹配子查询,只有匹配 query_expression_parens
规则匹配结果这一种备选方案,Bison 语法如下:
subquery:
query_expression_parens %prec SUBQUERY_AS_EXPR
{
$$= NEW_PTN PT_subquery(@$, $1);
}
;
query_expression_parens
规则
query_expression_parens
规则用于匹配子查询,包含如下两种备选方案:
- 依次匹配
(
、query_expression_parens
规则匹配结果和)
,通过这个备选方案,使query_expression_parens
规则外可以嵌套任意层数的括号 - 依次匹配
(
、query_expression_with_opt_locking_clauses
规则匹配结果和)
Bison 语法如下:
query_expression_parens:
'(' query_expression_parens ')'
{ $$ = $2;
if ($$ != nullptr) $$->m_pos = @$;
}
| '(' query_expression_with_opt_locking_clauses')'
{ $$ = $2;
if ($$ != nullptr) $$->m_pos = @$;
}
;
query_expression_with_opt_locking_clauses
规则
query_expression_with_opt_locking_clauses
规则用于匹配子查询中的查询语句,该规则包含如下两种备选方案:
- 匹配
query_expression
规则匹配结果 - 依次匹配
query_expression
规则匹配结果和locking_clause_list
规则匹配结果
通过以上两种备选方案,实现了匹配 query_expression
规则匹配结果和可选的 locking_clause_list
规则匹配结果的效果,Bison 语法如下:
query_expression_with_opt_locking_clauses:
query_expression { $$ = $1; }
| query_expression locking_clause_list
{
$$ = NEW_PTN PT_locking(@$, $1, $2);
}
;
locking_clause_list
规则
locking_clause_list
规则用于匹配锁模式子句,有如下两种备选方案,实现了匹配任意数量的 locking_clause
子句的效果,Bison 语法如下:
locking_clause_list:
locking_clause_list locking_clause
{
$$= $1;
if ($$->push_back($2))
MYSQL_YYABORT; // OOM
}
| locking_clause
{
$$= NEW_PTN PT_locking_clause_list(@$, YYTHD->mem_root);
if ($$ == nullptr || $$->push_back($1))
MYSQL_YYABORT; // OOM
}
;
locking_clause
规则
locking_clause
规则用于匹配锁模式子句,有如下三种备选方案:
- 依次匹配
FOR
关键字、lock_strength
规则匹配结果、opt_locked_row_action
规则匹配结果 - 依次匹配
FOR
关键字、lock_strength
规则匹配结果、table_locking_list
规则匹配结果、opt_locked_row_action
规则匹配结果 - 依次匹配
LOCK
关键字、IN
关键字、SHARE
关键字、MODE
关键字
通过第一种和第二种备选方案,实现了可选的 table_locking_list
效果。其中:
lock_strength
规则用于匹配UPDATE
或SHARE
。opt_locked_row_action
规则用于匹配可选的SKIP LOCKED
或NOWAIT
。
Bison 语法如下:
locking_clause:
FOR_SYM lock_strength opt_locked_row_action
{
$$= NEW_PTN PT_query_block_locking_clause(@$, $2, $3);
}
| FOR_SYM lock_strength table_locking_list opt_locked_row_action
{
$$= NEW_PTN PT_table_locking_clause(@$, $2, $3, $4);
}
| LOCK_SYM IN_SYM SHARE_SYM MODE_SYM
{
$$= NEW_PTN PT_query_block_locking_clause(@$, Lock_strength::SHARE);
}
;
lock_strength
规则
lock_strength
规则用于匹配 UPDATE
关键字或 SHARE
关键字,Bison 语法如下:
lock_strength:
UPDATE_SYM { $$= Lock_strength::UPDATE; }
| SHARE_SYM { $$= Lock_strength::SHARE; }
;
opt_locked_row_action
规则
opt_locked_row_action
规则用于匹配可选的 SKIP LOCKED
或 NOWAIT
,有不匹配和匹配 locked_row_action
规则匹配结果两种备选方案,Bison 语法如下:
opt_locked_row_action:
%empty { $$= Locked_row_action::WAIT; }
| locked_row_action
;
locked_row_action
规则
locked_row_action
规则用于匹配 SKIP LOCKED
或 NOWAIT
,Bison 语法如下:
locked_row_action:
SKIP_SYM LOCKED_SYM { $$= Locked_row_action::SKIP; }
| NOWAIT_SYM { $$= Locked_row_action::NOWAIT; }
;
table_locking_list
规则
table_locking_list
规则用于匹配指定行锁的行,Bison 语法如下:
table_locking_list:
OF_SYM table_alias_ref_list { $$= $2; }
;
table_alias_ref_list
规则
table_alias_ref_list
规则用于匹配任意数量的逗号分隔的 table_ident_opt_wild
规则匹配结果,其中 table_ident_opt_wild
用于匹配行,Bison 语法如下:
table_alias_ref_list:
table_ident_opt_wild
{
$$.init(YYMEM_ROOT);
if ($$.push_back($1))
MYSQL_YYABORT; // OOM
}
| table_alias_ref_list ',' table_ident_opt_wild
{
$$= $1;
if ($$.push_back($3))
MYSQL_YYABORT; // OOM
}
;
table_ident_opt_wild
规则
table_ident_opt_wild
规则用于匹配行,有如下两种备选方案:
- 匹配
ident[.*]
:依次匹配ident
规则匹配结果和opt_wild
规则匹配结果 - 匹配
ident.ident[.*]
:依次匹配ident
规则匹配结果、.
、ident
规则匹配结果和opt_wild
规则匹配结果
table_ident_opt_wild:
ident opt_wild
{
$$= NEW_PTN Table_ident(to_lex_cstring($1));
if ($$ == nullptr)
MYSQL_YYABORT;
}
| ident '.' ident opt_wild
{
$$= NEW_PTN Table_ident(YYTHD->get_protocol(),
to_lex_cstring($1),
to_lex_cstring($3), 0);
if ($$ == nullptr)
MYSQL_YYABORT;
}
;
opt_wild
规则
opt_wild
规则用于匹配可选的 .*
,Bison 语法如下:
opt_wild:
%empty
| '.' '*'
;