MySQL 源码|51 - 语法解析:高级表达式

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

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

前置文档:

  • MySQL 源码|50 - 语法解析:基础表达式(simple_expr)

在梳理了基础表达式 simple_expr 之后,我们就可以梳理更高级的表达式了。高级表达式的相关关系如下图所示:其中绿色节点为本章节梳理,蓝色节点为之前章节已梳理,红色节点为后续章节梳理。

MySQL 源码|51 - 语法解析:高级表达式_第1张图片

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 = @$;
          }
        ;

你可能感兴趣的:(MySQL源码,mysql,源码,语法解析,高级表达式)