mirror of
https://github.com/MariaDB/server.git
synced 2025-12-24 11:21:21 +03:00
merge with MySQL 5.5.27
manually checked every change, reverted incorrect or stupid changes.
This commit is contained in:
@@ -6096,8 +6096,26 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name,
|
||||
}
|
||||
else
|
||||
{
|
||||
MDL_request_list mdl_requests;
|
||||
MDL_request target_db_mdl_request;
|
||||
|
||||
target_mdl_request.init(MDL_key::TABLE, new_db, new_name,
|
||||
MDL_EXCLUSIVE, MDL_TRANSACTION);
|
||||
mdl_requests.push_front(&target_mdl_request);
|
||||
|
||||
/*
|
||||
If we are moving the table to a different database, we also
|
||||
need IX lock on the database name so that the target database
|
||||
is protected by MDL while the table is moved.
|
||||
*/
|
||||
if (new_db != db)
|
||||
{
|
||||
target_db_mdl_request.init(MDL_key::SCHEMA, new_db, "",
|
||||
MDL_INTENTION_EXCLUSIVE,
|
||||
MDL_TRANSACTION);
|
||||
mdl_requests.push_front(&target_db_mdl_request);
|
||||
}
|
||||
|
||||
/*
|
||||
Global intention exclusive lock must have been already acquired when
|
||||
table to be altered was open, so there is no need to do it here.
|
||||
@@ -6106,14 +6124,10 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name,
|
||||
"", "",
|
||||
MDL_INTENTION_EXCLUSIVE));
|
||||
|
||||
if (thd->mdl_context.try_acquire_lock(&target_mdl_request))
|
||||
if (thd->mdl_context.acquire_locks(&mdl_requests,
|
||||
thd->variables.lock_wait_timeout))
|
||||
DBUG_RETURN(TRUE);
|
||||
if (target_mdl_request.ticket == NULL)
|
||||
{
|
||||
/* Table exists and is locked by some thread. */
|
||||
my_error(ER_TABLE_EXISTS_ERROR, MYF(0), new_alias);
|
||||
DBUG_RETURN(TRUE);
|
||||
}
|
||||
|
||||
DEBUG_SYNC(thd, "locked_table_name");
|
||||
/*
|
||||
Table maybe does not exist, but we got an exclusive lock
|
||||
@@ -6539,11 +6553,23 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name,
|
||||
the primary key is not added and dropped in the same statement.
|
||||
Otherwise we have to recreate the table.
|
||||
need_copy_table is no-zero at this place.
|
||||
|
||||
Also, in-place is not possible if we add a primary key
|
||||
and drop another key in the same statement. If the drop fails,
|
||||
we will not be able to revert adding of primary key.
|
||||
*/
|
||||
if ( pk_changed < 2 )
|
||||
{
|
||||
if ((alter_flags & needed_inplace_with_read_flags) ==
|
||||
needed_inplace_with_read_flags)
|
||||
if ((needed_inplace_with_read_flags & HA_INPLACE_ADD_PK_INDEX_NO_WRITE) &&
|
||||
index_drop_count > 0)
|
||||
{
|
||||
/*
|
||||
Do copy, not in-place ALTER.
|
||||
Avoid setting ALTER_TABLE_METADATA_ONLY.
|
||||
*/
|
||||
}
|
||||
else if ((alter_flags & needed_inplace_with_read_flags) ==
|
||||
needed_inplace_with_read_flags)
|
||||
{
|
||||
/* All required in-place flags to allow concurrent reads are present. */
|
||||
need_copy_table= ALTER_TABLE_METADATA_ONLY;
|
||||
@@ -6821,17 +6847,38 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name,
|
||||
Tell the handler to prepare for drop indexes.
|
||||
This re-numbers the indexes to get rid of gaps.
|
||||
*/
|
||||
if ((error= table->file->prepare_drop_index(table, key_numbers,
|
||||
index_drop_count)))
|
||||
error= table->file->prepare_drop_index(table, key_numbers,
|
||||
index_drop_count);
|
||||
if (!error)
|
||||
{
|
||||
table->file->print_error(error, MYF(0));
|
||||
goto err_new_table_cleanup;
|
||||
/* Tell the handler to finally drop the indexes. */
|
||||
error= table->file->final_drop_index(table);
|
||||
}
|
||||
|
||||
/* Tell the handler to finally drop the indexes. */
|
||||
if ((error= table->file->final_drop_index(table)))
|
||||
if (error)
|
||||
{
|
||||
table->file->print_error(error, MYF(0));
|
||||
if (index_add_count) // Drop any new indexes added.
|
||||
{
|
||||
/*
|
||||
Temporarily set table-key_info to include information about the
|
||||
indexes added above that we now need to drop.
|
||||
*/
|
||||
KEY *save_key_info= table->key_info;
|
||||
table->key_info= key_info_buffer;
|
||||
if ((error= table->file->prepare_drop_index(table, index_add_buffer,
|
||||
index_add_count)))
|
||||
table->file->print_error(error, MYF(0));
|
||||
else if ((error= table->file->final_drop_index(table)))
|
||||
table->file->print_error(error, MYF(0));
|
||||
table->key_info= save_key_info;
|
||||
}
|
||||
|
||||
/*
|
||||
Mark this TABLE instance as stale to avoid
|
||||
out-of-sync index information.
|
||||
*/
|
||||
table->m_needs_reopen= true;
|
||||
goto err_new_table_cleanup;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user