mirror of
https://github.com/MariaDB/server.git
synced 2025-01-19 13:32:33 +01:00
[t:3987], merge hcr handlerton work to main
git-svn-id: file:///svn/mysql/tokudb-engine/tokudb-engine@38554 c7de825b-a66e-492c-adef-691d508d4ae1
This commit is contained in:
parent
c33f2ba0e7
commit
1017889c14
4 changed files with 128 additions and 15 deletions
|
@ -8029,7 +8029,7 @@ bool columns_have_default_null_blobs(
|
|||
return retval;
|
||||
}
|
||||
|
||||
bool tables_have_same_keys(TABLE* table, TABLE* altered_table, bool print_error) {
|
||||
bool tables_have_same_keys(TABLE* table, TABLE* altered_table, bool print_error, bool check_field_index) {
|
||||
bool retval;
|
||||
if (table->s->keys != altered_table->s->keys) {
|
||||
if (print_error) {
|
||||
|
@ -8116,7 +8116,13 @@ bool tables_have_same_keys(TABLE* table, TABLE* altered_table, bool print_error)
|
|||
retval = false;
|
||||
goto cleanup;
|
||||
}
|
||||
if (!are_two_fields_same(curr_orig_field,curr_altered_field)) {
|
||||
bool are_fields_same;
|
||||
are_fields_same = (check_field_index) ?
|
||||
(curr_orig_part->fieldnr == curr_altered_part->fieldnr &&
|
||||
fields_are_same_type(curr_orig_field, curr_altered_field)) :
|
||||
(are_two_fields_same(curr_orig_field,curr_altered_field));
|
||||
|
||||
if (!are_fields_same) {
|
||||
if (print_error) {
|
||||
sql_print_error(
|
||||
"Key %s has different field at index %d",
|
||||
|
@ -8144,7 +8150,7 @@ void ha_tokudb::print_alter_info(
|
|||
uint table_changes
|
||||
)
|
||||
{
|
||||
printf("***are keys of two tables same? %d\n", tables_have_same_keys(table,altered_table,false));
|
||||
printf("***are keys of two tables same? %d\n", tables_have_same_keys(table,altered_table,false, false));
|
||||
printf("***alter flags set ***\n");
|
||||
for (uint i = 0; i < HA_MAX_ALTER_FLAGS; i++) {
|
||||
if (alter_flags->is_set(i)) {
|
||||
|
@ -8244,22 +8250,85 @@ cleanup:
|
|||
return retval;
|
||||
}
|
||||
|
||||
bool column_rename_supported(
|
||||
HA_ALTER_INFO* alter_info,
|
||||
TABLE* orig_table,
|
||||
TABLE* new_table
|
||||
)
|
||||
{
|
||||
bool retval = false;
|
||||
bool keys_same_for_cr;
|
||||
uint num_fields_with_different_names = 0;
|
||||
uint field_with_different_name = orig_table->s->fields;
|
||||
if (orig_table->s->fields != new_table->s->fields) {
|
||||
retval = false;
|
||||
goto cleanup;
|
||||
}
|
||||
if (alter_info->contains_first_or_after) {
|
||||
retval = false;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
for (uint i = 0; i < orig_table->s->fields; i++) {
|
||||
Field* orig_field = orig_table->field[i];
|
||||
Field* new_field = new_table->field[i];
|
||||
if (!fields_are_same_type(orig_field, new_field)) {
|
||||
retval = false;
|
||||
goto cleanup;
|
||||
}
|
||||
if (!fields_have_same_name(orig_field, new_field)) {
|
||||
num_fields_with_different_names++;
|
||||
field_with_different_name = i;
|
||||
}
|
||||
}
|
||||
// only allow one renamed field
|
||||
if (num_fields_with_different_names != 1) {
|
||||
retval = false;
|
||||
goto cleanup;
|
||||
}
|
||||
assert(field_with_different_name < orig_table->s->fields);
|
||||
//
|
||||
// at this point, we have verified that the two tables have
|
||||
// the same field types and with ONLY one field with a different name.
|
||||
// We have also identified the field with the different name
|
||||
//
|
||||
// Now we need to check the indexes
|
||||
//
|
||||
keys_same_for_cr = tables_have_same_keys(
|
||||
orig_table,
|
||||
new_table,
|
||||
false,
|
||||
true
|
||||
);
|
||||
if (!keys_same_for_cr) {
|
||||
retval = false;
|
||||
goto cleanup;
|
||||
}
|
||||
retval = true;
|
||||
cleanup:
|
||||
return retval;
|
||||
}
|
||||
|
||||
int ha_tokudb::check_if_supported_alter(TABLE *altered_table,
|
||||
HA_CREATE_INFO *create_info,
|
||||
HA_ALTER_FLAGS *alter_flags,
|
||||
HA_ALTER_INFO *alter_info,
|
||||
uint table_changes)
|
||||
{
|
||||
TOKUDB_DBUG_ENTER("check_if_supported_alter");
|
||||
int retval;
|
||||
THD* thd = ha_thd();
|
||||
bool keys_same = tables_have_same_keys(table,altered_table, false);
|
||||
bool keys_same = tables_have_same_keys(table,altered_table, false, false);
|
||||
|
||||
|
||||
if (tokudb_debug & TOKUDB_DEBUG_ALTER_TABLE_INFO) {
|
||||
printf("has after or first %d\n", alter_info->contains_first_or_after);
|
||||
print_alter_info(altered_table, create_info, alter_flags, table_changes);
|
||||
}
|
||||
bool has_added_columns = alter_flags->is_set(HA_ADD_COLUMN);
|
||||
bool has_dropped_columns = alter_flags->is_set(HA_DROP_COLUMN);
|
||||
bool has_column_rename = alter_flags->is_set(HA_CHANGE_COLUMN) &&
|
||||
alter_flags->is_set(HA_ALTER_COLUMN_NAME);
|
||||
//
|
||||
// We do not check for changes to foreign keys or primary keys. They are not supported
|
||||
// Changing the primary key implies changing keys in all dictionaries. that is why we don't
|
||||
|
@ -8272,6 +8341,7 @@ int ha_tokudb::check_if_supported_alter(TABLE *altered_table,
|
|||
bool has_non_indexing_changes = false;
|
||||
bool has_non_dropped_changes = false;
|
||||
bool has_non_added_changes = false;
|
||||
bool has_non_column_rename_changes = false;
|
||||
for (uint i = 0; i < HA_MAX_ALTER_FLAGS; i++) {
|
||||
if (i == HA_DROP_INDEX ||
|
||||
i == HA_DROP_UNIQUE_INDEX ||
|
||||
|
@ -8285,6 +8355,17 @@ int ha_tokudb::check_if_supported_alter(TABLE *altered_table,
|
|||
break;
|
||||
}
|
||||
}
|
||||
for (uint i = 0; i < HA_MAX_ALTER_FLAGS; i++) {
|
||||
if (i == HA_ALTER_COLUMN_NAME||
|
||||
i == HA_CHANGE_COLUMN)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (alter_flags->is_set(i)) {
|
||||
has_non_column_rename_changes = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
for (uint i = 0; i < HA_MAX_ALTER_FLAGS; i++) {
|
||||
if (i == HA_DROP_COLUMN) {
|
||||
continue;
|
||||
|
@ -8406,6 +8487,29 @@ int ha_tokudb::check_if_supported_alter(TABLE *altered_table,
|
|||
else if (has_added_columns && !has_non_added_changes) {
|
||||
retval = HA_ALTER_SUPPORTED_WAIT_LOCK;
|
||||
}
|
||||
else if (has_column_rename && !has_non_column_rename_changes) {
|
||||
// we have identified a possible column rename,
|
||||
// but let's do some more checks
|
||||
|
||||
// we will only allow an hcr if there are no changes
|
||||
// in column positions
|
||||
if (alter_info->contains_first_or_after) {
|
||||
retval = (get_disable_slow_alter(thd)) ? HA_ALTER_ERROR : HA_ALTER_NOT_SUPPORTED;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
// now need to verify that one and only one column
|
||||
// has changed only its name. If we find anything to
|
||||
// the contrary, we don't allow it, also check indexes
|
||||
|
||||
bool cr_supported = column_rename_supported(alter_info, table, altered_table);
|
||||
if (cr_supported) {
|
||||
retval = HA_ALTER_SUPPORTED_WAIT_LOCK;
|
||||
}
|
||||
else {
|
||||
retval = (get_disable_slow_alter(thd)) ? HA_ALTER_ERROR : HA_ALTER_NOT_SUPPORTED;
|
||||
}
|
||||
}
|
||||
else {
|
||||
retval = (get_disable_slow_alter(thd)) ? HA_ALTER_ERROR : HA_ALTER_NOT_SUPPORTED;
|
||||
}
|
||||
|
@ -8841,8 +8945,8 @@ int ha_tokudb::alter_table_phase2(
|
|||
u_int32_t max_new_desc_size = 0;
|
||||
uchar* row_desc_buff = NULL;
|
||||
uchar* column_extra = NULL;
|
||||
bool dropping_indexes = alter_info->index_drop_count > 0 && !tables_have_same_keys(table,altered_table,false);
|
||||
bool adding_indexes = alter_info->index_add_count > 0 && !tables_have_same_keys(table,altered_table,false);
|
||||
bool dropping_indexes = alter_info->index_drop_count > 0 && !tables_have_same_keys(table,altered_table,false, false);
|
||||
bool adding_indexes = alter_info->index_add_count > 0 && !tables_have_same_keys(table,altered_table,false, false);
|
||||
tokudb_trx_data* trx = (tokudb_trx_data *) thd_data_get(thd, tokudb_hton->slot);
|
||||
|
||||
is_fast_alter_running = true;
|
||||
|
@ -8926,7 +9030,7 @@ int ha_tokudb::alter_table_phase2(
|
|||
error = HA_ERR_UNSUPPORTED;
|
||||
goto cleanup;
|
||||
}
|
||||
if (!tables_have_same_keys(table, altered_table, true)) {
|
||||
if (!tables_have_same_keys(table, altered_table, true, false)) {
|
||||
error = HA_ERR_UNSUPPORTED;
|
||||
goto cleanup;
|
||||
}
|
||||
|
|
|
@ -567,6 +567,7 @@ public:
|
|||
int check_if_supported_alter(TABLE *altered_table,
|
||||
HA_CREATE_INFO *create_info,
|
||||
HA_ALTER_FLAGS *alter_flags,
|
||||
HA_ALTER_INFO *alter_info,
|
||||
uint table_changes
|
||||
);
|
||||
int alter_table_phase1(THD *thd,
|
||||
|
|
|
@ -2861,8 +2861,7 @@ bool fields_have_same_name(
|
|||
return strcmp(a->field_name, b->field_name) == 0;
|
||||
}
|
||||
|
||||
|
||||
bool are_two_fields_same(
|
||||
bool fields_are_same_type(
|
||||
Field* a,
|
||||
Field* b
|
||||
)
|
||||
|
@ -2871,11 +2870,6 @@ bool are_two_fields_same(
|
|||
enum_field_types a_mysql_type = a->real_type();
|
||||
enum_field_types b_mysql_type = b->real_type();
|
||||
// make sure have same names
|
||||
if (strcmp(a->field_name, b->field_name) != 0) {
|
||||
retval = false;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
// make sure have same types
|
||||
if (a_mysql_type != b_mysql_type) {
|
||||
retval = false;
|
||||
|
@ -2999,3 +2993,12 @@ cleanup:
|
|||
}
|
||||
|
||||
|
||||
bool are_two_fields_same(
|
||||
Field* a,
|
||||
Field* b
|
||||
)
|
||||
{
|
||||
return fields_have_same_name(a, b) && fields_are_same_type(a, b);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -366,6 +366,11 @@ bool fields_have_same_name(
|
|||
Field* b
|
||||
);
|
||||
|
||||
bool fields_are_same_type(
|
||||
Field* a,
|
||||
Field* b
|
||||
);
|
||||
|
||||
bool are_two_fields_same(
|
||||
Field* a,
|
||||
Field* b
|
||||
|
|
Loading…
Reference in a new issue