1
0
mirror of https://github.com/MariaDB/server.git synced 2025-07-29 05:21:33 +03:00

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, &current_arena);
  ...
  thd->restore_active_arena(thd->spcont->callers_arena, &current_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.
This commit is contained in:
Alexander Barkov
2018-11-13 18:59:38 +04:00
parent 45769429d9
commit 13cd4cf436
5 changed files with 106 additions and 11 deletions

View File

@ -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;