summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander Barkov <bar@mariadb.com>2022-10-25 11:53:39 +0400
committerAlexander Barkov <bar@mariadb.com>2022-10-25 17:34:25 +0400
commitf1bbc1cd19d0d81fee5433efcb570a8845172241 (patch)
tree2e5a6b7808116456b4baea44ae15f69bbe1e24e8
parent8c5d323326d9d527e9a5e08c69eb6085953eb130 (diff)
downloadmariadb-git-f1bbc1cd19d0d81fee5433efcb570a8845172241.tar.gz
MDEV-28545 MyISAM reorganize partition corrupt older table format
The ALTER related code cannot do at the same time both: - modify partitions - change column data types Explicit changing of a column data type together with a partition change is prohibited by the parter, so this is not allowed and returns a syntax error: ALTER TABLE t MODIFY ts BIGINT, DROP PARTITION p1; This fix additionally disables implicit data type upgrade (e.g. from "MariaDB 5.3 TIME" to "MySQL 5.6 TIME", or the other way around according to the current mysql56_temporal_format) in case of an ALTER modifying partitions, e.g.: ALTER TABLE t DROP PARTITION p1; In such commands now only the partition change happens, while the data types stay unchanged. One can additionally run: ALTER TABLE t FORCE; either before or after the ALTER modifying partitions to upgrade data types according to mysql56_temporal_format.
-rw-r--r--mysql-test/main/partition_alter.result23
-rw-r--r--mysql-test/main/partition_alter.test26
-rw-r--r--sql/field.cc2
-rw-r--r--sql/field.h7
-rw-r--r--sql/sql_insert.cc10
-rw-r--r--sql/sql_table.cc12
6 files changed, 78 insertions, 2 deletions
diff --git a/mysql-test/main/partition_alter.result b/mysql-test/main/partition_alter.result
index 2b0a09d2653..37e975deb0e 100644
--- a/mysql-test/main/partition_alter.result
+++ b/mysql-test/main/partition_alter.result
@@ -212,3 +212,26 @@ test.t check status OK
delete from t order by b limit 1;
drop table t;
# End of 10.3 tests
+#
+# Start of 10.4 tests
+#
+#
+# MDEV-28545 MyISAM reorganize partition corrupt older table format
+#
+SET GLOBAL mysql56_temporal_format=OFF;
+CREATE TABLE t (ts timestamp, KEY (ts)) ENGINE=MyISAM
+PARTITION BY RANGE (unix_timestamp(ts)) (
+PARTITION p1 VALUES LESS THAN (1645398000),
+PARTITION pn VALUES LESS THAN MAXVALUE
+);
+SET GLOBAL mysql56_temporal_format=ON;
+FLUSH TABLES;
+ALTER TABLE t DROP PARTITION p1;
+CHECK TABLE t;
+Table Op Msg_type Msg_text
+test.t check status OK
+DROP TABLE t;
+SET GLOBAL mysql56_temporal_format=DEFAULT;
+#
+# End of 10.4 tests
+#
diff --git a/mysql-test/main/partition_alter.test b/mysql-test/main/partition_alter.test
index 7a80779e386..23ad5ece0e4 100644
--- a/mysql-test/main/partition_alter.test
+++ b/mysql-test/main/partition_alter.test
@@ -197,3 +197,29 @@ delete from t order by b limit 1;
drop table t;
--echo # End of 10.3 tests
+
+--echo #
+--echo # Start of 10.4 tests
+--echo #
+
+--echo #
+--echo # MDEV-28545 MyISAM reorganize partition corrupt older table format
+--echo #
+
+SET GLOBAL mysql56_temporal_format=OFF;
+CREATE TABLE t (ts timestamp, KEY (ts)) ENGINE=MyISAM
+PARTITION BY RANGE (unix_timestamp(ts)) (
+ PARTITION p1 VALUES LESS THAN (1645398000),
+ PARTITION pn VALUES LESS THAN MAXVALUE
+);
+
+SET GLOBAL mysql56_temporal_format=ON;
+FLUSH TABLES;
+ALTER TABLE t DROP PARTITION p1;
+CHECK TABLE t;
+DROP TABLE t;
+SET GLOBAL mysql56_temporal_format=DEFAULT;
+
+--echo #
+--echo # End of 10.4 tests
+--echo #
diff --git a/sql/field.cc b/sql/field.cc
index 853b0c62f14..bf27780e776 100644
--- a/sql/field.cc
+++ b/sql/field.cc
@@ -11020,8 +11020,6 @@ Column_definition::Column_definition(THD *thd, Field *old_field,
type_handler()->Column_definition_reuse_fix_attributes(thd, this, old_field);
- type_handler()->Column_definition_implicit_upgrade(this);
-
/*
Copy the default (constant/function) from the column object orig_field, if
supplied. We do this if all these conditions are met:
diff --git a/sql/field.h b/sql/field.h
index 7534a506edc..9d40caf0932 100644
--- a/sql/field.h
+++ b/sql/field.h
@@ -5203,6 +5203,13 @@ public:
bool vers_check_timestamp(const Lex_table_name &table_name) const;
bool vers_check_bigint(const Lex_table_name &table_name) const;
+
+ static void upgrade_data_types(List<Create_field> &list)
+ {
+ List_iterator<Create_field> it(list);
+ while (Create_field *f= it++)
+ f->type_handler()->Column_definition_implicit_upgrade(f);
+ }
};
diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc
index aeb39871025..76fd6385041 100644
--- a/sql/sql_insert.cc
+++ b/sql/sql_insert.cc
@@ -4346,6 +4346,16 @@ TABLE *select_create::create_table_from_items(THD *thd, List<Item> *items,
alter_info->create_list.push_back(cr_field, thd->mem_root);
}
+ /*
+ Item*::type_handler() always returns pointers to
+ type_handler_{time2|datetime2|timestamp2} no matter what
+ the current mysql56_temporal_format says.
+ Let's convert them according to mysql56_temporal_format.
+ QQ: This perhaps should eventually be fixed to have Item*::type_handler()
+ respect mysql56_temporal_format, and remove the upgrade from here.
+ */
+ Create_field::upgrade_data_types(alter_info->create_list);
+
if (create_info->check_fields(thd, alter_info,
create_table->table_name,
create_table->db,
diff --git a/sql/sql_table.cc b/sql/sql_table.cc
index 6aae927800e..efa5c06dd2a 100644
--- a/sql/sql_table.cc
+++ b/sql/sql_table.cc
@@ -10068,6 +10068,18 @@ do_continue:;
set_table_default_charset(thd, create_info, alter_ctx.db);
+ /*
+ The ALTER related code cannot alter partitions and change column data types
+ at the same time. So in case of partition change statements like:
+ ALTER TABLE t1 DROP PARTITION p1;
+ we skip implicit data type upgrade (such as "MariaDB 5.3 TIME" to
+ "MySQL 5.6 TIME" or vice versa according to mysql56_temporal_format).
+ Note, one can run a separate "ALTER TABLE t1 FORCE;" statement
+ before or after the partition change ALTER statement to upgrade data types.
+ */
+ if (IF_PARTITIONING(!fast_alter_partition, 1))
+ Create_field::upgrade_data_types(alter_info->create_list);
+
if (create_info->check_fields(thd, alter_info,
table_list->table_name, table_list->db) ||
create_info->fix_period_fields(thd, alter_info))