MySQL 源码|52 - FROM 子句和 JOIN 子句

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

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

前置文档:


下面开始逐步梳理 DQL 语句 query_specification 规则中的各个组成部分,之前已经梳理了 ORDER BY 子句和 GROUP BY 子句,现在来看 FROM 子句和 JOIN 子句,在 opt_from_clause 规则中,同时匹配 FROM 子句和 JOIN 子句。

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

在这里插入图片描述

opt_from_clause 规则

MySQL 参考手册标准语法:[FROM table_references [PARTITION partition_list]],其中 table_referencestbl_name [[AS] alias] [index_hint]MySQL 参考手册 - 15.2.13 SELECT Statement

opt_from_clause 规则匹配可选的 FROM 子句,Bison 语法如下:

opt_from_clause:
          %empty %prec EMPTY_FROM_CLAUSE { $$.init(YYMEM_ROOT); }
        | from_clause
        ;
from_clause 规则

from_clause 规则匹配 FROM 子句,包含 FROM 关键字和 from_tables 规则匹配结果,Bison 语法如下:

from_clause:
          FROM from_tables { $$= $2; }
        ;
from_tables 规则

from_tables 规则匹配 DUAL 关键字或 table_reference_list 规则匹配结果,其中 DUAL 表示虚拟表,Bison 语法如下:

from_tables:
          DUAL_SYM { $$.init(YYMEM_ROOT); }
        | table_reference_list
        ;
table_reference_list 规则

table_reference_list 规则用于匹配逗号分隔的任意数量 table_refernce 规则匹配结果,Bison 语法如下:

table_reference_list:
          table_reference
          {
            $$.init(YYMEM_ROOT);
            if ($$.push_back($1))
              MYSQL_YYABORT; // OOM
          }
        | table_reference_list ',' table_reference
          {
            $$= $1;
            if ($$.push_back($3))
              MYSQL_YYABORT; // OOM
          }
        ;
table_reference 规则

table_reference 规则用于匹配查询的表或关联的表,有如下三种备选方案:

  • 匹配 table_factor 规则匹配结果:用于匹配单个表
  • 匹配 joined_table 规则匹配结果:用于匹配多表关联
  • 依次匹配 {OJ 关键字、esc_table_reference 规则匹配结果和 }:其中 esc_table_reference 规则匹配 table_factor 规则匹配结果或 joined_table 规则匹配结果

Bison 语法如下:

table_reference:
          table_factor { $$= $1; }
        | joined_table { $$= $1; }
        | '{' OJ_SYM esc_table_reference '}'
          {
            /*
              The ODBC escape syntax for Outer Join.

              All productions from table_factor and joined_table can be escaped,
              not only the '{LEFT | RIGHT} [OUTER] JOIN' syntax.
            */
            $$ = $3;
          }
        ;
esc_table_reference 规则

esc_table_reference 规则匹配 table_factor 规则匹配结果或 joined_table 规则匹配结果,Bison 语法如下:

esc_table_reference:
          table_factor { $$= $1; }
        | joined_table { $$= $1; }
        ;
joined_table 规则

joined_table 规则用于匹配多表关联,包含如下 6 种备选方案:

  • table_reference inner_join_type table_reference ON_SYM expr:用于匹配使用 ON 关键字指定关联规则的内关联子句
    • 其中 inner_join_type 规则匹配 JOININNER JOINCROSS JOINSTRAIGHT_JOIN 中的任意一个
  • table_reference inner_join_type table_reference USING ( using_list ):匹配使用 USING 函数指定关联规则的内关联子句
    • 其中 using_list 规则匹配标识符的列表
  • table_reference outer_join_type table_reference ON_SYM expr:匹配使用 ON 关键字指定关联规则的外关联子句
    • 其中 outer_join_type 规则匹配 LEFT JOINLEFT OUTER JOINRIGHT JOINRIGHT OUTER JOIN 中的任意一个
  • table_reference outer_join_type table_reference USING ( using_list ):匹配使用 USING 函数指定关联规则的外关联子句
  • table_reference inner_join_type table_reference:匹配没有指定关联规则的内关联子句
  • table_reference natural_join_type table_factor:匹配没有指定关联规则的 NATURAL 关联子句
    • 其中 natural_join_type 规则匹配 NATURAL JOINNATURAL INNER JOINNATURAL LEFT JOINNATURAL LEFT OUTER JOINNATURAL RIGHT JOINNATURAL RIGHT OUTER JOIN 中的任意一个

