Fix for bug #9286: SESSION/GLOBAL should be disallowed for user variables(for 5.0)

parent 390e0bbc
...@@ -180,6 +180,7 @@ select coercibility(@v1),coercibility(@v2),coercibility(@v3),coercibility(@v4); ...@@ -180,6 +180,7 @@ select coercibility(@v1),coercibility(@v2),coercibility(@v3),coercibility(@v4);
coercibility(@v1) coercibility(@v2) coercibility(@v3) coercibility(@v4) coercibility(@v1) coercibility(@v2) coercibility(@v3) coercibility(@v4)
2 2 2 2 2 2 2 2
set session @honk=99; set session @honk=99;
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '@honk=99' at line 1
set one_shot @honk=99; set one_shot @honk=99;
ERROR HY000: The 'SET ONE_SHOT' syntax is reserved for purposes internal to the MySQL server ERROR HY000: The 'SET ONE_SHOT' syntax is reserved for purposes internal to the MySQL server
set @first_var= NULL; set @first_var= NULL;
......
...@@ -116,6 +116,7 @@ select coercibility(@v1),coercibility(@v2),coercibility(@v3),coercibility(@v4); ...@@ -116,6 +116,7 @@ select coercibility(@v1),coercibility(@v2),coercibility(@v3),coercibility(@v4);
# #
# Bug #9286 SESSION/GLOBAL should be disallowed for user variables # Bug #9286 SESSION/GLOBAL should be disallowed for user variables
# #
--error 1064
set session @honk=99; set session @honk=99;
--error 1382 --error 1382
set one_shot @honk=99; set one_shot @honk=99;
......
...@@ -32,7 +32,7 @@ extern TYPELIB bool_typelib, delay_key_write_typelib, sql_mode_typelib; ...@@ -32,7 +32,7 @@ extern TYPELIB bool_typelib, delay_key_write_typelib, sql_mode_typelib;
enum enum_var_type enum enum_var_type
{ {
OPT_DEFAULT, OPT_SESSION, OPT_GLOBAL OPT_DEFAULT= 0, OPT_SESSION, OPT_GLOBAL
}; };
typedef int (*sys_check_func)(THD *, set_var *); typedef int (*sys_check_func)(THD *, set_var *);
......
...@@ -698,7 +698,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); ...@@ -698,7 +698,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
opt_var_ident_type delete_option opt_temporary all_or_any opt_distinct opt_var_ident_type delete_option opt_temporary all_or_any opt_distinct
opt_ignore_leaves fulltext_options spatial_type union_option opt_ignore_leaves fulltext_options spatial_type union_option
start_transaction_opts opt_chain opt_release start_transaction_opts opt_chain opt_release
union_opt select_derived_init union_opt select_derived_init option_type option_type2
%type <ulong_num> %type <ulong_num>
ulong_num raid_types merge_insert_types ulong_num raid_types merge_insert_types
...@@ -7475,7 +7475,7 @@ option_type_value: ...@@ -7475,7 +7475,7 @@ option_type_value:
lex->sphead->m_tmp_query= lex->tok_start; lex->sphead->m_tmp_query= lex->tok_start;
} }
} }
option_type option_value ext_option_value
{ {
LEX *lex= Lex; LEX *lex= Lex;
...@@ -7516,11 +7516,15 @@ option_type_value: ...@@ -7516,11 +7516,15 @@ option_type_value:
}; };
option_type: option_type:
/* empty */ {} option_type2 {}
| GLOBAL_SYM { Lex->option_type= OPT_GLOBAL; } | GLOBAL_SYM { $$=OPT_GLOBAL; }
| LOCAL_SYM { Lex->option_type= OPT_SESSION; } | LOCAL_SYM { $$=OPT_SESSION; }
| SESSION_SYM { Lex->option_type= OPT_SESSION; } | SESSION_SYM { $$=OPT_SESSION; }
| ONE_SHOT_SYM { Lex->option_type= OPT_SESSION; Lex->one_shot_set= 1; } ;
option_type2:
/* empty */ { $$= OPT_DEFAULT; }
| ONE_SHOT_SYM { Lex->one_shot_set= 1; $$= OPT_SESSION; }
; ;
opt_var_type: opt_var_type:
...@@ -7537,89 +7541,110 @@ opt_var_ident_type: ...@@ -7537,89 +7541,110 @@ opt_var_ident_type:
| SESSION_SYM '.' { $$=OPT_SESSION; } | SESSION_SYM '.' { $$=OPT_SESSION; }
; ;
option_value: ext_option_value:
'@' ident_or_text equal expr sys_option_value
{ | option_type2 option_value;
Lex->var_list.push_back(new set_var_user(new Item_func_set_user_var($2,$4)));
}
| internal_variable_name equal set_expr_or_default
{
LEX *lex=Lex;
if ($1.var == &trg_new_row_fake_var) sys_option_value:
{ option_type internal_variable_name equal set_expr_or_default
/* We are in trigger and assigning value to field of new row */ {
Item *it; LEX *lex=Lex;
sp_instr_set_trigger_field *i;
if (lex->query_tables)
{
my_message(ER_SP_SUBSELECT_NYI, ER(ER_SP_SUBSELECT_NYI),
MYF(0));
YYABORT;
}
if ($3)
it= $3;
else
{
/* QQ: Shouldn't this be field's default value ? */
it= new Item_null();
}
if (!(i= new sp_instr_set_trigger_field(
lex->sphead->instructions(), lex->spcont,
$1.base_name, it)))
YYABORT;
/*
Let us add this item to list of all Item_trigger_field
objects in trigger.
*/
lex->trg_table_fields.link_in_list((byte *)&i->trigger_field,
(byte **)&i->trigger_field.next_trg_field);
lex->sphead->add_instr(i); if ($2.var == &trg_new_row_fake_var)
{
/* We are in trigger and assigning value to field of new row */
Item *it;
sp_instr_set_trigger_field *i;
if ($1)
{
yyerror(ER(ER_SYNTAX_ERROR));
YYABORT;
} }
else if ($1.var) if (lex->query_tables)
{ /* System variable */ {
lex->var_list.push_back(new set_var(lex->option_type, $1.var, my_message(ER_SP_SUBSELECT_NYI, ER(ER_SP_SUBSELECT_NYI),
&$1.base_name, $3)); MYF(0));
} YYABORT;
}
if ($4)
it= $4;
else else
{ {
/* An SP local variable */ /* QQ: Shouldn't this be field's default value ? */
sp_pcontext *ctx= lex->spcont; it= new Item_null();
sp_pvar_t *spv; }
sp_instr_set *i;
Item *it;
spv= ctx->find_pvar(&$1.base_name); if (!(i= new sp_instr_set_trigger_field(
lex->sphead->instructions(), lex->spcont,
$2.base_name, it)))
YYABORT;
if ($3) /*
it= $3; Let us add this item to list of all Item_trigger_field
else if (spv->dflt) objects in trigger.
it= spv->dflt; */
else lex->trg_table_fields.link_in_list((byte *)&i->trigger_field,
it= new Item_null(); (byte **)&i->trigger_field.next_trg_field);
i= new sp_instr_set(lex->sphead->instructions(), ctx,
spv->offset, it, spv->type, lex, TRUE); lex->sphead->add_instr(i);
lex->sphead->add_instr(i); }
spv->isset= TRUE; else if ($2.var)
} { /* System variable */
} if ($1)
lex->option_type= (enum_var_type)$1;
lex->var_list.push_back(new set_var(lex->option_type, $2.var,
&$2.base_name, $4));
}
else
{
/* An SP local variable */
sp_pcontext *ctx= lex->spcont;
sp_pvar_t *spv;
sp_instr_set *i;
Item *it;
if ($1)
{
yyerror(ER(ER_SYNTAX_ERROR));
YYABORT;
}
spv= ctx->find_pvar(&$2.base_name);
if ($4)
it= $4;
else if (spv->dflt)
it= spv->dflt;
else
it= new Item_null();
i= new sp_instr_set(lex->sphead->instructions(), ctx,
spv->offset, it, spv->type, lex, TRUE);
lex->sphead->add_instr(i);
spv->isset= TRUE;
}
}
| option_type TRANSACTION_SYM ISOLATION LEVEL_SYM isolation_types
{
LEX *lex=Lex;
if (!$1)
lex->option_type= (enum_var_type)$1;
lex->var_list.push_back(new set_var(lex->option_type,
find_sys_var("tx_isolation"),
&null_lex_str,
new Item_int((int32) $5)));
}
;
option_value:
'@' ident_or_text equal expr
{
Lex->var_list.push_back(new set_var_user(new Item_func_set_user_var($2,$4)));
}
| '@' '@' opt_var_ident_type internal_variable_name equal set_expr_or_default | '@' '@' opt_var_ident_type internal_variable_name equal set_expr_or_default
{ {
LEX *lex=Lex; LEX *lex=Lex;
lex->var_list.push_back(new set_var((enum_var_type) $3, $4.var, lex->var_list.push_back(new set_var((enum_var_type) $3, $4.var,
&$4.base_name, $6)); &$4.base_name, $6));
} }
| TRANSACTION_SYM ISOLATION LEVEL_SYM isolation_types
{
LEX *lex=Lex;
lex->var_list.push_back(new set_var(lex->option_type,
find_sys_var("tx_isolation"),
&null_lex_str,
new Item_int((int32) $4)));
}
| charset old_or_new_charset_name_or_default | charset old_or_new_charset_name_or_default
{ {
THD *thd= YYTHD; THD *thd= YYTHD;
......
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