diff options
author | Alexander Barkov <bar@mariadb.org> | 2016-08-09 12:08:11 +0400 |
---|---|---|
committer | Alexander Barkov <bar@mariadb.org> | 2017-04-05 15:02:39 +0400 |
commit | 36b80caed12cd629c7b067eb9e3273832fe6a4d0 (patch) | |
tree | 53710060e4ed8fb8e585326326fb5e3f9bed9db2 | |
parent | 0281757e824bfac4d68b24400d2cc74ced1093ca (diff) | |
download | mariadb-git-36b80caed12cd629c7b067eb9e3273832fe6a4d0.tar.gz |
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()
-rw-r--r-- | sql/sp_pcontext.cc | 6 | ||||
-rw-r--r-- | sql/sp_pcontext.h | 22 | ||||
-rw-r--r-- | sql/sql_lex.cc | 123 | ||||
-rw-r--r-- | sql/sql_lex.h | 8 | ||||
-rw-r--r-- | sql/sql_yacc.yy | 151 | ||||
-rw-r--r-- | sql/sql_yacc_ora.yy | 151 |
6 files changed, 185 insertions, 276 deletions
diff --git a/sql/sp_pcontext.cc b/sql/sp_pcontext.cc index 9a6353c9337..a2258e8db34 100644 --- a/sql/sp_pcontext.cc +++ b/sql/sp_pcontext.cc @@ -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 { uint i= m_conditions.elements(); @@ -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) ++m_max_cursor_index; @@ -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, bool current_scope_only) const { diff --git a/sql/sp_pcontext.h b/sql/sp_pcontext.h index 2a080536b8a..1ef99219e8e 100644 --- a/sql/sp_pcontext.h +++ b/sql/sp_pcontext.h @@ -192,7 +192,7 @@ public: sp_condition_value *value; public: - sp_condition(LEX_STRING _name, sp_condition_value *_value) + sp_condition(const LEX_STRING _name, sp_condition_value *_value) :Sql_alloc(), name(_name), value(_value) @@ -422,11 +422,22 @@ public: // 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. - sp_condition_value *find_condition(LEX_STRING name, + sp_condition_value *find_condition(const LEX_STRING name, 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. @@ -467,10 +478,11 @@ public: // Cursors. ///////////////////////////////////////////////////////////////////////// - bool add_cursor(LEX_STRING name); + bool add_cursor(const LEX_STRING name); /// 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). const LEX_STRING *find_cursor(uint offset) const; diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index 4be04cbde8d..bed046659a2 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -5185,6 +5185,129 @@ bool LEX::init_default_internal_variable(struct sys_var_with_base *variable, 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 uint binlog_unsafe_map[256]; diff --git a/sql/sql_lex.h b/sql/sql_lex.h index a298bf33968..fd99489881d 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -3071,6 +3071,14 @@ public: LEX_STRING dbname, LEX_STRING name); bool init_default_internal_variable(struct sys_var_with_base *variable, 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); Item_splocal *create_item_for_sp_var(LEX_STRING name, sp_variable *spvar, const char *start_in_q, diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 4c08c0fbc43..3f56cf42409 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -1949,7 +1949,7 @@ END_OF_INPUT %type <num> sp_decl_idents sp_handler_type sp_hcond_list %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 <spname> sp_name %type <splabel> sp_block_content @@ -2997,161 +2997,44 @@ sp_decls: ; sp_decl: - DECLARE_SYM sp_decl_idents - { - 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); + DECLARE_SYM sp_decl_body { $$= $2; } + ; - lex->sphead->reset_lex(thd); - pctx->declare_var_boundary($2); - thd->lex->init_last_field(&spvar->field_def, spvar->name.str, - thd->variables.collation_database); +sp_decl_body: + sp_decl_idents + { + Lex->sp_variable_declarations_init(thd, $1); } type_with_opt_collate sp_opt_default { - LEX *lex= Lex; - 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)) + if (Lex->sp_variable_declarations_finalize(thd, $1, $3, $4)) MYSQL_YYABORT; - $$.vars= $2; + $$.vars= $1; $$.conds= $$.hndlrs= $$.curs= 0; } - | DECLARE_SYM ident CONDITION_SYM FOR_SYM sp_cond + | ident CONDITION_SYM FOR_SYM sp_cond { - LEX *lex= Lex; - 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)) + if (Lex->spcont->declare_condition(thd, $1, $4)) MYSQL_YYABORT; $$.vars= $$.hndlrs= $$.curs= 0; $$.conds= 1; } - | DECLARE_SYM sp_handler_type HANDLER_SYM FOR_SYM + | sp_handler_type HANDLER_SYM FOR_SYM { - LEX *lex= Lex; - 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))) + if (Lex->sp_handler_declaration_init(thd, $1)) MYSQL_YYABORT; } sp_hcond_list sp_proc_stmt { - LEX *lex= Lex; - sp_head *sp= lex->sphead; - 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(); - + if (Lex->sp_handler_declaration_finalize(thd, $1)) + MYSQL_YYABORT; $$.vars= $$.conds= $$.curs= 0; $$.hndlrs= 1; } - | DECLARE_SYM ident CURSOR_SYM FOR_SYM sp_cursor_stmt + | ident CURSOR_SYM FOR_SYM sp_cursor_stmt { - LEX *lex= Lex; - 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)) + if (Lex->sp_declare_cursor(thd, $1, $4)) MYSQL_YYABORT; $$.vars= $$.conds= $$.hndlrs= 0; $$.curs= 1; diff --git a/sql/sql_yacc_ora.yy b/sql/sql_yacc_ora.yy index 5fee7673b86..4f089005a2e 100644 --- a/sql/sql_yacc_ora.yy +++ b/sql/sql_yacc_ora.yy @@ -1329,7 +1329,7 @@ END_OF_INPUT %type <num> sp_decl_idents sp_handler_type sp_hcond_list %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 <spname> sp_name %type <splabel> sp_block_content @@ -2383,161 +2383,44 @@ sp_decls: ; sp_decl: - DECLARE_SYM sp_decl_idents - { - 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); + DECLARE_SYM sp_decl_body { $$= $2; } + ; - lex->sphead->reset_lex(thd); - pctx->declare_var_boundary($2); - thd->lex->init_last_field(&spvar->field_def, spvar->name.str, - thd->variables.collation_database); +sp_decl_body: + sp_decl_idents + { + Lex->sp_variable_declarations_init(thd, $1); } type_with_opt_collate sp_opt_default { - LEX *lex= Lex; - 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)) + if (Lex->sp_variable_declarations_finalize(thd, $1, $3, $4)) MYSQL_YYABORT; - $$.vars= $2; + $$.vars= $1; $$.conds= $$.hndlrs= $$.curs= 0; } - | DECLARE_SYM ident CONDITION_SYM FOR_SYM sp_cond + | ident CONDITION_SYM FOR_SYM sp_cond { - LEX *lex= Lex; - 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)) + if (Lex->spcont->declare_condition(thd, $1, $4)) MYSQL_YYABORT; $$.vars= $$.hndlrs= $$.curs= 0; $$.conds= 1; } - | DECLARE_SYM sp_handler_type HANDLER_SYM FOR_SYM + | sp_handler_type HANDLER_SYM FOR_SYM { - LEX *lex= Lex; - 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))) + if (Lex->sp_handler_declaration_init(thd, $1)) MYSQL_YYABORT; } sp_hcond_list sp_proc_stmt { - LEX *lex= Lex; - sp_head *sp= lex->sphead; - 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(); - + if (Lex->sp_handler_declaration_finalize(thd, $1)) + MYSQL_YYABORT; $$.vars= $$.conds= $$.curs= 0; $$.hndlrs= 1; } - | DECLARE_SYM ident CURSOR_SYM FOR_SYM sp_cursor_stmt + | ident CURSOR_SYM FOR_SYM sp_cursor_stmt { - LEX *lex= Lex; - 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)) + if (Lex->sp_declare_cursor(thd, $1, $4)) MYSQL_YYABORT; $$.vars= $$.conds= $$.hndlrs= 0; $$.curs= 1; |