mirror of
https://github.com/MariaDB/server.git
synced 2025-01-16 03:52:35 +01:00
cleanup: key parts comparison
Engine specific code moved to engine.
This commit is contained in:
parent
5a42a114fd
commit
7ccc1710a0
5 changed files with 121 additions and 64 deletions
|
@ -6953,6 +6953,20 @@ void handler::set_lock_type(enum thr_lock_type lock)
|
||||||
table->reginfo.lock_type= lock;
|
table->reginfo.lock_type= lock;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Compare_keys handler::compare_key_parts(const Field &old_field,
|
||||||
|
const Column_definition &new_field,
|
||||||
|
const KEY_PART_INFO &old_part,
|
||||||
|
const KEY_PART_INFO &new_part) const
|
||||||
|
{
|
||||||
|
if (!old_field.is_equal(new_field))
|
||||||
|
return Compare_keys::NotEqual;
|
||||||
|
|
||||||
|
if (old_part.length != new_part.length)
|
||||||
|
return Compare_keys::NotEqual;
|
||||||
|
|
||||||
|
return Compare_keys::Equal;
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef WITH_WSREP
|
#ifdef WITH_WSREP
|
||||||
/**
|
/**
|
||||||
@details
|
@details
|
||||||
|
|
|
@ -2936,6 +2936,13 @@ public:
|
||||||
virtual ~Handler_share() {}
|
virtual ~Handler_share() {}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum class Compare_keys : uint32_t
|
||||||
|
{
|
||||||
|
Equal,
|
||||||
|
EqualButKeyPartLength,
|
||||||
|
EqualButComment,
|
||||||
|
NotEqual
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
The handler class is the interface for dynamically loadable
|
The handler class is the interface for dynamically loadable
|
||||||
|
@ -4877,6 +4884,13 @@ public:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Used for ALTER TABLE.
|
||||||
|
Some engines can handle some differences in indexes by themself. */
|
||||||
|
virtual Compare_keys compare_key_parts(const Field &old_field,
|
||||||
|
const Column_definition &new_field,
|
||||||
|
const KEY_PART_INFO &old_part,
|
||||||
|
const KEY_PART_INFO &new_part) const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
Handler_share *get_ha_share_ptr();
|
Handler_share *get_ha_share_ptr();
|
||||||
void set_ha_share_ptr(Handler_share *arg_ha_share);
|
void set_ha_share_ptr(Handler_share *arg_ha_share);
|
||||||
|
|
120
sql/sql_table.cc
120
sql/sql_table.cc
|
@ -6579,38 +6579,68 @@ static int compare_uint(const uint *s, const uint *t)
|
||||||
return (*s < *t) ? -1 : ((*s > *t) ? 1 : 0);
|
return (*s < *t) ? -1 : ((*s > *t) ? 1 : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
enum class Compare_keys : uint32_t
|
static Compare_keys merge(Compare_keys current, Compare_keys add) {
|
||||||
{
|
if (current == Compare_keys::Equal)
|
||||||
Equal,
|
return add;
|
||||||
EqualButKeyPartLength,
|
|
||||||
EqualButComment,
|
if (add == Compare_keys::Equal)
|
||||||
NotEqual
|
return current;
|
||||||
};
|
|
||||||
|
if (current == add)
|
||||||
|
return current;
|
||||||
|
|
||||||
|
if (current == Compare_keys::EqualButComment) {
|
||||||
|
return Compare_keys::NotEqual;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (current == Compare_keys::EqualButKeyPartLength) {
|
||||||
|
if (add == Compare_keys::EqualButComment)
|
||||||
|
return Compare_keys::NotEqual;
|
||||||
|
DBUG_ASSERT(add == Compare_keys::NotEqual);
|
||||||
|
return Compare_keys::NotEqual;
|
||||||
|
}
|
||||||
|
|
||||||
|
DBUG_ASSERT(current == Compare_keys::NotEqual);
|
||||||
|
return current;
|
||||||
|
}
|
||||||
|
|
||||||
Compare_keys compare_keys_but_name(const KEY *table_key, const KEY *new_key,
|
Compare_keys compare_keys_but_name(const KEY *table_key, const KEY *new_key,
|
||||||
Alter_info *alter_info, const TABLE *table,
|
Alter_info *alter_info, const TABLE *table,
|
||||||
const KEY *const new_pk,
|
const KEY *const new_pk,
|
||||||
const KEY *const old_pk)
|
const KEY *const old_pk)
|
||||||
{
|
{
|
||||||
Compare_keys result= Compare_keys::Equal;
|
if (table_key->algorithm != new_key->algorithm)
|
||||||
|
return Compare_keys::NotEqual;
|
||||||
|
|
||||||
if ((table_key->algorithm != new_key->algorithm) ||
|
if ((table_key->flags & HA_KEYFLAG_MASK) !=
|
||||||
((table_key->flags & HA_KEYFLAG_MASK) !=
|
(new_key->flags & HA_KEYFLAG_MASK))
|
||||||
(new_key->flags & HA_KEYFLAG_MASK)) ||
|
return Compare_keys::NotEqual;
|
||||||
(table_key->user_defined_key_parts != new_key->user_defined_key_parts))
|
|
||||||
|
if (table_key->user_defined_key_parts != new_key->user_defined_key_parts)
|
||||||
return Compare_keys::NotEqual;
|
return Compare_keys::NotEqual;
|
||||||
|
|
||||||
if (table_key->block_size != new_key->block_size)
|
if (table_key->block_size != new_key->block_size)
|
||||||
return Compare_keys::NotEqual;
|
return Compare_keys::NotEqual;
|
||||||
|
|
||||||
|
/*
|
||||||
|
Rebuild the index if following condition get satisfied:
|
||||||
|
|
||||||
|
(i) Old table doesn't have primary key, new table has it and vice-versa
|
||||||
|
(ii) Primary key changed to another existing index
|
||||||
|
*/
|
||||||
|
if ((new_key == new_pk) != (table_key == old_pk))
|
||||||
|
return Compare_keys::NotEqual;
|
||||||
|
|
||||||
if (engine_options_differ(table_key->option_struct, new_key->option_struct,
|
if (engine_options_differ(table_key->option_struct, new_key->option_struct,
|
||||||
table->file->ht->index_options))
|
table->file->ht->index_options))
|
||||||
return Compare_keys::NotEqual;
|
return Compare_keys::NotEqual;
|
||||||
|
|
||||||
const KEY_PART_INFO *end=
|
Compare_keys result= Compare_keys::Equal;
|
||||||
table_key->key_part + table_key->user_defined_key_parts;
|
|
||||||
for (const KEY_PART_INFO *key_part= table_key->key_part,
|
for (const KEY_PART_INFO *
|
||||||
*new_part= new_key->key_part;
|
key_part= table_key->key_part,
|
||||||
|
*new_part= new_key->key_part,
|
||||||
|
*end= table_key->key_part + table_key->user_defined_key_parts;
|
||||||
key_part < end; key_part++, new_part++)
|
key_part < end; key_part++, new_part++)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
|
@ -6618,61 +6648,23 @@ Compare_keys compare_keys_but_name(const KEY *table_key, const KEY *new_key,
|
||||||
object with adjusted length. So below we have to check field
|
object with adjusted length. So below we have to check field
|
||||||
indexes instead of simply comparing pointers to Field objects.
|
indexes instead of simply comparing pointers to Field objects.
|
||||||
*/
|
*/
|
||||||
Create_field *new_field= alter_info->create_list.elem(new_part->fieldnr);
|
const Create_field &new_field=
|
||||||
if (!new_field->field ||
|
*alter_info->create_list.elem(new_part->fieldnr);
|
||||||
new_field->field->field_index != key_part->fieldnr - 1)
|
|
||||||
|
if (!new_field.field ||
|
||||||
|
new_field.field->field_index != key_part->fieldnr - 1)
|
||||||
|
{
|
||||||
return Compare_keys::NotEqual;
|
return Compare_keys::NotEqual;
|
||||||
|
|
||||||
/*
|
|
||||||
If there is a change in index length due to column expansion
|
|
||||||
like varchar(X) changed to varchar(X + N) and has a compatible
|
|
||||||
packed data representation, we mark it for fast/INPLACE change
|
|
||||||
in index definition. InnoDB supports INPLACE for this cases
|
|
||||||
|
|
||||||
Key definition has changed if we are using a different field or
|
|
||||||
if the user key part length is different.
|
|
||||||
*/
|
|
||||||
const Field *old_field= table->field[key_part->fieldnr - 1];
|
|
||||||
|
|
||||||
bool is_equal= old_field->is_equal(*new_field);
|
|
||||||
/* TODO: below is an InnoDB specific code which should be moved to InnoDB */
|
|
||||||
if (!is_equal)
|
|
||||||
{
|
|
||||||
if (!key_part->field->can_be_converted_by_engine(*new_field))
|
|
||||||
return Compare_keys::NotEqual;
|
|
||||||
|
|
||||||
if (!Charset(old_field->charset())
|
|
||||||
.eq_collation_specific_names(new_field->charset))
|
|
||||||
return Compare_keys::NotEqual;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (key_part->length != new_part->length)
|
auto compare= table->file->compare_key_parts(
|
||||||
{
|
*table->field[key_part->fieldnr - 1], new_field, *key_part, *new_part);
|
||||||
if (key_part->length != old_field->field_length ||
|
result= merge(result, compare);
|
||||||
key_part->length >= new_part->length || is_equal)
|
|
||||||
{
|
|
||||||
return Compare_keys::NotEqual;
|
|
||||||
}
|
|
||||||
result= Compare_keys::EqualButKeyPartLength;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
Rebuild the index if following condition get satisfied:
|
|
||||||
|
|
||||||
(i) Old table doesn't have primary key, new table has it and vice-versa
|
|
||||||
(ii) Primary key changed to another existing index
|
|
||||||
*/
|
|
||||||
if ((new_key == new_pk) != (table_key == old_pk))
|
|
||||||
return Compare_keys::NotEqual;
|
|
||||||
|
|
||||||
/* Check that key comment is not changed. */
|
/* Check that key comment is not changed. */
|
||||||
if (cmp(table_key->comment, new_key->comment) != 0)
|
if (cmp(table_key->comment, new_key->comment) != 0)
|
||||||
{
|
result= merge(result, Compare_keys::EqualButComment);
|
||||||
if (result != Compare_keys::Equal)
|
|
||||||
return Compare_keys::NotEqual;
|
|
||||||
result= Compare_keys::EqualButComment;
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
|
@ -21138,6 +21138,38 @@ ha_innobase::can_convert_blob(const Field_blob* field,
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Compare_keys ha_innobase::compare_key_parts(
|
||||||
|
const Field &old_field, const Column_definition &new_field,
|
||||||
|
const KEY_PART_INFO &old_part, const KEY_PART_INFO &new_part) const
|
||||||
|
{
|
||||||
|
const bool is_equal= old_field.is_equal(new_field);
|
||||||
|
|
||||||
|
if (!is_equal)
|
||||||
|
{
|
||||||
|
if (!old_field.can_be_converted_by_engine(new_field))
|
||||||
|
return Compare_keys::NotEqual;
|
||||||
|
|
||||||
|
if (!Charset(old_field.charset())
|
||||||
|
.eq_collation_specific_names(new_field.charset))
|
||||||
|
{
|
||||||
|
return Compare_keys::NotEqual;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (old_part.length != new_part.length)
|
||||||
|
{
|
||||||
|
if (old_part.length != old_field.field_length ||
|
||||||
|
old_part.length >= new_part.length || is_equal)
|
||||||
|
{
|
||||||
|
return Compare_keys::NotEqual;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Compare_keys::EqualButKeyPartLength;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Compare_keys::Equal;
|
||||||
|
}
|
||||||
|
|
||||||
/******************************************************************//**
|
/******************************************************************//**
|
||||||
Use this when the args are passed to the format string from
|
Use this when the args are passed to the format string from
|
||||||
errmsg-utf8.txt directly as is.
|
errmsg-utf8.txt directly as is.
|
||||||
|
|
|
@ -445,6 +445,11 @@ public:
|
||||||
/** @return whether innodb_strict_mode is active */
|
/** @return whether innodb_strict_mode is active */
|
||||||
bool is_innodb_strict_mode()
|
bool is_innodb_strict_mode()
|
||||||
{ return is_innodb_strict_mode(m_user_thd); }
|
{ return is_innodb_strict_mode(m_user_thd); }
|
||||||
|
Compare_keys
|
||||||
|
compare_key_parts(const Field& old_field,
|
||||||
|
const Column_definition& new_field,
|
||||||
|
const KEY_PART_INFO& old_part,
|
||||||
|
const KEY_PART_INFO& new_part) const override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
dberr_t innobase_get_autoinc(ulonglong* value);
|
dberr_t innobase_get_autoinc(ulonglong* value);
|
||||||
|
|
Loading…
Reference in a new issue