mirror of
https://github.com/MariaDB/server.git
synced 2025-07-29 05:21:33 +03:00
MDEV-33442 REPAIR TABLE corrupts UUIDs
Problem: REPAIR TABLE executed for a pre-MDEV-29959 table (with the old UUID format) updated the server version in the FRM file without rewriting the data, so it created a new FRM for old UUIDs. After that MariaDB could not read UUIDs correctly. Fix: - Adding a new virtual method in class Type_handler: virtual bool type_handler_for_implicit_upgrade() const; * For the up-to-date data types it returns "this". * For the data types which need to be implicitly upgraded during REPAIR TABLE or ALTER TABLE, it returns a pointer to a new replacement data type handler. Old VARCHAR and old UUID type handlers override this method. See more comments below. - Changing the semantics of the method Type_handler::Column_definition_implicit_upgrade(Column_definition *c) to the opposite, so now: * c->type_handler() references the old data type (to upgrade from) * "this" references the new data type (to upgrade to). Before this change Column_definition_implicit_upgrade() was supposed to be called with the old data type handler (to upgrade from). Renaming the method to Column_definition_implicit_upgrade_to_this(), to avoid automatic merges in this method. Reflecting this change in Create_field::upgrade_data_types(). - Replacing the hard-coded data type tests inside handler::check_old_types() to a call for the new virtual method Type_handler::type_handler_for_implicit_upgrade() - Overriding Type_handler_fbt::type_handler_for_implicit_upgrade() to call a new method FbtImpl::type_handler_for_implicit_upgrade(). Reasoning: Type_handler_fbt is a template, so it has access only to "this". So in case of UUID data types, the type handler for old UUID knows nothing about the type handler of new UUID inside sql_type_fixedbin.h. So let's have Type_handler_fbt delegate type_handler_for_implicit_upgrade() to its Type_collection, which knows both new UUID and old UUID. - Adding Type_collection_uuid::type_handler_for_implicit_upgrade(). It returns a pointer to the new UUID type handler. - Overriding Type_handler_var_string::type_handler_for_implicit_upgrade() to return a pointer to type_handler_varchar (true VARCHAR). - Cleanup: these two methods: handler::check_old_types() handler::ha_check_for_upgrade() were always called consequently. So moving the call for check_old_types() inside ha_check_for_upgrade(), and making check_old_types() private. - Cleanup: removing the "bool varchar" parameter from fill_alter_inplace_info(), as its not used any more.
This commit is contained in:
@ -3836,6 +3836,16 @@ public:
|
||||
const Type_handler *res= type_handler_base();
|
||||
return res ? res : this;
|
||||
}
|
||||
/*
|
||||
In 10.11.8 the semantics of this method has changed to the opposite.
|
||||
It used to be called with the old data type handler as "this".
|
||||
Now it's called with the new data type hander as "this".
|
||||
To avoid problems during merges, the method name was renamed.
|
||||
*/
|
||||
virtual const Type_handler *type_handler_for_implicit_upgrade() const
|
||||
{
|
||||
return this;
|
||||
}
|
||||
virtual const Type_handler *type_handler_for_comparison() const= 0;
|
||||
virtual const Type_handler *type_handler_for_native_format() const
|
||||
{
|
||||
@ -3981,9 +3991,13 @@ public:
|
||||
virtual bool validate_implicit_default_value(THD *thd,
|
||||
const Column_definition &def)
|
||||
const;
|
||||
// Automatic upgrade, e.g. for ALTER TABLE t1 FORCE
|
||||
virtual void Column_definition_implicit_upgrade(Column_definition *c) const
|
||||
{ }
|
||||
/*
|
||||
Automatic upgrade, e.g. for REPAIR or ALTER TABLE t1 FORCE
|
||||
- from the data type specified in old->type_handler()
|
||||
- to the data type specified in "this"
|
||||
*/
|
||||
virtual void Column_definition_implicit_upgrade_to_this(
|
||||
Column_definition *old) const;
|
||||
// Validate CHECK constraint after the parser
|
||||
virtual bool Column_definition_validate_check_constraint(THD *thd,
|
||||
Column_definition *c)
|
||||
@ -6188,7 +6202,8 @@ public:
|
||||
const Type_handler *type_handler_for_comparison() const override;
|
||||
int stored_field_cmp_to_item(THD *thd, Field *field, Item *item)
|
||||
const override;
|
||||
void Column_definition_implicit_upgrade(Column_definition *c) const override;
|
||||
void Column_definition_implicit_upgrade_to_this(
|
||||
Column_definition *old) const override;
|
||||
bool Column_definition_fix_attributes(Column_definition *c) const override;
|
||||
bool
|
||||
Column_definition_attributes_frm_unpack(Column_definition_attributes *attr,
|
||||
@ -6512,7 +6527,8 @@ public:
|
||||
const Type_cast_attributes &attr) const override;
|
||||
bool validate_implicit_default_value(THD *thd, const Column_definition &def)
|
||||
const override;
|
||||
void Column_definition_implicit_upgrade(Column_definition *c) const override;
|
||||
void Column_definition_implicit_upgrade_to_this(
|
||||
Column_definition *old) const override;
|
||||
bool Column_definition_fix_attributes(Column_definition *c) const override;
|
||||
bool
|
||||
Column_definition_attributes_frm_unpack(Column_definition_attributes *attr,
|
||||
@ -6650,7 +6666,8 @@ public:
|
||||
{
|
||||
return true;
|
||||
}
|
||||
void Column_definition_implicit_upgrade(Column_definition *c) const override;
|
||||
void Column_definition_implicit_upgrade_to_this(
|
||||
Column_definition *old) const override;
|
||||
bool
|
||||
Column_definition_attributes_frm_unpack(Column_definition_attributes *attr,
|
||||
TABLE_SHARE *share,
|
||||
@ -7000,6 +7017,7 @@ public:
|
||||
{
|
||||
return MYSQL_TYPE_VARCHAR;
|
||||
}
|
||||
const Type_handler *type_handler_for_implicit_upgrade() const override;
|
||||
const Type_handler *type_handler_for_tmp_table(const Item *item) const override
|
||||
{
|
||||
return varstring_type_handler(item);
|
||||
@ -7007,7 +7025,6 @@ public:
|
||||
uint32 max_display_length_for_field(const Conv_source &src) const override;
|
||||
void show_binlog_type(const Conv_source &src, const Field &dst, String *str)
|
||||
const override;
|
||||
void Column_definition_implicit_upgrade(Column_definition *c) const override;
|
||||
bool Column_definition_fix_attributes(Column_definition *c) const override;
|
||||
bool Column_definition_prepare_stage2(Column_definition *c,
|
||||
handler *file,
|
||||
|
Reference in New Issue
Block a user