Bison 语法如下:

joined_table:
          table_reference inner_join_type table_reference ON_SYM expr
          {
            $$= NEW_PTN PT_joined_table_on(@$, $1, @2, $2, $3, $5);
          }
        | table_reference inner_join_type table_reference USING
          '(' using_list ')'
          {
            $$= NEW_PTN PT_joined_table_using(@$, $1, @2, $2, $3, $6);
          }
        | table_reference outer_join_type table_reference ON_SYM expr
          {
            $$= NEW_PTN PT_joined_table_on(@$, $1, @2, $2, $3, $5);
          }
        | table_reference outer_join_type table_reference USING '(' using_list ')'
          {
            $$= NEW_PTN PT_joined_table_using(@$, $1, @2, $2, $3, $6);
          }
        | table_reference inner_join_type table_reference
          %prec CONDITIONLESS_JOIN
          {
            auto this_cross_join= NEW_PTN PT_cross_join(@$, $1, @2, $2, nullptr);

            if ($3 == nullptr)
              MYSQL_YYABORT; // OOM

            $$= $3->add_cross_join(this_cross_join);
          }
        | table_reference natural_join_type table_factor
          {
            $$= NEW_PTN PT_joined_table_using(@$, $1, @2, $2, $3);
          }
        ;
inner_join_type 规则

inner_join_type 规则用于匹配 JOININNER JOINCROSS JOINSTRAIGHT_JOIN 中的任意一个,Bison 语法如下:

inner_join_type:
          JOIN_SYM                         { $$= JTT_INNER; }
        | INNER_SYM JOIN_SYM               { $$= JTT_INNER; }
        | CROSS JOIN_SYM                   { $$= JTT_INNER; }
        | STRAIGHT_JOIN                    { $$= JTT_STRAIGHT_INNER; }
outer_join_type 规则

outer_join_type 规则用于匹配 LEFT JOINLEFT OUTER JOINRIGHT JOINRIGHT OUTER JOIN 中的任意一个,其中 opt_outer 匹配可选的 OUTER 关键字,Bison 语法如下:

outer_join_type:
          LEFT opt_outer JOIN_SYM          { $$= JTT_LEFT; }
        | RIGHT opt_outer JOIN_SYM         { $$= JTT_RIGHT; }
        ;
natural_join_type 规则

natural_join_type 规则用于匹配 NATURAL JOINNATURAL INNER JOINNATURAL LEFT JOINNATURAL LEFT OUTER JOINNATURAL RIGHT JOINNATURAL RIGHT OUTER JOIN 中的任意一个,其中 opt_inner 匹配可选的 INNER 关键字,opt_outer 匹配可选的 OUTER 关键字,Bison 语法如下:

natural_join_type:
          NATURAL opt_inner JOIN_SYM       { $$= JTT_NATURAL_INNER; }
        | NATURAL RIGHT opt_outer JOIN_SYM { $$= JTT_NATURAL_RIGHT; }
        | NATURAL LEFT opt_outer JOIN_SYM  { $$= JTT_NATURAL_LEFT; }
        ;
opt_inner 规则

opt_inner 规则匹配可选的 INNER 关键字,Bison 规则如下:

opt_inner:
          %empty
        | INNER_SYM
        ;
opt_outer 规则

opt_outer 规则匹配可选的 OUTER 关键字,Bison 规则如下:

opt_outer:
          %empty
        | OUTER_SYM
        ;
using_list 规则

using_list 规则用于匹配标识符的列表,Bison 语法如下:

using_list:
          ident_string_list
        ;
ident_string_list 规则

ident_string_list 规则用于匹配逗号分隔的任意数量标识符的列表,Bison 语法如下:

ident_string_list:
          ident
          {
            $$= NEW_PTN List<String>;
            String *s= NEW_PTN String(const_cast<const char *>($1.str),
                                               $1.length,
                                               system_charset_info);
            if ($$ == nullptr || s == nullptr || $$->push_back(s))
              MYSQL_YYABORT;
          }
        | ident_string_list ',' ident
          {
            String *s= NEW_PTN String(const_cast<const char *>($3.str),
                                               $3.length,
                                               system_charset_info);
            if (s == nullptr || $1->push_back(s))
              MYSQL_YYABORT;
            $$= $1;
          }
        ;
table_factor 规则

