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()
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)
{
List_iterator_fast<my_var> var_li(var_list);
......@@ -3751,21 +3763,9 @@ int select_dumpvar::send_data(List<Item> &items)
}
while ((mv= var_li++) && (item= it++))
{
if (mv->local)
{
if (thd->spcont->set_variable(thd, mv->offset, &item))
if (mv->set(thd, 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());
}
......
......@@ -4773,21 +4773,35 @@ class multi_update :public select_result_interceptor
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 {
......
......@@ -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 <dyncol_def_list> dyncall_create_list
%type <myvar> select_outvar
%type <NONE>
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;
}
;
......
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