diff --git a/mysql-test/main/create_or_replace.result b/mysql-test/main/create_or_replace.result index 46645bb910f..142856d603f 100644 --- a/mysql-test/main/create_or_replace.result +++ b/mysql-test/main/create_or_replace.result @@ -800,6 +800,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 7d783710c17..c18c8b9eb7c 100644 --- a/mysql-test/main/create_or_replace.test +++ b/mysql-test/main/create_or_replace.test @@ -602,6 +602,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 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; } diff --git a/sql/table.h b/sql/table.h index b8087bd056d..72db38a82f2 100644 --- a/sql/table.h +++ b/sql/table.h @@ -41,6 +41,7 @@ class Item; /* Needed by ORDER */ typedef Item (*Item_ptr); +class Item_change_list; class Item_subselect; class Item_field; class GRANT_TABLE; @@ -1511,6 +1512,7 @@ public: bool get_fields_in_item_tree; /* Signal to fix_field */ List 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: