summaryrefslogtreecommitdiff
path: root/sql/sp_head.cc
diff options
context:
space:
mode:
authorAlexander Barkov <bar@mariadb.com>2018-11-13 18:59:38 +0400
committerAlexander Barkov <bar@mariadb.com>2018-11-14 14:23:43 +0400
commit13cd4cf436c1f7c38c6d9dfd8077c98fc655336b (patch)
treebb442f9d539b4b68c4acb44ded4b0607bdbd398f /sql/sp_head.cc
parent45769429d9a3bfa37ead21aa0d36214f980a00d7 (diff)
downloadmariadb-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, &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.
Diffstat (limited to 'sql/sp_head.cc')
-rw-r--r--sql/sp_head.cc24
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, &current_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, &current_arena);
row->row_create_items(thd, &defs);
- thd->restore_active_arena(thd->spcont->callers_arena, &current_arena);
- }
+ thd->restore_active_arena(thd->spcont->callers_arena, &current_arena);
tmp.close(thd);
}
}