From 276bd123b7b9cf516c8ddd7a28952f6e1275aa8c Mon Sep 17 00:00:00 2001 From: unknown <konstantin@mysql.com> Date: Fri, 19 Aug 2005 17:03:21 +0400 Subject: [PATCH] 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 --- mysql-test/r/sp.result | 66 ++++++++++++++++++++++++++++++++++++++++++ mysql-test/t/sp.test | 66 ++++++++++++++++++++++++++++++++++++++++++ sql/sp_head.cc | 4 +-- sql/sp_head.h | 2 -- 4 files changed, 134 insertions(+), 4 deletions(-) diff --git a/mysql-test/r/sp.result b/mysql-test/r/sp.result index 78bf22d0b2..d1d4103547 100644 --- a/mysql-test/r/sp.result +++ b/mysql-test/r/sp.result @@ -3100,4 +3100,70 @@ end| call p_bug11247(10)| drop function f_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; diff --git a/mysql-test/t/sp.test b/mysql-test/t/sp.test index cde5d3922a..f3e7c3e07a 100644 --- a/mysql-test/t/sp.test +++ b/mysql-test/t/sp.test @@ -3928,6 +3928,72 @@ end| call p_bug11247(10)| drop function f_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 diff --git a/sql/sp_head.cc b/sql/sp_head.cc index 26d76804fc..f119ef1ec2 100644 --- a/sql/sp_head.cc +++ b/sql/sp_head.cc @@ -1986,7 +1986,7 @@ sp_instr_hpush_jump::execute(THD *thd, uint *nextp) sp_cond_type_t *p; 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; DBUG_RETURN(0); @@ -2003,7 +2003,7 @@ sp_instr_hpush_jump::print(String *str) str->append(" f="); str->qs_append(m_frame); str->append(" h="); - str->qs_append(m_handler); + str->qs_append(m_ip+1); } uint diff --git a/sql/sp_head.h b/sql/sp_head.h index e15b68be15..8ae7834eb2 100644 --- a/sql/sp_head.h +++ b/sql/sp_head.h @@ -714,7 +714,6 @@ public: sp_instr_hpush_jump(uint ip, sp_pcontext *ctx, int htype, uint fp) : sp_instr_jump(ip, ctx), m_type(htype), m_frame(fp) { - m_handler= ip+1; m_cond.empty(); } @@ -743,7 +742,6 @@ private: int m_type; // Handler type uint m_frame; - uint m_handler; // Location of handler List<struct sp_cond_type> m_cond; }; // class sp_instr_hpush_jump : public sp_instr_jump -- 2.30.9