table_factor 规则用于匹配各种类型的表语句,包含如下 6 种备选方案:

  • single_table 规则匹配结果:用于匹配使用名称获取的单个表
  • single_table_parens 规则匹配结果:用于匹配使用任意层括号框柱的 single_table 规则匹配结果
  • derived_table 规则匹配结果:用于匹配子查询生成的表
  • joined_table_parens 规则匹配结果:用于匹配使用任意层括号框柱的 joined_table 规则匹配结果
  • table_reference_list_parens 规则匹配结果:用于匹配使用任意层括号框柱的,使用逗号分隔的 table_reference 规则匹配结果
  • table_function 规则匹配结果:用于匹配 JSON_TABLE 函数

Bison 语法如下:

table_factor:
          single_table
        | single_table_parens
        | derived_table { $$ = $1; }
        | joined_table_parens
          { $$= NEW_PTN PT_table_factor_joined_table(@$, $1); }
        | table_reference_list_parens
          { $$= NEW_PTN PT_table_reference_list_parens(@$, $1); }
        | table_function { $$ = $1; }
        ;
single_table 规则

single_table 规则用于匹配使用名称获取的单个表,仅包含依次匹配 table_ident 规则匹配结果、opt_use_partition 规则匹配结果、opt_table_alias 规则匹配结果和 opt_key_definition 规则匹配结果这一种备选方案,其中:

  • table_ident 规则用于匹配 identident.ident,即包含与不包含 schema 的两种表名
  • opt_use_partition 规则用于匹配可选的 PARTITION 子句
  • opt_table_alias 规则用于匹配可选的 AS 子句用于指定别名
  • opt_key_definition 规则用于匹配可选的 USE 子句用于指定索引

Bison 语法如下:

single_table:
          table_ident opt_use_partition opt_table_alias opt_key_definition
          {
            $$= NEW_PTN PT_table_factor_table_ident(@$, $1, $2, $3, $4);
          }
        ;
table_ident 规则

table_ident 规则用于匹配 identident.ident,即包含与不包含 schema 的两种表名,Bison 语法如下:

table_ident:
          ident
          {
            $$= NEW_PTN Table_ident(to_lex_cstring($1));
            if ($$ == nullptr)
              MYSQL_YYABORT;
          }
        | ident '.' ident
          {
            auto schema_name = YYCLIENT_NO_SCHEMA ? LEX_CSTRING{}
                                                  : to_lex_cstring($1.str);
            $$= NEW_PTN Table_ident(schema_name, to_lex_cstring($3));
            if ($$ == nullptr)
              MYSQL_YYABORT;
          }
        ;
opt_use_partition 规则

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

opt_use_partition:
          %empty { $$= nullptr; }
        | use_partition
        ;
use_partition 规则

use_partition 规则用于匹配 PARTITION 子句,Bison 语法如下:

use_partition:
          PARTITION_SYM '(' using_list ')'
          {
            $$= $3;
          }
        ;
opt_table_alias 规则

opt_table_alias 规则用于匹配可选的 AS 子句用于指定别名,其中 opt_as 规则用于匹配可选的 AS 关键字,Bison 语法如下:

opt_table_alias:
          %empty { $$ = NULL_CSTR; }
        | opt_as ident { $$ = to_lex_cstring($2); }
        ;
opt_as 规则

opt_as 规则用于匹配可选的 AS 关键字,Bison 语法如下:

opt_as:
          %empty
        | AS
        ;
opt_key_definition 规则

opt_key_definition 规则用于匹配可选的 USE 子句用于指定索引,Bison 语法如下:

opt_key_definition:
          opt_index_hints_list
        ;
opt_index_hints_list 规则

opt_index_hints_list 规则用于匹配可选的 USE 子句用于指定索引,Bison 语法如下:

opt_index_hints_list:
          %empty { $$= nullptr; }
        | index_hints_list
        ;
index_hints_list 规则

index_hints_list 规则用于匹配空格分隔的任意数量的 USE 子句,Bison 语法如下:

index_hints_list:
          index_hint_definition
        | index_hints_list index_hint_definition
          {
            $2->concat($1);
            $$= $2;
          }
        ;
index_hint_definition 规则

