diff --git a/mysql-test/r/sp.result b/mysql-test/r/sp.result index c3b4039d12d..231ca329f3d 100644 --- a/mysql-test/r/sp.result +++ b/mysql-test/r/sp.result @@ -3868,5 +3868,22 @@ drop procedure bug10100pv| drop procedure bug10100pd| drop procedure bug10100pc| drop view v1| +drop procedure if exists bug13729| +drop table if exists t3| +create table t3 (s1 int, primary key (s1))| +insert into t3 values (1),(2)| +create procedure bug13729() +begin +declare continue handler for sqlexception select 55; +update t3 set s1 = 1; +end| +call bug13729()| +55 +55 +select * from t3| +s1 +1 +2 +drop procedure bug13729| drop table t3| drop table t1,t2; diff --git a/mysql-test/r/sp_trans.result b/mysql-test/r/sp_trans.result index bb742d0d3d7..8f2bd9985fc 100644 --- a/mysql-test/r/sp_trans.result +++ b/mysql-test/r/sp_trans.result @@ -369,3 +369,59 @@ drop procedure bug13825_0| drop procedure bug13825_1| drop procedure bug13825_2| drop table t1, t2| +drop table if exists t3| +drop procedure if exists bug14840_1| +drop procedure if exists bug14840_2| +create table t3 +( +x int, +y int, +primary key (x) +) engine=InnoDB| +create procedure bug14840_1() +begin +declare err int default 0; +declare continue handler for sqlexception +set err = err + 1; +start transaction; +update t3 set x = 1, y = 42 where x = 2; +insert into t3 values (3, 4711); +if err > 0 then +rollback; +else +commit; +end if; +select * from t3; +end| +create procedure bug14840_2() +begin +declare err int default 0; +declare continue handler for sqlexception +begin +set err = err + 1; +select err as 'Ping'; +end; +update t3 set x = 1, y = 42 where x = 2; +update t3 set x = 1, y = 42 where x = 2; +insert into t3 values (3, 4711); +select * from t3; +end| +insert into t3 values (1, 3), (2, 5)| +call bug14840_1()| +x y +1 3 +2 5 +delete from t3| +insert into t3 values (1, 3), (2, 5)| +call bug14840_2()| +Ping +1 +Ping +2 +x y +1 3 +2 5 +3 4711 +drop procedure bug14840_1| +drop procedure bug14840_2| +drop table t3| diff --git a/mysql-test/t/sp.test b/mysql-test/t/sp.test index def6afc000e..56b64532ab8 100644 --- a/mysql-test/t/sp.test +++ b/mysql-test/t/sp.test @@ -4773,6 +4773,29 @@ drop procedure bug10100pv| drop procedure bug10100pd| drop procedure bug10100pc| drop view v1| +# BUG#13729: Stored procedures: packet error after exception handled +# +--disable_warnings +drop procedure if exists bug13729| +drop table if exists t3| +--enable_warnings + +create table t3 (s1 int, primary key (s1))| + +insert into t3 values (1),(2)| + +create procedure bug13729() +begin + declare continue handler for sqlexception select 55; + + update t3 set s1 = 1; +end| + +call bug13729()| +# Used to cause Packets out of order +select * from t3| + +drop procedure bug13729| drop table t3| diff --git a/mysql-test/t/sp_trans.test b/mysql-test/t/sp_trans.test index d72eaf5dca0..308d4ad5c33 100644 --- a/mysql-test/t/sp_trans.test +++ b/mysql-test/t/sp_trans.test @@ -355,6 +355,70 @@ drop procedure bug13825_2| drop table t1, t2| +# +# BUG#14840: CONTINUE handler problem +# +--disable_warnings +drop table if exists t3| +drop procedure if exists bug14840_1| +drop procedure if exists bug14840_2| +--enable_warnings + +create table t3 +( + x int, + y int, + primary key (x) +) engine=InnoDB| + +# This used to hang the client since the insert returned with an +# error status (left over from the update) even though it succeeded, +# which caused the execution to end at that point. +create procedure bug14840_1() +begin + declare err int default 0; + declare continue handler for sqlexception + set err = err + 1; + + start transaction; + update t3 set x = 1, y = 42 where x = 2; + insert into t3 values (3, 4711); + if err > 0 then + rollback; + else + commit; + end if; + select * from t3; +end| + +# A simpler (non-transactional) case: insert at select should be done +create procedure bug14840_2() +begin + declare err int default 0; + declare continue handler for sqlexception + begin + set err = err + 1; + select err as 'Ping'; + end; + + update t3 set x = 1, y = 42 where x = 2; + update t3 set x = 1, y = 42 where x = 2; + insert into t3 values (3, 4711); + select * from t3; +end| + +insert into t3 values (1, 3), (2, 5)| +call bug14840_1()| + +delete from t3| +insert into t3 values (1, 3), (2, 5)| +call bug14840_2()| + +drop procedure bug14840_1| +drop procedure bug14840_2| +drop table t3| + + # # BUG#NNNN: New bug synopsis # diff --git a/sql/sql_update.cc b/sql/sql_update.cc index 039aa0f71fa..50f8e35a9e9 100644 --- a/sql/sql_update.cc +++ b/sql/sql_update.cc @@ -465,7 +465,12 @@ int mysql_update(THD *thd, } else if (!ignore || error != HA_ERR_FOUND_DUPP_KEY) { - thd->fatal_error(); // Force error message + /* + If (ignore && error == HA_ERR_FOUND_DUPP_KEY) we don't have to + do anything; otherwise... + */ + if (error != HA_ERR_FOUND_DUPP_KEY) + thd->fatal_error(); /* Other handler errors are fatal */ table->file->print_error(error,MYF(0)); error= 1; break; @@ -1259,7 +1264,12 @@ bool multi_update::send_data(List ¬_used_values) updated--; if (!ignore || error != HA_ERR_FOUND_DUPP_KEY) { - thd->fatal_error(); // Force error message + /* + If (ignore && error == HA_ERR_FOUND_DUPP_KEY) we don't have to + do anything; otherwise... + */ + if (error != HA_ERR_FOUND_DUPP_KEY) + thd->fatal_error(); /* Other handler errors are fatal */ table->file->print_error(error,MYF(0)); DBUG_RETURN(1); }