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 /sql/sp_head.cc | |
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 'sql/sp_head.cc')
-rw-r--r-- | sql/sp_head.cc | 24 |
1 files changed, 13 insertions, 11 deletions
diff --git a/sql/sp_head.cc b/sql/sp_head.cc index c8b9576fe88..28411509adf 100644 --- a/sql/sp_head.cc +++ b/sql/sp_head.cc @@ -4475,19 +4475,21 @@ sp_instr_cursor_copy_struct::exec_core(THD *thd, uint *nextp) if (!(ret= tmp.open(thd))) { Row_definition_list defs; + /* + Create row elements on the caller arena. + It's the same arena that was used during sp_rcontext::create(). + This puts cursor%ROWTYPE elements on the same mem_root + where explicit ROW elements and table%ROWTYPE reside: + - tmp.export_structure() allocates new Spvar_definition instances + and their components (such as TYPELIBs). + - row->row_create_items() creates new Item_field instances. + They all are created on the same mem_root. + */ + Query_arena current_arena; + thd->set_n_backup_active_arena(thd->spcont->callers_arena, ¤t_arena); if (!(ret= tmp.export_structure(thd, &defs))) - { - /* - Create row elements on the caller arena. - It's the same arena that was used during sp_rcontext::create(). - This puts cursor%ROWTYPE elements on the same mem_root - where explicit ROW elements and table%ROWTYPE reside. - */ - Query_arena current_arena; - thd->set_n_backup_active_arena(thd->spcont->callers_arena, ¤t_arena); row->row_create_items(thd, &defs); - thd->restore_active_arena(thd->spcont->callers_arena, ¤t_arena); - } + thd->restore_active_arena(thd->spcont->callers_arena, ¤t_arena); tmp.close(thd); } } |