目录文档:MySQL 源码|源码剖析文档目录
源码位置(版本 = MySQL 8.0.37):sql/sql_yacc.yy
前置文档:
在梳理了基础表达式 simple_expr
之后,我们就可以梳理更高级的表达式了。高级表达式的相关关系如下图所示:其中绿色节点为本章节梳理,蓝色节点为之前章节已梳理,红色节点为后续章节梳理。
bit_expr
规则布尔表达式(bit_expr
)作为比基础表达式(simple_expr
)更高一级的表达式,主要匹配如下两种情况:
simple_expr
表达式本身simple_expr
表达式与其他表达式进行二元计算的结果具体包含如下 15 种备选方案:
bit_expr
规则匹配结果、|
和 bit_expr
规则匹配结果:用于匹配任意数量的 |
运算符表达式bit_expr
规则匹配结果、&
和 bit_expr
规则匹配结果:用于匹配任意数量的 &
运算符表达式bit_expr
规则匹配结果、<<
(SHIFT_LEFT
规则)和 bit_expr
规则匹配结果:用于匹配任意数量的 <<
运算符表达式bit_expr
规则匹配结果、>>
(SHIFT_RIGHT
规则)和 bit_expr
规则匹配结果:用于匹配任意数量的 >>
运算符表达式bit_expr
规则匹配结果、+
和 bit_expr
规则匹配结果:用于匹配任意数量的 +
运算符表达式bit_expr
规则匹配结果、-
和 bit_expr
规则匹配结果:用于匹配任意数量的 -
运算符表达式bit_expr
规则表达式、+
、INTERVAL
关键字、expr
规则匹配结果和 interval
规则匹配结果:用于匹配任意数量的 +
时间表达式bit_expr
规则表达式、-
、INTERVAL
关键字、expr
规则匹配结果和 interval
规则匹配结果:用于匹配任意数量的 -
时间表达式bit_expr
规则匹配结果、*
和 bit_expr
规则匹配结果:用于匹配任意数量的 *
运算符表达式bit_expr
规则匹配结果、/
和 bit_expr
规则匹配结果:用于匹配任意数量的 /
运算符表达式bit_expr
规则匹配结果、%
和 bit_expr
规则匹配结果:用于匹配任意数量的 %
运算符表达式bit_expr
规则匹配结果、DIV
关键字和 bit_expr
规则匹配结果:用于匹配任意数量的 DIV
关键字表达式bit_expr
规则匹配结果、MOD
关键字和 bit_expr
规则匹配结果:用于匹配任意数量的 MOD
关键字表达式bit_expr
规则匹配结果、^
和 bit_expr
规则匹配结果:用于匹配任意数量的 ^
运算符表达式simple_expr
规则匹配结果Bison 语法如下:
bit_expr:
bit_expr '|' bit_expr %prec '|'
{
$$= NEW_PTN Item_func_bit_or(@$, $1, $3);
}
| bit_expr '&' bit_expr %prec '&'
{
$$= NEW_PTN Item_func_bit_and(@$, $1, $3);
}
| bit_expr SHIFT_LEFT bit_expr %prec SHIFT_LEFT
{
$$= NEW_PTN Item_func_shift_left(@$, $1, $3);
}
| bit_expr SHIFT_RIGHT bit_expr %prec SHIFT_RIGHT
{
$$= NEW_PTN Item_func_shift_right(@$, $1, $3);
}
| bit_expr '+' bit_expr %prec '+'
{
$$= NEW_PTN Item_func_plus(@$, $1, $3);
}
| bit_expr '-' bit_expr %prec '-'
{
$$= NEW_PTN Item_func_minus(@$, $1, $3);
}
| bit_expr '+' INTERVAL_SYM expr interval %prec '+'
{
$$= NEW_PTN Item_date_add_interval(@$, $1, $4, $5, 0);
}
| bit_expr '-' INTERVAL_SYM expr interval %prec '-'
{
$$= NEW_PTN Item_date_add_interval(@$, $1, $4, $5, 1);
}
| bit_expr '*' bit_expr %prec '*'
{
$$= NEW_PTN Item_func_mul(@$, $1, $3);
}
| bit_expr '/' bit_expr %prec '/'
{
$$= NEW_PTN Item_func_div(@$, $1,$3);
}
| bit_expr '%' bit_expr %prec '%'
{
$$= NEW_PTN Item_func_mod(@$, $1,$3);
}
| bit_expr DIV_SYM bit_expr %prec DIV_SYM
{
$$= NEW_PTN Item_func_div_int(@$, $1,$3);
}
| bit_expr MOD_SYM bit_expr %prec MOD_SYM
{
$$= NEW_PTN Item_func_mod(@$, $1, $3);
}
| bit_expr '^' bit_expr
{
$$= NEW_PTN Item_func_bit_xor(@$, $1, $3);
}
| simple_expr %prec SET_VAR
;
predicate
规则谓语表达式(predicate
)作为比位表达式(bit_expr
)更高一级的表达式,主要匹配如下两种情况:
bit_expr
表达式本身bit_expr
表达式与其他语法结构组合的表达式具体包含如下 17 种备选方案:
标准语法 | Bison 语法 | 说明 |
---|---|---|
bit_expr IN table_subquery |
bit_expr IN_SYM table_subquery |
table_subquery 规则匹配多行子查询 |
bit_expr NOT IN table_subquery |
bit_expr not IN_SYM table_subquery |
table_subquery 规则匹配多行子查询 |
bit_expr IN (expr) |
bit_expr IN_SYM '(' expr ')' |
|
bit_expr IN (expr[, expr_list]) |
bit_expr IN_SYM '(' expr ',' expr_list ')' |
|
bit_expr NOT IN (expr) |
bit_expr not IN_SYM '(' expr ')' |
|
bit_expr NOT IN (expr[, expr_list]) |
bit_expr not IN_SYM '(' expr ',' expr_list ')' |
|
bit_expr MEMBER [OF] (simple_expr) |
bit_expr MEMBER_SYM opt_of '(' simple_expr ')' |
opt_of 规则匹配可选的 OF 关键字 |
bit_expr BETWEEN bit_expr AND predicate |
bit_expr BETWEEN_SYM bit_expr AND_SYM predicate |
|
bit_expr NOT BETWEEN bit_expr AND predicate |
bit_expr not BETWEEN_SYM bit_expr AND_SYM predicate |
|
bit_expr SOUNDS LIKE bit_expr |
bit_expr SOUNDS_SYM LIKE bit_expr |
|
bit_expr LIKE simple_expr |
bit_expr LIKE simple_expr |
|
bit_expr LIKE simple_expr ESCAPE simple_expr |
bit_expr LIKE simple_expr ESCAPE_SYM simple_expr |
|
bit_expr NOT LIKE simple_expr |
bit_expr not LIKE simple_expr |
|
bit_expr NOT LIKE simple_expr ESCAPE simple_expr |
bit_expr not LIKE simple_expr ESCAPE_SYM simple_expr |
|
bit_expr REGEXP bit_expr |
bit_expr REGEXP bit_expr |
|
bit_expr NOT REGEXP bit_expr |
bit_expr not REGEXP bit_expr |
|
bit_expr |
bit_expr |
Bison 语法如下:
predicate:
bit_expr IN_SYM table_subquery
{
$$= NEW_PTN Item_in_subselect(@$, $1, $3);
}
| bit_expr not IN_SYM table_subquery
{
Item *item= NEW_PTN Item_in_subselect(@$, $1, $4);
$$= NEW_PTN PTI_truth_transform(@$, item, Item::BOOL_NEGATED);
}
| bit_expr IN_SYM '(' expr ')'
{
$$= NEW_PTN PTI_handle_sql2003_note184_exception(@$, $1, false, $4);
}
| bit_expr IN_SYM '(' expr ',' expr_list ')'
{
if ($6 == nullptr || $6->push_front($4) || $6->push_front($1))
MYSQL_YYABORT;
$$= NEW_PTN Item_func_in(@$, $6, false);
}
| bit_expr not IN_SYM '(' expr ')'
{
$$= NEW_PTN PTI_handle_sql2003_note184_exception(@$, $1, true, $5);
}
| bit_expr not IN_SYM '(' expr ',' expr_list ')'
{
if ($7 == nullptr)
MYSQL_YYABORT;
$7->push_front($5);
$7->value.push_front($1);
$$= NEW_PTN Item_func_in(@$, $7, true);
}
| bit_expr MEMBER_SYM opt_of '(' simple_expr ')'
{
$$= NEW_PTN Item_func_member_of(@$, $1, $5);
}
| bit_expr BETWEEN_SYM bit_expr AND_SYM predicate
{
$$= NEW_PTN Item_func_between(@$, $1, $3, $5, false);
}
| bit_expr not BETWEEN_SYM bit_expr AND_SYM predicate
{
$$= NEW_PTN Item_func_between(@$, $1, $4, $6, true);
}
| bit_expr SOUNDS_SYM LIKE bit_expr
{
Item *item1= NEW_PTN Item_func_soundex(@$, $1);
Item *item4= NEW_PTN Item_func_soundex(@$, $4);
if ((item1 == nullptr) || (item4 == nullptr))
MYSQL_YYABORT;
$$= NEW_PTN Item_func_eq(@$, item1, item4);
}
| bit_expr LIKE simple_expr
{
$$ = NEW_PTN Item_func_like(@$, $1, $3);
}
| bit_expr LIKE simple_expr ESCAPE_SYM simple_expr %prec LIKE
{
$$ = NEW_PTN Item_func_like(@$, $1, $3, $5);
}
| bit_expr not LIKE simple_expr
{
auto item = NEW_PTN Item_func_like(@$, $1, $4);
$$ = NEW_PTN Item_func_not(@$, item);
}
| bit_expr not LIKE simple_expr ESCAPE_SYM simple_expr %prec LIKE
{
auto item = NEW_PTN Item_func_like(@$, $1, $4, $6);
$$ = NEW_PTN Item_func_not(@$, item);
}
| bit_expr REGEXP bit_expr
{
auto args= NEW_PTN PT_item_list(@$);
args->push_back($1);
args->push_back($3);
$$= NEW_PTN Item_func_regexp_like(@1, args);
}
| bit_expr not REGEXP bit_expr
{
auto args= NEW_PTN PT_item_list(@$);
args->push_back($1);
args->push_back($4);
Item *item= NEW_PTN Item_func_regexp_like(@$, args);
$$= NEW_PTN PTI_truth_transform(@$, item, Item::BOOL_NEGATED);
}
| bit_expr %prec SET_VAR
;
opt_of
规则opt_of
规则用于匹配可选的 OF
关键字,Bison 语法如下:
opt_of:
OF_SYM
| %empty
;
bool_pri
规则布尔表达式(bool_pri
)作为比谓语表达式(predicate
)更高一级的表达式,主要匹配如下两种情况:
predicate
表达式本身predicate
表达式与 IS
或比较运算符连接的表达式具体包含如下 5 种备选方案:
标准语法 | Bison 语法 | 说明 |
---|---|---|
bool_pri IS NULL |
bool_pri IS NULL_SYM |
|
bool_pri IS NOT NULL |
bool_pri IS not NULL_SYM |
|
bool_pri 比较运算符 (expr) |
bool_pri comp_op predicate |
comp_op 规则匹配比较运算符 |
`bool_pri 比较运算符 ALL | ANY table_subquery` | bool_pri comp_op all_or_any table_subquery |
predicate |
predicate |
Bison 语法如下:
bool_pri:
bool_pri IS NULL_SYM %prec IS
{
$$= NEW_PTN Item_func_isnull(@$, $1);
}
| bool_pri IS not NULL_SYM %prec IS
{
$$= NEW_PTN Item_func_isnotnull(@$, $1);
}
| bool_pri comp_op predicate
{
$$= NEW_PTN PTI_comp_op(@$, $1, $2, $3);
}
| bool_pri comp_op all_or_any table_subquery %prec EQ
{
if ($2 == &comp_equal_creator)
YYTHD->syntax_error_at(@2);
$$= NEW_PTN PTI_comp_op_all(@$, $1, $2, $3, $4);
}
| predicate %prec SET_VAR
;
comp_op
规则comp_op
规则用于匹配比较运算符,具体匹配 =
(EQ
规则)、<=>
(EQUAL_SYM
规则)、>=
(GE
规则)、>
(GT_SYM
规则)、<=
(LE
规则)、<
(LT
规则)、!=
或 <>
(NE
规则),Bison 语法如下:
comp_op:
EQ { $$ = &comp_eq_creator; }
| EQUAL_SYM { $$ = &comp_equal_creator; }
| GE { $$ = &comp_ge_creator; }
| GT_SYM { $$ = &comp_gt_creator; }
| LE { $$ = &comp_le_creator; }
| LT { $$ = &comp_lt_creator; }
| NE { $$ = &comp_ne_creator; }
;
all_or_any
规则all_or_any
规则用于匹配 ALL
关键字或 ANY
关键字,Bison 语法如下:
all_or_any:
ALL { $$ = 1; }
| ANY_SYM { $$ = 0; }
;
expr
规则一般表达式(expr
)作为比布尔表达式(bool_pri
)更高一级的表达式,主要匹配如下两种情况:
bool_pri
表达式本身bool_pri
表达式由优先级最低的运算符连接的表达式具体包含如下 12 种备选方案:
标准语法 | Bison 语法 | 说明 |
---|---|---|
expr OR expr |
expr or expr |
匹配任意数量的 OR 二元表达式 |
expr XOR expr |
expr XOR expr |
匹配任意数量的 XOR 二元表达式 |
expr AND expr |
expr and expr |
匹配任意数量的 AND 二元表达式 |
NOT expr |
NOT_SYM expr |
匹配任意数量的 NOT 一元表达式 |
bool_pri IS TRUE |
bool_pri IS TRUE_SYM |
匹配 IS TRUE 表达式 |
bool_pri IS NOT TRUE |
bool_pri IS not TRUE_SYM |
匹配 IS NOT TRUE 表达式 |
bool_pri IS FALSE |
bool_pri IS FALSE_SYM |
匹配 IS FALSE 表达式 |
bool_pri IS NOT FALSE |
bool_pri IS not FALSE_SYM |
匹配 IS NOT FALSE 表达式 |
bool_pri IS UNKNOWN |
bool_pri IS UNKNOWN_SYM |
匹配 IS UNKNOWN 表达式 |
bool_pri IS NOT UNKNOWN |
bool_pri IS not UNKNOWN_SYM |
匹配 IS NOT UNKNOWN 表达式 |
bool_pri |
bool_pri |
expr_list
规则expr_list
规则用于匹配用逗号分隔的任意数量一般表达式(expr
规则),Bison 语法如下:
expr_list:
expr
{
$$= NEW_PTN PT_item_list(@$);
if ($$ == nullptr || $$->push_back($1))
MYSQL_YYABORT;
}
| expr_list ',' expr
{
if ($1 == nullptr || $1->push_back($3))
MYSQL_YYABORT;
$$= $1;
// This will override location of earlier list, until we get the
// whole location.
$$->m_pos = @$;
}
;