mirror of
https://github.com/MariaDB/server.git
synced 2025-08-08 11:22:35 +03:00
A fix and a test case for "Bug #12168 'DECLARE CONTINUE HANDLER FOR
NOT FOUND ...' in conditional handled incorrectly". Whenever we remove an instruction during optimization, we need to adjust instruction numbers (ip - instruction pointer) stored in all instructions. In addition to that, sp_instr_hpush_jump, which corresponds to DECLARE CONTINUE HANDLER needs adjustment for m_handler, which holds the number of instruction with the continue handler. In the bug report, a wrong ip stored in m_handler was pointing at FETCH, which resulted in an error message and abnormal SP termination. The fix is to just remove m_handler member from sp_instr_hpush_jump, as it's always points to the instruction next to the DECLARE statement itself (m_ip+1). mysql-test/r/sp.result: Test results fixed (Bug#12168) mysql-test/t/sp.test: A test case for Bug#12168 "'DECLARE CONTINUE HANDLER FOR NOT FOUND ...' in conditional handled incorrectly" sql/sp_head.cc: Remove m_handler (the number of continue handler instruction) as it always equal to m_ip+1 sql/sp_head.h: Remove m_handler (the number of continue handler instruction) as it always equal to m_ip+1
This commit is contained in:
@@ -3100,4 +3100,70 @@ end|
|
|||||||
call p_bug11247(10)|
|
call p_bug11247(10)|
|
||||||
drop function f_bug11247|
|
drop function f_bug11247|
|
||||||
drop procedure p_bug11247|
|
drop procedure p_bug11247|
|
||||||
|
drop procedure if exists bug12168|
|
||||||
|
drop table if exists t1, t2|
|
||||||
|
create table t1 (a int)|
|
||||||
|
insert into t1 values (1),(2),(3),(4)|
|
||||||
|
create table t2 (a int)|
|
||||||
|
create procedure bug12168(arg1 char(1))
|
||||||
|
begin
|
||||||
|
declare b, c integer;
|
||||||
|
if arg1 = 'a' then
|
||||||
|
begin
|
||||||
|
declare c1 cursor for select a from t1 where a % 2;
|
||||||
|
declare continue handler for not found set b = 1;
|
||||||
|
set b = 0;
|
||||||
|
open c1;
|
||||||
|
c1_repeat: repeat
|
||||||
|
fetch c1 into c;
|
||||||
|
if (b = 1) then
|
||||||
|
leave c1_repeat;
|
||||||
|
end if;
|
||||||
|
insert into t2 values (c);
|
||||||
|
until b = 1
|
||||||
|
end repeat;
|
||||||
|
end;
|
||||||
|
end if;
|
||||||
|
if arg1 = 'b' then
|
||||||
|
begin
|
||||||
|
declare c2 cursor for select a from t1 where not a % 2;
|
||||||
|
declare continue handler for not found set b = 1;
|
||||||
|
set b = 0;
|
||||||
|
open c2;
|
||||||
|
c2_repeat: repeat
|
||||||
|
fetch c2 into c;
|
||||||
|
if (b = 1) then
|
||||||
|
leave c2_repeat;
|
||||||
|
end if;
|
||||||
|
insert into t2 values (c);
|
||||||
|
until b = 1
|
||||||
|
end repeat;
|
||||||
|
end;
|
||||||
|
end if;
|
||||||
|
end|
|
||||||
|
call bug12168('a')|
|
||||||
|
select * from t2|
|
||||||
|
a
|
||||||
|
1
|
||||||
|
3
|
||||||
|
truncate t2|
|
||||||
|
call bug12168('b')|
|
||||||
|
select * from t2|
|
||||||
|
a
|
||||||
|
2
|
||||||
|
4
|
||||||
|
truncate t2|
|
||||||
|
call bug12168('a')|
|
||||||
|
select * from t2|
|
||||||
|
a
|
||||||
|
1
|
||||||
|
3
|
||||||
|
truncate t2|
|
||||||
|
call bug12168('b')|
|
||||||
|
select * from t2|
|
||||||
|
a
|
||||||
|
2
|
||||||
|
4
|
||||||
|
truncate t2|
|
||||||
|
drop procedure if exists bug12168|
|
||||||
drop table t1,t2;
|
drop table t1,t2;
|
||||||
|
@@ -3928,6 +3928,72 @@ end|
|
|||||||
call p_bug11247(10)|
|
call p_bug11247(10)|
|
||||||
drop function f_bug11247|
|
drop function f_bug11247|
|
||||||
drop procedure p_bug11247|
|
drop procedure p_bug11247|
|
||||||
|
#
|
||||||
|
# BUG#12168: "'DECLARE CONTINUE HANDLER FOR NOT FOUND ...' in conditional
|
||||||
|
# handled incorrectly"
|
||||||
|
#
|
||||||
|
--disable_warnings
|
||||||
|
drop procedure if exists bug12168|
|
||||||
|
drop table if exists t1, t2|
|
||||||
|
--enable_warnings
|
||||||
|
|
||||||
|
create table t1 (a int)|
|
||||||
|
insert into t1 values (1),(2),(3),(4)|
|
||||||
|
|
||||||
|
create table t2 (a int)|
|
||||||
|
|
||||||
|
create procedure bug12168(arg1 char(1))
|
||||||
|
begin
|
||||||
|
declare b, c integer;
|
||||||
|
if arg1 = 'a' then
|
||||||
|
begin
|
||||||
|
declare c1 cursor for select a from t1 where a % 2;
|
||||||
|
declare continue handler for not found set b = 1;
|
||||||
|
set b = 0;
|
||||||
|
open c1;
|
||||||
|
c1_repeat: repeat
|
||||||
|
fetch c1 into c;
|
||||||
|
if (b = 1) then
|
||||||
|
leave c1_repeat;
|
||||||
|
end if;
|
||||||
|
|
||||||
|
insert into t2 values (c);
|
||||||
|
until b = 1
|
||||||
|
end repeat;
|
||||||
|
end;
|
||||||
|
end if;
|
||||||
|
if arg1 = 'b' then
|
||||||
|
begin
|
||||||
|
declare c2 cursor for select a from t1 where not a % 2;
|
||||||
|
declare continue handler for not found set b = 1;
|
||||||
|
set b = 0;
|
||||||
|
open c2;
|
||||||
|
c2_repeat: repeat
|
||||||
|
fetch c2 into c;
|
||||||
|
if (b = 1) then
|
||||||
|
leave c2_repeat;
|
||||||
|
end if;
|
||||||
|
|
||||||
|
insert into t2 values (c);
|
||||||
|
until b = 1
|
||||||
|
end repeat;
|
||||||
|
end;
|
||||||
|
end if;
|
||||||
|
end|
|
||||||
|
|
||||||
|
call bug12168('a')|
|
||||||
|
select * from t2|
|
||||||
|
truncate t2|
|
||||||
|
call bug12168('b')|
|
||||||
|
select * from t2|
|
||||||
|
truncate t2|
|
||||||
|
call bug12168('a')|
|
||||||
|
select * from t2|
|
||||||
|
truncate t2|
|
||||||
|
call bug12168('b')|
|
||||||
|
select * from t2|
|
||||||
|
truncate t2|
|
||||||
|
drop procedure if exists bug12168|
|
||||||
|
|
||||||
#
|
#
|
||||||
# BUG#NNNN: New bug synopsis
|
# BUG#NNNN: New bug synopsis
|
||||||
|
@@ -1986,7 +1986,7 @@ sp_instr_hpush_jump::execute(THD *thd, uint *nextp)
|
|||||||
sp_cond_type_t *p;
|
sp_cond_type_t *p;
|
||||||
|
|
||||||
while ((p= li++))
|
while ((p= li++))
|
||||||
thd->spcont->push_handler(p, m_handler, m_type, m_frame);
|
thd->spcont->push_handler(p, m_ip+1, m_type, m_frame);
|
||||||
|
|
||||||
*nextp= m_dest;
|
*nextp= m_dest;
|
||||||
DBUG_RETURN(0);
|
DBUG_RETURN(0);
|
||||||
@@ -2003,7 +2003,7 @@ sp_instr_hpush_jump::print(String *str)
|
|||||||
str->append(" f=");
|
str->append(" f=");
|
||||||
str->qs_append(m_frame);
|
str->qs_append(m_frame);
|
||||||
str->append(" h=");
|
str->append(" h=");
|
||||||
str->qs_append(m_handler);
|
str->qs_append(m_ip+1);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint
|
uint
|
||||||
|
@@ -714,7 +714,6 @@ public:
|
|||||||
sp_instr_hpush_jump(uint ip, sp_pcontext *ctx, int htype, uint fp)
|
sp_instr_hpush_jump(uint ip, sp_pcontext *ctx, int htype, uint fp)
|
||||||
: sp_instr_jump(ip, ctx), m_type(htype), m_frame(fp)
|
: sp_instr_jump(ip, ctx), m_type(htype), m_frame(fp)
|
||||||
{
|
{
|
||||||
m_handler= ip+1;
|
|
||||||
m_cond.empty();
|
m_cond.empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -743,7 +742,6 @@ private:
|
|||||||
|
|
||||||
int m_type; // Handler type
|
int m_type; // Handler type
|
||||||
uint m_frame;
|
uint m_frame;
|
||||||
uint m_handler; // Location of handler
|
|
||||||
List<struct sp_cond_type> m_cond;
|
List<struct sp_cond_type> m_cond;
|
||||||
|
|
||||||
}; // class sp_instr_hpush_jump : public sp_instr_jump
|
}; // class sp_instr_hpush_jump : public sp_instr_jump
|
||||||
|
Reference in New Issue
Block a user