diff options
author | Alexander Barkov <bar@mariadb.com> | 2018-11-13 18:59:38 +0400 |
---|---|---|
committer | Alexander Barkov <bar@mariadb.com> | 2018-11-14 14:23:43 +0400 |
commit | 13cd4cf436c1f7c38c6d9dfd8077c98fc655336b (patch) | |
tree | bb442f9d539b4b68c4acb44ded4b0607bdbd398f /mysql-test/main | |
parent | 45769429d9a3bfa37ead21aa0d36214f980a00d7 (diff) | |
download | mariadb-git-13cd4cf436c1f7c38c6d9dfd8077c98fc655336b.tar.gz |
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.
Diffstat (limited to 'mysql-test/main')
-rw-r--r-- | mysql-test/main/sp-cursor.result | 24 | ||||
-rw-r--r-- | mysql-test/main/sp-cursor.test | 21 |
2 files changed, 45 insertions, 0 deletions
diff --git a/mysql-test/main/sp-cursor.result b/mysql-test/main/sp-cursor.result index f1dd8ed5eaa..42952be16e2 100644 --- a/mysql-test/main/sp-cursor.result +++ b/mysql-test/main/sp-cursor.result @@ -713,3 +713,27 @@ END; $$ CALL p1; DROP PROCEDURE p1; +# +# 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() +BEGIN +FOR rec IN (SELECT en1 FROM t1) +DO +SELECT rec.en1; +END FOR; +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/main/sp-cursor.test b/mysql-test/main/sp-cursor.test index 735514ff376..97483ef9caf 100644 --- a/mysql-test/main/sp-cursor.test +++ b/mysql-test/main/sp-cursor.test @@ -723,3 +723,24 @@ $$ DELIMITER ;$$ CALL p1; DROP PROCEDURE p1; + + +--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() +BEGIN + FOR rec IN (SELECT en1 FROM t1) + DO + SELECT rec.en1; + END FOR; +END; +$$ +DELIMITER ;$$ +CALL p1(); +DROP PROCEDURE p1; +DROP TABLE t1; |