From 13cd4cf436c1f7c38c6d9dfd8077c98fc655336b Mon Sep 17 00:00:00 2001 From: Alexander Barkov Date: Tue, 13 Nov 2018 18:59:38 +0400 Subject: MDEV-17278 CURSOR FOR LOOP - ERROR: unexpected end of stream, read 0 bytes (SERVER CRASH) sp_instr_cursor_copy_struct::exec_core() created TYPELIBs on a wrong mem_root, the one which is initialized in sp_head::execute(), this code: /* init per-instruction memroot */ init_sql_alloc(&execute_mem_root, "per_instruction_memroot", MEM_ROOT_BLOCK_SIZE, 0, MYF(0)); This memory root cleans up after every sp_instr_xxx executed, so later sp_instr_cfetch::execute() tried to use already freed and trashed memory. Changing sp_instr_cursor_copy_struct::exec_core() to call tmp.export_structure() inside this block (not outside of it): thd->set_n_backup_active_arena(thd->spcont->callers_arena, ¤t_arena); ... thd->restore_active_arena(thd->spcont->callers_arena, ¤t_arena); So now TYPELIBs created by sp_instr_cursor_copy_struct::exec_core() are still available and valid when sp_instr_cfetch::execute() is called. They are freed at the end of dispatch_command() corresponding to the "CALL p1" statement. --- .../suite/compat/oracle/r/sp-cursor-rowtype.result | 25 ++++++++++++++++++++++ .../suite/compat/oracle/t/sp-cursor-rowtype.test | 23 ++++++++++++++++++++ 2 files changed, 48 insertions(+) (limited to 'mysql-test/suite/compat') diff --git a/mysql-test/suite/compat/oracle/r/sp-cursor-rowtype.result b/mysql-test/suite/compat/oracle/r/sp-cursor-rowtype.result index 093d52ba4e3..a60bbc38883 100644 --- a/mysql-test/suite/compat/oracle/r/sp-cursor-rowtype.result +++ b/mysql-test/suite/compat/oracle/r/sp-cursor-rowtype.result @@ -1479,3 +1479,28 @@ f1() 1 DROP FUNCTION f1; DROP TABLE t1; +# +# MDEV-17278 CURSOR FOR LOOP - ERROR: unexpected end of stream, read 0 bytes (SERVER CRASH) +# +CREATE TABLE t1 (id2 int, id int, en1 enum('aaa','a','b','c')); +INSERT INTO t1 VALUES(1,1,'aaa'),(2,2,'a'),(3,3,'b'),(4,4,'c'); +CREATE PROCEDURE p1() +AS +BEGIN +FOR rec IN (SELECT en1 FROM t1) +LOOP +SELECT rec.en1; +END LOOP; +END; +$$ +CALL p1(); +rec.en1 +aaa +rec.en1 +a +rec.en1 +b +rec.en1 +c +DROP PROCEDURE p1; +DROP TABLE t1; diff --git a/mysql-test/suite/compat/oracle/t/sp-cursor-rowtype.test b/mysql-test/suite/compat/oracle/t/sp-cursor-rowtype.test index 31e28d5c8de..ba0ca9b6a60 100644 --- a/mysql-test/suite/compat/oracle/t/sp-cursor-rowtype.test +++ b/mysql-test/suite/compat/oracle/t/sp-cursor-rowtype.test @@ -1572,3 +1572,26 @@ DELIMITER ;$$ SELECT f1(); DROP FUNCTION f1; DROP TABLE t1; + + +--echo # +--echo # MDEV-17278 CURSOR FOR LOOP - ERROR: unexpected end of stream, read 0 bytes (SERVER CRASH) +--echo # + +CREATE TABLE t1 (id2 int, id int, en1 enum('aaa','a','b','c')); +INSERT INTO t1 VALUES(1,1,'aaa'),(2,2,'a'),(3,3,'b'),(4,4,'c'); + +DELIMITER $$; +CREATE PROCEDURE p1() +AS +BEGIN + FOR rec IN (SELECT en1 FROM t1) + LOOP + SELECT rec.en1; + END LOOP; +END; +$$ +DELIMITER ;$$ +CALL p1(); +DROP PROCEDURE p1; +DROP TABLE t1; -- cgit v1.2.1