diff options
Diffstat (limited to 'sql/sql_table.cc')
-rw-r--r-- | sql/sql_table.cc | 67 |
1 files changed, 58 insertions, 9 deletions
diff --git a/sql/sql_table.cc b/sql/sql_table.cc index f98ac676525..a5cc386d740 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -2618,7 +2618,8 @@ int prepare_create_field(Create_field *sql_field, MAX_FIELD_CHARLENGTH) { my_printf_error(ER_TOO_BIG_FIELDLENGTH, ER(ER_TOO_BIG_FIELDLENGTH), - MYF(0), sql_field->field_name, MAX_FIELD_CHARLENGTH); + MYF(0), sql_field->field_name, + static_cast<ulong>(MAX_FIELD_CHARLENGTH)); DBUG_RETURN(1); } } @@ -3614,12 +3615,12 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info, (MODE_STRICT_TRANS_TABLES | MODE_STRICT_ALL_TABLES))) { my_error(ER_TOO_LONG_INDEX_COMMENT, MYF(0), - key_info->name, (uint) INDEX_COMMENT_MAXLEN); + key_info->name, static_cast<ulong>(INDEX_COMMENT_MAXLEN)); DBUG_RETURN(-1); } char warn_buff[MYSQL_ERRMSG_SIZE]; my_snprintf(warn_buff, sizeof(warn_buff), ER(ER_TOO_LONG_INDEX_COMMENT), - key_info->name, (uint) INDEX_COMMENT_MAXLEN); + key_info->name, static_cast<ulong>(INDEX_COMMENT_MAXLEN)); /* do not push duplicate warnings */ if (!check_duplicate_warning(thd, warn_buff, strlen(warn_buff))) push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN, @@ -3747,7 +3748,8 @@ static bool prepare_blob_field(THD *thd, Create_field *sql_field) MODE_STRICT_ALL_TABLES))) { my_error(ER_TOO_BIG_FIELDLENGTH, MYF(0), sql_field->field_name, - MAX_FIELD_VARCHARLENGTH / sql_field->charset->mbmaxlen); + static_cast<ulong>(MAX_FIELD_VARCHARLENGTH / + sql_field->charset->mbmaxlen)); DBUG_RETURN(1); } sql_field->sql_type= MYSQL_TYPE_BLOB; @@ -5678,6 +5680,8 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name, uint index_drop_count= 0; uint *index_drop_buffer= NULL; uint index_add_count= 0; + handler_add_index *add= NULL; + bool pending_inplace_add_index= false; uint *index_add_buffer= NULL; uint candidate_key_count= 0; bool no_pk; @@ -6432,6 +6436,9 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name, } thd->count_cuted_fields= CHECK_FIELD_IGNORE; + if (error) + goto err_new_table_cleanup; + /* If we did not need to copy, we might still need to add/drop indexes. */ if (! new_table) { @@ -6463,7 +6470,8 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name, key_part->field= table->field[key_part->fieldnr]; } /* Add the indexes. */ - if ((error= table->file->add_index(table, key_info, index_add_count))) + if ((error= table->file->add_index(table, key_info, index_add_count, + &add))) { /* Exchange the key_info for the error message. If we exchange @@ -6475,11 +6483,27 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name, table->key_info= save_key_info; goto err_new_table_cleanup; } + pending_inplace_add_index= true; } /*end of if (index_add_count)*/ if (index_drop_count) { + /* Currently we must finalize add index if we also drop indexes */ + if (pending_inplace_add_index) + { + /* Committing index changes needs exclusive metadata lock. */ + DBUG_ASSERT(thd->mdl_context.is_lock_owner(MDL_key::TABLE, + table_list->db, + table_list->table_name, + MDL_EXCLUSIVE)); + if ((error= table->file->final_add_index(add, true))) + { + table->file->print_error(error, MYF(0)); + goto err_new_table_cleanup; + } + pending_inplace_add_index= false; + } /* The prepare_drop_index() method takes an array of key numbers. */ key_numbers= (uint*) thd->alloc(sizeof(uint) * index_drop_count); keyno_p= key_numbers; @@ -6520,11 +6544,14 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name, } /*end of if (! new_table) for add/drop index*/ - if (error) - goto err_new_table_cleanup; - if (table->s->tmp_table != NO_TMP_TABLE) { + /* + In-place operations are not supported for temporary tables, so + we don't have to call final_add_index() in this case. The assert + verifies that in-place add index has not been done. + */ + DBUG_ASSERT(!pending_inplace_add_index); /* Close lock if this is a transactional table */ if (thd->lock) { @@ -6591,8 +6618,30 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name, my_casedn_str(files_charset_info, old_name); if (wait_while_table_is_used(thd, table, HA_EXTRA_PREPARE_FOR_RENAME)) + { + if (pending_inplace_add_index) + { + pending_inplace_add_index= false; + table->file->final_add_index(add, false); + } + // Mark this TABLE instance as stale to avoid out-of-sync index information. + table->m_needs_reopen= true; goto err_new_table_cleanup; - + } + if (pending_inplace_add_index) + { + pending_inplace_add_index= false; + DBUG_EXECUTE_IF("alter_table_rollback_new_index", { + table->file->final_add_index(add, false); + my_error(ER_UNKNOWN_ERROR, MYF(0)); + goto err_new_table_cleanup; + }); + if ((error= table->file->final_add_index(add, true))) + { + table->file->print_error(error, MYF(0)); + goto err_new_table_cleanup; + } + } close_all_tables_for_name(thd, table->s, new_name != table_name || new_db != db); |