mirror of
https://github.com/MariaDB/server.git
synced 2026-01-06 05:22:24 +03:00
Bug#47627 SET @@{global.session}.local_variable in stored routine causes crash
Adding @@session and @@global prefixes to a declared variable in a stored procedure the server would lead to a crash. The reason was that during the parsing of the syntactic rule 'option_value' an uninitialized set_var object was pushed to the parameter stack of the SET statement. The parent rule 'option_type_value' interpreted the existence of variables on the parameter stack as an assignment and wrapped it in a sp_instr_set object. As the procedure later was executed an attempt was made to run the method 'check()' on an uninitialized member object (NULL value) belonging to the previously created but uninitialized object.
This commit is contained in:
@@ -6979,6 +6979,51 @@ CALL p1;
|
||||
ERROR 42S22: Unknown column 'A.b' in 'IN/ALL/ANY subquery'
|
||||
DROP PROCEDURE p1;
|
||||
DROP TABLE t1, t2;
|
||||
#
|
||||
# Bug47627 SET @@{global.session}.local_variable in stored routine causes crash
|
||||
#
|
||||
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 v INT DEFAULT 0;
|
||||
SET @@global.query_cache_size= 0;
|
||||
SET @@session.identity= 1;
|
||||
SELECT @@session.identity;
|
||||
SELECT @@global.query_cache_size;
|
||||
END//
|
||||
CALL p5();
|
||||
@@session.identity
|
||||
1
|
||||
@@global.query_cache_size
|
||||
0
|
||||
DROP PROCEDURE p2;
|
||||
DROP PROCEDURE p5;
|
||||
# ------------------------------------------------------------------
|
||||
# -- End of 5.1 tests
|
||||
# ------------------------------------------------------------------
|
||||
|
||||
@@ -8263,7 +8263,51 @@ CALL p1;
|
||||
DROP PROCEDURE p1;
|
||||
DROP TABLE t1, t2;
|
||||
|
||||
|
||||
--echo #
|
||||
--echo # Bug47627 SET @@{global.session}.local_variable in stored routine causes crash
|
||||
--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 v INT DEFAULT 0;
|
||||
SET @@global.query_cache_size= 0;
|
||||
SET @@session.identity= 1;
|
||||
SELECT @@session.identity;
|
||||
SELECT @@global.query_cache_size;
|
||||
END//
|
||||
delimiter ;//
|
||||
CALL p5();
|
||||
DROP PROCEDURE p2;
|
||||
DROP PROCEDURE p5;
|
||||
--echo # ------------------------------------------------------------------
|
||||
--echo # -- End of 5.1 tests
|
||||
--echo # ------------------------------------------------------------------
|
||||
|
||||
@@ -11783,8 +11783,17 @@ option_type:
|
||||
;
|
||||
|
||||
option_type2:
|
||||
/* empty */ { $$= OPT_DEFAULT; }
|
||||
| ONE_SHOT_SYM { Lex->one_shot_set= 1; $$= OPT_SESSION; }
|
||||
/* empty */
|
||||
{
|
||||
$$= OPT_DEFAULT;
|
||||
Lex->option_type= OPT_DEFAULT;
|
||||
}
|
||||
| ONE_SHOT_SYM
|
||||
{
|
||||
Lex->one_shot_set= 1;
|
||||
$$= OPT_SESSION;
|
||||
Lex->option_type= OPT_SESSION;
|
||||
}
|
||||
;
|
||||
|
||||
opt_var_type:
|
||||
@@ -11795,10 +11804,26 @@ opt_var_type:
|
||||
;
|
||||
|
||||
opt_var_ident_type:
|
||||
/* empty */ { $$=OPT_DEFAULT; }
|
||||
| GLOBAL_SYM '.' { $$=OPT_GLOBAL; }
|
||||
| LOCAL_SYM '.' { $$=OPT_SESSION; }
|
||||
| SESSION_SYM '.' { $$=OPT_SESSION; }
|
||||
/* empty */
|
||||
{
|
||||
$$=OPT_DEFAULT;
|
||||
Lex->option_type= OPT_DEFAULT;
|
||||
}
|
||||
| GLOBAL_SYM '.'
|
||||
{
|
||||
$$=OPT_GLOBAL;
|
||||
Lex->option_type= OPT_GLOBAL;
|
||||
}
|
||||
| LOCAL_SYM '.'
|
||||
{
|
||||
$$=OPT_SESSION;
|
||||
Lex->option_type= OPT_SESSION;
|
||||
}
|
||||
| SESSION_SYM '.'
|
||||
{
|
||||
$$=OPT_SESSION;
|
||||
Lex->option_type= OPT_SESSION;
|
||||
}
|
||||
;
|
||||
|
||||
ext_option_value:
|
||||
@@ -12038,8 +12063,22 @@ internal_variable_name:
|
||||
sp_pcontext *spc= lex->spcont;
|
||||
sp_variable_t *spv;
|
||||
|
||||
/* We have to lookup here since local vars can shadow sysvars */
|
||||
if (!spc || !(spv = spc->find_variable(&$1)))
|
||||
/*
|
||||
We have to lookup here since local vars can shadow sysvars.
|
||||
|
||||
We also have to inspect the option_type first since the variable
|
||||
identifier might have been prefixed with @@session or @@global
|
||||
prefixes. Without this check we would wrongly identify them
|
||||
as SP local variables.
|
||||
*/
|
||||
if (lex->option_type == OPT_DEFAULT && spc &&
|
||||
(spv= spc->find_variable(&$1)))
|
||||
{
|
||||
/* An SP local variable */
|
||||
$$.var= NULL;
|
||||
$$.base_name= $1;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Not an SP local variable */
|
||||
sys_var *tmp=find_sys_var(thd, $1.str, $1.length);
|
||||
@@ -12056,12 +12095,6 @@ internal_variable_name:
|
||||
lex->sphead->m_flags|= sp_head::HAS_SET_AUTOCOMMIT_STMT;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* An SP local variable */
|
||||
$$.var= NULL;
|
||||
$$.base_name= $1;
|
||||
}
|
||||
}
|
||||
| ident '.' ident
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user