Merge remote-tracking branch 'origin/10.0' into 10.1

This commit is contained in:
Monty 2018-05-24 11:08:02 +03:00
commit e744c687ca
31 changed files with 606 additions and 131 deletions

View file

@ -302,7 +302,7 @@ static bool mysql_admin_table(THD* thd, TABLE_LIST* tables,
HA_CHECK_OPT* check_opt,
const char *operator_name,
thr_lock_type lock_type,
bool open_for_modify,
bool org_open_for_modify,
bool repair_table_use_frm,
uint extra_open_options,
int (*prepare_func)(THD *, TABLE_LIST *,
@ -365,10 +365,11 @@ static bool mysql_admin_table(THD* thd, TABLE_LIST* tables,
for (table= tables; table; table= table->next_local)
{
char table_name[SAFE_NAME_LEN*2+2];
char* db = table->db;
char *db= table->db;
bool fatal_error=0;
bool open_error;
bool collect_eis= FALSE;
bool open_for_modify= org_open_for_modify;
DBUG_PRINT("admin", ("table: '%s'.'%s'", table->db, table->table_name));
strxmov(table_name, db, ".", table->table_name, NullS);
@ -406,8 +407,8 @@ static bool mysql_admin_table(THD* thd, TABLE_LIST* tables,
/*
CHECK TABLE command is allowed for views as well. Check on alter flags
to differentiate from ALTER TABLE...CHECK PARTITION on which view is not
allowed.
to differentiate from ALTER TABLE...CHECK PARTITION on which view is
not allowed.
*/
if (lex->alter_info.flags & Alter_info::ALTER_ADMIN_PARTITION ||
view_operator_func == NULL)
@ -1102,7 +1103,7 @@ send_result_message:
}
}
/* Error path, a admin command failed. */
if (thd->transaction_rollback_request)
if (thd->transaction_rollback_request || fatal_error)
{
/*
Unlikely, but transaction rollback was requested by one of storage

View file

@ -155,10 +155,11 @@ static void mysql_ha_close_table(SQL_HANDLER *handler)
{
THD *thd= handler->thd;
TABLE *table= handler->table;
DBUG_ENTER("mysql_ha_close_table");
/* check if table was already closed */
if (!table)
return;
DBUG_VOID_RETURN;
if (!table->s->tmp_table)
{
@ -184,6 +185,7 @@ static void mysql_ha_close_table(SQL_HANDLER *handler)
}
my_free(handler->lock);
handler->init();
DBUG_VOID_RETURN;
}
/*

View file

@ -520,6 +520,8 @@ void init_update_queries(void)
There are other statements that deal with temporary tables and open
them, but which are not listed here. The thing is that the order of
pre-opening temporary tables for those statements is somewhat custom.
Note that SQLCOM_RENAME_TABLE should not be in this list!
*/
sql_command_flags[SQLCOM_CREATE_TABLE]|= CF_PREOPEN_TMP_TABLES;
sql_command_flags[SQLCOM_DROP_TABLE]|= CF_PREOPEN_TMP_TABLES;
@ -533,7 +535,6 @@ void init_update_queries(void)
sql_command_flags[SQLCOM_INSERT_SELECT]|= CF_PREOPEN_TMP_TABLES;
sql_command_flags[SQLCOM_DELETE]|= CF_PREOPEN_TMP_TABLES;
sql_command_flags[SQLCOM_DELETE_MULTI]|= CF_PREOPEN_TMP_TABLES;
sql_command_flags[SQLCOM_RENAME_TABLE]|= CF_PREOPEN_TMP_TABLES;
sql_command_flags[SQLCOM_REPLACE_SELECT]|= CF_PREOPEN_TMP_TABLES;
sql_command_flags[SQLCOM_SELECT]|= CF_PREOPEN_TMP_TABLES;
sql_command_flags[SQLCOM_SET_OPTION]|= CF_PREOPEN_TMP_TABLES;
@ -5995,6 +5996,60 @@ static bool execute_show_status(THD *thd, TABLE_LIST *all_tables)
}
/*
Find out if a table is a temporary table
A table is a temporary table if it's a temporary table or
there has been before a temporary table that has been renamed
to the current name.
Some examples:
A->B B is a temporary table if and only if A is a temp.
A->B, B->C Second B is temp if A is temp
A->B, A->C Second A can't be temp as if A was temp then B is temp
and Second A can only be a normal table. C is also not temp
*/
static TABLE *find_temporary_table_for_rename(THD *thd,
TABLE_LIST *first_table,
TABLE_LIST *cur_table)
{
TABLE_LIST *table;
TABLE *res= 0;
bool found= 0;
DBUG_ENTER("find_temporary_table_for_rename");
/* Find last instance when cur_table is in TO part */
for (table= first_table;
table != cur_table;
table= table->next_local->next_local)
{
TABLE_LIST *next= table->next_local;
if (!strcmp(table->get_db_name(), cur_table->get_db_name()) &&
!strcmp(table->get_table_name(), cur_table->get_table_name()))
{
/* Table was moved away, can't be same as 'table' */
found= 1;
res= 0; // Table can't be a temporary table
}
if (!strcmp(next->get_db_name(), cur_table->get_db_name()) &&
!strcmp(next->get_table_name(), cur_table->get_table_name()))
{
/*
Table has matching name with new name of this table. cur_table should
have same temporary type as this table.
*/
found= 1;
res= table->table;
}
}
if (!found)
res= find_temporary_table(thd, table);
DBUG_RETURN(res);
}
static bool check_rename_table(THD *thd, TABLE_LIST *first_table,
TABLE_LIST *all_tables)
{
@ -6011,13 +6066,19 @@ static bool check_rename_table(THD *thd, TABLE_LIST *first_table,
&table->next_local->grant.m_internal,
0, 0))
return 1;
/* check if these are refering to temporary tables */
table->table= find_temporary_table_for_rename(thd, first_table, table);
table->next_local->table= table->table;
TABLE_LIST old_list, new_list;
/*
we do not need initialize old_list and new_list because we will
come table[0] and table->next[0] there
copy table[0] and table->next[0] there
*/
old_list= table[0];
new_list= table->next_local[0];
if (check_grant(thd, ALTER_ACL | DROP_ACL, &old_list, FALSE, 1, FALSE) ||
(!test_all_bits(table->next_local->grant.privilege,
INSERT_ACL | CREATE_ACL) &&

View file

@ -222,7 +222,7 @@ do_rename_temporary(THD *thd, TABLE_LIST *ren_table, TABLE_LIST *new_table,
new_alias= (lower_case_table_names == 2) ? new_table->alias :
new_table->table_name;
if (is_temporary_table(new_table))
if (find_temporary_table(thd, new_table))
{
my_error(ER_TABLE_EXISTS_ERROR, MYF(0), new_alias);
DBUG_RETURN(1); // This can't be skipped

View file

@ -1518,7 +1518,8 @@ public:
~Stat_table_write_iter()
{
cleanup();
/* Ensure that cleanup has been run */
DBUG_ASSERT(rowid_buf == 0);
}
};

View file

@ -5835,10 +5835,28 @@ drop_create_field:
List_iterator<Alter_drop> drop_it(alter_info->drop_list);
Alter_drop *drop;
bool remove_drop;
ulonglong left_flags= 0;
while ((drop= drop_it++))
{
ulonglong cur_flag= 0;
switch (drop->type) {
case Alter_drop::COLUMN:
cur_flag= Alter_info::ALTER_DROP_COLUMN;
break;
case Alter_drop::FOREIGN_KEY:
cur_flag= Alter_info::DROP_FOREIGN_KEY;
break;
case Alter_drop::KEY:
cur_flag= Alter_info::ALTER_DROP_INDEX;
break;
default:
break;
}
if (!drop->drop_if_exists)
{
left_flags|= cur_flag;
continue;
}
remove_drop= TRUE;
if (drop->type == Alter_drop::COLUMN)
{
@ -5915,12 +5933,15 @@ drop_create_field:
ER_THD(thd, ER_CANT_DROP_FIELD_OR_KEY),
drop->name);
drop_it.remove();
if (alter_info->drop_list.is_empty())
alter_info->flags&= ~(Alter_info::ALTER_DROP_COLUMN |
Alter_info::ALTER_DROP_INDEX |
Alter_info::DROP_FOREIGN_KEY);
}
else
left_flags|= cur_flag;
}
/* Reset state to what's left in drop list */
alter_info->flags&= ~(Alter_info::ALTER_DROP_COLUMN |
Alter_info::ALTER_DROP_INDEX |
Alter_info::DROP_FOREIGN_KEY);
alter_info->flags|= left_flags;
}
/* ALTER TABLE ADD KEY IF NOT EXISTS */