1
0
mirror of https://github.com/MariaDB/server.git synced 2025-07-27 18:02:13 +03:00

Merge tag 'mariadb-10.0.36' into 10.0-galera

This commit is contained in:
Jan Lindström
2018-08-02 11:44:02 +03:00
306 changed files with 6756 additions and 4049 deletions

View File

@ -131,7 +131,7 @@ static void sql_kill(THD *thd, longlong id, killed_state state, killed_type type
static void sql_kill_user(THD *thd, LEX_USER *user, killed_state state);
static bool lock_tables_precheck(THD *thd, TABLE_LIST *tables);
static bool execute_show_status(THD *, TABLE_LIST *);
static bool check_rename_table(THD *, TABLE_LIST *, TABLE_LIST *);
static bool execute_rename_table(THD *, TABLE_LIST *, TABLE_LIST *);
const char *any_db="*any*"; // Special symbol for check_access
@ -199,7 +199,7 @@ static bool some_non_temp_table_to_be_updated(THD *thd, TABLE_LIST *tables)
/*
Implicitly commit a active transaction if statement requires so.
Check whether the statement implicitly commits an active transaction.
@param thd Thread handle.
@param mask Bitmask used for the SQL command match.
@ -207,7 +207,7 @@ static bool some_non_temp_table_to_be_updated(THD *thd, TABLE_LIST *tables)
@return 0 No implicit commit
@return 1 Do a commit
*/
static bool stmt_causes_implicit_commit(THD *thd, uint mask)
bool stmt_causes_implicit_commit(THD *thd, uint mask)
{
LEX *lex= thd->lex;
bool skip= FALSE;
@ -464,6 +464,9 @@ void init_update_queries(void)
sql_command_flags[SQLCOM_TRUNCATE]|= CF_FORCE_ORIGINAL_BINLOG_FORMAT;
/* We don't want to replicate DROP for temp tables in row format */
sql_command_flags[SQLCOM_DROP_TABLE]|= CF_FORCE_ORIGINAL_BINLOG_FORMAT;
/* We don't want to replicate CREATE/DROP INDEX for temp tables in row format */
sql_command_flags[SQLCOM_CREATE_INDEX]|= CF_FORCE_ORIGINAL_BINLOG_FORMAT;
sql_command_flags[SQLCOM_DROP_INDEX]|= CF_FORCE_ORIGINAL_BINLOG_FORMAT;
/* One can change replication mode with SET */
sql_command_flags[SQLCOM_SET_OPTION]|= CF_FORCE_ORIGINAL_BINLOG_FORMAT;
@ -502,6 +505,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;
@ -515,7 +520,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;
@ -3248,7 +3252,7 @@ case SQLCOM_PREPARE:
TABLE_LIST *duplicate;
if ((duplicate= unique_table(thd, lex->query_tables,
lex->query_tables->next_global,
0)))
CHECK_DUP_FOR_CREATE)))
{
update_non_unique_table_error(lex->query_tables, "CREATE",
duplicate);
@ -3474,12 +3478,7 @@ end_with_restore_list:
#endif /* HAVE_REPLICATION */
case SQLCOM_RENAME_TABLE:
{
if (check_rename_table(thd, first_table, all_tables))
goto error;
WSREP_TO_ISOLATION_BEGIN(0, 0, first_table)
if (mysql_rename_tables(thd, first_table, 0))
if (execute_rename_table(thd, first_table, all_tables))
goto error;
break;
}
@ -5839,8 +5838,61 @@ static bool execute_show_status(THD *thd, TABLE_LIST *all_tables)
}
static bool check_rename_table(THD *thd, TABLE_LIST *first_table,
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 execute_rename_table(THD *thd, TABLE_LIST *first_table,
TABLE_LIST *all_tables)
{
DBUG_ASSERT(first_table == all_tables && first_table != 0);
TABLE_LIST *table;
@ -5855,13 +5907,19 @@ static bool check_rename_table(THD *thd, TABLE_LIST *first_table,
&table->next_local->grant.m_internal,
0, 0))
return true;
/* 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) &&
@ -5870,7 +5928,14 @@ static bool check_rename_table(THD *thd, TABLE_LIST *first_table,
return true;
}
return false;
WSREP_TO_ISOLATION_BEGIN(0, 0, first_table)
return mysql_rename_tables(thd, first_table, 0);
#ifdef WITH_WSREP
error:
return true;
#endif
}