diff options
Diffstat (limited to 'storage/innobase/handler/handler0alter.cc')
-rw-r--r-- | storage/innobase/handler/handler0alter.cc | 131 |
1 files changed, 79 insertions, 52 deletions
diff --git a/storage/innobase/handler/handler0alter.cc b/storage/innobase/handler/handler0alter.cc index f9791f5fa97..153484c9941 100644 --- a/storage/innobase/handler/handler0alter.cc +++ b/storage/innobase/handler/handler0alter.cc @@ -400,7 +400,10 @@ innobase_need_rebuild( const Alter_inplace_info* ha_alter_info, const TABLE* altered_table) { - if (ha_alter_info->handler_flags + Alter_inplace_info::HA_ALTER_FLAGS alter_inplace_flags = + ha_alter_info->handler_flags & ~(INNOBASE_INPLACE_IGNORE); + + if (alter_inplace_flags == Alter_inplace_info::CHANGE_CREATE_OPTION && !(ha_alter_info->create_info->used_fields & (HA_CREATE_USED_ROW_FORMAT @@ -1293,7 +1296,6 @@ innobase_find_fk_index( while (index != NULL) { if (!(index->type & DICT_FTS) - && !dict_index_has_virtual(index) && dict_foreign_qualify_index( table, col_names, columns, n_cols, index, NULL, true, 0, @@ -2466,6 +2468,7 @@ innobase_fts_check_doc_id_index_in_def( return(FTS_NOT_EXIST_DOC_ID_INDEX); } + /*******************************************************************//** Create an index table where indexes are ordered as follows: @@ -2534,35 +2537,16 @@ innobase_create_key_defs( (only prefix/part of the column is indexed), MySQL will treat the index as a PRIMARY KEY unless the table already has one. */ - if (n_add > 0 && !new_primary && got_default_clust - && (key_info[*add].flags & HA_NOSAME) - && !(key_info[*add].flags & HA_KEY_HAS_PART_KEY_SEG)) { - uint key_part = key_info[*add].user_defined_key_parts; - - new_primary = true; - - while (key_part--) { - const uint maybe_null - = key_info[*add].key_part[key_part].key_type - & FIELDFLAG_MAYBE_NULL; - bool is_v - = innobase_is_v_fld( - key_info[*add].key_part[key_part].field); - DBUG_ASSERT(!maybe_null - == !key_info[*add].key_part[key_part]. - field->real_maybe_null()); - - if (maybe_null || is_v) { - new_primary = false; - break; - } - } + ut_ad(altered_table->s->primary_key == 0 + || altered_table->s->primary_key == MAX_KEY); + + if (got_default_clust && !new_primary) { + new_primary = (altered_table->s->primary_key != MAX_KEY); } const bool rebuild = new_primary || add_fts_doc_id || innobase_need_rebuild(ha_alter_info, table); - /* Reserve one more space if new_primary is true, and we might need to add the FTS_DOC_ID_INDEX */ indexdef = indexdefs = static_cast<index_def_t*>( @@ -2576,8 +2560,14 @@ innobase_create_key_defs( ulint primary_key_number; if (new_primary) { - DBUG_ASSERT(n_add > 0); - primary_key_number = *add; + if (n_add == 0) { + DBUG_ASSERT(got_default_clust); + DBUG_ASSERT(altered_table->s->primary_key + == 0); + primary_key_number = 0; + } else { + primary_key_number = *add; + } } else if (got_default_clust) { /* Create the GEN_CLUST_INDEX */ index_def_t* index = indexdef++; @@ -4782,6 +4772,8 @@ new_clustered_failed: ctx->add_cols = add_cols; } else { DBUG_ASSERT(!innobase_need_rebuild(ha_alter_info, old_table)); + DBUG_ASSERT(old_table->s->primary_key + == altered_table->s->primary_key); for (dict_index_t* index = dict_table_get_first_index(user_table); @@ -6082,7 +6074,7 @@ err_exit: } if (!(ha_alter_info->handler_flags & INNOBASE_ALTER_DATA) - || (ha_alter_info->handler_flags + || ((ha_alter_info->handler_flags & ~INNOBASE_INPLACE_IGNORE) == Alter_inplace_info::CHANGE_CREATE_OPTION && !innobase_need_rebuild(ha_alter_info, table))) { @@ -6306,6 +6298,26 @@ alter_templ_needs_rebuild( return(false); } +/** Get the name of an erroneous key. +@param[in] error_key_num InnoDB number of the erroneus key +@param[in] ha_alter_info changes that were being performed +@param[in] table InnoDB table +@return the name of the erroneous key */ +static +const char* +get_error_key_name( + ulint error_key_num, + const Alter_inplace_info* ha_alter_info, + const dict_table_t* table) +{ + if (error_key_num == ULINT_UNDEFINED) { + return(FTS_DOC_ID_INDEX_NAME); + } else if (ha_alter_info->key_count == 0) { + return(dict_table_get_first_index(table)->name); + } else { + return(ha_alter_info->key_info_buffer[error_key_num].name); + } +} /** Alter the table structure in-place with operations specified using Alter_inplace_info. @@ -6346,7 +6358,7 @@ ok_exit: DBUG_RETURN(false); } - if (ha_alter_info->handler_flags + if ((ha_alter_info->handler_flags & ~INNOBASE_INPLACE_IGNORE) == Alter_inplace_info::CHANGE_CREATE_OPTION && !innobase_need_rebuild(ha_alter_info, table)) { goto ok_exit; @@ -6443,15 +6455,6 @@ ok_exit: ctx->add_autoinc, ctx->sequence, ctx->skip_pk_sort, ctx->m_stage, add_v, eval_table); - if (s_templ) { - ut_ad(ctx->need_rebuild() || ctx->num_to_add_vcol > 0 - || rebuild_templ); - dict_free_vc_templ(s_templ); - UT_DELETE(s_templ); - - ctx->new_table->vc_templ = old_templ; - } - #ifndef DBUG_OFF oom: #endif /* !DBUG_OFF */ @@ -6467,6 +6470,15 @@ oom: onlineddl_rowlog_pct_used = 0; onlineddl_pct_progress = 0; + if (s_templ) { + ut_ad(ctx->need_rebuild() || ctx->num_to_add_vcol > 0 + || rebuild_templ); + dict_free_vc_templ(s_templ); + UT_DELETE(s_templ); + + ctx->new_table->vc_templ = old_templ; + } + DEBUG_SYNC_C("inplace_after_index_build"); DBUG_EXECUTE_IF("create_index_fail", @@ -6506,17 +6518,13 @@ oom: case DB_ONLINE_LOG_TOO_BIG: DBUG_ASSERT(ctx->online); my_error(ER_INNODB_ONLINE_LOG_TOO_BIG, MYF(0), - (m_prebuilt->trx->error_key_num == ULINT_UNDEFINED) - ? FTS_DOC_ID_INDEX_NAME - : ha_alter_info->key_info_buffer[ - m_prebuilt->trx->error_key_num].name); + get_error_key_name(m_prebuilt->trx->error_key_num, + ha_alter_info, m_prebuilt->table)); break; case DB_INDEX_CORRUPT: my_error(ER_INDEX_CORRUPT, MYF(0), - (m_prebuilt->trx->error_key_num == ULINT_UNDEFINED) - ? FTS_DOC_ID_INDEX_NAME - : ha_alter_info->key_info_buffer[ - m_prebuilt->trx->error_key_num].name); + get_error_key_name(m_prebuilt->trx->error_key_num, + ha_alter_info, m_prebuilt->table)); break; case DB_DECRYPTION_FAILED: { String str; @@ -7724,11 +7732,31 @@ commit_try_rebuild( if (ctx->online) { DEBUG_SYNC_C("row_log_table_apply2_before"); + dict_vcol_templ_t* s_templ = NULL; + + if (ctx->new_table->n_v_cols > 0) { + s_templ = UT_NEW_NOKEY( + dict_vcol_templ_t()); + s_templ->vtempl = NULL; + + innobase_build_v_templ( + altered_table, ctx->new_table, s_templ, + NULL, true); + ctx->new_table->vc_templ = s_templ; + } + error = row_log_table_apply( ctx->thr, user_table, altered_table, static_cast<ha_innobase_inplace_ctx*>( ha_alter_info->handler_ctx)->m_stage); + if (s_templ) { + ut_ad(ctx->need_rebuild()); + dict_free_vc_templ(s_templ); + UT_DELETE(s_templ); + ctx->new_table->vc_templ = NULL; + } + ulint err_key = thr_get_trx(ctx->thr)->error_key_num; switch (error) { @@ -7750,14 +7778,13 @@ commit_try_rebuild( DBUG_RETURN(true); case DB_ONLINE_LOG_TOO_BIG: my_error(ER_INNODB_ONLINE_LOG_TOO_BIG, MYF(0), - ha_alter_info->key_info_buffer[0].name); + get_error_key_name(err_key, ha_alter_info, + rebuilt_table)); DBUG_RETURN(true); case DB_INDEX_CORRUPT: my_error(ER_INDEX_CORRUPT, MYF(0), - (err_key == ULINT_UNDEFINED) - ? FTS_DOC_ID_INDEX_NAME - : ha_alter_info->key_info_buffer[err_key] - .name); + get_error_key_name(err_key, ha_alter_info, + rebuilt_table)); DBUG_RETURN(true); default: my_error_innodb(error, table_name, user_table->flags); |