Skip to content

Commit f1bbc1c

Browse files
committed
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.
1 parent 8c5d323 commit f1bbc1c

File tree

6 files changed

+78
-2
lines changed

6 files changed

+78
-2
lines changed

mysql-test/main/partition_alter.result

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -212,3 +212,26 @@ test.t check status OK
212212
delete from t order by b limit 1;
213213
drop table t;
214214
# End of 10.3 tests
215+
#
216+
# Start of 10.4 tests
217+
#
218+
#
219+
# MDEV-28545 MyISAM reorganize partition corrupt older table format
220+
#
221+
SET GLOBAL mysql56_temporal_format=OFF;
222+
CREATE TABLE t (ts timestamp, KEY (ts)) ENGINE=MyISAM
223+
PARTITION BY RANGE (unix_timestamp(ts)) (
224+
PARTITION p1 VALUES LESS THAN (1645398000),
225+
PARTITION pn VALUES LESS THAN MAXVALUE
226+
);
227+
SET GLOBAL mysql56_temporal_format=ON;
228+
FLUSH TABLES;
229+
ALTER TABLE t DROP PARTITION p1;
230+
CHECK TABLE t;
231+
Table Op Msg_type Msg_text
232+
test.t check status OK
233+
DROP TABLE t;
234+
SET GLOBAL mysql56_temporal_format=DEFAULT;
235+
#
236+
# End of 10.4 tests
237+
#

mysql-test/main/partition_alter.test

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -197,3 +197,29 @@ delete from t order by b limit 1;
197197
drop table t;
198198

199199
--echo # End of 10.3 tests
200+
201+
--echo #
202+
--echo # Start of 10.4 tests
203+
--echo #
204+
205+
--echo #
206+
--echo # MDEV-28545 MyISAM reorganize partition corrupt older table format
207+
--echo #
208+
209+
SET GLOBAL mysql56_temporal_format=OFF;
210+
CREATE TABLE t (ts timestamp, KEY (ts)) ENGINE=MyISAM
211+
PARTITION BY RANGE (unix_timestamp(ts)) (
212+
PARTITION p1 VALUES LESS THAN (1645398000),
213+
PARTITION pn VALUES LESS THAN MAXVALUE
214+
);
215+
216+
SET GLOBAL mysql56_temporal_format=ON;
217+
FLUSH TABLES;
218+
ALTER TABLE t DROP PARTITION p1;
219+
CHECK TABLE t;
220+
DROP TABLE t;
221+
SET GLOBAL mysql56_temporal_format=DEFAULT;
222+
223+
--echo #
224+
--echo # End of 10.4 tests
225+
--echo #

sql/field.cc

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11020,8 +11020,6 @@ Column_definition::Column_definition(THD *thd, Field *old_field,
1102011020

1102111021
type_handler()->Column_definition_reuse_fix_attributes(thd, this, old_field);
1102211022

11023-
type_handler()->Column_definition_implicit_upgrade(this);
11024-
1102511023
/*
1102611024
Copy the default (constant/function) from the column object orig_field, if
1102711025
supplied. We do this if all these conditions are met:

sql/field.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5203,6 +5203,13 @@ class Create_field :public Column_definition
52035203

52045204
bool vers_check_timestamp(const Lex_table_name &table_name) const;
52055205
bool vers_check_bigint(const Lex_table_name &table_name) const;
5206+
5207+
static void upgrade_data_types(List<Create_field> &list)
5208+
{
5209+
List_iterator<Create_field> it(list);
5210+
while (Create_field *f= it++)
5211+
f->type_handler()->Column_definition_implicit_upgrade(f);
5212+
}
52065213
};
52075214

52085215

sql/sql_insert.cc

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4346,6 +4346,16 @@ TABLE *select_create::create_table_from_items(THD *thd, List<Item> *items,
43464346
alter_info->create_list.push_back(cr_field, thd->mem_root);
43474347
}
43484348

4349+
/*
4350+
Item*::type_handler() always returns pointers to
4351+
type_handler_{time2|datetime2|timestamp2} no matter what
4352+
the current mysql56_temporal_format says.
4353+
Let's convert them according to mysql56_temporal_format.
4354+
QQ: This perhaps should eventually be fixed to have Item*::type_handler()
4355+
respect mysql56_temporal_format, and remove the upgrade from here.
4356+
*/
4357+
Create_field::upgrade_data_types(alter_info->create_list);
4358+
43494359
if (create_info->check_fields(thd, alter_info,
43504360
create_table->table_name,
43514361
create_table->db,

sql/sql_table.cc

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10068,6 +10068,18 @@ do_continue:;
1006810068

1006910069
set_table_default_charset(thd, create_info, alter_ctx.db);
1007010070

10071+
/*
10072+
The ALTER related code cannot alter partitions and change column data types
10073+
at the same time. So in case of partition change statements like:
10074+
ALTER TABLE t1 DROP PARTITION p1;
10075+
we skip implicit data type upgrade (such as "MariaDB 5.3 TIME" to
10076+
"MySQL 5.6 TIME" or vice versa according to mysql56_temporal_format).
10077+
Note, one can run a separate "ALTER TABLE t1 FORCE;" statement
10078+
before or after the partition change ALTER statement to upgrade data types.
10079+
*/
10080+
if (IF_PARTITIONING(!fast_alter_partition, 1))
10081+
Create_field::upgrade_data_types(alter_info->create_list);
10082+
1007110083
if (create_info->check_fields(thd, alter_info,
1007210084
table_list->table_name, table_list->db) ||
1007310085
create_info->fix_period_fields(thd, alter_info))

0 commit comments

Comments
 (0)