Merge of fix for Bug#48459
This commit is contained in:
commit
fa61292476
@ -4335,7 +4335,7 @@ com_status(String *buffer __attribute__((unused)),
|
|||||||
Don't remove "limit 1",
|
Don't remove "limit 1",
|
||||||
it is protection againts SQL_SELECT_LIMIT=0
|
it is protection againts SQL_SELECT_LIMIT=0
|
||||||
*/
|
*/
|
||||||
if (mysql_store_result_for_lazy(&result))
|
if (!mysql_store_result_for_lazy(&result))
|
||||||
{
|
{
|
||||||
MYSQL_ROW cur=mysql_fetch_row(result);
|
MYSQL_ROW cur=mysql_fetch_row(result);
|
||||||
if (cur)
|
if (cur)
|
||||||
@ -4379,7 +4379,7 @@ com_status(String *buffer __attribute__((unused)),
|
|||||||
if (mysql_errno(&mysql) == CR_SERVER_GONE_ERROR)
|
if (mysql_errno(&mysql) == CR_SERVER_GONE_ERROR)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (mysql_store_result_for_lazy(&result))
|
if (!mysql_store_result_for_lazy(&result))
|
||||||
{
|
{
|
||||||
MYSQL_ROW cur=mysql_fetch_row(result);
|
MYSQL_ROW cur=mysql_fetch_row(result);
|
||||||
if (cur)
|
if (cur)
|
||||||
|
13
mysql-test/r/bug47671.result
Normal file
13
mysql-test/r/bug47671.result
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
#
|
||||||
|
# Bug#47671 - wrong character-set after upgrade from 5.1.34 to 5.1.39
|
||||||
|
#
|
||||||
|
# Extract only charset information from 'status' command output using regex
|
||||||
|
--------------
|
||||||
|
|
||||||
|
Server characterset: utf8
|
||||||
|
Db characterset: utf8
|
||||||
|
Client characterset: utf8
|
||||||
|
Conn. characterset: utf8
|
||||||
|
|
||||||
|
--------------
|
||||||
|
|
@ -6979,6 +6979,64 @@ CALL p1;
|
|||||||
ERROR 42S22: Unknown column 'A.b' in 'IN/ALL/ANY subquery'
|
ERROR 42S22: Unknown column 'A.b' in 'IN/ALL/ANY subquery'
|
||||||
DROP PROCEDURE p1;
|
DROP PROCEDURE p1;
|
||||||
DROP TABLE t1, t2;
|
DROP TABLE t1, t2;
|
||||||
|
#
|
||||||
|
# Bug#47627: SET @@{global.session}.local_variable in stored routine causes crash
|
||||||
|
# Bug#48626: Crash or lost connection using SET for declared variables with @@
|
||||||
|
#
|
||||||
|
DROP PROCEDURE IF EXISTS p1;
|
||||||
|
DROP PROCEDURE IF EXISTS p2;
|
||||||
|
DROP PROCEDURE IF EXISTS p3;
|
||||||
|
CREATE PROCEDURE p1()
|
||||||
|
BEGIN
|
||||||
|
DECLARE v INT DEFAULT 0;
|
||||||
|
SET @@SESSION.v= 10;
|
||||||
|
END//
|
||||||
|
ERROR HY000: Unknown system variable 'v'
|
||||||
|
CREATE PROCEDURE p2()
|
||||||
|
BEGIN
|
||||||
|
DECLARE v INT DEFAULT 0;
|
||||||
|
SET v= 10;
|
||||||
|
END//
|
||||||
|
call p2()//
|
||||||
|
CREATE PROCEDURE p3()
|
||||||
|
BEGIN
|
||||||
|
DECLARE v INT DEFAULT 0;
|
||||||
|
SELECT @@SESSION.v;
|
||||||
|
END//
|
||||||
|
ERROR HY000: Unknown system variable 'v'
|
||||||
|
CREATE PROCEDURE p4()
|
||||||
|
BEGIN
|
||||||
|
DECLARE v INT DEFAULT 0;
|
||||||
|
SET @@GLOBAL.v= 10;
|
||||||
|
END//
|
||||||
|
ERROR HY000: Unknown system variable 'v'
|
||||||
|
CREATE PROCEDURE p5()
|
||||||
|
BEGIN
|
||||||
|
DECLARE init_connect INT DEFAULT 0;
|
||||||
|
SET init_connect= 10;
|
||||||
|
SET @@GLOBAL.init_connect= 'SELECT 1';
|
||||||
|
SET @@SESSION.IDENTITY= 1;
|
||||||
|
SELECT @@SESSION.IDENTITY;
|
||||||
|
SELECT @@GLOBAL.init_connect;
|
||||||
|
SELECT init_connect;
|
||||||
|
END//
|
||||||
|
CREATE PROCEDURE p6()
|
||||||
|
BEGIN
|
||||||
|
DECLARE v INT DEFAULT 0;
|
||||||
|
SET @@v= 0;
|
||||||
|
END//
|
||||||
|
ERROR HY000: Unknown system variable 'v'
|
||||||
|
SET @old_init_connect= @@GLOBAL.init_connect;
|
||||||
|
CALL p5();
|
||||||
|
@@SESSION.IDENTITY
|
||||||
|
1
|
||||||
|
@@GLOBAL.init_connect
|
||||||
|
SELECT 1
|
||||||
|
init_connect
|
||||||
|
10
|
||||||
|
SET @@GLOBAL.init_connect= @old_init_connect;
|
||||||
|
DROP PROCEDURE p2;
|
||||||
|
DROP PROCEDURE p5;
|
||||||
# ------------------------------------------------------------------
|
# ------------------------------------------------------------------
|
||||||
# -- End of 5.1 tests
|
# -- End of 5.1 tests
|
||||||
# ------------------------------------------------------------------
|
# ------------------------------------------------------------------
|
||||||
|
1
mysql-test/t/bug47671-master.opt
Normal file
1
mysql-test/t/bug47671-master.opt
Normal file
@ -0,0 +1 @@
|
|||||||
|
--default-character-set=utf8 --skip-character-set-client-handshake
|
6
mysql-test/t/bug47671.test
Normal file
6
mysql-test/t/bug47671.test
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
--echo #
|
||||||
|
--echo # Bug#47671 - wrong character-set after upgrade from 5.1.34 to 5.1.39
|
||||||
|
--echo #
|
||||||
|
--echo # Extract only charset information from 'status' command output using regex
|
||||||
|
--replace_regex /.*mysql.*// /Connection.*// /Current.*// /SSL.*// /Using.*// /Server version.*// /Protocol.*// /UNIX.*// /Uptime.*// /Threads.*//
|
||||||
|
--exec $MYSQL -u root test -e "status";
|
@ -8263,6 +8263,73 @@ CALL p1;
|
|||||||
DROP PROCEDURE p1;
|
DROP PROCEDURE p1;
|
||||||
DROP TABLE t1, t2;
|
DROP TABLE t1, t2;
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # Bug#47627: SET @@{global.session}.local_variable in stored routine causes crash
|
||||||
|
--echo # Bug#48626: Crash or lost connection using SET for declared variables with @@
|
||||||
|
--echo #
|
||||||
|
|
||||||
|
--disable_warnings
|
||||||
|
DROP PROCEDURE IF EXISTS p1;
|
||||||
|
DROP PROCEDURE IF EXISTS p2;
|
||||||
|
DROP PROCEDURE IF EXISTS p3;
|
||||||
|
--enable_warnings
|
||||||
|
|
||||||
|
delimiter //;
|
||||||
|
|
||||||
|
--error ER_UNKNOWN_SYSTEM_VARIABLE
|
||||||
|
CREATE PROCEDURE p1()
|
||||||
|
BEGIN
|
||||||
|
DECLARE v INT DEFAULT 0;
|
||||||
|
SET @@SESSION.v= 10;
|
||||||
|
END//
|
||||||
|
|
||||||
|
CREATE PROCEDURE p2()
|
||||||
|
BEGIN
|
||||||
|
DECLARE v INT DEFAULT 0;
|
||||||
|
SET v= 10;
|
||||||
|
END//
|
||||||
|
call p2()//
|
||||||
|
|
||||||
|
--error ER_UNKNOWN_SYSTEM_VARIABLE
|
||||||
|
CREATE PROCEDURE p3()
|
||||||
|
BEGIN
|
||||||
|
DECLARE v INT DEFAULT 0;
|
||||||
|
SELECT @@SESSION.v;
|
||||||
|
END//
|
||||||
|
|
||||||
|
--error ER_UNKNOWN_SYSTEM_VARIABLE
|
||||||
|
CREATE PROCEDURE p4()
|
||||||
|
BEGIN
|
||||||
|
DECLARE v INT DEFAULT 0;
|
||||||
|
SET @@GLOBAL.v= 10;
|
||||||
|
END//
|
||||||
|
|
||||||
|
CREATE PROCEDURE p5()
|
||||||
|
BEGIN
|
||||||
|
DECLARE init_connect INT DEFAULT 0;
|
||||||
|
SET init_connect= 10;
|
||||||
|
SET @@GLOBAL.init_connect= 'SELECT 1';
|
||||||
|
SET @@SESSION.IDENTITY= 1;
|
||||||
|
SELECT @@SESSION.IDENTITY;
|
||||||
|
SELECT @@GLOBAL.init_connect;
|
||||||
|
SELECT init_connect;
|
||||||
|
END//
|
||||||
|
|
||||||
|
--error ER_UNKNOWN_SYSTEM_VARIABLE
|
||||||
|
CREATE PROCEDURE p6()
|
||||||
|
BEGIN
|
||||||
|
DECLARE v INT DEFAULT 0;
|
||||||
|
SET @@v= 0;
|
||||||
|
END//
|
||||||
|
|
||||||
|
delimiter ;//
|
||||||
|
|
||||||
|
SET @old_init_connect= @@GLOBAL.init_connect;
|
||||||
|
CALL p5();
|
||||||
|
SET @@GLOBAL.init_connect= @old_init_connect;
|
||||||
|
|
||||||
|
DROP PROCEDURE p2;
|
||||||
|
DROP PROCEDURE p5;
|
||||||
|
|
||||||
--echo # ------------------------------------------------------------------
|
--echo # ------------------------------------------------------------------
|
||||||
--echo # -- End of 5.1 tests
|
--echo # -- End of 5.1 tests
|
||||||
|
@ -960,12 +960,23 @@ int Arg_comparator::set_cmp_func(Item_result_field *owner_arg,
|
|||||||
(*b)->field_type() == MYSQL_TYPE_YEAR))
|
(*b)->field_type() == MYSQL_TYPE_YEAR))
|
||||||
{
|
{
|
||||||
is_nulls_eq= is_owner_equal_func();
|
is_nulls_eq= is_owner_equal_func();
|
||||||
|
year_as_datetime= FALSE;
|
||||||
|
|
||||||
if ((*a)->is_datetime())
|
if ((*a)->is_datetime())
|
||||||
{
|
{
|
||||||
year_as_datetime= TRUE;
|
year_as_datetime= TRUE;
|
||||||
get_value_a_func= &get_datetime_value;
|
get_value_a_func= &get_datetime_value;
|
||||||
} else if ((*a)->field_type() == MYSQL_TYPE_YEAR)
|
} else if ((*a)->field_type() == MYSQL_TYPE_YEAR)
|
||||||
get_value_a_func= &get_year_value;
|
get_value_a_func= &get_year_value;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
Because convert_constant_item is called only for EXECUTE in PS mode
|
||||||
|
the value of get_value_x_func set in PREPARE might be not
|
||||||
|
valid for EXECUTE.
|
||||||
|
*/
|
||||||
|
get_value_a_func= NULL;
|
||||||
|
}
|
||||||
|
|
||||||
if ((*b)->is_datetime())
|
if ((*b)->is_datetime())
|
||||||
{
|
{
|
||||||
@ -973,6 +984,8 @@ int Arg_comparator::set_cmp_func(Item_result_field *owner_arg,
|
|||||||
get_value_b_func= &get_datetime_value;
|
get_value_b_func= &get_datetime_value;
|
||||||
} else if ((*b)->field_type() == MYSQL_TYPE_YEAR)
|
} else if ((*b)->field_type() == MYSQL_TYPE_YEAR)
|
||||||
get_value_b_func= &get_year_value;
|
get_value_b_func= &get_year_value;
|
||||||
|
else
|
||||||
|
get_value_b_func= NULL;
|
||||||
|
|
||||||
func= &Arg_comparator::compare_year;
|
func= &Arg_comparator::compare_year;
|
||||||
return 0;
|
return 0;
|
||||||
|
252
sql/sql_yacc.yy
252
sql/sql_yacc.yy
@ -389,6 +389,138 @@ void case_stmt_action_end_case(LEX *lex, bool simple)
|
|||||||
lex->sphead->do_cont_backpatch();
|
lex->sphead->do_cont_backpatch();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static bool
|
||||||
|
find_sys_var_null_base(THD *thd, struct sys_var_with_base *tmp)
|
||||||
|
{
|
||||||
|
tmp->var= find_sys_var(thd, tmp->base_name.str, tmp->base_name.length);
|
||||||
|
|
||||||
|
if (tmp->var == NULL)
|
||||||
|
my_error(ER_UNKNOWN_SYSTEM_VARIABLE, MYF(0), tmp->base_name.str);
|
||||||
|
else
|
||||||
|
tmp->base_name= null_lex_str;
|
||||||
|
|
||||||
|
return thd->is_error();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
Helper action for a SET statement.
|
||||||
|
Used to push a system variable into the assignment list.
|
||||||
|
|
||||||
|
@param thd the current thread
|
||||||
|
@param tmp the system variable with base name
|
||||||
|
@param var_type the scope of the variable
|
||||||
|
@param val the value being assigned to the variable
|
||||||
|
|
||||||
|
@return TRUE if error, FALSE otherwise.
|
||||||
|
*/
|
||||||
|
|
||||||
|
static bool
|
||||||
|
set_system_variable(THD *thd, struct sys_var_with_base *tmp,
|
||||||
|
enum enum_var_type var_type, Item *val)
|
||||||
|
{
|
||||||
|
set_var *var;
|
||||||
|
LEX *lex= thd->lex;
|
||||||
|
|
||||||
|
/* No AUTOCOMMIT from a stored function or trigger. */
|
||||||
|
if (lex->spcont && tmp->var == &sys_autocommit)
|
||||||
|
lex->sphead->m_flags|= sp_head::HAS_SET_AUTOCOMMIT_STMT;
|
||||||
|
|
||||||
|
if (! (var= new set_var(var_type, tmp->var, &tmp->base_name, val)))
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
return lex->var_list.push_back(var);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
Helper action for a SET statement.
|
||||||
|
Used to push a SP local variable into the assignment list.
|
||||||
|
|
||||||
|
@param thd the current thread
|
||||||
|
@param var_type the SP local variable
|
||||||
|
@param val the value being assigned to the variable
|
||||||
|
|
||||||
|
@return TRUE if error, FALSE otherwise.
|
||||||
|
*/
|
||||||
|
|
||||||
|
static bool
|
||||||
|
set_local_variable(THD *thd, sp_variable_t *spv, Item *val)
|
||||||
|
{
|
||||||
|
Item *it;
|
||||||
|
LEX *lex= thd->lex;
|
||||||
|
sp_instr_set *sp_set;
|
||||||
|
|
||||||
|
if (val)
|
||||||
|
it= val;
|
||||||
|
else if (spv->dflt)
|
||||||
|
it= spv->dflt;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
it= new (thd->mem_root) Item_null();
|
||||||
|
if (it == NULL)
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
sp_set= new sp_instr_set(lex->sphead->instructions(), lex->spcont,
|
||||||
|
spv->offset, it, spv->type, lex, TRUE);
|
||||||
|
|
||||||
|
return (sp_set == NULL || lex->sphead->add_instr(sp_set));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
Helper action for a SET statement.
|
||||||
|
Used to SET a field of NEW row.
|
||||||
|
|
||||||
|
@param thd the current thread
|
||||||
|
@param name the field name
|
||||||
|
@param val the value being assigned to the row
|
||||||
|
|
||||||
|
@return TRUE if error, FALSE otherwise.
|
||||||
|
*/
|
||||||
|
|
||||||
|
static bool
|
||||||
|
set_trigger_new_row(THD *thd, LEX_STRING *name, Item *val)
|
||||||
|
{
|
||||||
|
LEX *lex= thd->lex;
|
||||||
|
Item_trigger_field *trg_fld;
|
||||||
|
sp_instr_set_trigger_field *sp_fld;
|
||||||
|
|
||||||
|
/* QQ: Shouldn't this be field's default value ? */
|
||||||
|
if (! val)
|
||||||
|
val= new Item_null();
|
||||||
|
|
||||||
|
DBUG_ASSERT(lex->trg_chistics.action_time == TRG_ACTION_BEFORE &&
|
||||||
|
(lex->trg_chistics.event == TRG_EVENT_INSERT ||
|
||||||
|
lex->trg_chistics.event == TRG_EVENT_UPDATE));
|
||||||
|
|
||||||
|
trg_fld= new (thd->mem_root)
|
||||||
|
Item_trigger_field(lex->current_context(),
|
||||||
|
Item_trigger_field::NEW_ROW,
|
||||||
|
name->str, UPDATE_ACL, FALSE);
|
||||||
|
|
||||||
|
if (trg_fld == NULL)
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
sp_fld= new sp_instr_set_trigger_field(lex->sphead->instructions(),
|
||||||
|
lex->spcont, trg_fld, val, lex);
|
||||||
|
|
||||||
|
if (sp_fld == NULL)
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
/*
|
||||||
|
Let us add this item to list of all Item_trigger_field
|
||||||
|
objects in trigger.
|
||||||
|
*/
|
||||||
|
lex->trg_table_fields.link_in_list((uchar *) trg_fld,
|
||||||
|
(uchar **) &trg_fld->next_trg_field);
|
||||||
|
|
||||||
|
return lex->sphead->add_instr(sp_fld);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Helper to resolve the SQL:2003 Syntax exception 1) in <in predicate>.
|
Helper to resolve the SQL:2003 Syntax exception 1) in <in predicate>.
|
||||||
See SQL:2003, Part 2, section 8.4 <in predicate>, Note 184, page 383.
|
See SQL:2003, Part 2, section 8.4 <in predicate>, Note 184, page 383.
|
||||||
@ -11830,98 +11962,42 @@ sys_option_value:
|
|||||||
option_type internal_variable_name equal set_expr_or_default
|
option_type internal_variable_name equal set_expr_or_default
|
||||||
{
|
{
|
||||||
THD *thd= YYTHD;
|
THD *thd= YYTHD;
|
||||||
LEX *lex=Lex;
|
LEX *lex= Lex;
|
||||||
|
LEX_STRING *name= &$2.base_name;
|
||||||
|
|
||||||
if ($2.var == trg_new_row_fake_var)
|
if ($2.var == trg_new_row_fake_var)
|
||||||
{
|
{
|
||||||
/* We are in trigger and assigning value to field of new row */
|
/* We are in trigger and assigning value to field of new row */
|
||||||
Item *it;
|
|
||||||
Item_trigger_field *trg_fld;
|
|
||||||
sp_instr_set_trigger_field *sp_fld;
|
|
||||||
LINT_INIT(sp_fld);
|
|
||||||
if ($1)
|
if ($1)
|
||||||
{
|
{
|
||||||
my_parse_error(ER(ER_SYNTAX_ERROR));
|
my_parse_error(ER(ER_SYNTAX_ERROR));
|
||||||
MYSQL_YYABORT;
|
MYSQL_YYABORT;
|
||||||
}
|
}
|
||||||
if ($4)
|
if (set_trigger_new_row(YYTHD, name, $4))
|
||||||
it= $4;
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* QQ: Shouldn't this be field's default value ? */
|
|
||||||
it= new Item_null();
|
|
||||||
}
|
|
||||||
|
|
||||||
DBUG_ASSERT(lex->trg_chistics.action_time == TRG_ACTION_BEFORE &&
|
|
||||||
(lex->trg_chistics.event == TRG_EVENT_INSERT ||
|
|
||||||
lex->trg_chistics.event == TRG_EVENT_UPDATE));
|
|
||||||
|
|
||||||
trg_fld= new (thd->mem_root)
|
|
||||||
Item_trigger_field(Lex->current_context(),
|
|
||||||
Item_trigger_field::NEW_ROW,
|
|
||||||
$2.base_name.str,
|
|
||||||
UPDATE_ACL, FALSE);
|
|
||||||
if (trg_fld == NULL)
|
|
||||||
MYSQL_YYABORT;
|
|
||||||
|
|
||||||
sp_fld= new sp_instr_set_trigger_field(lex->sphead->
|
|
||||||
instructions(),
|
|
||||||
lex->spcont,
|
|
||||||
trg_fld,
|
|
||||||
it, lex);
|
|
||||||
if (sp_fld == NULL)
|
|
||||||
MYSQL_YYABORT;
|
|
||||||
|
|
||||||
/*
|
|
||||||
Let us add this item to list of all Item_trigger_field
|
|
||||||
objects in trigger.
|
|
||||||
*/
|
|
||||||
lex->trg_table_fields.link_in_list((uchar *)trg_fld,
|
|
||||||
(uchar **) &trg_fld->
|
|
||||||
next_trg_field);
|
|
||||||
|
|
||||||
if (lex->sphead->add_instr(sp_fld))
|
|
||||||
MYSQL_YYABORT;
|
MYSQL_YYABORT;
|
||||||
}
|
}
|
||||||
else if ($2.var)
|
else if ($2.var)
|
||||||
{ /* System variable */
|
{
|
||||||
if ($1)
|
if ($1)
|
||||||
lex->option_type= $1;
|
lex->option_type= $1;
|
||||||
set_var *var= new set_var(lex->option_type, $2.var,
|
|
||||||
&$2.base_name, $4);
|
/* It is a system variable. */
|
||||||
if (var == NULL)
|
if (set_system_variable(thd, &$2, lex->option_type, $4))
|
||||||
MYSQL_YYABORT;
|
MYSQL_YYABORT;
|
||||||
lex->var_list.push_back(var);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* An SP local variable */
|
sp_pcontext *spc= lex->spcont;
|
||||||
sp_pcontext *ctx= lex->spcont;
|
sp_variable_t *spv= spc->find_variable(name);
|
||||||
sp_variable_t *spv;
|
|
||||||
sp_instr_set *sp_set;
|
|
||||||
Item *it;
|
|
||||||
if ($1)
|
if ($1)
|
||||||
{
|
{
|
||||||
my_parse_error(ER(ER_SYNTAX_ERROR));
|
my_parse_error(ER(ER_SYNTAX_ERROR));
|
||||||
MYSQL_YYABORT;
|
MYSQL_YYABORT;
|
||||||
}
|
}
|
||||||
|
|
||||||
spv= ctx->find_variable(&$2.base_name);
|
/* It is a local variable. */
|
||||||
|
if (set_local_variable(thd, spv, $4))
|
||||||
if ($4)
|
|
||||||
it= $4;
|
|
||||||
else if (spv->dflt)
|
|
||||||
it= spv->dflt;
|
|
||||||
else
|
|
||||||
{
|
|
||||||
it= new (thd->mem_root) Item_null();
|
|
||||||
if (it == NULL)
|
|
||||||
MYSQL_YYABORT;
|
|
||||||
}
|
|
||||||
sp_set= new sp_instr_set(lex->sphead->instructions(), ctx,
|
|
||||||
spv->offset, it, spv->type, lex, TRUE);
|
|
||||||
if (sp_set == NULL ||
|
|
||||||
lex->sphead->add_instr(sp_set))
|
|
||||||
MYSQL_YYABORT;
|
MYSQL_YYABORT;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -11957,11 +12033,16 @@ option_value:
|
|||||||
}
|
}
|
||||||
| '@' '@' 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;
|
THD *thd= YYTHD;
|
||||||
set_var *var= new set_var($3, $4.var, &$4.base_name, $6);
|
struct sys_var_with_base tmp= $4;
|
||||||
if (var == NULL)
|
/* Lookup if necessary: must be a system variable. */
|
||||||
|
if (tmp.var == NULL)
|
||||||
|
{
|
||||||
|
if (find_sys_var_null_base(thd, &tmp))
|
||||||
|
MYSQL_YYABORT;
|
||||||
|
}
|
||||||
|
if (set_system_variable(thd, &tmp, $3, $6))
|
||||||
MYSQL_YYABORT;
|
MYSQL_YYABORT;
|
||||||
lex->var_list.push_back(var);
|
|
||||||
}
|
}
|
||||||
| charset old_or_new_charset_name_or_default
|
| charset old_or_new_charset_name_or_default
|
||||||
{
|
{
|
||||||
@ -12054,31 +12135,26 @@ internal_variable_name:
|
|||||||
ident
|
ident
|
||||||
{
|
{
|
||||||
THD *thd= YYTHD;
|
THD *thd= YYTHD;
|
||||||
LEX *lex= thd->lex;
|
sp_pcontext *spc= thd->lex->spcont;
|
||||||
sp_pcontext *spc= lex->spcont;
|
|
||||||
sp_variable_t *spv;
|
sp_variable_t *spv;
|
||||||
|
|
||||||
/* We have to lookup here since local vars can shadow sysvars */
|
/* Best effort lookup for system variable. */
|
||||||
if (!spc || !(spv = spc->find_variable(&$1)))
|
if (!spc || !(spv = spc->find_variable(&$1)))
|
||||||
{
|
{
|
||||||
|
struct sys_var_with_base tmp= {NULL, $1};
|
||||||
|
|
||||||
/* Not an SP local variable */
|
/* Not an SP local variable */
|
||||||
sys_var *tmp=find_sys_var(thd, $1.str, $1.length);
|
if (find_sys_var_null_base(thd, &tmp))
|
||||||
if (!tmp)
|
|
||||||
MYSQL_YYABORT;
|
MYSQL_YYABORT;
|
||||||
$$.var= tmp;
|
|
||||||
$$.base_name= null_lex_str;
|
$$= tmp;
|
||||||
if (spc && tmp == &sys_autocommit)
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
We don't allow setting AUTOCOMMIT from a stored function
|
|
||||||
or trigger.
|
|
||||||
*/
|
|
||||||
lex->sphead->m_flags|= sp_head::HAS_SET_AUTOCOMMIT_STMT;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* An SP local variable */
|
/*
|
||||||
|
Possibly an SP local variable (or a shadowed sysvar).
|
||||||
|
Will depend on the context of the SET statement.
|
||||||
|
*/
|
||||||
$$.var= NULL;
|
$$.var= NULL;
|
||||||
$$.base_name= $1;
|
$$.base_name= $1;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user