From 1e0a11a3c74c9e434ce43edbe3ece3852f539c36 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Sat, 16 Aug 2014 08:46:27 +0200 Subject: [PATCH] cleanup: class my_var * split my_var class in three - base my_var and two descencants, move properties into descendants, remove if(), create a virtual method instead * factor out the common code in the select_var_ident parser rule --- sql/sql_class.cc | 28 ++++++++++++++-------------- sql/sql_class.h | 34 ++++++++++++++++++++++++---------- sql/sql_yacc.yy | 46 ++++++++++++++++++---------------------------- 3 files changed, 56 insertions(+), 52 deletions(-) diff --git a/sql/sql_class.cc b/sql/sql_class.cc index ad50f0b45a5..12c30a8ea38 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -3731,6 +3731,18 @@ Statement_map::~Statement_map() my_hash_free(&st_hash); } +bool my_var_user::set(THD *thd, Item *item) +{ + Item_func_set_user_var *suv= new Item_func_set_user_var(name, item); + suv->save_item_result(item); + return suv->fix_fields(thd, 0) || suv->update(); +} + +bool my_var_sp::set(THD *thd, Item *item) +{ + return thd->spcont->set_variable(thd, offset, &item); +} + int select_dumpvar::send_data(List &items) { List_iterator_fast var_li(var_list); @@ -3751,20 +3763,8 @@ int select_dumpvar::send_data(List &items) } while ((mv= var_li++) && (item= it++)) { - if (mv->local) - { - if (thd->spcont->set_variable(thd, mv->offset, &item)) - DBUG_RETURN(1); - } - else - { - Item_func_set_user_var *suv= new Item_func_set_user_var(mv->s, item); - suv->save_item_result(item); - if (suv->fix_fields(thd, 0)) - DBUG_RETURN (1); - if (suv->update()) - DBUG_RETURN (1); - } + if (mv->set(thd, item)) + DBUG_RETURN(1); } DBUG_RETURN(thd->is_error()); } diff --git a/sql/sql_class.h b/sql/sql_class.h index 9360af8464e..acf4d79b5c5 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -4773,21 +4773,35 @@ public: class my_var : public Sql_alloc { public: - LEX_STRING s; -#ifndef DBUG_OFF + const LEX_STRING name; + enum type { SESSION_VAR, LOCAL_VAR, PARAM_VAR }; + type scope; + my_var(const LEX_STRING& j, enum type s) : name(j), scope(s) { } + virtual ~my_var() {} + virtual bool set(THD *thd, Item *val) = 0; +}; + +class my_var_sp: public my_var { +public: + uint offset; + enum_field_types type; /* Routine to which this Item_splocal belongs. Used for checking if correct runtime context is used for variable handling. */ sp_head *sp; -#endif - bool local; - uint offset; - enum_field_types type; - my_var (LEX_STRING& j, bool i, uint o, enum_field_types t) - :s(j), local(i), offset(o), type(t) - {} - ~my_var() {} + my_var_sp(const LEX_STRING& j, uint o, enum_field_types t, sp_head *s) + : my_var(j, LOCAL_VAR), offset(o), type(t), sp(s) { } + ~my_var_sp() { } + bool set(THD *thd, Item *val); +}; + +class my_var_user: public my_var { +public: + my_var_user(const LEX_STRING& j) + : my_var(j, SESSION_VAR) { } + ~my_var_user() { } + bool set(THD *thd, Item *val); }; class select_dumpvar :public select_result_interceptor { diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index deb16b17405..dc6381b4c3a 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -933,6 +933,7 @@ static bool sp_create_assignment_instr(THD *thd, bool no_lookahead) struct { int vars, conds, hndlrs, curs; } spblock; sp_name *spname; LEX *lex; + class my_var *myvar; sp_head *sphead; struct p_elem_val *p_elem_value; enum index_hint_type index_hint; @@ -1804,6 +1805,8 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); %type dyncall_create_list +%type select_outvar + %type analyze_stmt_command query verb_clause create change select do drop insert replace insert2 @@ -11557,16 +11560,13 @@ select_var_list: | select_var_ident {} ; -select_var_ident: - '@' ident_or_text +select_var_ident: select_outvar { - LEX *lex=Lex; - if (lex->result) + if (Lex->result) { - my_var *var= new my_var($2,0,0,(enum_field_types)0); - if (var == NULL) + if ($1 == NULL) MYSQL_YYABORT; - ((select_dumpvar *)lex->result)->var_list.push_back(var); + ((select_dumpvar *)Lex->result)->var_list.push_back($1); } else { @@ -11574,37 +11574,27 @@ select_var_ident: The parser won't create select_result instance only if it's an EXPLAIN. */ - DBUG_ASSERT(lex->describe); + DBUG_ASSERT(Lex->describe); } } + ; + +select_outvar: + '@' ident_or_text + { + $$ = Lex->result ? new my_var_user($2) : NULL; + } | ident_or_text { - LEX *lex=Lex; sp_variable *t; - if (!lex->spcont || !(t=lex->spcont->find_variable($1, false))) + if (!Lex->spcont || !(t= Lex->spcont->find_variable($1, false))) { my_error(ER_SP_UNDECLARED_VAR, MYF(0), $1.str); MYSQL_YYABORT; } - if (lex->result) - { - my_var *var= new my_var($1,1,t->offset,t->type); - if (var == NULL) - MYSQL_YYABORT; - ((select_dumpvar *)lex->result)->var_list.push_back(var); -#ifndef DBUG_OFF - var->sp= lex->sphead; -#endif - } - else - { - /* - The parser won't create select_result instance only - if it's an EXPLAIN. - */ - DBUG_ASSERT(lex->describe); - } + $$ = Lex->result ? new my_var_sp($1, t->offset, t->type, Lex->sphead) + : NULL; } ;