diff options
Diffstat (limited to 'storage/xtradb/handler/handler0alter.cc')
-rw-r--r-- | storage/xtradb/handler/handler0alter.cc | 89 |
1 files changed, 73 insertions, 16 deletions
diff --git a/storage/xtradb/handler/handler0alter.cc b/storage/xtradb/handler/handler0alter.cc index 21859cb5447..13c6752ce8f 100644 --- a/storage/xtradb/handler/handler0alter.cc +++ b/storage/xtradb/handler/handler0alter.cc @@ -46,7 +46,7 @@ Smart ALTER TABLE #include "srv0mon.h" #include "fts0priv.h" #include "pars0pars.h" - +#include "row0sel.h" #include "ha_innodb.h" /** Operations for creating secondary indexes (no rebuild needed) */ @@ -240,6 +240,7 @@ ha_innobase::check_if_supported_inplace_alter( innobase_get_err_msg(ER_READ_ONLY_MODE); DBUG_RETURN(HA_ALTER_INPLACE_NOT_SUPPORTED); } else if (srv_created_new_raw || srv_force_recovery) { + ha_alter_info->unsupported_reason = innobase_get_err_msg(ER_READ_ONLY_MODE); DBUG_RETURN(HA_ALTER_INPLACE_NOT_SUPPORTED); @@ -2532,15 +2533,16 @@ innobase_drop_fts_index_table( /** Get the new column names if any columns were renamed @param ha_alter_info Data used during in-place alter @param altered_table MySQL table that is being altered +@param table MySQL table as it is before the ALTER operation @param user_table InnoDB table as it is before the ALTER operation @param heap Memory heap for the allocation @return array of new column names in rebuilt_table, or NULL if not renamed */ static __attribute__((nonnull, warn_unused_result)) const char** innobase_get_col_names( -/*===================*/ Alter_inplace_info* ha_alter_info, const TABLE* altered_table, + const TABLE* table, const dict_table_t* user_table, mem_heap_t* heap) { @@ -2548,19 +2550,31 @@ innobase_get_col_names( uint i; DBUG_ENTER("innobase_get_col_names"); - DBUG_ASSERT(user_table->n_def > altered_table->s->fields); + DBUG_ASSERT(user_table->n_def > table->s->fields); DBUG_ASSERT(ha_alter_info->handler_flags & Alter_inplace_info::ALTER_COLUMN_NAME); cols = static_cast<const char**>( - mem_heap_alloc(heap, user_table->n_def * sizeof *cols)); + mem_heap_zalloc(heap, user_table->n_def * sizeof *cols)); + + i = 0; + List_iterator_fast<Create_field> cf_it( + ha_alter_info->alter_info->create_list); + while (const Create_field* new_field = cf_it++) { + DBUG_ASSERT(i < altered_table->s->fields); - for (i = 0; i < altered_table->s->fields; i++) { - const Field* field = altered_table->field[i]; - cols[i] = field->field_name; + for (uint old_i = 0; table->field[old_i]; old_i++) { + if (new_field->field == table->field[old_i]) { + cols[old_i] = new_field->field_name; + break; + } + } + + i++; } /* Copy the internal column names. */ + i = table->s->fields; cols[i] = dict_table_get_col_name(user_table, i); while (++i < user_table->n_def) { @@ -2776,7 +2790,7 @@ prepare_inplace_alter_table_dict( /* The initial space id 0 may be overridden later. */ ctx->new_table = dict_mem_table_create( - new_table_name, 0, n_cols, flags, flags2); + new_table_name, 0, n_cols, flags, flags2, false); /* The rebuilt indexed_table will use the renamed column names. */ ctx->col_names = NULL; @@ -3346,6 +3360,9 @@ ha_innobase::prepare_inplace_alter_table( ulint fts_doc_col_no = ULINT_UNDEFINED; bool add_fts_doc_id = false; bool add_fts_doc_id_idx = false; +#ifdef _WIN32 + bool add_fts_idx = false; +#endif /* _WIN32 */ DBUG_ENTER("prepare_inplace_alter_table"); DBUG_ASSERT(!ha_alter_info->handler_ctx); @@ -3494,6 +3511,9 @@ check_if_ok_to_rename: & ~(HA_FULLTEXT | HA_PACK_KEY | HA_BINARY_PACK_KEY))); +#ifdef _WIN32 + add_fts_idx = true; +#endif /* _WIN32 */ continue; } @@ -3504,6 +3524,20 @@ check_if_ok_to_rename: } } +#ifdef _WIN32 + /* We won't be allowed to add fts index to a table with + fts indexes already but without AUX_HEX_NAME set. + This means the aux tables of the table failed to + rename to hex format but new created aux tables + shall be in hex format, which is contradictory. + It's only for Windows. */ + if (!DICT_TF2_FLAG_IS_SET(indexed_table, DICT_TF2_FTS_AUX_HEX_NAME) + && indexed_table->fts != NULL && add_fts_idx) { + my_error(ER_INNODB_FT_AUX_NOT_HEX_ID, MYF(0)); + goto err_exit_no_heap; + } +#endif /* _WIN32 */ + /* Check existing index definitions for too-long column prefixes as well, in case max_col_len shrunk. */ for (const dict_index_t* index @@ -3537,8 +3571,8 @@ check_if_ok_to_rename: if (ha_alter_info->handler_flags & Alter_inplace_info::ALTER_COLUMN_NAME) { col_names = innobase_get_col_names( - ha_alter_info, altered_table, indexed_table, - heap); + ha_alter_info, altered_table, table, + indexed_table, heap); } else { col_names = NULL; } @@ -4608,16 +4642,39 @@ commit_get_autoinc( & Alter_inplace_info::CHANGE_CREATE_OPTION) && (ha_alter_info->create_info->used_fields & HA_CREATE_USED_AUTO)) { - /* An AUTO_INCREMENT value was supplied, but the table - was not rebuilt. Get the user-supplied value or the - last value from the sequence. */ - ut_ad(old_table->found_next_number_field); + /* An AUTO_INCREMENT value was supplied, but the table was not + rebuilt. Get the user-supplied value or the last value from the + sequence. */ + ib_uint64_t max_value_table; + dberr_t err; + + Field* autoinc_field = + old_table->found_next_number_field; + + dict_index_t* index = dict_table_get_index_on_first_col( + ctx->old_table, autoinc_field->field_index); max_autoinc = ha_alter_info->create_info->auto_increment_value; dict_table_autoinc_lock(ctx->old_table); - if (max_autoinc < ctx->old_table->autoinc) { - max_autoinc = ctx->old_table->autoinc; + + err = row_search_max_autoinc( + index, autoinc_field->field_name, &max_value_table); + + if (err != DB_SUCCESS) { + ut_ad(0); + max_autoinc = 0; + } else if (max_autoinc <= max_value_table) { + ulonglong col_max_value; + ulonglong offset; + + col_max_value = innobase_get_int_col_max_value( + old_table->found_next_number_field); + + offset = ctx->prebuilt->autoinc_offset; + max_autoinc = innobase_next_autoinc( + max_value_table, 1, 1, offset, + col_max_value); } dict_table_autoinc_unlock(ctx->old_table); } else { |