Commit 36b80cae authored by Alexander Barkov's avatar Alexander Barkov

Moving the code from *.yy to new methods to LEX and sp_context

Adding:
  LEX::sp_variable_declarations_init()
  LEX::sp_variable_declarations_finalize()
  LEX::sp_handler_declaration_init()
  LEX::sp_handler_declaration_finalize()
  LEX::sp_declare_cursor()
  sp_context::declare_condition()
parent 0281757e
...@@ -249,7 +249,7 @@ bool sp_pcontext::add_condition(THD *thd, ...@@ -249,7 +249,7 @@ bool sp_pcontext::add_condition(THD *thd,
} }
sp_condition_value *sp_pcontext::find_condition(LEX_STRING name, sp_condition_value *sp_pcontext::find_condition(const LEX_STRING name,
bool current_scope_only) const bool current_scope_only) const
{ {
uint i= m_conditions.elements(); uint i= m_conditions.elements();
...@@ -415,7 +415,7 @@ sp_pcontext::find_handler(const char *sql_state, ...@@ -415,7 +415,7 @@ sp_pcontext::find_handler(const char *sql_state,
} }
bool sp_pcontext::add_cursor(LEX_STRING name) bool sp_pcontext::add_cursor(const LEX_STRING name)
{ {
if (m_cursors.elements() == m_max_cursor_index) if (m_cursors.elements() == m_max_cursor_index)
++m_max_cursor_index; ++m_max_cursor_index;
...@@ -424,7 +424,7 @@ bool sp_pcontext::add_cursor(LEX_STRING name) ...@@ -424,7 +424,7 @@ bool sp_pcontext::add_cursor(LEX_STRING name)
} }
bool sp_pcontext::find_cursor(LEX_STRING name, bool sp_pcontext::find_cursor(const LEX_STRING name,
uint *poff, uint *poff,
bool current_scope_only) const bool current_scope_only) const
{ {
......
...@@ -192,7 +192,7 @@ class sp_condition : public Sql_alloc ...@@ -192,7 +192,7 @@ class sp_condition : public Sql_alloc
sp_condition_value *value; sp_condition_value *value;
public: public:
sp_condition(LEX_STRING _name, sp_condition_value *_value) sp_condition(const LEX_STRING _name, sp_condition_value *_value)
:Sql_alloc(), :Sql_alloc(),
name(_name), name(_name),
value(_value) value(_value)
...@@ -422,11 +422,22 @@ class sp_pcontext : public Sql_alloc ...@@ -422,11 +422,22 @@ class sp_pcontext : public Sql_alloc
// Conditions. // Conditions.
///////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////
bool add_condition(THD *thd, LEX_STRING name, sp_condition_value *value); bool add_condition(THD *thd, const LEX_STRING name,
sp_condition_value *value);
/// See comment for find_variable() above. /// See comment for find_variable() above.
sp_condition_value *find_condition(LEX_STRING name, sp_condition_value *find_condition(const LEX_STRING name,
bool current_scope_only) const; bool current_scope_only) const;
bool declare_condition(THD *thd, const LEX_STRING name,
sp_condition_value *val)
{
if (find_condition(name, true))
{
my_error(ER_SP_DUP_COND, MYF(0), name.str);
return true;
}
return add_condition(thd, name, val);
}
///////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////
// Handlers. // Handlers.
...@@ -467,10 +478,11 @@ class sp_pcontext : public Sql_alloc ...@@ -467,10 +478,11 @@ class sp_pcontext : public Sql_alloc
// Cursors. // Cursors.
///////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////
bool add_cursor(LEX_STRING name); bool add_cursor(const LEX_STRING name);
/// See comment for find_variable() above. /// See comment for find_variable() above.
bool find_cursor(LEX_STRING name, uint *poff, bool current_scope_only) const; bool find_cursor(const LEX_STRING name,
uint *poff, bool current_scope_only) const;
/// Find cursor by offset (for debugging only). /// Find cursor by offset (for debugging only).
const LEX_STRING *find_cursor(uint offset) const; const LEX_STRING *find_cursor(uint offset) const;
......
...@@ -5185,6 +5185,129 @@ bool LEX::init_default_internal_variable(struct sys_var_with_base *variable, ...@@ -5185,6 +5185,129 @@ bool LEX::init_default_internal_variable(struct sys_var_with_base *variable,
return false; return false;
} }
void LEX::sp_variable_declarations_init(THD *thd, int nvars)
{
// get the last variable:
uint num_vars= spcont->context_var_count();
uint var_idx= spcont->var_context2runtime(num_vars - 1);
sp_variable *spvar= spcont->find_variable(var_idx);
sphead->reset_lex(thd);
spcont->declare_var_boundary(nvars);
thd->lex->init_last_field(&spvar->field_def, spvar->name.str,
thd->variables.collation_database);
}
bool LEX::sp_variable_declarations_finalize(THD *thd, int nvars,
const Lex_field_type_st &type,
Item *dflt_value_item)
{
uint num_vars= spcont->context_var_count();
if (!dflt_value_item &&
!(dflt_value_item= new (thd->mem_root) Item_null(thd)))
return true;
/* QQ Set to the var_type with null_value? */
for (uint i= num_vars - nvars ; i < num_vars ; i++)
{
uint var_idx= spcont->var_context2runtime(i);
sp_variable *spvar= spcont->find_variable(var_idx);
bool last= i == num_vars - 1;
if (!spvar)
return true;
if (!last)
spvar->field_def= *last_field;
spvar->default_value= dflt_value_item;
spvar->field_def.field_name= spvar->name.str;
if (sphead->fill_field_definition(thd, &spvar->field_def))
return true;
spvar->field_def.pack_flag |= FIELDFLAG_MAYBE_NULL;
/* The last instruction is responsible for freeing LEX. */
sp_instr_set *is= new (this->thd->mem_root)
sp_instr_set(sphead->instructions(),
spcont, var_idx, dflt_value_item,
type.field_type(), this, last);
if (is == NULL || sphead->add_instr(is))
return true;
}
spcont->declare_var_boundary(0);
return sphead->restore_lex(thd);
}
bool LEX::sp_declare_cursor(THD *thd, const LEX_STRING name, LEX *cursor_stmt)
{
uint offp;
sp_instr_cpush *i;
if (spcont->find_cursor(name, &offp, true))
{
my_error(ER_SP_DUP_CURS, MYF(0), name.str);
return true;
}
i= new (thd->mem_root)
sp_instr_cpush(sphead->instructions(), spcont, cursor_stmt,
spcont->current_cursor_count());
return i == NULL || sphead->add_instr(i) || spcont->add_cursor(name);
}
bool LEX::sp_handler_declaration_init(THD *thd, int type)
{
sp_handler *h= spcont->add_handler(thd, (sp_handler::enum_type) type);
spcont= spcont->push_context(thd, sp_pcontext::HANDLER_SCOPE);
sp_instr_hpush_jump *i=
new (thd->mem_root) sp_instr_hpush_jump(sphead->instructions(), spcont, h);
if (i == NULL || sphead->add_instr(i))
return true;
/* For continue handlers, mark end of handler scope. */
if (type == sp_handler::CONTINUE &&
sphead->push_backpatch(thd, i, spcont->last_label()))
return true;
if (sphead->push_backpatch(thd, i, spcont->push_label(thd, empty_lex_str, 0)))
return true;
return false;
}
bool LEX::sp_handler_declaration_finalize(THD *thd, int type)
{
sp_label *hlab= spcont->pop_label(); /* After this hdlr */
sp_instr_hreturn *i;
if (type == sp_handler::CONTINUE)
{
i= new (thd->mem_root) sp_instr_hreturn(sphead->instructions(), spcont);
if (i == NULL ||
sphead->add_instr(i))
return true;
}
else
{ /* EXIT or UNDO handler, just jump to the end of the block */
i= new (thd->mem_root) sp_instr_hreturn(sphead->instructions(), spcont);
if (i == NULL ||
sphead->add_instr(i) ||
sphead->push_backpatch(thd, i, spcont->last_label())) /* Block end */
return true;
}
sphead->backpatch(hlab);
spcont= spcont->pop_context();
return false;
}
#ifdef MYSQL_SERVER #ifdef MYSQL_SERVER
uint binlog_unsafe_map[256]; uint binlog_unsafe_map[256];
......
...@@ -3071,6 +3071,14 @@ struct LEX: public Query_tables_list ...@@ -3071,6 +3071,14 @@ struct LEX: public Query_tables_list
LEX_STRING dbname, LEX_STRING name); LEX_STRING dbname, LEX_STRING name);
bool init_default_internal_variable(struct sys_var_with_base *variable, bool init_default_internal_variable(struct sys_var_with_base *variable,
LEX_STRING name); LEX_STRING name);
void sp_variable_declarations_init(THD *thd, int nvars);
bool sp_variable_declarations_finalize(THD *thd, int nvars,
const Lex_field_type_st &type,
Item *def);
bool sp_handler_declaration_init(THD *thd, int type);
bool sp_handler_declaration_finalize(THD *thd, int type);
bool sp_declare_cursor(THD *thd, const LEX_STRING name, LEX *cursor_stmt);
bool set_local_variable(sp_variable *spv, Item *val); bool set_local_variable(sp_variable *spv, Item *val);
Item_splocal *create_item_for_sp_var(LEX_STRING name, sp_variable *spvar, Item_splocal *create_item_for_sp_var(LEX_STRING name, sp_variable *spvar,
const char *start_in_q, const char *start_in_q,
......
...@@ -1949,7 +1949,7 @@ END_OF_INPUT ...@@ -1949,7 +1949,7 @@ END_OF_INPUT
%type <num> sp_decl_idents sp_handler_type sp_hcond_list %type <num> sp_decl_idents sp_handler_type sp_hcond_list
%type <spcondvalue> sp_cond sp_hcond sqlstate signal_value opt_signal_value %type <spcondvalue> sp_cond sp_hcond sqlstate signal_value opt_signal_value
%type <spblock> sp_decls sp_decl %type <spblock> sp_decls sp_decl sp_decl_body
%type <lex> sp_cursor_stmt %type <lex> sp_cursor_stmt
%type <spname> sp_name %type <spname> sp_name
%type <splabel> sp_block_content %type <splabel> sp_block_content
...@@ -2997,161 +2997,44 @@ sp_decls: ...@@ -2997,161 +2997,44 @@ sp_decls:
; ;
sp_decl: sp_decl:
DECLARE_SYM sp_decl_idents DECLARE_SYM sp_decl_body { $$= $2; }
{ ;
LEX *lex= Lex;
sp_pcontext *pctx= lex->spcont;
// get the last variable:
uint num_vars= pctx->context_var_count();
uint var_idx= pctx->var_context2runtime(num_vars - 1);
sp_variable *spvar= pctx->find_variable(var_idx);
lex->sphead->reset_lex(thd); sp_decl_body:
pctx->declare_var_boundary($2); sp_decl_idents
thd->lex->init_last_field(&spvar->field_def, spvar->name.str, {
thd->variables.collation_database); Lex->sp_variable_declarations_init(thd, $1);
} }
type_with_opt_collate type_with_opt_collate
sp_opt_default sp_opt_default
{ {
LEX *lex= Lex; if (Lex->sp_variable_declarations_finalize(thd, $1, $3, $4))
sp_pcontext *pctx= lex->spcont;
uint num_vars= pctx->context_var_count();
Item *dflt_value_item= $5;
if (!dflt_value_item)
{
dflt_value_item= new (thd->mem_root) Item_null(thd);
if (dflt_value_item == NULL)
MYSQL_YYABORT;
/* QQ Set to the var_type with null_value? */
}
for (uint i = num_vars-$2 ; i < num_vars ; i++)
{
uint var_idx= pctx->var_context2runtime(i);
sp_variable *spvar= pctx->find_variable(var_idx);
bool last= i == num_vars - 1;
if (!spvar)
MYSQL_YYABORT;
if (!last)
spvar->field_def= *lex->last_field;
spvar->default_value= dflt_value_item;
spvar->field_def.field_name= spvar->name.str;
if (lex->sphead->fill_field_definition(thd, &spvar->field_def))
{
MYSQL_YYABORT;
}
spvar->field_def.pack_flag |= FIELDFLAG_MAYBE_NULL;
/* The last instruction is responsible for freeing LEX. */
sp_instr_set *is= new (lex->thd->mem_root)
sp_instr_set(lex->sphead->instructions(),
pctx, var_idx, dflt_value_item,
$4.field_type(), lex, last);
if (is == NULL || lex->sphead->add_instr(is))
MYSQL_YYABORT;
}
pctx->declare_var_boundary(0);
if (lex->sphead->restore_lex(thd))
MYSQL_YYABORT; MYSQL_YYABORT;
$$.vars= $2; $$.vars= $1;
$$.conds= $$.hndlrs= $$.curs= 0; $$.conds= $$.hndlrs= $$.curs= 0;
} }
| DECLARE_SYM ident CONDITION_SYM FOR_SYM sp_cond | ident CONDITION_SYM FOR_SYM sp_cond
{ {
LEX *lex= Lex; if (Lex->spcont->declare_condition(thd, $1, $4))
sp_pcontext *spc= lex->spcont;
if (spc->find_condition($2, TRUE))
my_yyabort_error((ER_SP_DUP_COND, MYF(0), $2.str));
if(spc->add_condition(thd, $2, $5))
MYSQL_YYABORT; MYSQL_YYABORT;
$$.vars= $$.hndlrs= $$.curs= 0; $$.vars= $$.hndlrs= $$.curs= 0;
$$.conds= 1; $$.conds= 1;
} }
| DECLARE_SYM sp_handler_type HANDLER_SYM FOR_SYM | sp_handler_type HANDLER_SYM FOR_SYM
{ {
LEX *lex= Lex; if (Lex->sp_handler_declaration_init(thd, $1))
sp_head *sp= lex->sphead;
sp_handler *h= lex->spcont->add_handler(thd,
(sp_handler::enum_type) $2);
lex->spcont= lex->spcont->push_context(thd,
sp_pcontext::HANDLER_SCOPE);
sp_pcontext *ctx= lex->spcont;
sp_instr_hpush_jump *i=
new (thd->mem_root) sp_instr_hpush_jump(sp->instructions(),
ctx, h);
if (i == NULL || sp->add_instr(i))
MYSQL_YYABORT;
/* For continue handlers, mark end of handler scope. */
if ($2 == sp_handler::CONTINUE &&
sp->push_backpatch(thd, i, ctx->last_label()))
MYSQL_YYABORT;
if (sp->push_backpatch(thd, i, ctx->push_label(thd, empty_lex_str, 0)))
MYSQL_YYABORT; MYSQL_YYABORT;
} }
sp_hcond_list sp_proc_stmt sp_hcond_list sp_proc_stmt
{ {
LEX *lex= Lex; if (Lex->sp_handler_declaration_finalize(thd, $1))
sp_head *sp= lex->sphead; MYSQL_YYABORT;
sp_pcontext *ctx= lex->spcont;
sp_label *hlab= lex->spcont->pop_label(); /* After this hdlr */
sp_instr_hreturn *i;
if ($2 == sp_handler::CONTINUE)
{
i= new (thd->mem_root)
sp_instr_hreturn(sp->instructions(), ctx);
if (i == NULL ||
sp->add_instr(i))
MYSQL_YYABORT;
}
else
{ /* EXIT or UNDO handler, just jump to the end of the block */
i= new (thd->mem_root)
sp_instr_hreturn(sp->instructions(), ctx);
if (i == NULL ||
sp->add_instr(i) ||
sp->push_backpatch(thd, i, lex->spcont->last_label())) /* Block end */
MYSQL_YYABORT;
}
lex->sphead->backpatch(hlab);
lex->spcont= ctx->pop_context();
$$.vars= $$.conds= $$.curs= 0; $$.vars= $$.conds= $$.curs= 0;
$$.hndlrs= 1; $$.hndlrs= 1;
} }
| DECLARE_SYM ident CURSOR_SYM FOR_SYM sp_cursor_stmt | ident CURSOR_SYM FOR_SYM sp_cursor_stmt
{ {
LEX *lex= Lex; if (Lex->sp_declare_cursor(thd, $1, $4))
sp_head *sp= lex->sphead;
sp_pcontext *ctx= lex->spcont;
uint offp;
sp_instr_cpush *i;
if (ctx->find_cursor($2, &offp, TRUE))
my_yyabort_error((ER_SP_DUP_CURS, MYF(0), $2.str));
i= new (thd->mem_root)
sp_instr_cpush(sp->instructions(), ctx, $5,
ctx->current_cursor_count());
if (i == NULL || sp->add_instr(i) || ctx->add_cursor($2))
MYSQL_YYABORT; MYSQL_YYABORT;
$$.vars= $$.conds= $$.hndlrs= 0; $$.vars= $$.conds= $$.hndlrs= 0;
$$.curs= 1; $$.curs= 1;
......
...@@ -1329,7 +1329,7 @@ END_OF_INPUT ...@@ -1329,7 +1329,7 @@ END_OF_INPUT
%type <num> sp_decl_idents sp_handler_type sp_hcond_list %type <num> sp_decl_idents sp_handler_type sp_hcond_list
%type <spcondvalue> sp_cond sp_hcond sqlstate signal_value opt_signal_value %type <spcondvalue> sp_cond sp_hcond sqlstate signal_value opt_signal_value
%type <spblock> sp_decls sp_decl %type <spblock> sp_decls sp_decl sp_decl_body
%type <lex> sp_cursor_stmt %type <lex> sp_cursor_stmt
%type <spname> sp_name %type <spname> sp_name
%type <splabel> sp_block_content %type <splabel> sp_block_content
...@@ -2383,161 +2383,44 @@ sp_decls: ...@@ -2383,161 +2383,44 @@ sp_decls:
; ;
sp_decl: sp_decl:
DECLARE_SYM sp_decl_idents DECLARE_SYM sp_decl_body { $$= $2; }
{ ;
LEX *lex= Lex;
sp_pcontext *pctx= lex->spcont;
// get the last variable:
uint num_vars= pctx->context_var_count();
uint var_idx= pctx->var_context2runtime(num_vars - 1);
sp_variable *spvar= pctx->find_variable(var_idx);
lex->sphead->reset_lex(thd); sp_decl_body:
pctx->declare_var_boundary($2); sp_decl_idents
thd->lex->init_last_field(&spvar->field_def, spvar->name.str, {
thd->variables.collation_database); Lex->sp_variable_declarations_init(thd, $1);
} }
type_with_opt_collate type_with_opt_collate
sp_opt_default sp_opt_default
{ {
LEX *lex= Lex; if (Lex->sp_variable_declarations_finalize(thd, $1, $3, $4))
sp_pcontext *pctx= lex->spcont;
uint num_vars= pctx->context_var_count();
Item *dflt_value_item= $5;
if (!dflt_value_item)
{
dflt_value_item= new (thd->mem_root) Item_null(thd);
if (dflt_value_item == NULL)
MYSQL_YYABORT;
/* QQ Set to the var_type with null_value? */
}
for (uint i = num_vars-$2 ; i < num_vars ; i++)
{
uint var_idx= pctx->var_context2runtime(i);
sp_variable *spvar= pctx->find_variable(var_idx);
bool last= i == num_vars - 1;
if (!spvar)
MYSQL_YYABORT;
if (!last)
spvar->field_def= *lex->last_field;
spvar->default_value= dflt_value_item;
spvar->field_def.field_name= spvar->name.str;
if (lex->sphead->fill_field_definition(thd, &spvar->field_def))
{
MYSQL_YYABORT;
}
spvar->field_def.pack_flag |= FIELDFLAG_MAYBE_NULL;
/* The last instruction is responsible for freeing LEX. */
sp_instr_set *is= new (lex->thd->mem_root)
sp_instr_set(lex->sphead->instructions(),
pctx, var_idx, dflt_value_item,
$4.field_type(), lex, last);
if (is == NULL || lex->sphead->add_instr(is))
MYSQL_YYABORT;
}
pctx->declare_var_boundary(0);
if (lex->sphead->restore_lex(thd))
MYSQL_YYABORT; MYSQL_YYABORT;
$$.vars= $2; $$.vars= $1;
$$.conds= $$.hndlrs= $$.curs= 0; $$.conds= $$.hndlrs= $$.curs= 0;
} }
| DECLARE_SYM ident CONDITION_SYM FOR_SYM sp_cond | ident CONDITION_SYM FOR_SYM sp_cond
{ {
LEX *lex= Lex; if (Lex->spcont->declare_condition(thd, $1, $4))
sp_pcontext *spc= lex->spcont;
if (spc->find_condition($2, TRUE))
my_yyabort_error((ER_SP_DUP_COND, MYF(0), $2.str));
if(spc->add_condition(thd, $2, $5))
MYSQL_YYABORT; MYSQL_YYABORT;
$$.vars= $$.hndlrs= $$.curs= 0; $$.vars= $$.hndlrs= $$.curs= 0;
$$.conds= 1; $$.conds= 1;
} }
| DECLARE_SYM sp_handler_type HANDLER_SYM FOR_SYM | sp_handler_type HANDLER_SYM FOR_SYM
{ {
LEX *lex= Lex; if (Lex->sp_handler_declaration_init(thd, $1))
sp_head *sp= lex->sphead;
sp_handler *h= lex->spcont->add_handler(thd,
(sp_handler::enum_type) $2);
lex->spcont= lex->spcont->push_context(thd,
sp_pcontext::HANDLER_SCOPE);
sp_pcontext *ctx= lex->spcont;
sp_instr_hpush_jump *i=
new (thd->mem_root) sp_instr_hpush_jump(sp->instructions(),
ctx, h);
if (i == NULL || sp->add_instr(i))
MYSQL_YYABORT;
/* For continue handlers, mark end of handler scope. */
if ($2 == sp_handler::CONTINUE &&
sp->push_backpatch(thd, i, ctx->last_label()))
MYSQL_YYABORT;
if (sp->push_backpatch(thd, i, ctx->push_label(thd, empty_lex_str, 0)))
MYSQL_YYABORT; MYSQL_YYABORT;
} }
sp_hcond_list sp_proc_stmt sp_hcond_list sp_proc_stmt
{ {
LEX *lex= Lex; if (Lex->sp_handler_declaration_finalize(thd, $1))
sp_head *sp= lex->sphead; MYSQL_YYABORT;
sp_pcontext *ctx= lex->spcont;
sp_label *hlab= lex->spcont->pop_label(); /* After this hdlr */
sp_instr_hreturn *i;
if ($2 == sp_handler::CONTINUE)
{
i= new (thd->mem_root)
sp_instr_hreturn(sp->instructions(), ctx);
if (i == NULL ||
sp->add_instr(i))
MYSQL_YYABORT;
}
else
{ /* EXIT or UNDO handler, just jump to the end of the block */
i= new (thd->mem_root)
sp_instr_hreturn(sp->instructions(), ctx);
if (i == NULL ||
sp->add_instr(i) ||
sp->push_backpatch(thd, i, lex->spcont->last_label())) /* Block end */
MYSQL_YYABORT;
}
lex->sphead->backpatch(hlab);
lex->spcont= ctx->pop_context();
$$.vars= $$.conds= $$.curs= 0; $$.vars= $$.conds= $$.curs= 0;
$$.hndlrs= 1; $$.hndlrs= 1;
} }
| DECLARE_SYM ident CURSOR_SYM FOR_SYM sp_cursor_stmt | ident CURSOR_SYM FOR_SYM sp_cursor_stmt
{ {
LEX *lex= Lex; if (Lex->sp_declare_cursor(thd, $1, $4))
sp_head *sp= lex->sphead;
sp_pcontext *ctx= lex->spcont;
uint offp;
sp_instr_cpush *i;
if (ctx->find_cursor($2, &offp, TRUE))
my_yyabort_error((ER_SP_DUP_CURS, MYF(0), $2.str));
i= new (thd->mem_root)
sp_instr_cpush(sp->instructions(), ctx, $5,
ctx->current_cursor_count());
if (i == NULL || sp->add_instr(i) || ctx->add_cursor($2))
MYSQL_YYABORT; MYSQL_YYABORT;
$$.vars= $$.conds= $$.hndlrs= 0; $$.vars= $$.conds= $$.hndlrs= 0;
$$.curs= 1; $$.curs= 1;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment