From 732d1ec3aef8000885d7faa908a2c448e1b21d17 Mon Sep 17 00:00:00 2001 From: Aleksey Midenkov Date: Thu, 27 Jul 2023 19:43:45 +0300 Subject: [PATCH] MDEV-29873 MSAN uninitialized value errors in bcmp / prep_alter_part_table upon re-partitioning by system time memcmp() tries to compare beyond the last member of interval because sizeof(Vers_part_info::interval) is 80. It is sizeof of variable, sizeof of type is 76. Now we compare interval_t struct C++ way. --- mysql-test/suite/versioning/r/partition.result | 7 +++++++ mysql-test/suite/versioning/t/partition.test | 9 +++++++++ sql/partition_info.h | 7 ++++++- sql/sql_partition.cc | 5 +---- 4 files changed, 23 insertions(+), 5 deletions(-) diff --git a/mysql-test/suite/versioning/r/partition.result b/mysql-test/suite/versioning/r/partition.result index 58497db555b35..fd2804cbf3888 100644 --- a/mysql-test/suite/versioning/r/partition.result +++ b/mysql-test/suite/versioning/r/partition.result @@ -3406,4 +3406,11 @@ f() drop procedure p; drop function f; drop table t; +# +# MDEV-29873 MSAN uninitialized value errors in bcmp / +# prep_alter_part_table upon re-partitioning by system time +# +create table t (a int) with system versioning partition by system_time interval 5 week; +alter table t partition by system_time interval 10 week; +drop table t; set global innodb_stats_persistent= @save_persistent; diff --git a/mysql-test/suite/versioning/t/partition.test b/mysql-test/suite/versioning/t/partition.test index d15be0959ec24..3013353d23f35 100644 --- a/mysql-test/suite/versioning/t/partition.test +++ b/mysql-test/suite/versioning/t/partition.test @@ -2624,6 +2624,15 @@ drop procedure p; drop function f; drop table t; +--echo # +--echo # MDEV-29873 MSAN uninitialized value errors in bcmp / +--echo # prep_alter_part_table upon re-partitioning by system time +--echo # +create table t (a int) with system versioning partition by system_time interval 5 week; +alter table t partition by system_time interval 10 week; +# cleanup +drop table t; + --disable_prepare_warnings set global innodb_stats_persistent= @save_persistent; --source suite/versioning/common_finish.inc diff --git a/sql/partition_info.h b/sql/partition_info.h index 833a231e6ce3c..3a8c3a3752435 100644 --- a/sql/partition_info.h +++ b/sql/partition_info.h @@ -78,11 +78,16 @@ struct Vers_part_info : public Sql_alloc } return false; } - struct { + struct interval_t { my_time_t start; INTERVAL step; enum interval_type type; bool is_set() const { return type < INTERVAL_LAST; } + bool operator==(const interval_t &rhs) const + { + /* TODO: equivalent intervals like 1 hour and 60 mins should be considered equal */ + return start == rhs.start && type == rhs.type && !memcmp(&step, &rhs.step, sizeof(INTERVAL)); + } } interval; ulonglong limit; bool auto_hist; diff --git a/sql/sql_partition.cc b/sql/sql_partition.cc index ba9a370a06890..8c0efb7d3d0b2 100644 --- a/sql/sql_partition.cc +++ b/sql/sql_partition.cc @@ -6035,10 +6035,7 @@ the generated partition syntax in a correct manner. { if (part_info->vers_info->interval.is_set() && ( !tab_part_info->vers_info->interval.is_set() || - /* TODO: equivalent intervals like 1 hour and 60 mins should be considered equal */ - memcmp(&part_info->vers_info->interval, - &tab_part_info->vers_info->interval, - sizeof(Vers_part_info::interval)))) + part_info->vers_info->interval == tab_part_info->vers_info->interval)) { /* If interval is changed we can not do fast alter */ tab_part_info= tab_part_info->get_clone(thd);