Description:
1. A procedure has a exception handler that does a SELECT.
2. Its body calls a procedure that does a SELECT of a function
3. that function raises an exception. (by SIGNAL or actual exception).
mysql client returns ERROR 2027 (HY000): Malformed packet
and looses connection to server.
JDBC returns
Exception: java.lang.StringIndexOutOfBoundsException
Message: offset 1, count 1, length
removing the select in the exception handler causes mysql server to crash instead of ERROR 2027 (HY000): Malformed packet.
mysql> delimiter ^
mysql> create database if not exists bug^
Query OK, 1 row affected, 1 warning (0.00 sec)
mysql> drop procedure if exists bug.proc1^
Query OK, 0 rows affected (0.00 sec)
mysql> drop procedure if exists bug.proc2^
Query OK, 0 rows affected (0.00 sec)
mysql> drop function if exists bug.test^
Query OK, 0 rows affected (0.00 sec)
mysql>
mysql> create procedure bug.proc1()
-> begin
-> declare exit handler for sqlexception
-> begin
-> select "in exception handler"; /*removing this causes mysql server to crash instead of ERROR 2027 (HY000): Malformed packet*/
-> end;
-> call bug.proc2();
-> end;
-> ^
Query OK, 0 rows affected (0.00 sec)
mysql> create procedure bug.proc2()
-> begin
-> select bug.test(); /* doing the SIGNAL SQLSTATE '45000' here instead in the callee, removes ERROR 2027 (HY000): Malformed packet */
-> end;
-> ^
Query OK, 0 rows affected (0.00 sec)
mysql> create function bug.test() returns text
-> begin
-> SIGNAL SQLSTATE '45000'; /* or a real sql exception */
-> return "returned from bug.test function";
-> end;
-> ^
Query OK, 0 rows affected (0.00 sec)
mysql> call bug.proc1();
-> ^
ERROR 2027 (HY000): Malformed packet
mysql> select version()^
ERROR 2013 (HY000): Lost connection to MySQL server during query
mysql> select version()^
ERROR 2006 (HY000): MySQL server has gone away
No connection. Trying to reconnect...
Connection id: 51
Current database: *** NONE ***
+-----------+
| version() |
+-----------+
| 5.7.26 |
+-----------+
1 row in set (0.01 sec)
mysql>
How to repeat:
delimiter ^
create database if not exists bug^
drop procedure if exists bug.proc1^
drop procedure if exists bug.proc2^
drop function if exists bug.test^
create procedure bug.proc1()
begin
declare exit handler for sqlexception
begin
select "in exception handler"; /*removing this causes mysql server to crash instead of ERROR 2027 (HY000): Malformed packet*/
end;
call bug.proc2();
end;
^
create procedure bug.proc2()
begin
select bug.test(); /* doing the SIGNAL SQLSTATE '45000' here instead in the callee, removes ERROR 2027 (HY000): Malformed packet */
end;
^
create function bug.test() returns text
begin
SIGNAL SQLSTATE '45000';
return "returned from bug.test function";
end;
^
call bug.proc1();
^
Suggested fix:
shouldn't do that!
The result of
call bug.proc1();
should the result set from the select in the exception handler;