index_hint_definition 规则用于匹配 USE 子句,有如下两种备选方案:

  • 依次匹配 index_hint_type 规则匹配结果、key_or_index 规则匹配结果和 index_hint_clause 规则匹配结果
    • index_hint_type 规则用于匹配 FORCE 关键字或 IGNORE 关键字
    • key_or_index 规则用于匹配 KEY 关键字或 INDEX 关键字
    • index_hint_clause 规则用于匹配可选的 FOR JOINFOR ORDER BYFOR GROUP BY
  • 依次匹配 USE 关键字、key_or_index 规则匹配结果和 index_hint_clause 规则匹配结果

Bison 语法如下:

index_hint_definition:
          index_hint_type key_or_index index_hint_clause
          '(' key_usage_list ')'
          {
            init_index_hints($5, $1, $3);
            $$= $5;
          }
        | USE_SYM key_or_index index_hint_clause
          '(' opt_key_usage_list ')'
          {
            init_index_hints($5, INDEX_HINT_USE, $3);
            $$= $5;
          }
       ;
index_hint_type 规则

index_hint_type 规则用于匹配 FORCE 关键字或 IGNORE 关键字,Bison 语法如下:

index_hint_type:
          FORCE_SYM  { $$= INDEX_HINT_FORCE; }
        | IGNORE_SYM { $$= INDEX_HINT_IGNORE; }
        ;
key_or_index 规则

key_or_index 规则用于匹配 KEY 关键字或 INDEX 关键字,Bison 语法如下:

key_or_index:
          KEY_SYM {}
        | INDEX_SYM {}
        ;
index_hint_clause 规则

index_hint_clause 规则用于匹配可选的 FOR JOINFOR ORDER BYFOR GROUP BY,Bison 语法如下:

index_hint_clause:
          %empty
          {
            $$= old_mode ?  INDEX_HINT_MASK_JOIN : INDEX_HINT_MASK_ALL;
          }
        | FOR_SYM JOIN_SYM      { $$= INDEX_HINT_MASK_JOIN;  }
        | FOR_SYM ORDER_SYM BY  { $$= INDEX_HINT_MASK_ORDER; }
        | FOR_SYM GROUP_SYM BY  { $$= INDEX_HINT_MASK_GROUP; }
        ;
single_table_parens 规则

single_table_parens 规则用于匹配使用任意层括号框柱的 single_table 规则匹配结果,Bison 语法如下:

single_table:
          table_ident opt_use_partition opt_table_alias opt_key_definition
          {
            $$= NEW_PTN PT_table_factor_table_ident(@$, $1, $2, $3, $4);
          }
        ;
joined_table_parens 规则

joined_table_parens 规则用于匹配使用任意层括号框柱的 joined_table 规则匹配结果,Bison 语法如下:

joined_table_parens:
          '(' joined_table_parens ')' { $$= $2; }
        | '(' joined_table ')' { $$= $2; }
        ;
table_reference_list_parens 规则

table_reference_list_parens 规则用于匹配使用任意层括号框柱的,使用逗号分隔的 table_reference 规则匹配结果,Bison 语法如下:

table_reference_list_parens:
          '(' table_reference_list_parens ')' { $$= $2; }
        | '(' table_reference_list ',' table_reference ')'
          {
            $$= $2;
            if ($$.push_back($4))
              MYSQL_YYABORT; // OOM
          }
        ;
derived_table 规则

