Commit 6574612d authored by unknown's avatar unknown
Browse files

Fix for BUG#13549 "Server crash with nested stored procedures

if inner routine has more local variables than outer one, and
one of its last variables was used as argument to NOT operator".

THD::spcont was non-0 when we were parsing stored routine/trigger
definition during execution of another stored routine. This confused
methods of Item_splocal and forced them use wrong runtime context.
Fix ensures that we always have THD::spcont equal to zero during
routine/trigger body parsing. This also allows to avoid problems
with errors which occur during parsing and SQL exception handlers.


mysql-test/r/sp.result:
  Test suite for bug#13549.
mysql-test/r/trigger.result:
  Test suite for bug#13549.
mysql-test/t/sp.test:
  Test suite for bug#13549.
mysql-test/t/trigger.test:
  Test suite for bug#13549.
sql/item.cc:
  Protection against using wrong context by SP local variable.
sql/item.h:
  Protection against using wrong context by SP local variable.
sql/protocol.cc:
  An incorrect macro name fixed.
sql/protocol.h:
  An incorrect macro name fixed.
sql/sp.cc:
  Do not allow SP which we are parsing to use other SP
  context (BUG#13549).
sql/sp_head.cc:
  Protection against using wrong context by SP local variable.
sql/sp_rcontext.h:
  Protection against using wrong context by SP local variable.
sql/sql_cache.h:
  An incorrect macro name fixed.
sql/sql_class.cc:
  Protection against using wrong context by SP local variable.
sql/sql_class.h:
  Protection against using wrong context by SP local variable.
sql/sql_trigger.cc:
  Do not allow Trigger which we are parsing to use
  other SP context (BUG#13549).
sql/sql_yacc.yy:
  Protection against using wrong context by SP local variable.
parent 3410309f
Loading
Loading
Loading
Loading
+17 −0
Original line number Diff line number Diff line
@@ -3435,4 +3435,21 @@ Table Create Table
tm1	CREATE TEMPORARY TABLE `tm1` (
  `spv1` decimal(6,3) default NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
drop procedure bug12589_1|
drop procedure bug12589_2|
drop procedure bug12589_3|
drop procedure if exists bug13549_1|
drop procedure if exists bug13549_2|
CREATE PROCEDURE `bug13549_2`()
begin
call bug13549_1();
end|
CREATE PROCEDURE `bug13549_1`()
begin
declare done int default 0;
set done= not done;
end|
CALL bug13549_2()|
drop procedure bug13549_2|
drop procedure bug13549_1|
drop table t1,t2;
+14 −0
Original line number Diff line number Diff line
@@ -738,3 +738,17 @@ f1
1
drop trigger t1_bi;
drop tables t1, t2;
create table t1 (a int);
drop procedure if exists p2;
CREATE PROCEDURE `p2`()
begin
insert into t1 values (1);
end//
create trigger trg before insert on t1 for each row 
begin 
declare done int default 0;
set done= not done;
end//
CALL p2();
drop procedure p2;
drop table t1;
+27 −0
Original line number Diff line number Diff line
@@ -4313,7 +4313,34 @@ call bug12589_1()|
# No warnings here
call bug12589_2()|
call bug12589_3()|
drop procedure bug12589_1|
drop procedure bug12589_2|
drop procedure bug12589_3|

#
# BUG#13549 "Server crash with nested stored procedures".
# Server should not crash when during execution of stored procedure
# we have to parse trigger/function definition and this new trigger/
# function has more local variables declared than invoking stored
# procedure and last of these variables is used in argument of NOT
# operator.
#
--disable_warnings
drop procedure if exists bug13549_1|
drop procedure if exists bug13549_2|
--enable_warnings
CREATE PROCEDURE `bug13549_2`()
begin
  call bug13549_1();
end|
CREATE PROCEDURE `bug13549_1`()
begin
  declare done int default 0;
  set done= not done;
end|
CALL bug13549_2()|
drop procedure bug13549_2|
drop procedure bug13549_1|

#
# BUG#NNNN: New bug synopsis
+28 −0
Original line number Diff line number Diff line
@@ -875,3 +875,31 @@ drop function f1;
drop view v1;
drop table t1, t2, t3;
--enable_parsing

#
# BUG#13549 "Server crash with nested stored procedures".
# Server should not crash when during execution of stored procedure
# we have to parse trigger/function definition and this new trigger/
# function has more local variables declared than invoking stored
# procedure and last of these variables is used in argument of NOT
# operator.
#
create table t1 (a int);
--disable_warnings
drop procedure if exists p2;
--enable_warnings
DELIMITER //;
CREATE PROCEDURE `p2`()
begin
  insert into t1 values (1);
end//
create trigger trg before insert on t1 for each row 
begin 
  declare done int default 0;
  set done= not done;
end//
DELIMITER ;//
CALL p2();
drop procedure p2;
drop table t1;
+6 −1
Original line number Diff line number Diff line
@@ -868,7 +868,7 @@ Item *
Item_splocal::this_item()
{
  THD *thd= current_thd;

  DBUG_ASSERT(owner == thd->spcont->owner);
  return thd->spcont->get_item(m_offset);
}

@@ -876,6 +876,7 @@ Item_splocal::this_item()
Item **
Item_splocal::this_item_addr(THD *thd, Item **addr)
{
  DBUG_ASSERT(owner == thd->spcont->owner);
  return thd->spcont->get_item_addr(m_offset);
}

@@ -884,6 +885,7 @@ Item_splocal::this_const_item() const
{
  THD *thd= current_thd;

  DBUG_ASSERT(owner == thd->spcont->owner);
  return thd->spcont->get_item(m_offset);
}

@@ -893,7 +895,10 @@ Item_splocal::type() const
  THD *thd= current_thd;

  if (thd->spcont)
  {
    DBUG_ASSERT(owner == thd->spcont->owner);
    return thd->spcont->get_item(m_offset)->type();
  }
  return NULL_ITEM;		// Anything but SUBSELECT_ITEM
}

Loading