Commit 0fc49ccf authored by Dmitry Shulga's avatar Dmitry Shulga

Fixed bug#54375 - Error in stored procedure leaves connection

in different default schema.

In strict mode, when data truncation or conversion happens,
THD::killed is set to THD::KILL_BAD_DATA.

This is abuse of KILL mechanism to guarantee that execution
of statement is aborted.

The stored procedures execution, on the other hand,
upon detection that a connection was killed, would
terminate immediately, without trying to restore the caller's
context, in particular, restore the caller's current schema.

The fix is, when terminating a stored procedure execution,
to only bypass cleanup if the entire connection was killed,
not in case of other forms of KILL.
parent ce3a7f4b
...@@ -73,4 +73,40 @@ CALL p1 (); ...@@ -73,4 +73,40 @@ CALL p1 ();
ERROR HY000: Trigger does not exist ERROR HY000: Trigger does not exist
DROP TABLE t1; DROP TABLE t1;
DROP PROCEDURE p1; DROP PROCEDURE p1;
#
# Bug#54375: Error in stored procedure leaves connection
# in different default schema
#
SET @@SQL_MODE = 'STRICT_ALL_TABLES';
DROP DATABASE IF EXISTS db1;
CREATE DATABASE db1;
USE db1;
DROP TABLE IF EXISTS t1;
CREATE TABLE t1 (c1 int NOT NULL PRIMARY KEY);
INSERT INTO t1 VALUES (1);
CREATE FUNCTION f1 (
some_value int
)
RETURNS smallint
DETERMINISTIC
BEGIN
INSERT INTO t1 SET c1 = some_value;
RETURN(LAST_INSERT_ID());
END$$
DROP DATABASE IF EXISTS db2;
CREATE DATABASE db2;
USE db2;
SELECT DATABASE();
DATABASE()
db2
SELECT db1.f1(1);
ERROR 23000: Duplicate entry '1' for key 'PRIMARY'
SELECT DATABASE();
DATABASE()
db2
USE test;
DROP FUNCTION db1.f1;
DROP TABLE db1.t1;
DROP DATABASE db1;
DROP DATABASE db2;
End of 5.1 tests End of 5.1 tests
...@@ -101,4 +101,41 @@ CALL p1 (); ...@@ -101,4 +101,41 @@ CALL p1 ();
DROP TABLE t1; DROP TABLE t1;
DROP PROCEDURE p1; DROP PROCEDURE p1;
--echo #
--echo # Bug#54375: Error in stored procedure leaves connection
--echo # in different default schema
--echo #
--disable_warnings
SET @@SQL_MODE = 'STRICT_ALL_TABLES';
DROP DATABASE IF EXISTS db1;
CREATE DATABASE db1;
USE db1;
DROP TABLE IF EXISTS t1;
CREATE TABLE t1 (c1 int NOT NULL PRIMARY KEY);
INSERT INTO t1 VALUES (1);
DELIMITER $$;
CREATE FUNCTION f1 (
some_value int
)
RETURNS smallint
DETERMINISTIC
BEGIN
INSERT INTO t1 SET c1 = some_value;
RETURN(LAST_INSERT_ID());
END$$
DELIMITER ;$$
DROP DATABASE IF EXISTS db2;
CREATE DATABASE db2;
--enable_warnings
USE db2;
SELECT DATABASE();
--error ER_DUP_ENTRY
SELECT db1.f1(1);
SELECT DATABASE();
USE test;
DROP FUNCTION db1.f1;
DROP TABLE db1.t1;
DROP DATABASE db1;
DROP DATABASE db2;
--echo End of 5.1 tests --echo End of 5.1 tests
...@@ -1372,7 +1372,7 @@ sp_head::execute(THD *thd) ...@@ -1372,7 +1372,7 @@ sp_head::execute(THD *thd)
If the DB has changed, the pointer has changed too, but the If the DB has changed, the pointer has changed too, but the
original thd->db will then have been freed original thd->db will then have been freed
*/ */
if (cur_db_changed && !thd->killed) if (cur_db_changed && thd->killed != THD::KILL_CONNECTION)
{ {
/* /*
Force switching back to the saved current database, because it may be Force switching back to the saved current database, because it may be
......
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