From 24fff8267d0722b20ca780cf144ce27560df1394 Mon Sep 17 00:00:00 2001 From: Aleksey Midenkov Date: Wed, 31 Aug 2022 11:55:05 +0300 Subject: MDEV-25292 gcol.gcol_bugfixes --ps fix Related to MDEV-24176. 1. vcol_fix_expr() generates new tree changes: Type_std_attributes::agg_item_set_converter() does change_item_tree(). The changes are allocated on expr_arena (via Vcol_expr_context as per MDEV-24176). 2. vcol_cleanup_expr() doesn't remove these changes (can be a bug of Type_std_attributes or per design). 3. Atomic CREATE OR REPLACE renames old table to backup (finalize_atomic_replace()). It does that via rename_table_and_triggers() and that closes table share and releases expr_arena root. Hence now we have Item corpses in thd->change_list. 4. PS cleanup phase tries to rollback thd->change_list and accesses already freed item corpses. The fix saves and restores change_list on vcol_fix_expr()/vcol_cleanup_expr(). --- sql/table.cc | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) (limited to 'sql/table.cc') diff --git a/sql/table.cc b/sql/table.cc index 5e17eb60b30..e1161fd98c3 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -3723,6 +3723,13 @@ bool TABLE::vcol_fix_expr(THD *thd) return false; } + if (!thd->Item_change_list::is_empty()) + { + DBUG_ASSERT(!saved_change_list); + saved_change_list= new Item_change_list; + thd->move_elements_to(saved_change_list); + } + Vcol_expr_context expr_ctx(thd, this); if (expr_ctx.init()) return true; @@ -3743,7 +3750,12 @@ error: bool TABLE::vcol_cleanup_expr(THD *thd) { if (vcol_refix_list.is_empty()) + { + DBUG_ASSERT(!saved_change_list); return false; + } + + thd->rollback_item_tree_changes(); List_iterator it(vcol_refix_list); bool result= false; @@ -3751,6 +3763,15 @@ bool TABLE::vcol_cleanup_expr(THD *thd) while (Virtual_column_info *vcol= it++) result|= vcol->cleanup_session_expr(); + if (saved_change_list) + { + DBUG_ASSERT(!vcol_refix_list.is_empty()); + DBUG_ASSERT(!saved_change_list->is_empty()); + saved_change_list->move_elements_to(thd); + delete saved_change_list; + saved_change_list= NULL; + } + DBUG_ASSERT(!result || thd->get_stmt_da()->is_error()); return result; } -- cgit v1.2.1