summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAleksey Midenkov <midenok@gmail.com>2023-01-18 16:52:09 +0300
committerAleksey Midenkov <midenok@gmail.com>2023-01-26 17:15:20 +0300
commitaaa043c56a6c6ef226dd34eaf861614ce56f9064 (patch)
tree3a1ede1dcb9616de9c3423462ee20cbfa6cc6ee6
parent059222ea882d26e3e59eebfb66b6e699fc50e975 (diff)
downloadmariadb-git-aaa043c56a6c6ef226dd34eaf861614ce56f9064.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().
-rw-r--r--mysql-test/main/create_or_replace.result6
-rw-r--r--mysql-test/main/create_or_replace.test6
-rw-r--r--sql/table.cc21
-rw-r--r--sql/table.h2
4 files changed, 35 insertions, 0 deletions
diff --git a/mysql-test/main/create_or_replace.result b/mysql-test/main/create_or_replace.result
index e5a998bb5bb..69fdc51b794 100644
--- a/mysql-test/main/create_or_replace.result
+++ b/mysql-test/main/create_or_replace.result
@@ -811,6 +811,12 @@ create or replace table t1 (old int);
show create trigger a;
ERROR HY000: Trigger does not exist
drop table t1;
+# PS: check thd->change_list sanity
+create table t1 (a int not null, b char(10) as (concat('', dayname('2020-02-02')))) collate utf8_bin;
+prepare stmt from 'insert into t1 (b) values (2)';
+create or replace table t1 (x int);
+drop table t1;
+drop prepare stmt;
# Foreign keys
create table t1 (x int primary key, y int) engine innodb;
create table t2 (x int references t1(x)) engine innodb;
diff --git a/mysql-test/main/create_or_replace.test b/mysql-test/main/create_or_replace.test
index d688efdf0a7..d055092bc70 100644
--- a/mysql-test/main/create_or_replace.test
+++ b/mysql-test/main/create_or_replace.test
@@ -620,6 +620,12 @@ create or replace table t1 (old int);
--error ER_TRG_DOES_NOT_EXIST
show create trigger a;
drop table t1;
+--echo # PS: check thd->change_list sanity
+create table t1 (a int not null, b char(10) as (concat('', dayname('2020-02-02')))) collate utf8_bin;
+prepare stmt from 'insert into t1 (b) values (2)';
+create or replace table t1 (x int);
+drop table t1;
+drop prepare stmt;
--echo # Foreign keys
--list_files $MYSQLD_DATADIR/test *sql*
create table t1 (x int primary key, y int) engine innodb;
diff --git a/sql/table.cc b/sql/table.cc
index 6200288d930..0d0d3102ce8 100644
--- a/sql/table.cc
+++ b/sql/table.cc
@@ -3732,6 +3732,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;
@@ -3752,7 +3759,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;
@@ -3760,6 +3772,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;
}
diff --git a/sql/table.h b/sql/table.h
index 196d1337efd..0c79bbe68c2 100644
--- a/sql/table.h
+++ b/sql/table.h
@@ -54,6 +54,7 @@
class Item; /* Needed by ORDER */
typedef Item (*Item_ptr);
+class Item_change_list;
class Item_subselect;
class Item_field;
class GRANT_TABLE;
@@ -1535,6 +1536,7 @@ public:
bool get_fields_in_item_tree; /* Signal to fix_field */
List<Virtual_column_info> vcol_refix_list;
private:
+ Item_change_list *saved_change_list;
bool m_needs_reopen;
bool created; /* For tmp tables. TRUE <=> tmp table was actually created.*/
public: