您的位置:首页 > 数据库 > MySQL

MySQL内核技术之“SQL语法修改”

2017-08-29 07:29 836 查看
在本例中,我们添加一个hint:

select /*+ PARALLEL(4) */ * from t1;


注意,这里的 /*+ PARALLEL(4) */ 就是hint。 这个是MySQL 5.7之后的新特性,语法规则和Oracle一致。

为了支持这个语法需要改动yacc相关的文件。具体包括:

sql/lex.h

sql/sql_hints.yacc

sql/opt_hints.h

sql/opt_hints.cc

sql/parse_tree_hints.h

sql/parse_tree_hints.cc

1. 在lex.h中,增加关键字:

{ SYM_H("PARALLEL",               PARALLEL_EXECUTION_HINT)},

2. 在opt_hint.h中添加对应的class:

/**
Parse tree hint object for table level hints.
*/

class PT_table_level_hint : public PT_hint
{
const LEX_CSTRING qb_name;
Hint_param_table_list table_list;

typedef PT_hint super;
public:
PT_table_level_hint(const LEX_CSTRING qb_name_arg,
const Hint_param_table_list &table_list_arg,
bool switch_state_arg,
opt_hints_enum hint_type_arg)
: PT_hint(hint_type_arg, switch_state_arg),
qb_name(qb_name_arg), table_list(table_list_arg)
{}

/**
Function handles table level hint. It also creates
table hint object (Opt_hints_table) if it does not
exist.

@param pc  Pointer to Parse_context object

@return  true in case of error,
false otherwise
*/
virtual bool contextualize(Parse_context *pc);
};

3. 在opt_hints.cc中,添加新的class的处理函数:

bool PT_hint_parallel_execution::contextualize(Parse_context *pc)
{
if (super::contextualize(pc))
return true;

if (pc->thd->lex->sql_command != SQLCOM_SELECT || // not a SELECT statement
pc->thd->lex->sphead ||                       // or in a SP/trigger/event
pc->select != pc->thd->lex->select_lex)       // or in a subquery
{
push_warning(pc->thd, Sql_condition::SL_WARNING,
ER_WARN_UNSUPPORTED_PARALLEL_EXECUTION,
ER_THD(pc->thd, ER_WARN_UNSUPPORTED_PARALLEL_EXECUTION));
return false;
}

Opt_hints_global *global_hint= get_global_hints(pc);
if (global_hint->is_specified(type()))
{
// Hint duplication: /*+ PARALLEL ... PARALLEL */
print_warn(pc->thd, ER_WARN_CONFLICTING_HINT,
NULL, NULL, NULL, this);
return false;
}

pc->thd->lex->degree_of_parallel= m_degree_of_parallel;
global_hint->set_switch(switch_on(), type(), false);
global_hint->parallel_execution= this;
return false;
}


该函数的目的是把PARALLEL关键字中的参数拿出来。

4. 修改sql_hints.yy文件,添加token和解析方法:

%token PARALLEL_EXECUTION_HINT

%type <hint>
hint
max_execution_time_hint
parallel_execution_hint

hint:
index_level_hint
| table_level_hint
| qb_level_hint
| qb_name_hint
| max_execution_time_hint
| parallel_execution_hint
;

parallel_execution_hint:
PARALLEL_EXECUTION_HINT '(' HINT_ARG_NUMBER ')'
{
int error;
char *end= const_cast<char *>($3.str + $3.length);
longlong n= my_strtoll10($3.str, &end, &error);
if (error != 0 || end != $3.str + $3.length || n > UINT_MAX32)
{
scanner->syntax_warning(ER_THD(thd,
ER_WARN_BAD_PARALLEL_EXECUTION));
$$= NULL;
}
else
{
$$= NEW_PTN PT_hint_parallel_execution(n);
if ($$ == NULL)
YYABORT; // OOM
}
}
;
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: