mirror of
https://github.com/MariaDB/server.git
synced 2025-07-30 16:24:05 +03:00
Bug#7011
Fix replication for multi-update new test - rpl_multi_update2
This commit is contained in:
@ -56,6 +56,8 @@ static int check_for_max_user_connections(USER_CONN *uc);
|
||||
static void decrease_user_connections(USER_CONN *uc);
|
||||
static bool check_db_used(THD *thd,TABLE_LIST *tables);
|
||||
static bool check_merge_table_access(THD *thd, char *db, TABLE_LIST *tables);
|
||||
static bool check_multi_update_lock(THD *thd, TABLE_LIST *tables,
|
||||
List<Item> *fields);
|
||||
static void mysql_init_query(THD *thd);
|
||||
static void remove_escape(char *name);
|
||||
static void refresh_status(void);
|
||||
@ -1338,10 +1340,28 @@ mysql_execute_command(void)
|
||||
LEX *lex= &thd->lex;
|
||||
TABLE_LIST *tables=(TABLE_LIST*) lex->select_lex.table_list.first;
|
||||
SELECT_LEX *select_lex = lex->select;
|
||||
bool slave_fake_lock= 0;
|
||||
MYSQL_LOCK *fake_prev_lock= 0;
|
||||
DBUG_ENTER("mysql_execute_command");
|
||||
|
||||
if (thd->slave_thread)
|
||||
{
|
||||
if (lex->sql_command == SQLCOM_MULTI_UPDATE)
|
||||
{
|
||||
DBUG_PRINT("info",("need faked locked tables"));
|
||||
|
||||
if (check_multi_update_lock(thd, tables, &select_lex->item_list))
|
||||
goto error;
|
||||
|
||||
/* Fix for replication, the tables are opened and locked,
|
||||
now we pretend that we have performed a LOCK TABLES action */
|
||||
|
||||
fake_prev_lock= thd->locked_tables;
|
||||
if (thd->lock)
|
||||
thd->locked_tables= thd->lock;
|
||||
thd->lock= 0;
|
||||
slave_fake_lock= 1;
|
||||
}
|
||||
/*
|
||||
Skip if we are in the slave thread, some table rules have been
|
||||
given and the table list says the query should not be replicated
|
||||
@ -1949,7 +1969,7 @@ mysql_execute_command(void)
|
||||
if (select_lex->item_list.elements != lex->value_list.elements)
|
||||
{
|
||||
send_error(&thd->net,ER_WRONG_VALUE_COUNT);
|
||||
DBUG_VOID_RETURN;
|
||||
goto error;
|
||||
}
|
||||
{
|
||||
const char *msg= 0;
|
||||
@ -2641,6 +2661,14 @@ mysql_execute_command(void)
|
||||
send_error(&thd->net,thd->killed ? ER_SERVER_SHUTDOWN : 0);
|
||||
|
||||
error:
|
||||
if (unlikely(slave_fake_lock))
|
||||
{
|
||||
DBUG_PRINT("info",("undoing faked lock"));
|
||||
thd->lock= thd->locked_tables;
|
||||
thd->locked_tables= fake_prev_lock;
|
||||
if (thd->lock == thd->locked_tables)
|
||||
thd->lock= 0;
|
||||
}
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
||||
@ -3907,3 +3935,54 @@ bool check_simple_select()
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
Setup locking for multi-table updates. Used by the replication slave.
|
||||
Replication slave SQL thread examines (all_tables_not_ok()) the
|
||||
locking state of referenced tables to determine if the query has to
|
||||
be executed or ignored. Since in multi-table update, the
|
||||
'default' lock is read-only, this lock is corrected early enough by
|
||||
calling this function, before the slave decides to execute/ignore.
|
||||
|
||||
SYNOPSIS
|
||||
check_multi_update_lock()
|
||||
thd Current thread
|
||||
tables List of user-supplied tables
|
||||
fields List of fields requiring update
|
||||
|
||||
RETURN VALUES
|
||||
0 ok
|
||||
1 error
|
||||
*/
|
||||
static bool check_multi_update_lock(THD *thd, TABLE_LIST *tables,
|
||||
List<Item> *fields)
|
||||
{
|
||||
bool res= 1;
|
||||
TABLE_LIST *table;
|
||||
DBUG_ENTER("check_multi_update_lock");
|
||||
|
||||
if (check_db_used(thd, tables))
|
||||
goto error;
|
||||
|
||||
/*
|
||||
Ensure that we have UPDATE or SELECT privilege for each table
|
||||
The exact privilege is checked in mysql_multi_update()
|
||||
*/
|
||||
for (table= tables ; table ; table= table->next)
|
||||
{
|
||||
TABLE_LIST *save= table->next;
|
||||
table->next= 0;
|
||||
if (check_one_table_access(thd, UPDATE_ACL, table, 1) &&
|
||||
check_one_table_access(thd, SELECT_ACL, table, 0))
|
||||
goto error;
|
||||
table->next= save;
|
||||
}
|
||||
|
||||
if (mysql_multi_update_lock(thd, tables, fields))
|
||||
goto error;
|
||||
|
||||
res= 0;
|
||||
|
||||
error:
|
||||
DBUG_RETURN(res);
|
||||
}
|
||||
|
Reference in New Issue
Block a user