summaryrefslogtreecommitdiff
path: root/sql/table.cc
diff options
context:
space:
mode:
authorAleksey Midenkov <midenok@gmail.com>2022-08-31 11:55:05 +0300
committerAleksey Midenkov <midenok@gmail.com>2022-08-31 11:55:05 +0300
commit24fff8267d0722b20ca780cf144ce27560df1394 (patch)
tree4169f75f1a43abdb26292baa0dad477fd8937249 /sql/table.cc
parent2af15914cb3ae204d3b413995a96c7722ad60d93 (diff)
downloadmariadb-git-24fff8267d0722b20ca780cf144ce27560df1394.tar.gz
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().
Diffstat (limited to 'sql/table.cc')
-rw-r--r--sql/table.cc21
1 files changed, 21 insertions, 0 deletions
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<Virtual_column_info> 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;
}