在本例中,我们添加一个hint:
select /*+ PARALLEL(4) */ * from t1;
为了支持这个语法需要改动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);
};
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;
}
4. 修改sql_hints.yy文件,添加token和解析方法:
%token PARALLEL_EXECUTION_HINT
%type
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($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
}
}
;