From 66832e3a6474967da7dcf22cd1c5e9368b699ef1 Mon Sep 17 00:00:00 2001 From: Daniel Black Date: Thu, 14 Apr 2022 13:28:51 +1000 Subject: [PATCH 01/11] mtr: extend gdb backtace info bt full - to include args and locals. set print sevenbit on - it is more useful to be able to see the exact bytes (in case something is dumped as a string and not hexadecimal digits) set print static-members off - there are many interesting (non-const) static members set frame-arguments all - even non-printables are useful to see. Let's make our bb logs give a little bit more detail on those hard to reproduce bugs. Tests on rhel7's gdb-7.6.1-120.el7 --- mysql-test/lib/My/CoreDump.pm | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/mysql-test/lib/My/CoreDump.pm b/mysql-test/lib/My/CoreDump.pm index 1ba94223b68..9d1dd27cf88 100644 --- a/mysql-test/lib/My/CoreDump.pm +++ b/mysql-test/lib/My/CoreDump.pm @@ -78,7 +78,10 @@ sub _gdb { my ($tmp, $tmp_name) = tempfile(); print $tmp "bt\n", - "thread apply all bt\n", + "set print sevenbit on\n", + "set print static-members off\n", + "set print frame-arguments all\n", + "thread apply all bt full\n", "quit\n"; close $tmp or die "Error closing $tmp_name: $!"; From c05fd700970ad45735caed3a6f9930d4ce19a3bd Mon Sep 17 00:00:00 2001 From: Alexander Barkov Date: Thu, 14 Apr 2022 16:11:04 +0400 Subject: [PATCH 02/11] MDEV-26323 use-after-poison issue of MariaDB server --- mysql-test/r/plugin.result | 9 +++++++++ mysql-test/t/plugin.test | 17 +++++++++++++++++ sql/sql_plugin.cc | 3 ++- 3 files changed, 28 insertions(+), 1 deletion(-) diff --git a/mysql-test/r/plugin.result b/mysql-test/r/plugin.result index 04931001901..6020747aec4 100644 --- a/mysql-test/r/plugin.result +++ b/mysql-test/r/plugin.result @@ -353,4 +353,13 @@ select * from mysql.plugin WHERE name='unexisting_plugin'; name dl UNINSTALL PLUGIN unexisting_plugin; ERROR 42000: PLUGIN unexisting_plugin does not exist +# +# MDEV-26323 use-after-poison issue of MariaDB server +# +INSTALL PLUGIN DEALLOCATE SONAME ''; +ERROR HY000: Can't open shared library '.so' +INSTALL PLUGIN DEALLOCATE SONAME 'x'; +ERROR HY000: Can't open shared library 'x.so' +INSTALL PLUGIN DEALLOCATE SONAME 'xx'; +ERROR HY000: Can't open shared library 'xx.so' # End of 10.2 tests diff --git a/mysql-test/t/plugin.test b/mysql-test/t/plugin.test index d2e828b2589..5ac616a1310 100644 --- a/mysql-test/t/plugin.test +++ b/mysql-test/t/plugin.test @@ -295,4 +295,21 @@ select * from mysql.plugin WHERE name='unexisting_plugin'; --error ER_SP_DOES_NOT_EXIST UNINSTALL PLUGIN unexisting_plugin; +--echo # +--echo # MDEV-26323 use-after-poison issue of MariaDB server +--echo # + +--replace_regex /library '.*[\\/].(dll|so)' [(].*[)]/library '.so'/ +--error ER_CANT_OPEN_LIBRARY +INSTALL PLUGIN DEALLOCATE SONAME ''; + +--replace_regex /library '.*[\\/]x.(dll|so)' [(].*[)]/library 'x.so'/ +--error ER_CANT_OPEN_LIBRARY +INSTALL PLUGIN DEALLOCATE SONAME 'x'; + +--replace_regex /library '.*[\\/]xx.(dll|so)' [(].*[)]/library 'xx.so'/ +--error ER_CANT_OPEN_LIBRARY +INSTALL PLUGIN DEALLOCATE SONAME 'xx'; + + --echo # End of 10.2 tests diff --git a/sql/sql_plugin.cc b/sql/sql_plugin.cc index 97bc17042b2..75631faccaa 100644 --- a/sql/sql_plugin.cc +++ b/sql/sql_plugin.cc @@ -372,7 +372,8 @@ bool check_valid_path(const char *path, size_t len) static void fix_dl_name(MEM_ROOT *root, LEX_STRING *dl) { const size_t so_ext_len= sizeof(SO_EXT) - 1; - if (my_strcasecmp(&my_charset_latin1, dl->str + dl->length - so_ext_len, + if (dl->length < so_ext_len || + my_strcasecmp(&my_charset_latin1, dl->str + dl->length - so_ext_len, SO_EXT)) { char *s= (char*)alloc_root(root, dl->length + so_ext_len + 1); From b5e16a6e0381b28b598da80b414168ce9a5016e5 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Wed, 13 Apr 2022 22:48:46 +0200 Subject: [PATCH 03/11] MDEV-26061 MariaDB server crash at Field::set_default * Item_default_value::fix_fields creates a copy of its argument's field. * Field::default_value is changed when its expression is prepared in unpack_vcol_info_from_frm() This means we must unpack any vcol expression that includes DEFAULT(x) strictly after unpacking x->default_value. To avoid building and solving this dependency graph on every table open, we update Item_default_value::field->default_value after all vcols are unpacked and fixed. --- mysql-test/r/check_constraint.result | 15 +++++++++++++++ mysql-test/t/check_constraint.test | 17 +++++++++++++++++ sql/item.cc | 6 ++++++ sql/item.h | 1 + 4 files changed, 39 insertions(+) diff --git a/mysql-test/r/check_constraint.result b/mysql-test/r/check_constraint.result index 3511af84166..988e49b274d 100644 --- a/mysql-test/r/check_constraint.result +++ b/mysql-test/r/check_constraint.result @@ -235,3 +235,18 @@ a b insert t1 (b) values (1); ERROR 23000: CONSTRAINT `CONSTRAINT_1` failed for `test`.`t1` drop table t1; +# +# MDEV-26061 MariaDB server crash at Field::set_default +# +create table t1 (v2 date check (v1 like default (v1)), v1 date default (from_days ('x'))); +Warnings: +Warning 1292 Truncated incorrect INTEGER value: 'x' +insert ignore into t1 values ( 'x' , 'x' ) ; +Warnings: +Warning 1265 Data truncated for column 'v2' at row 1 +Warning 1265 Data truncated for column 'v1' at row 1 +Warning 1292 Truncated incorrect INTEGER value: 'x' +drop table t1; +# +# End of 10.2 tests +# diff --git a/mysql-test/t/check_constraint.test b/mysql-test/t/check_constraint.test index 93538fd1666..05145d9d434 100644 --- a/mysql-test/t/check_constraint.test +++ b/mysql-test/t/check_constraint.test @@ -176,3 +176,20 @@ select * from t1 where a is null; --error ER_CONSTRAINT_FAILED insert t1 (b) values (1); drop table t1; + +--echo # +--echo # MDEV-26061 MariaDB server crash at Field::set_default +--echo # + +create table t1 (v2 date check (v1 like default (v1)), v1 date default (from_days ('x'))); +insert ignore into t1 values ( 'x' , 'x' ) ; +drop table t1; + +--echo # +--echo # End of 10.2 tests +--echo # + +# 10.3 test +#create table t1 (d timestamp check (default (d) is true)) as select 1; +#show create table t1; +#drop table t1; diff --git a/sql/item.cc b/sql/item.cc index 6e5d2ee45a2..cf824039b56 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -8976,6 +8976,12 @@ bool Item_default_value::eq(const Item *item, bool binary_cmp) const } +bool Item_default_value::check_field_expression_processor(void *) +{ + field->default_value= ((Item_field *)(arg->real_item()))->field->default_value; + return 0; +} + bool Item_default_value::fix_fields(THD *thd, Item **items) { Item *real_arg; diff --git a/sql/item.h b/sql/item.h index 290ff11a0f8..0823f064af8 100644 --- a/sql/item.h +++ b/sql/item.h @@ -5507,6 +5507,7 @@ public: Item *get_tmp_table_item(THD *thd) { return this; } Item_field *field_for_view_update() { return 0; } bool update_vcol_processor(void *arg) { return 0; } + bool check_field_expression_processor(void *arg); bool check_func_default_processor(void *arg) { return true; } bool enchant_default_with_arg_processor(void *arg); From cc08c43ed642ce8f5fc2c35bd1e917f220987c66 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Thu, 14 Apr 2022 10:16:54 +0200 Subject: [PATCH 04/11] cleanup: remove Item_default_value::cached_field --- sql/item.cc | 7 ++----- sql/item.h | 9 ++++----- 2 files changed, 6 insertions(+), 10 deletions(-) diff --git a/sql/item.cc b/sql/item.cc index cf824039b56..502ca799181 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -1055,8 +1055,7 @@ bool Item_field::check_field_expression_processor(void *arg) (!field->vcol_info && !org_field->vcol_info)) && field->field_index >= org_field->field_index)) { - my_error(ER_EXPRESSION_REFERS_TO_UNINIT_FIELD, - MYF(0), + my_error(ER_EXPRESSION_REFERS_TO_UNINIT_FIELD, MYF(0), org_field->field_name, field->field_name); return 1; } @@ -9024,7 +9023,6 @@ bool Item_default_value::fix_fields(THD *thd, Item **items) } if (!(def_field= (Field*) thd->alloc(field_arg->field->size_of()))) goto error; - cached_field= def_field; memcpy((void *)def_field, (void *)field_arg->field, field_arg->field->size_of()); def_field->reset_fields(); @@ -9063,8 +9061,7 @@ bool Item_default_value::enchant_default_with_arg_processor(void *proc_arg) void Item_default_value::cleanup() { - delete cached_field; // Free cached blob data - cached_field= 0; + delete field; // Free cached blob data Item_field::cleanup(); } diff --git a/sql/item.h b/sql/item.h index 0823f064af8..35454c69734 100644 --- a/sql/item.h +++ b/sql/item.h @@ -5455,18 +5455,17 @@ protected: Item_default_value(THD *thd, Name_resolution_context *context_arg, Item *a) :Item_field(thd, context_arg, (const char *)NULL, (const char *)NULL, (const char *)NULL), - arg(a), cached_field(NULL) {} + arg(a) {} public: Item *arg; - Field *cached_field; Item_default_value(THD *thd, Name_resolution_context *context_arg) :Item_field(thd, context_arg, (const char *)NULL, (const char *)NULL, (const char *)NULL), - arg(NULL), cached_field(NULL) {} + arg(NULL) {} Item_default_value(THD *thd, Name_resolution_context *context_arg, Field *a) :Item_field(thd, context_arg, (const char *)NULL, (const char *)NULL, (const char *)NULL), - arg(NULL),cached_field(NULL) {} + arg(NULL) {} enum Type type() const { return DEFAULT_VALUE_ITEM; } bool vcol_assignment_allowed_value() const { return true; } bool eq(const Item *item, bool binary_cmp) const; @@ -5498,7 +5497,7 @@ public: return false; } table_map used_tables() const; - virtual void update_used_tables() + void update_used_tables() { if (field && field->default_value) field->default_value->expr->update_used_tables(); From 4681b6f2d8c82b4ec5cf115e83698251963d80d5 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Thu, 14 Apr 2022 21:45:20 +0200 Subject: [PATCH 05/11] MDEV-26281 ASAN use-after-poison when complex conversion is involved in blob the bug was that in_vector array in Item_func_in was allocated in the statement arena, not in the table->expr_arena. revert part of the 5acd391e8b2d. Instead, change the arena correctly in fix_all_session_vcol_exprs(). Remove TABLE_ARENA, that was introduced in 5acd391e8b2d to force item tree changes to be rolled back (because they were allocated in the wrong arena and didn't persist. now they do) --- mysql-test/suite/vcol/r/wrong_arena.result | 19 ++++++++++++++++++ mysql-test/suite/vcol/t/wrong_arena.test | 23 ++++++++++++++++------ sql/sql_base.cc | 9 +++------ sql/sql_class.h | 5 ++--- sql/table.cc | 15 ++------------ 5 files changed, 43 insertions(+), 28 deletions(-) diff --git a/mysql-test/suite/vcol/r/wrong_arena.result b/mysql-test/suite/vcol/r/wrong_arena.result index c105a069b7f..8edcd5c881f 100644 --- a/mysql-test/suite/vcol/r/wrong_arena.result +++ b/mysql-test/suite/vcol/r/wrong_arena.result @@ -1,3 +1,6 @@ +# +# MDEV-9690 concurrent queries with virtual columns crash in temporal code +# create table t1 (a datetime, # get_datetime_value b int as (a > 1), # Arg_comparator @@ -59,6 +62,9 @@ a b Warnings: Warning 1292 Incorrect datetime value: '1' drop table t1; +# +# MDEV-13435 Crash when selecting virtual columns generated using JSON functions +# create table t1 ( id int not null , js varchar(1000) not null, @@ -68,3 +74,16 @@ select * from t1; id js t 0 {"default" : {"start": "00:00:00", "end":"23:59:50"}} NULL drop table t1; +# +# MDEV-26281 ASAN use-after-poison when complex conversion is involved in blob +# +create table t1 (v2 blob as ('a' is null), a1 int, a char(1) as (cast(a1 in (0,current_user() is null) as char(16777216) ))); +insert ignore into t1 values ('x','x',v2) ; +Warnings: +Warning 1906 The value specified for generated column 'v2' in table 't1' has been ignored +Warning 1366 Incorrect integer value: 'x' for column `test`.`t1`.`a1` at row 1 +Warning 1906 The value specified for generated column 'a' in table 't1' has been ignored +drop table t1; +# +# End of 10.2 tests +# diff --git a/mysql-test/suite/vcol/t/wrong_arena.test b/mysql-test/suite/vcol/t/wrong_arena.test index 8ac1af5c36b..296cb68f5c0 100644 --- a/mysql-test/suite/vcol/t/wrong_arena.test +++ b/mysql-test/suite/vcol/t/wrong_arena.test @@ -3,9 +3,9 @@ # not in the TABLE::expr_arena. # -# -# MDEV-9690 concurrent queries with virtual columns crash in temporal code -# +--echo # +--echo # MDEV-9690 concurrent queries with virtual columns crash in temporal code +--echo # create table t1 (a datetime, # get_datetime_value b int as (a > 1), # Arg_comparator @@ -40,9 +40,9 @@ connection default; select * from t1; drop table t1; -# -# MDEV-13435 Crash when selecting virtual columns generated using JSON functions -# +--echo # +--echo # MDEV-13435 Crash when selecting virtual columns generated using JSON functions +--echo # create table t1 ( id int not null , js varchar(1000) not null, @@ -50,3 +50,14 @@ create table t1 ( insert into t1(id,js) values (0, '{"default" : {"start": "00:00:00", "end":"23:59:50"}}'); select * from t1; drop table t1; + +--echo # +--echo # MDEV-26281 ASAN use-after-poison when complex conversion is involved in blob +--echo # +create table t1 (v2 blob as ('a' is null), a1 int, a char(1) as (cast(a1 in (0,current_user() is null) as char(16777216) ))); +insert ignore into t1 values ('x','x',v2) ; +drop table t1; + +--echo # +--echo # End of 10.2 tests +--echo # diff --git a/sql/sql_base.cc b/sql/sql_base.cc index a6c07600591..ce6fd4cbe64 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -5010,16 +5010,13 @@ static bool fix_all_session_vcol_exprs(THD *thd, TABLE_LIST *tables) if (!table->placeholder() && t->s->vcols_need_refixing && table->lock_type >= TL_WRITE_ALLOW_WRITE) { - Query_arena *stmt_backup= thd->stmt_arena; - if (thd->stmt_arena->is_conventional()) - thd->stmt_arena= t->expr_arena; + Query_arena backup_arena; + thd->set_n_backup_active_arena(t->expr_arena, &backup_arena); if (table->security_ctx) thd->security_ctx= table->security_ctx; - error= t->fix_vcol_exprs(thd); - thd->security_ctx= save_security_ctx; - thd->stmt_arena= stmt_backup; + thd->restore_active_arena(t->expr_arena, &backup_arena); } } DBUG_RETURN(error); diff --git a/sql/sql_class.h b/sql/sql_class.h index d3d54e11671..54c9d4ac870 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -967,7 +967,7 @@ public: /* We build without RTTI, so dynamic_cast can't be used. */ enum Type { - STATEMENT, PREPARED_STATEMENT, STORED_PROCEDURE, TABLE_ARENA + STATEMENT, PREPARED_STATEMENT, STORED_PROCEDURE }; Query_arena(MEM_ROOT *mem_root_arg, enum enum_state state_arg) : @@ -3728,8 +3728,7 @@ public: bool is_item_tree_change_register_required() { - return !stmt_arena->is_conventional() - || stmt_arena->type() == Query_arena::TABLE_ARENA; + return !stmt_arena->is_conventional(); } void change_item_tree(Item **place, Item *new_value) diff --git a/sql/table.cc b/sql/table.cc index 1f7b6452303..81116cb19cc 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -47,17 +47,6 @@ #define MYSQL57_GENERATED_FIELD 128 #define MYSQL57_GCOL_HEADER_SIZE 4 -class Table_arena: public Query_arena -{ -public: - Table_arena(MEM_ROOT *mem_root, enum enum_state state_arg) : - Query_arena(mem_root, state_arg){} - virtual Type type() const - { - return TABLE_ARENA; - } -}; - static Virtual_column_info * unpack_vcol_info_from_frm(THD *, MEM_ROOT *, TABLE *, String *, Virtual_column_info **, bool *); static bool check_vcol_forward_refs(Field *, Virtual_column_info *); @@ -1031,8 +1020,8 @@ bool parse_vcol_defs(THD *thd, MEM_ROOT *mem_root, TABLE *table, We need to use CONVENTIONAL_EXECUTION here to ensure that any new items created by fix_fields() are not reverted. */ - table->expr_arena= new (alloc_root(mem_root, sizeof(Table_arena))) - Table_arena(mem_root, + table->expr_arena= new (alloc_root(mem_root, sizeof(Query_arena))) + Query_arena(mem_root, Query_arena::STMT_CONVENTIONAL_EXECUTION); if (!table->expr_arena) DBUG_RETURN(1); From c274853c0797801de0398699d60c8579c45d1f61 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Thu, 14 Apr 2022 21:54:19 +0200 Subject: [PATCH 06/11] MDEV-25638 Assertion `!result' failed in convert_const_to_int When fixing vcols, fix_fields might call convert_const_to_int(). And that will try to read the field value (from record[0]). Mark the table as having no data to prevent that, because record[0] is not initialized yet. --- mysql-test/r/check_constraint.result | 31 ++++++++++++++++++++++++++++ mysql-test/t/check_constraint.test | 19 +++++++++++++++++ sql/table.cc | 1 + 3 files changed, 51 insertions(+) diff --git a/mysql-test/r/check_constraint.result b/mysql-test/r/check_constraint.result index 988e49b274d..345441a71eb 100644 --- a/mysql-test/r/check_constraint.result +++ b/mysql-test/r/check_constraint.result @@ -236,6 +236,37 @@ insert t1 (b) values (1); ERROR 23000: CONSTRAINT `CONSTRAINT_1` failed for `test`.`t1` drop table t1; # +# MDEV-25638 Assertion `!result' failed in convert_const_to_int +# +create table t1 (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 t1; +v1 +Warnings: +Warning 1292 Truncated incorrect DOUBLE value: 'x' +Warning 1292 Truncated incorrect DOUBLE value: 'x111' +select v1 from t1; +v1 +select * from t1; +v1 +prepare stmt from "select * from t1"; +execute stmt; +v1 +execute stmt; +v1 +flush tables; +select * from t1; +v1 +Warnings: +Warning 1292 Truncated incorrect DOUBLE value: 'x' +Warning 1292 Truncated incorrect DOUBLE value: 'x111' +select * from t1; +v1 +deallocate prepare stmt; +drop table t1; +# # MDEV-26061 MariaDB server crash at Field::set_default # create table t1 (v2 date check (v1 like default (v1)), v1 date default (from_days ('x'))); diff --git a/mysql-test/t/check_constraint.test b/mysql-test/t/check_constraint.test index 05145d9d434..70d5a0c73ca 100644 --- a/mysql-test/t/check_constraint.test +++ b/mysql-test/t/check_constraint.test @@ -177,6 +177,25 @@ select * from t1 where a is null; insert t1 (b) values (1); drop table t1; +--echo # +--echo # MDEV-25638 Assertion `!result' failed in convert_const_to_int +--echo # + +--enable_prepare_warnings +create table t1 (v1 bigint check (v1 not in ('x' , 'x111'))) ; +select * from t1; +select v1 from t1; +select * from t1; +prepare stmt from "select * from t1"; +execute stmt; +execute stmt; +flush tables; +select * from t1; +select * from t1; +deallocate prepare stmt; +drop table t1; +--disable_prepare_warnings + --echo # --echo # MDEV-26061 MariaDB server crash at Field::set_default --echo # diff --git a/sql/table.cc b/sql/table.cc index 81116cb19cc..a5f1a5d96cf 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -3093,6 +3093,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))) From e4e25d2bacc067417c35750f5f6c44cad10c81de Mon Sep 17 00:00:00 2001 From: Oleksandr Byelkin Date: Thu, 14 Apr 2022 13:51:46 +0200 Subject: [PATCH 07/11] MDEV-26423 MariaDB server crash in Create_tmp_table::finalize Removed prohibition of creating temporary field of Item_default_value (added by mistake by 1d9b043a1f5db7ff229d5200652cff7a78ea6266 fix of MDEV-10780 and MDEV-11265). --- mysql-test/r/default.result | 9 +++++++++ mysql-test/r/default_innodb.result | 18 ++++++++++++++++++ mysql-test/t/default.test | 9 +++++++++ mysql-test/t/default_innodb.test | 22 ++++++++++++++++++++++ sql/item.h | 1 - 5 files changed, 58 insertions(+), 1 deletion(-) create mode 100644 mysql-test/r/default_innodb.result create mode 100644 mysql-test/t/default_innodb.test diff --git a/mysql-test/r/default.result b/mysql-test/r/default.result index c7179e29723..0c91e6b7e08 100644 --- a/mysql-test/r/default.result +++ b/mysql-test/r/default.result @@ -3404,4 +3404,13 @@ ERROR 01000: Expression for field `a` is referring to uninitialized field `a` show warnings; Level Code Message Error 4029 Expression for field `a` is referring to uninitialized field `a` +# +# MDEV-26423: MariaDB server crash in Create_tmp_table::finalize +# +CREATE TABLE t1 (pk varchar(36) DEFAULT uuid()); +INSERT INTO t1 VALUES (),(); +SELECT 1 FROM t1 GROUP BY DEFAULT(pk); +1 +1 +DROP TABLE t1; # end of 10.2 test diff --git a/mysql-test/r/default_innodb.result b/mysql-test/r/default_innodb.result new file mode 100644 index 00000000000..81e9672df24 --- /dev/null +++ b/mysql-test/r/default_innodb.result @@ -0,0 +1,18 @@ +# +# MDEV-26423: MariaDB server crash in Create_tmp_table::finalize +# +CREATE TABLE v0 ( +v2 DATE DEFAULT ( v1 MOD 68321183.000000 ) , +v1 DATETIME NULL ) engine=innodb; +SHOW DATABASES LIKE 'x'; +Database (x) +SELECT DISTINCT v2 , v1 , DEFAULT ( v2 ) FROM v0; +v2 v1 DEFAULT ( v2 ) +DROP TABLE v0; +CREATE TABLE t1 (v1 DATE, v2 DATE DEFAULT(v1)) engine=innodb; +SELECT DISTINCT DEFAULT(v2) FROM t1 ; +DEFAULT(v2) +DROP TABLE t1; +# +# End of 10.2 tests +# diff --git a/mysql-test/t/default.test b/mysql-test/t/default.test index a4fe74aefb5..e0233a3929a 100644 --- a/mysql-test/t/default.test +++ b/mysql-test/t/default.test @@ -2116,4 +2116,13 @@ DROP TABLE t1; create table t1 (a int as (a)); show warnings; + +--echo # +--echo # MDEV-26423: MariaDB server crash in Create_tmp_table::finalize +--echo # + +CREATE TABLE t1 (pk varchar(36) DEFAULT uuid()); +INSERT INTO t1 VALUES (),(); +SELECT 1 FROM t1 GROUP BY DEFAULT(pk); +DROP TABLE t1; --echo # end of 10.2 test diff --git a/mysql-test/t/default_innodb.test b/mysql-test/t/default_innodb.test new file mode 100644 index 00000000000..2fc74950845 --- /dev/null +++ b/mysql-test/t/default_innodb.test @@ -0,0 +1,22 @@ + +--source include/have_innodb.inc + +--echo # +--echo # MDEV-26423: MariaDB server crash in Create_tmp_table::finalize +--echo # + +CREATE TABLE v0 ( + v2 DATE DEFAULT ( v1 MOD 68321183.000000 ) , + v1 DATETIME NULL ) engine=innodb; +SHOW DATABASES LIKE 'x'; +SELECT DISTINCT v2 , v1 , DEFAULT ( v2 ) FROM v0; +DROP TABLE v0; + +CREATE TABLE t1 (v1 DATE, v2 DATE DEFAULT(v1)) engine=innodb; +SELECT DISTINCT DEFAULT(v2) FROM t1 ; +DROP TABLE t1; + + +--echo # +--echo # End of 10.2 tests +--echo # diff --git a/sql/item.h b/sql/item.h index 35454c69734..6b4ca89f3c7 100644 --- a/sql/item.h +++ b/sql/item.h @@ -5502,7 +5502,6 @@ public: if (field && field->default_value) field->default_value->expr->update_used_tables(); } - Field *get_tmp_table_field() { return 0; } Item *get_tmp_table_item(THD *thd) { return this; } Item_field *field_for_view_update() { return 0; } bool update_vcol_processor(void *arg) { return 0; } From 5aef0123a707415c56ffae48fc872e7d3ad292d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Tue, 19 Apr 2022 12:40:05 +0300 Subject: [PATCH 08/11] MDEV-28317 Assertion failures in row_undo_mod on recovery Starting with 10.3, an assertion would fail on the rollback of a recovered incomplete transaction if a table definition violates a FOREIGN KEY constraint. DICT_ERR_IGNORE_RECOVER_LOCK: Include also DICT_ERR_IGNORE_FK_NOKEY so that trx_resurrect_table_locks() will be able to load table definitions and resurrect IX locks. Previously, if the FOREIGN KEY constraints of a table were incomplete, the table would fail to load until rollback, and in 10.3 or later an assertion would fail that the rollback was not protected by a table IX lock. Thanks to commit 9de2e60d7491fcf3cd1f20a4be715ef0bedc316f there will be no problems to enforce subsequent FOREIGN KEY operations even though a table with invalid REFERENCES clause was loaded. --- mysql-test/suite/innodb/r/foreign_key.result | 27 ++++++++++++++++ mysql-test/suite/innodb/t/foreign_key.test | 34 ++++++++++++++++++++ storage/innobase/include/dict0types.h | 4 +-- 3 files changed, 63 insertions(+), 2 deletions(-) diff --git a/mysql-test/suite/innodb/r/foreign_key.result b/mysql-test/suite/innodb/r/foreign_key.result index d6420118f34..dc958724fef 100644 --- a/mysql-test/suite/innodb/r/foreign_key.result +++ b/mysql-test/suite/innodb/r/foreign_key.result @@ -137,6 +137,33 @@ SELECT unique_constraint_name FROM information_schema.referential_constraints WHERE table_name = 't2'; unique_constraint_name PRIMARY +# +# MDEV-28317 Assertion failure on rollback of FOREIGN KEY operation +# +SET foreign_key_checks=0; +CREATE TABLE parent(a INT PRIMARY KEY) ENGINE=InnoDB; +CREATE TABLE child(a INT,FOREIGN KEY(a) REFERENCES parent(a) ON DELETE CASCADE) +ENGINE=InnoDB; +INSERT INTO child VALUES(1); +ALTER TABLE child DROP INDEX a; +connect incomplete, localhost, root,,; +BEGIN; +DELETE FROM child; +connection default; +INSERT INTO parent SET a=0; +FLUSH TABLES; +disconnect incomplete; +INSERT INTO child SET a=0; +INSERT INTO child SET a=1; +ERROR 23000: Cannot add or update a child row: a foreign key constraint fails (`test`.`child`, CONSTRAINT `child_ibfk_1` FOREIGN KEY (`a`) REFERENCES `parent` (`a`) ON DELETE CASCADE) +DELETE FROM parent; +ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test`.`child`, CONSTRAINT `child_ibfk_1` FOREIGN KEY (`a`) REFERENCES `parent` (`a`) ON DELETE CASCADE) +ALTER TABLE child ADD INDEX(a); +DELETE FROM parent; +ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test`.`child`, CONSTRAINT `child_ibfk_1` FOREIGN KEY (`a`) REFERENCES `parent` (`a`) ON DELETE CASCADE) +ALTER TABLE child FORCE; +DELETE FROM parent; +DROP TABLE child,parent; SET @saved_frequency = @@GLOBAL.innodb_purge_rseg_truncate_frequency; SET GLOBAL innodb_purge_rseg_truncate_frequency = 1; SELECT unique_constraint_name FROM information_schema.referential_constraints diff --git a/mysql-test/suite/innodb/t/foreign_key.test b/mysql-test/suite/innodb/t/foreign_key.test index 1d4e5fd9d2a..af23dbdbb28 100644 --- a/mysql-test/suite/innodb/t/foreign_key.test +++ b/mysql-test/suite/innodb/t/foreign_key.test @@ -102,7 +102,41 @@ INSERT INTO t2 VALUES (1); SELECT unique_constraint_name FROM information_schema.referential_constraints WHERE table_name = 't2'; +--echo # +--echo # MDEV-28317 Assertion failure on rollback of FOREIGN KEY operation +--echo # + +SET foreign_key_checks=0; +CREATE TABLE parent(a INT PRIMARY KEY) ENGINE=InnoDB; +CREATE TABLE child(a INT,FOREIGN KEY(a) REFERENCES parent(a) ON DELETE CASCADE) +ENGINE=InnoDB; +INSERT INTO child VALUES(1); +ALTER TABLE child DROP INDEX a; + +connect(incomplete, localhost, root,,); +BEGIN; +DELETE FROM child; + +connection default; +INSERT INTO parent SET a=0; +FLUSH TABLES; + +--let $shutdown_timeout=0 --source include/restart_mysqld.inc +--let $shutdown_timeout= +disconnect incomplete; + +INSERT INTO child SET a=0; +--error ER_NO_REFERENCED_ROW_2 +INSERT INTO child SET a=1; +--error ER_ROW_IS_REFERENCED_2 +DELETE FROM parent; +ALTER TABLE child ADD INDEX(a); +--error ER_ROW_IS_REFERENCED_2 +DELETE FROM parent; +ALTER TABLE child FORCE; +DELETE FROM parent; +DROP TABLE child,parent; SET @saved_frequency = @@GLOBAL.innodb_purge_rseg_truncate_frequency; SET GLOBAL innodb_purge_rseg_truncate_frequency = 1; diff --git a/storage/innobase/include/dict0types.h b/storage/innobase/include/dict0types.h index bea08f398de..04c8b163b14 100644 --- a/storage/innobase/include/dict0types.h +++ b/storage/innobase/include/dict0types.h @@ -1,7 +1,7 @@ /***************************************************************************** Copyright (c) 1996, 2015, Oracle and/or its affiliates. All Rights Reserved. -Copyright (c) 2013, 2019, MariaDB Corporation. +Copyright (c) 2013, 2022, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -64,7 +64,7 @@ enum dict_err_ignore_t { DICT_ERR_IGNORE_INDEX_ROOT = 2, /*!< ignore error if index root page is FIL_NULL or incorrect value */ DICT_ERR_IGNORE_CORRUPT = 4, /*!< skip corrupted indexes */ - DICT_ERR_IGNORE_RECOVER_LOCK = 8, + DICT_ERR_IGNORE_RECOVER_LOCK = 8 | DICT_ERR_IGNORE_FK_NOKEY, /*!< Used when recovering table locks for resurrected transactions. Silently load a missing From a59f483c06b12e606747da3f864ed94615f038c0 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Sat, 16 Apr 2022 11:40:15 +0200 Subject: [PATCH 09/11] MDEV-28092 MariaDB SEGV issue add test --- mysql-test/suite/vcol/r/vcol_misc.result | 11 +++++++++++ mysql-test/suite/vcol/t/vcol_misc.test | 8 ++++++++ 2 files changed, 19 insertions(+) diff --git a/mysql-test/suite/vcol/r/vcol_misc.result b/mysql-test/suite/vcol/r/vcol_misc.result index 6c4975f2178..f13a20bf4c9 100644 --- a/mysql-test/suite/vcol/r/vcol_misc.result +++ b/mysql-test/suite/vcol/r/vcol_misc.result @@ -510,6 +510,17 @@ a b 13 14 DROP TABLE t1; SET sql_mode=DEFAULT; +create table t1 (b timestamp, a int as (1 in (dayofmonth (b between 'x' and current_user) = b))); +insert into t1(b) values ('2022-03-17 14:55:37'); +select 1 from t1 x natural join t1; +1 +1 +Warnings: +Warning 1292 Incorrect datetime value: 'x' +Warning 1292 Incorrect datetime value: 'root@localhost' +Warning 1292 Incorrect datetime value: 'x' +Warning 1292 Incorrect datetime value: 'root@localhost' +drop table t1; # # End of 10.2 tests # diff --git a/mysql-test/suite/vcol/t/vcol_misc.test b/mysql-test/suite/vcol/t/vcol_misc.test index 07f96f4e0b8..821dd418e64 100644 --- a/mysql-test/suite/vcol/t/vcol_misc.test +++ b/mysql-test/suite/vcol/t/vcol_misc.test @@ -488,6 +488,14 @@ SELECT * FROM t1; DROP TABLE t1; SET sql_mode=DEFAULT; +# +# MDEV-28092 MariaDB SEGV issue +# +create table t1 (b timestamp, a int as (1 in (dayofmonth (b between 'x' and current_user) = b))); +insert into t1(b) values ('2022-03-17 14:55:37'); +select 1 from t1 x natural join t1; +drop table t1; + --echo # --echo # End of 10.2 tests --echo # From 9c5fd0f624df846686742182825d964c546fac58 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Sat, 16 Apr 2022 11:53:44 +0200 Subject: [PATCH 10/11] vcols: cannot use CONTEXT_ANALYSIS_ONLY_VCOL_EXPR on fix_fields because CONTEXT_ANALYSIS_ONLY_VCOL_EXPR can be used only for, exactly, context analysys. Items fixed that way cannot be evaluated. But vcols are going to be evaluated, so they have to be fixed properly, for evaluation. --- mysql-test/suite/vcol/r/vcol_misc.result | 22 +++++++++++++++++++++- mysql-test/suite/vcol/t/vcol_misc.opt | 1 + mysql-test/suite/vcol/t/vcol_misc.test | 15 +++++++++++++++ sql/item.h | 8 ++++++++ sql/sql_lex.cc | 1 - 5 files changed, 45 insertions(+), 2 deletions(-) create mode 100644 mysql-test/suite/vcol/t/vcol_misc.opt diff --git a/mysql-test/suite/vcol/r/vcol_misc.result b/mysql-test/suite/vcol/r/vcol_misc.result index f13a20bf4c9..f4790a7cbec 100644 --- a/mysql-test/suite/vcol/r/vcol_misc.result +++ b/mysql-test/suite/vcol/r/vcol_misc.result @@ -227,7 +227,7 @@ show create table t1; Table Create Table t1 CREATE TABLE `t1` ( `a` bigint(20) DEFAULT NULL, - `b` bigint(20) GENERATED ALWAYS AS (`a` > '2') VIRTUAL + `b` bigint(20) GENERATED ALWAYS AS (`a` > 2) VIRTUAL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 insert into t1 (a) values (1),(3); select * from t1; @@ -522,5 +522,25 @@ Warning 1292 Incorrect datetime value: 'x' Warning 1292 Incorrect datetime value: 'root@localhost' drop table t1; # +# CONTEXT_ANALYSIS_ONLY_VCOL_EXPR +# +create table t1 (c1 char(1) character set ucs2 collate ucs2_test_ci, +v1 char(1) character set ucs2 collate ucs2_test_ci as (c1), +v2 int as (c1 = 'b'), +v3 int as (v1 = 'b')); +insert into t1 (c1) values ('a'); +select * from t1 where v1 = 'b'; +c1 v1 v2 v3 +a a 1 1 +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `c1` char(1) CHARACTER SET ucs2 COLLATE ucs2_test_ci DEFAULT NULL, + `v1` char(1) CHARACTER SET ucs2 GENERATED ALWAYS AS (`c1`) VIRTUAL, + `v2` int(11) GENERATED ALWAYS AS (`c1` = 'b') VIRTUAL, + `v3` int(11) GENERATED ALWAYS AS (`v1` = 'b') VIRTUAL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +drop table t1; +# # End of 10.2 tests # diff --git a/mysql-test/suite/vcol/t/vcol_misc.opt b/mysql-test/suite/vcol/t/vcol_misc.opt new file mode 100644 index 00000000000..fd1faea4f8e --- /dev/null +++ b/mysql-test/suite/vcol/t/vcol_misc.opt @@ -0,0 +1 @@ +--character-sets-dir=$MYSQL_TEST_DIR/std_data/ldml/ diff --git a/mysql-test/suite/vcol/t/vcol_misc.test b/mysql-test/suite/vcol/t/vcol_misc.test index 821dd418e64..b37b9e8f3d5 100644 --- a/mysql-test/suite/vcol/t/vcol_misc.test +++ b/mysql-test/suite/vcol/t/vcol_misc.test @@ -496,6 +496,21 @@ insert into t1(b) values ('2022-03-17 14:55:37'); select 1 from t1 x natural join t1; drop table t1; +--echo # +--echo # CONTEXT_ANALYSIS_ONLY_VCOL_EXPR +--echo # + +--source include/have_ucs2.inc +create table t1 (c1 char(1) character set ucs2 collate ucs2_test_ci, + v1 char(1) character set ucs2 collate ucs2_test_ci as (c1), + v2 int as (c1 = 'b'), + v3 int as (v1 = 'b')); +insert into t1 (c1) values ('a'); +select * from t1 where v1 = 'b'; +show create table t1; +drop table t1; + --echo # --echo # End of 10.2 tests --echo # + diff --git a/sql/item.h b/sql/item.h index 6b4ca89f3c7..07c17901afd 100644 --- a/sql/item.h +++ b/sql/item.h @@ -5807,10 +5807,18 @@ public: } return mark_unsupported_function("cache", arg, VCOL_IMPOSSIBLE); } + bool fix_fields(THD *thd, Item **ref) + { + fixed= 1; + if (example && !example->fixed) + return example->fix_fields(thd, ref); + return 0; + } void cleanup() { clear(); Item_basic_constant::cleanup(); + fixed= 0; } /** Check if saved item has a non-NULL value. diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index 47ff2836aba..22ee8801e3a 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -193,7 +193,6 @@ init_lex_with_single_table(THD *thd, TABLE *table, LEX *lex) return TRUE; context->resolve_in_table_list_only(table_list); lex->use_only_table_context= TRUE; - lex->context_analysis_only|= CONTEXT_ANALYSIS_ONLY_VCOL_EXPR; select_lex->cur_pos_in_select_list= UNDEF_POS; table->map= 1; //To ensure correct calculation of const item table_list->table= table; From 5ba77222e9fe7af8ff403816b5338b18b342053c Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Tue, 19 Apr 2022 17:09:19 +0200 Subject: [PATCH 11/11] MDEV-21028 Server crashes in Query_arena::set_query_arena upon SELECT from view if the view has algorithm=temptable it is not updatable, so DEFAULT() for its fields is meaningless, and thus it's NULL or 0/'' for NOT NULL columns. --- mysql-test/r/func_default.result | 43 ++++++++++++++++++++++++++++++++ mysql-test/t/func_default.test | 26 +++++++++++++++++++ sql/sql_select.cc | 3 ++- 3 files changed, 71 insertions(+), 1 deletion(-) diff --git a/mysql-test/r/func_default.result b/mysql-test/r/func_default.result index 8721270ca1c..2b5c869ee66 100644 --- a/mysql-test/r/func_default.result +++ b/mysql-test/r/func_default.result @@ -159,5 +159,48 @@ a 10 DROP TABLE t1; # +# MDEV-21028 Server crashes in Query_arena::set_query_arena upon SELECT from view +# +create table t1 (a datetime default current_timestamp); +insert into t1 () values (),(); +create algorithm=temptable view v1 as select * from t1; +create algorithm=merge view v2 as select * from t1; +select default(a) = now() from v1; +default(a) = now() +NULL +NULL +select default(a) = now() from v2; +default(a) = now() +1 +1 +select table_name,is_updatable from information_schema.views; +table_name is_updatable +v1 NO +v2 YES +drop view v1, v2; +drop table t1; +create table t1 (v1 timestamp) select 'x'; +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `v1` timestamp NOT NULL DEFAULT current_timestamp() ON UPDATE current_timestamp(), + `x` varchar(1) NOT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +select default(v1) from (select v1 from t1) dt; +default(v1) +2001-01-01 10:20:30 +select default(v1) from (select v1 from t1 group by v1) dt; +default(v1) +0000-00-00 00:00:00 +drop table t1; +create table t1 (a text default ''); +create algorithm=temptable view v1 as select * from t1; +insert into t1 values ('a'); +select default(a) from v1; +default(a) +NULL +drop view v1; +drop table t1; +# # End of 10.2 tests # diff --git a/mysql-test/t/func_default.test b/mysql-test/t/func_default.test index cba7842c68f..f542a279478 100644 --- a/mysql-test/t/func_default.test +++ b/mysql-test/t/func_default.test @@ -139,6 +139,32 @@ FROM t1; SELECT a FROM t1 WHERE CASE WHEN a THEN DEFAULT(a) END IS FALSE; DROP TABLE t1; +--echo # +--echo # MDEV-21028 Server crashes in Query_arena::set_query_arena upon SELECT from view +--echo # +create table t1 (a datetime default current_timestamp); +insert into t1 () values (),(); +create algorithm=temptable view v1 as select * from t1; +create algorithm=merge view v2 as select * from t1; +select default(a) = now() from v1; +select default(a) = now() from v2; +select table_name,is_updatable from information_schema.views; +drop view v1, v2; +drop table t1; + +create table t1 (v1 timestamp) select 'x'; +show create table t1; +select default(v1) from (select v1 from t1) dt; +select default(v1) from (select v1 from t1 group by v1) dt; +drop table t1; + +create table t1 (a text default ''); +create algorithm=temptable view v1 as select * from t1; +insert into t1 values ('a'); +select default(a) from v1; +drop view v1; +drop table t1; + --echo # --echo # End of 10.2 tests --echo # diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 2a646a9931d..d2186f60709 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -16333,7 +16333,8 @@ Field *create_tmp_field_from_field(THD *thd, Field *org_field, table->s->db_create_options|= HA_OPTION_PACK_RECORD; else if (org_field->type() == FIELD_TYPE_DOUBLE) ((Field_double *) new_field)->not_fixed= TRUE; - new_field->vcol_info= 0; + new_field->vcol_info= new_field->default_value= + new_field->check_constraint= 0; new_field->cond_selectivity= 1.0; new_field->next_equal_field= NULL; new_field->option_list= NULL;