Commit e9507f0e authored by pem@mysql.comhem.se's avatar pem@mysql.comhem.se

Fixed BUG#4579: Execution of SP crashes server.

Sub-CALLs of procedures zapped thd->current_arena for good.
parent ed32dbba
...@@ -1387,6 +1387,27 @@ group_concat(v) ...@@ -1387,6 +1387,27 @@ group_concat(v)
yz,yz yz,yz
drop procedure bug3368| drop procedure bug3368|
drop table t3| drop table t3|
drop table if exists t3|
create table t3 (f1 int, f2 int);
insert into t3 values (1,1);
create procedure bug4579_1 ()
begin
declare sf1 int;
select f1 into sf1 from t3 where f1=1 and f2=1;
update t3 set f2 = f2 + 1 where f1=1 and f2=1;
call bug4579_2();
end|
create procedure bug4579_2 ()
begin
end|
call bug4579_1()|
call bug4579_1()|
Warnings:
call bug4579_1()|
Warnings:
drop procedure bug4579_1|
drop procedure bug4579_2|
drop table t3|
drop table if exists fac| drop table if exists fac|
create table fac (n int unsigned not null primary key, f bigint unsigned)| create table fac (n int unsigned not null primary key, f bigint unsigned)|
create procedure ifac(n int unsigned) create procedure ifac(n int unsigned)
......
...@@ -1592,6 +1592,36 @@ call bug3368('yz')| ...@@ -1592,6 +1592,36 @@ call bug3368('yz')|
drop procedure bug3368| drop procedure bug3368|
drop table t3| drop table t3|
#
# BUG#4579
#
--disable_warnings
drop table if exists t3|
--enable_warnings
create table t3 (f1 int, f2 int);
insert into t3 values (1,1);
create procedure bug4579_1 ()
begin
declare sf1 int;
select f1 into sf1 from t3 where f1=1 and f2=1;
update t3 set f2 = f2 + 1 where f1=1 and f2=1;
call bug4579_2();
end|
create procedure bug4579_2 ()
begin
end|
call bug4579_1()|
call bug4579_1()|
call bug4579_1()|
drop procedure bug4579_1|
drop procedure bug4579_2|
drop table t3|
# #
# Some "real" examples # Some "real" examples
......
...@@ -377,9 +377,11 @@ sp_head::execute(THD *thd) ...@@ -377,9 +377,11 @@ sp_head::execute(THD *thd)
DBUG_ENTER("sp_head::execute"); DBUG_ENTER("sp_head::execute");
char olddb[128]; char olddb[128];
bool dbchanged; bool dbchanged;
sp_rcontext *ctx= thd->spcont; sp_rcontext *ctx;
int ret= 0; int ret= 0;
uint ip= 0; uint ip= 0;
Item_arena *old_arena;
#ifndef EMBEDDED_LIBRARY #ifndef EMBEDDED_LIBRARY
if (check_stack_overrun(thd, olddb)) if (check_stack_overrun(thd, olddb))
...@@ -392,10 +394,12 @@ sp_head::execute(THD *thd) ...@@ -392,10 +394,12 @@ sp_head::execute(THD *thd)
if ((ret= sp_use_new_db(thd, m_db.str, olddb, sizeof(olddb), 0, &dbchanged))) if ((ret= sp_use_new_db(thd, m_db.str, olddb, sizeof(olddb), 0, &dbchanged)))
goto done; goto done;
if (ctx) if ((ctx= thd->spcont))
ctx->clear_handler(); ctx->clear_handler();
thd->query_error= 0; thd->query_error= 0;
old_arena= thd->current_arena;
thd->current_arena= this; thd->current_arena= this;
do do
{ {
sp_instr *i; sp_instr *i;
...@@ -433,14 +437,14 @@ sp_head::execute(THD *thd) ...@@ -433,14 +437,14 @@ sp_head::execute(THD *thd)
} while (ret == 0 && !thd->killed && !thd->query_error && } while (ret == 0 && !thd->killed && !thd->query_error &&
!thd->net.report_error); !thd->net.report_error);
if (thd->current_arena)
cleanup_items(thd->current_arena->free_list);
thd->current_arena= old_arena;
done: done:
DBUG_PRINT("info", ("ret=%d killed=%d query_error=%d", DBUG_PRINT("info", ("ret=%d killed=%d query_error=%d",
ret, thd->killed, thd->query_error)); ret, thd->killed, thd->query_error));
if (thd->current_arena)
cleanup_items(thd->current_arena->free_list);
thd->current_arena= 0;
if (thd->killed || thd->query_error || thd->net.report_error) if (thd->killed || thd->query_error || thd->net.report_error)
ret= -1; ret= -1;
/* If the DB has changed, the pointer has changed too, but the /* If the DB has changed, the pointer has changed too, but the
......
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