Commit 1e0a11a3 authored by Sergei Golubchik's avatar Sergei Golubchik

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
parent 624888b4
...@@ -3731,6 +3731,18 @@ Statement_map::~Statement_map() ...@@ -3731,6 +3731,18 @@ Statement_map::~Statement_map()
my_hash_free(&st_hash); 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<Item> &items) int select_dumpvar::send_data(List<Item> &items)
{ {
List_iterator_fast<my_var> var_li(var_list); List_iterator_fast<my_var> var_li(var_list);
...@@ -3751,20 +3763,8 @@ int select_dumpvar::send_data(List<Item> &items) ...@@ -3751,20 +3763,8 @@ int select_dumpvar::send_data(List<Item> &items)
} }
while ((mv= var_li++) && (item= it++)) while ((mv= var_li++) && (item= it++))
{ {
if (mv->local) if (mv->set(thd, item))
{ DBUG_RETURN(1);
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);
}
} }
DBUG_RETURN(thd->is_error()); DBUG_RETURN(thd->is_error());
} }
......
...@@ -4773,21 +4773,35 @@ class multi_update :public select_result_interceptor ...@@ -4773,21 +4773,35 @@ class multi_update :public select_result_interceptor
class my_var : public Sql_alloc { class my_var : public Sql_alloc {
public: public:
LEX_STRING s; const LEX_STRING name;
#ifndef DBUG_OFF 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 Routine to which this Item_splocal belongs. Used for checking if correct
runtime context is used for variable handling. runtime context is used for variable handling.
*/ */
sp_head *sp; sp_head *sp;
#endif my_var_sp(const LEX_STRING& j, uint o, enum_field_types t, sp_head *s)
bool local; : my_var(j, LOCAL_VAR), offset(o), type(t), sp(s) { }
uint offset; ~my_var_sp() { }
enum_field_types type; bool set(THD *thd, Item *val);
my_var (LEX_STRING& j, bool i, uint o, enum_field_types t) };
:s(j), local(i), offset(o), type(t)
{} class my_var_user: public my_var {
~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 { class select_dumpvar :public select_result_interceptor {
......
...@@ -933,6 +933,7 @@ static bool sp_create_assignment_instr(THD *thd, bool no_lookahead) ...@@ -933,6 +933,7 @@ static bool sp_create_assignment_instr(THD *thd, bool no_lookahead)
struct { int vars, conds, hndlrs, curs; } spblock; struct { int vars, conds, hndlrs, curs; } spblock;
sp_name *spname; sp_name *spname;
LEX *lex; LEX *lex;
class my_var *myvar;
sp_head *sphead; sp_head *sphead;
struct p_elem_val *p_elem_value; struct p_elem_val *p_elem_value;
enum index_hint_type index_hint; enum index_hint_type index_hint;
...@@ -1804,6 +1805,8 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); ...@@ -1804,6 +1805,8 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
%type <dyncol_def_list> dyncall_create_list %type <dyncol_def_list> dyncall_create_list
%type <myvar> select_outvar
%type <NONE> %type <NONE>
analyze_stmt_command analyze_stmt_command
query verb_clause create change select do drop insert replace insert2 query verb_clause create change select do drop insert replace insert2
...@@ -11557,16 +11560,13 @@ select_var_list: ...@@ -11557,16 +11560,13 @@ select_var_list:
| select_var_ident {} | select_var_ident {}
; ;
select_var_ident: select_var_ident: select_outvar
'@' ident_or_text
{ {
LEX *lex=Lex; if (Lex->result)
if (lex->result)
{ {
my_var *var= new my_var($2,0,0,(enum_field_types)0); if ($1 == NULL)
if (var == NULL)
MYSQL_YYABORT; MYSQL_YYABORT;
((select_dumpvar *)lex->result)->var_list.push_back(var); ((select_dumpvar *)Lex->result)->var_list.push_back($1);
} }
else else
{ {
...@@ -11574,37 +11574,27 @@ select_var_ident: ...@@ -11574,37 +11574,27 @@ select_var_ident:
The parser won't create select_result instance only The parser won't create select_result instance only
if it's an EXPLAIN. 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 | ident_or_text
{ {
LEX *lex=Lex;
sp_variable *t; 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); my_error(ER_SP_UNDECLARED_VAR, MYF(0), $1.str);
MYSQL_YYABORT; MYSQL_YYABORT;
} }
if (lex->result) $$ = Lex->result ? new my_var_sp($1, t->offset, t->type, Lex->sphead)
{ : NULL;
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);
}
} }
; ;
......
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