diff options
-rw-r--r-- | mysql-test/r/check.result | 34 | ||||
-rw-r--r-- | mysql-test/t/check.test | 21 | ||||
-rw-r--r-- | sql/item_cmpfunc.cc | 2 | ||||
-rw-r--r-- | sql/sql_class.h | 1 | ||||
-rw-r--r-- | sql/table.cc | 25 |
5 files changed, 82 insertions, 1 deletions
diff --git a/mysql-test/r/check.result b/mysql-test/r/check.result index 11ed734da0c..33f89735a15 100644 --- a/mysql-test/r/check.result +++ b/mysql-test/r/check.result @@ -102,3 +102,37 @@ Note 1091 Can't DROP CONSTRAINT `non_existing_constraint`; check that it exists insert into t1 () values (); ERROR 23000: CONSTRAINT `CONSTRAINT_1` failed for `test`.`t1` drop table t1; +# +# MDEV-25638: Assertion `!result' failed in convert_const_to_int +# +CREATE TABLE v0 ( v1 bigint CHECK ( v1 NOT IN ( 'x' , 'x111' ) ) ) ; +Warnings: +Warning 1292 Truncated incorrect DOUBLE value: 'x' +Warning 1292 Truncated incorrect DOUBLE value: 'x111' +select * from v0; +v1 +Warnings: +Warning 1292 Truncated incorrect DOUBLE value: 'x' +Warning 1292 Truncated incorrect DOUBLE value: 'x111' +select v1 from v0; +v1 +select * from v0; +v1 +prepare stmt from "select * from v0"; +execute stmt; +v1 +execute stmt; +v1 +flush tables; +select * from v0; +v1 +Warnings: +Warning 1292 Truncated incorrect DOUBLE value: 'x' +Warning 1292 Truncated incorrect DOUBLE value: 'x111' +select * from v0; +v1 +deallocate prepare stmt; +drop table v0; +# +# End of 10.2 test +# diff --git a/mysql-test/t/check.test b/mysql-test/t/check.test index 29587a9f623..9cefdee8418 100644 --- a/mysql-test/t/check.test +++ b/mysql-test/t/check.test @@ -124,3 +124,24 @@ alter table t1 drop constraint if exists non_existing_constraint; --error ER_CONSTRAINT_FAILED insert into t1 () values (); drop table t1; + +--echo # +--echo # MDEV-25638: Assertion `!result' failed in convert_const_to_int +--echo # + +CREATE TABLE v0 ( v1 bigint CHECK ( v1 NOT IN ( 'x' , 'x111' ) ) ) ; +select * from v0; +select v1 from v0; +select * from v0; +prepare stmt from "select * from v0"; +execute stmt; +execute stmt; +flush tables; +select * from v0; +select * from v0; +deallocate prepare stmt; +drop table v0; + +--echo # +--echo # End of 10.2 test +--echo # diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index 3a76982d80e..0907ec64232 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -471,7 +471,7 @@ static bool convert_const_to_int(THD *thd, Item_field *field_item, /* Restore the original field value. */ if (save_field_value) { - result= field->store(orig_field_val, TRUE); + result= field->store(orig_field_val, field_item->unsigned_flag); /* orig_field_val must be a valid value that can be restored back. */ DBUG_ASSERT(!result); } diff --git a/sql/sql_class.h b/sql/sql_class.h index d3d54e11671..6d9118cf0c4 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -1342,6 +1342,7 @@ public: change_list.move_elements_to(&to->change_list); } bool is_empty() { return change_list.is_empty(); } + void empty_change_list() { change_list.empty(); } }; diff --git a/sql/table.cc b/sql/table.cc index 1f7b6452303..662b2b0830a 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -1016,6 +1016,7 @@ bool parse_vcol_defs(THD *thd, MEM_ROOT *mem_root, TABLE *table, Virtual_column_info **check_constraint_ptr= table->check_constraints; sql_mode_t saved_mode= thd->variables.sql_mode; Query_arena backup_arena; + Item_change_list change_list_backup; Virtual_column_info *vcol= 0; StringBuffer<MAX_FIELD_WIDTH> expr_str; bool res= 1; @@ -1039,6 +1040,8 @@ bool parse_vcol_defs(THD *thd, MEM_ROOT *mem_root, TABLE *table, thd->set_n_backup_active_arena(table->expr_arena, &backup_arena); thd->stmt_arena= table->expr_arena; + // see following comment after end: label and near thd->empty_change_list() + thd->move_elements_to(&change_list_backup); thd->update_charset(&my_charset_utf8mb4_general_ci, table->s->table_charset); expr_str.append(&parse_vcol_keyword); thd->variables.sql_mode &= ~MODE_NO_BACKSLASH_ESCAPES; @@ -1167,6 +1170,27 @@ bool parse_vcol_defs(THD *thd, MEM_ROOT *mem_root, TABLE *table, end: thd->restore_active_arena(table->expr_arena, &backup_arena); thd->stmt_arena= backup_stmt_arena_ptr; + /* + A cycle of live of Items (expressions) in table is following: + + 1) Parsed in the query arena of the table + 2) Prepared with the permanent query arena of the table be active as a + runtime and stmt (permanent) arena (here is difference from usual + execution) + 3) usage (can be sorter of one query live (CREATE TABLE for example) or + longer then several queries (SELECT and using table cache), it is not a + problem because all fields are local to the table). + 4) cleanup and deallocate with the TABLE object + + With such live cycle we do not need to rollback temporary changes in + this item tree so can just remove them to avoid problem of a try to be + rollback with current query (if the cycle was sorter then the query it + will lead to changes in freed memory, in the other case it will + rollback changes after the first query which will not be redone for + the next query). + */ + thd->empty_change_list(); + change_list_backup.move_elements_to(thd); if (save_character_set_client) thd->update_charset(save_character_set_client, save_collation); thd->variables.sql_mode= saved_mode; @@ -3104,6 +3128,7 @@ enum open_frm_error open_table_from_share(THD *thd, TABLE_SHARE *share, outparam->s= share; outparam->db_stat= db_stat; outparam->write_row_record= NULL; + outparam->status= STATUS_NO_RECORD; if (share->incompatible_version && !(ha_open_flags & (HA_OPEN_FOR_ALTER | HA_OPEN_FOR_REPAIR))) |