mirror of
https://github.com/MariaDB/server.git
synced 2025-07-29 05:21:33 +03:00
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.
This commit is contained in:
@ -212,3 +212,26 @@ test.t check status OK
|
|||||||
delete from t order by b limit 1;
|
delete from t order by b limit 1;
|
||||||
drop table t;
|
drop table t;
|
||||||
# End of 10.3 tests
|
# 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
|
||||||
|
#
|
||||||
|
@ -197,3 +197,29 @@ delete from t order by b limit 1;
|
|||||||
drop table t;
|
drop table t;
|
||||||
|
|
||||||
--echo # End of 10.3 tests
|
--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 #
|
||||||
|
@ -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_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
|
Copy the default (constant/function) from the column object orig_field, if
|
||||||
supplied. We do this if all these conditions are met:
|
supplied. We do this if all these conditions are met:
|
||||||
|
@ -5203,6 +5203,13 @@ public:
|
|||||||
|
|
||||||
bool vers_check_timestamp(const Lex_table_name &table_name) const;
|
bool vers_check_timestamp(const Lex_table_name &table_name) const;
|
||||||
bool vers_check_bigint(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);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -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);
|
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,
|
if (create_info->check_fields(thd, alter_info,
|
||||||
create_table->table_name,
|
create_table->table_name,
|
||||||
create_table->db,
|
create_table->db,
|
||||||
|
@ -10068,6 +10068,18 @@ do_continue:;
|
|||||||
|
|
||||||
set_table_default_charset(thd, create_info, alter_ctx.db);
|
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,
|
if (create_info->check_fields(thd, alter_info,
|
||||||
table_list->table_name, table_list->db) ||
|
table_list->table_name, table_list->db) ||
|
||||||
create_info->fix_period_fields(thd, alter_info))
|
create_info->fix_period_fields(thd, alter_info))
|
||||||
|
Reference in New Issue
Block a user