derived_table 规则用于匹配子查询生成的表,有如下两种备选方案:

  • 依次匹配 table_subquery 规则匹配结果、opt_table_alias 规则匹配结果和 opt_derived_column_list 规则匹配结果
    • table_subquery 规则用于匹配多行子查询
    • opt_table_alias 规则用于匹配可选的 AS 子句指定别名
    • opt_derived_column_list 规则用于匹配可选的括号框柱、逗号分隔的列名的列表
  • 依次匹配 LATERAL 规则匹配结果、table_subquery 规则匹配结果、opt_table_alias 规则匹配结果和 opt_derived_column_list 规则匹配结果`

Bison 语法如下:

derived_table:
          table_subquery opt_table_alias opt_derived_column_list
          {
            /*
              The alias is actually not optional at all, but being MySQL we
              are friendly and give an informative error message instead of
              just 'syntax error'.
            */
            if ($2.str == nullptr)
              my_message(ER_DERIVED_MUST_HAVE_ALIAS,
                         ER_THD(YYTHD, ER_DERIVED_MUST_HAVE_ALIAS), MYF(0));

            $$= NEW_PTN PT_derived_table(@$, false, $1, $2, &$3);
          }
        | LATERAL_SYM table_subquery opt_table_alias opt_derived_column_list
          {
            if ($3.str == nullptr)
              my_message(ER_DERIVED_MUST_HAVE_ALIAS,
                         ER_THD(YYTHD, ER_DERIVED_MUST_HAVE_ALIAS), MYF(0));

            $$= NEW_PTN PT_derived_table(@$, true, $2, $3, &$4);
          }
        ;
opt_derived_column_list 规则

opt_derived_column_list 规则用于匹配可选的括号框柱、逗号分隔的列名的列表,其中 simple_ident_list 规则用于匹配逗号分隔的任意数量标识符的列表,Bison 语法如下:

opt_derived_column_list:
          %empty
          {
            /*
              Because () isn't accepted by the rule of
              simple_ident_list, we can use an empty array to
              designates that the parenthesised list was omitted.
            */
            $$.init(YYTHD->mem_root);
          }
        | '(' simple_ident_list ')'
          {
            $$= $2;
          }
        ;
simple_ident_list 规则

simple_ident_list 规则用于匹配逗号分隔的任意数量标识符的列表,Bison 语法如下:

simple_ident_list:
          ident
          {
            $$.init(YYTHD->mem_root);
            if ($$.push_back(to_lex_cstring($1)))
              MYSQL_YYABORT; /* purecov: inspected */
          }
        | simple_ident_list ',' ident
          {
            $$= $1;
            if ($$.push_back(to_lex_cstring($3)))
              MYSQL_YYABORT;  /* purecov: inspected */
          }
        ;
table_function 规则

table_function 规则用于匹配 JSON_TABLE 函数,详见 MySQL 参考手册 - 14.17.6 JSON Table Functions。标准语法如下:

JSON_TABLE(
    expr,
    path COLUMNS (column_list)
)   [AS] alias

column_list:
    column[, column][, ...]

column:
    name FOR ORDINALITY
    |  name type PATH string path [on_empty] [on_error]
    |  name type EXISTS PATH string path
    |  NESTED [PATH] path COLUMNS (column_list)

on_empty:
    {NULL | DEFAULT json_string | ERROR} ON EMPTY

on_error:
    {NULL | DEFAULT json_string | ERROR} ON ERROR

只有依次匹配 JONS_TABLE 关键字,(text_literal 规则匹配结果(字符串字面值)、columns_clause 规则匹配结果、)opt_table_alias 规则匹配结果(可选的 AS 子句指定别名)这一种备选方案,Bison 语法如下:

table_function:
          JSON_TABLE_SYM '(' expr ',' text_literal columns_clause ')'
          opt_table_alias
          {
            // Alias isn't optional, follow derived's behavior
            if ($8 == NULL_CSTR)
            {
              my_message(ER_TF_MUST_HAVE_ALIAS,
                         ER_THD(YYTHD, ER_TF_MUST_HAVE_ALIAS), MYF(0));
              MYSQL_YYABORT;
            }

            $$= NEW_PTN PT_table_factor_function(@$, $3, $5, $6, to_lex_string($8));
          }
        ;
columns_clause 规则

columns_clause 规则用于如下匹配标准语法:

COLUMNS (column_list)

column_list:
    column[, column][, ...]

column:
    name FOR ORDINALITY
    |  name type PATH string path [on_empty] [on_error]
    |  name type EXISTS PATH string path
    |  NESTED [PATH] path COLUMNS (column_list)

on_empty:
    {NULL | DEFAULT json_string | ERROR} ON EMPTY

on_error:
    {NULL | DEFAULT json_string | ERROR} ON ERROR

只有依次匹配 COLUMNS 关键字、(columns_list 规则匹配结果和 ) 这一种备选方案,Bison 语法如下:

columns_clause:
          COLUMNS '(' columns_list ')'
          {
            $$= $3;
          }
        ;
columns_list 规则

columns_list 规则用于匹配如下标准语法:

column[, column][, ...]

column:
    name FOR ORDINALITY
    |  name type PATH string path [on_empty] [on_error]
    |  name type EXISTS PATH string path
    |  NESTED [PATH] path COLUMNS (column_list)

on_empty:
    {NULL | DEFAULT json_string | ERROR} ON EMPTY

on_error:
    {NULL | DEFAULT json_string | ERROR} ON ERROR

在 Bison 语法中匹配任意数量的逗号分隔的 jt_column 规则匹配结果,Bison 语法如下:

columns_list:
          jt_column
          {
            $$= NEW_PTN Mem_root_array<PT_json_table_column *>(YYMEM_ROOT);
            if ($$ == nullptr || $$->push_back($1))
              MYSQL_YYABORT; // OOM
          }
        | columns_list ',' jt_column
          {
            $$= $1;
            if ($$->push_back($3))
              MYSQL_YYABORT; // OOM
          }
        ;
jt_column 规则

jt_column 规则用于匹配如下标准语法:

name FOR ORDINALITY
|  name type PATH string path [on_empty] [on_error]
|  name type EXISTS PATH string path
|  NESTED [PATH] path COLUMNS (column_list)

on_empty:
    {NULL | DEFAULT json_string | ERROR} ON EMPTY

on_error:
    {NULL | DEFAULT json_string | ERROR} ON ERROR

在 Bison 语法中包含 3 种备选方案:

  • ident FOR_SYM ORDINALITY_SYM:用于匹配第 1 种标准语法
  • ident type opt_collate jt_column_type PATH_SYM text_literal opt_on_empty_or_error_json_table:用于匹配第 2 种和第 3 种标准语法
    • type 规则用于匹配各种类型,稍后梳理
    • opt_collate 规则用于匹配可选的排序规则
    • jt_column_type 规则用于匹配可选的 EXISTS 关键字
    • text_literal 规则用于匹配字符串字面值
    • opt_on_empty_or_error_json_table 规则用于依次匹配可选的 ON EMPTY 子句和可选的 ON ERROR 子句
  • NESTED_SYM PATH_SYM text_literal columns_clause:用于匹配第 4 种标准语法

Bison 语法如下:

jt_column:
          ident FOR_SYM ORDINALITY_SYM
          {
            $$= NEW_PTN PT_json_table_column_for_ordinality(@$, $1);
          }
        | ident type opt_collate jt_column_type PATH_SYM text_literal
          opt_on_empty_or_error_json_table
          {
            auto column = make_unique_destroy_only<Json_table_column>(
                YYMEM_ROOT, $4, $6, $7.error.type, $7.error.default_string,
                $7.empty.type, $7.empty.default_string);
            if (column == nullptr) MYSQL_YYABORT;  // OOM
            $$ = NEW_PTN PT_json_table_column_with_path(@$, std::move(column), $1,
                                                        $2, $3);
          }
        | NESTED_SYM PATH_SYM text_literal columns_clause
          {
            $$= NEW_PTN PT_json_table_column_with_nested_path(@$, $3, $4);
          }
        ;
opt_collate 规则

opt_collate 规则用于匹配可选的排序规则,Bison 语法如下:

opt_collate:
          %empty { $$ = nullptr; }
        | COLLATE_SYM collation_name { $$ = $2; }
        ;
collation_name 规则

collation_name 规则用于匹配排序规则名称,Bison 语法如下:

collation_name:
          ident_or_text
          {
            if (!($$= mysqld_collation_get_by_name($1.str)))
              MYSQL_YYABORT;
            YYLIP->warn_on_deprecated_collation($$);
          }
        | BINARY_SYM { $$= &my_charset_bin; }
        ;
jt_column_type 规则

jt_column_type 规则用于匹配可选的 EXISTS 关键字,Bison 语法如下:

jt_column_type:
          %empty
          {
            $$= enum_jt_column::JTC_PATH;
          }
        | EXISTS
          {
            $$= enum_jt_column::JTC_EXISTS;
          }
        ;
opt_on_empty_or_error_json_table 规则

opt_on_empty_or_error_json_table 规则用于依次匹配可选的 ON EMPTY 子句和可选的 ON ERROR 子句(当 ON_ERRORON EMPTY 之前时会抛出警告),其中 opt_on_empty_or_error 规则用于依次匹配可选的 ON EMPTY 子句和可选的 ON ERROR 子句。Bison 语法如下:

// JSON_TABLE extends the syntax by allowing ON ERROR to come before ON EMPTY.
opt_on_empty_or_error_json_table:
          opt_on_empty_or_error { $$ = $1; }
        | on_error on_empty
          {
            push_warning(
              YYTHD, Sql_condition::SL_WARNING, ER_WARN_DEPRECATED_SYNTAX,
              ER_THD(YYTHD, ER_WARN_DEPRECATED_JSON_TABLE_ON_ERROR_ON_EMPTY));
            $$.error = $1;
            $$.empty = $2;
          }
        ;
  • 15
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

长行

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

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

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

打赏作者

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

抵扣说明:

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

余额充值