Manual merge 5.0-rpl -> 5.1-rpl.

involved bug#12691, bug#27571
parent e65d20b5
......@@ -235,4 +235,45 @@ drop table t1;
drop function f1;
drop function f2;
drop procedure p1;
create table t2 (b BIT(7));
create procedure sp_bug26199(bitvalue BIT(7))
begin
insert into t2 set b = bitvalue;
end //
create function sf_bug26199(b BIT(7)) returns int
begin
insert into t2 values(b);
return 0;
end//
call sp_bug26199(b'1110');
call sp_bug26199('\0');
select sf_bug26199(b'1111111');
sf_bug26199(b'1111111')
0
select sf_bug26199(b'101111111');
sf_bug26199(b'101111111')
0
Warnings:
Warning 1264 Out of range value for column 'b' at row 1
select sf_bug26199('\'');
sf_bug26199('\'')
0
select hex(b) from t2;
hex(b)
E
0
7F
7F
27
select hex(b) from t2;
hex(b)
E
0
7F
7F
27
drop table t2;
drop procedure sp_bug26199;
drop function sf_bug26199;
SET GLOBAL log_bin_trust_function_creators = 0;
end of the tests
......@@ -1804,70 +1804,6 @@ static int exec_relay_log_event(THD* thd, Relay_log_info* rli)
int const type_code= ev->get_type_code();
int exec_res= 0;
/*
*/
<<<<<<< gca sql/slave.cc 1.241.1.61
DBUG_PRINT("info",("type_code=%d, server_id=%d",type_code,ev->server_id));
if ((ev->server_id == (uint32) ::server_id &&
!replicate_same_server_id &&
type_code != FORMAT_DESCRIPTION_EVENT) ||
(rli->slave_skip_counter &&
type_code != ROTATE_EVENT && type_code != STOP_EVENT &&
type_code != START_EVENT_V3 && type_code!= FORMAT_DESCRIPTION_EVENT))
{
DBUG_PRINT("info", ("event skipped"));
if (thd->options & OPTION_BEGIN)
rli->inc_event_relay_log_pos();
else
{
rli->inc_group_relay_log_pos((type_code == ROTATE_EVENT ||
type_code == STOP_EVENT ||
type_code == FORMAT_DESCRIPTION_EVENT) ?
LL(0) : ev->log_pos,
1/* skip lock*/);
flush_relay_log_info(rli);
}
/*
Protect against common user error of setting the counter to 1
instead of 2 while recovering from an insert which used auto_increment,
rand or user var.
*/
if (rli->slave_skip_counter &&
!((type_code == INTVAR_EVENT ||
type_code == RAND_EVENT ||
type_code == USER_VAR_EVENT) &&
rli->slave_skip_counter == 1) &&
/*
The events from ourselves which have something to do with the relay
log itself must be skipped, true, but they mustn't decrement
rli->slave_skip_counter, because the user is supposed to not see
these events (they are not in the master's binlog) and if we
decremented, START SLAVE would for example decrement when it sees
the Rotate, so the event which the user probably wanted to skip
would not be skipped.
*/
!(ev->server_id == (uint32) ::server_id &&
(type_code == ROTATE_EVENT || type_code == STOP_EVENT ||
type_code == START_EVENT_V3 || type_code == FORMAT_DESCRIPTION_EVENT)))
--rli->slave_skip_counter;
pthread_mutex_unlock(&rli->data_lock);
delete ev;
return 0; // avoid infinite update loops
}
pthread_mutex_unlock(&rli->data_lock);
<<<<<<< local sql/slave.cc 1.321
DBUG_PRINT("exec_event",("%s(type_code: %d; server_id: %d)",
ev->get_type_str(), type_code, ev->server_id));
DBUG_PRINT("info", ("thd->options: %s%s; rli->last_event_start_time: %lu",
FLAGSTR(thd->options, OPTION_NOT_AUTOCOMMIT),
FLAGSTR(thd->options, OPTION_BEGIN),
rli->last_event_start_time));
/*
Execute the event to change the database and update the binary
log coordinates, but first we set some data that is needed for
......@@ -1891,10 +1827,15 @@ static int exec_relay_log_event(THD* thd, Relay_log_info* rli)
log (remember that now the relay log starts with its Format_desc,
has a Rotate etc).
*/
<<<<<<< remote sql/slave.cc 1.241.1.62
DBUG_PRINT("info",("type_code: %d; server_id: %d; slave_skip_counter: %d",
type_code, ev->server_id, rli->slave_skip_counter));
DBUG_PRINT("info", ("thd->options: %s%s; rli->last_event_start_time: %lu",
FLAGSTR(thd->options, OPTION_NOT_AUTOCOMMIT),
FLAGSTR(thd->options, OPTION_BEGIN),
rli->last_event_start_time));
/*
If the slave skip counter is positive, we still need to set the
OPTION_BEGIN flag correctly and not skip the log events that
......@@ -1951,7 +1892,7 @@ static int exec_relay_log_event(THD* thd, Relay_log_info* rli)
}
DBUG_PRINT("info", ("thd->options: %s",
(thd->options & OPTION_BEGIN) ? "OPTION_BEGIN" : ""))
(thd->options & OPTION_BEGIN) ? "OPTION_BEGIN" : ""));
/*
Protect against common user error of setting the counter to 1
......@@ -1991,8 +1932,6 @@ static int exec_relay_log_event(THD* thd, Relay_log_info* rli)
delete ev;
return 0; // avoid infinite update loops
}
pthread_mutex_unlock(&rli->data_lock);
>>>>>>>
thd->server_id = ev->server_id; // use the original server id for logging
thd->set_time(); // time the query
......@@ -2132,7 +2071,7 @@ static int exec_relay_log_event(THD* thd, Relay_log_info* rli)
non-transient error, the slave will stop with an error.
*/
rli->trans_retries= 0; // restart from fresh
DBUG_PRINT("info", ("Resetting retry counter, rli->trans_retries: %d",
DBUG_PRINT("info", ("Resetting retry counter, rli->trans_retries: %lu",
rli->trans_retries));
}
}
......@@ -2622,7 +2561,7 @@ pthread_handler_t handle_slave_sql(void *arg)
rli->ignore_log_space_limit= 0;
pthread_mutex_unlock(&rli->log_space_lock);
rli->trans_retries= 0; // start from "no error"
DBUG_PRINT("info", ("rli->trans_retries: %d", rli->trans_retries));
DBUG_PRINT("info", ("rli->trans_retries: %lu", rli->trans_retries));
if (init_relay_log_pos(rli,
rli->group_relay_log_name,
......
......@@ -352,12 +352,6 @@ cleanup:
{
if (error < 0)
thd->clear_error();
<<<<<<< gca sql/sql_delete.cc 1.144.1.57
Query_log_event qinfo(thd, thd->query, thd->query_length,
transactional_table, FALSE);
if (mysql_bin_log.write(&qinfo) && transactional_table)
<<<<<<< local sql/sql_delete.cc 1.230
/*
[binlog]: If 'handler::delete_all_rows()' was called and the
storage engine does not inject the rows itself, we replicate
......@@ -366,15 +360,10 @@ cleanup:
*/
int log_result= thd->binlog_query(THD::ROW_QUERY_TYPE,
thd->query, thd->query_length,
transactional_table, FALSE);
transactional_table, FALSE, killed_status);
if (log_result && transactional_table)
{
<<<<<<< remote sql/sql_delete.cc 1.144.1.58
Query_log_event qinfo(thd, thd->query, thd->query_length,
transactional_table, FALSE, killed_status);
if (mysql_bin_log.write(&qinfo) && transactional_table)
>>>>>>>
error=1;
}
}
......@@ -902,21 +891,11 @@ bool multi_delete::send_eof()
{
if (local_error == 0)
thd->clear_error();
<<<<<<< gca sql/sql_delete.cc 1.144.1.57
Query_log_event qinfo(thd, thd->query, thd->query_length,
transactional_tables, FALSE);
if (mysql_bin_log.write(&qinfo) && !normal_tables)
<<<<<<< local sql/sql_delete.cc 1.230
if (thd->binlog_query(THD::ROW_QUERY_TYPE,
thd->query, thd->query_length,
transactional_tables, FALSE) &&
transactional_tables, FALSE, killed_status) &&
!normal_tables)
{
<<<<<<< remote sql/sql_delete.cc 1.144.1.58
Query_log_event qinfo(thd, thd->query, thd->query_length,
transactional_tables, FALSE, killed_status);
if (mysql_bin_log.write(&qinfo) && !normal_tables)
>>>>>>>
local_error=1; // Log write failed: roll back the SQL statement
}
}
......
......@@ -3084,19 +3084,11 @@ void select_insert::send_error(uint errcode,const char *err)
bool select_insert::send_eof()
{
<<<<<<< gca sql/sql_insert.cc 1.146.1.105
int error, error2;
bool changed, transactional_table= table->file->has_transactions();
<<<<<<< local sql/sql_insert.cc 1.300
int error;
bool const trans_table= table->file->has_transactions();
ulonglong id;
bool changed;
<<<<<<< remote sql/sql_insert.cc 1.146.1.106
int error, error2;
bool changed, transactional_table= table->file->has_transactions();
THD::killed_state killed_status= thd->killed;
>>>>>>>
DBUG_ENTER("select_insert::send_eof");
DBUG_PRINT("enter", ("trans_table=%d, table_type='%s'",
trans_table, table->file->table_type()));
......@@ -3129,17 +3121,9 @@ bool select_insert::send_eof()
{
if (!error)
thd->clear_error();
<<<<<<< gca sql/sql_insert.cc 1.146.1.105
Query_log_event qinfo(thd, thd->query, thd->query_length,
transactional_table, FALSE);
mysql_bin_log.write(&qinfo);
}
if ((error2=ha_autocommit_or_rollback(thd,error)) && ! error)
error=error2;
<<<<<<< local sql/sql_insert.cc 1.300
thd->binlog_query(THD::ROW_QUERY_TYPE,
thd->query, thd->query_length,
trans_table, FALSE);
trans_table, FALSE, killed_status);
}
/*
We will call ha_autocommit_or_rollback() also for
......@@ -3155,14 +3139,6 @@ bool select_insert::send_eof()
}
table->file->ha_release_auto_increment();
<<<<<<< remote sql/sql_insert.cc 1.146.1.106
Query_log_event qinfo(thd, thd->query, thd->query_length,
transactional_table, FALSE, killed_status);
mysql_bin_log.write(&qinfo);
}
if ((error2=ha_autocommit_or_rollback(thd,error)) && ! error)
error=error2;
>>>>>>>
if (error)
{
table->file->print_error(error,MYF(0));
......
......@@ -430,12 +430,6 @@ bool mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list,
if (mysql_bin_log.is_open())
{
{
<<<<<<< gca sql/sql_load.cc 1.78.1.39
if (thd->transaction.stmt.modified_non_trans_table)
write_execute_load_query_log_event(thd, handle_duplicates,
ignore, transactional_table);
else
<<<<<<< local sql/sql_load.cc 1.131
/*
Make sure last block (the one which caused the error) gets
logged. This is needed because otherwise after write of (to
......@@ -461,17 +455,11 @@ bool mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list,
read_info.end_io_cache();
/* If the file was not empty, wrote_create_file is true */
if (lf_info.wrote_create_file)
<<<<<<< remote sql/sql_load.cc 1.78.1.40
if (thd->transaction.stmt.modified_non_trans_table)
write_execute_load_query_log_event(thd, handle_duplicates,
ignore, transactional_table,
killed_status);
else
>>>>>>>
{
if (thd->transaction.stmt.modified_non_trans_table)
write_execute_load_query_log_event(thd, handle_duplicates,
ignore, transactional_table);
ignore, transactional_table,
killed_status);
else
{
Delete_file_log_event d(thd, db, transactional_table);
......@@ -497,16 +485,6 @@ bool mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list,
if (mysql_bin_log.is_open())
{
/*
<<<<<<< gca sql/sql_load.cc 1.78.1.39
As already explained above, we need to call end_io_cache() or the last
block will be logged only after Execute_load_query_log_event (which is
wrong), when read_info is destroyed.
*/
read_info.end_io_cache();
if (lf_info.wrote_create_file)
write_execute_load_query_log_event(thd, handle_duplicates,
ignore, transactional_table);
<<<<<<< local sql/sql_load.cc 1.131
We need to do the job that is normally done inside
binlog_query() here, which is to ensure that the pending event
is written before tables are unlocked and before any other
......@@ -526,21 +504,10 @@ bool mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list,
read_info.end_io_cache();
if (lf_info.wrote_create_file)
{
write_execute_load_query_log_event(thd, handle_duplicates,
ignore, transactional_table);
write_execute_load_query_log_event(thd, handle_duplicates, ignore,
transactional_table,killed_status);
}
}
<<<<<<< remote sql/sql_load.cc 1.78.1.40
As already explained above, we need to call end_io_cache() or the last
block will be logged only after Execute_load_query_log_event (which is
wrong), when read_info is destroyed.
*/
read_info.end_io_cache();
if (lf_info.wrote_create_file)
write_execute_load_query_log_event(thd, handle_duplicates,
ignore, transactional_table,
killed_status);
>>>>>>>
}
#endif /*!EMBEDDED_LIBRARY*/
if (transactional_table)
......@@ -577,14 +544,8 @@ static bool write_execute_load_query_log_event(THD *thd,
(char*)thd->lex->fname_end - (char*)thd->query,
(duplicates == DUP_REPLACE) ? LOAD_DUP_REPLACE :
(ignore ? LOAD_DUP_IGNORE : LOAD_DUP_ERROR),
<<<<<<< gca sql/sql_load.cc 1.78.1.39
transactional_table, FALSE);
<<<<<<< local sql/sql_load.cc 1.131
transactional_table, FALSE);
e.flags|= LOG_EVENT_UPDATE_TABLE_MAP_VERSION_F;
<<<<<<< remote sql/sql_load.cc 1.78.1.40
transactional_table, FALSE, killed_err_arg);
>>>>>>>
e.flags|= LOG_EVENT_UPDATE_TABLE_MAP_VERSION_F;
return mysql_bin_log.write(&e);
}
......
......@@ -200,18 +200,10 @@ int mysql_update(THD *thd,
SQL_SELECT *select;
READ_RECORD info;
SELECT_LEX *select_lex= &thd->lex->select_lex;
<<<<<<< gca sql/sql_update.cc 1.154.2.70
bool need_reopen;
List<Item> all_fields;
<<<<<<< local sql/sql_update.cc 1.258
bool need_reopen;
ulonglong id;
List<Item> all_fields;
<<<<<<< remote sql/sql_update.cc 1.154.2.71
bool need_reopen;
List<Item> all_fields;
THD::killed_state killed_status= THD::NOT_KILLED;
>>>>>>>
DBUG_ENTER("mysql_update");
for ( ; ; )
......@@ -722,10 +714,7 @@ int mysql_update(THD *thd,
table->file->unlock_row();
thd->row_count++;
}
<<<<<<< gca sql/sql_update.cc 1.154.2.70
<<<<<<< local sql/sql_update.cc 1.258
dup_key_found= 0;
<<<<<<< remote sql/sql_update.cc 1.154.2.71
/*
Caching the killed status to pass as the arg to query event constuctor;
The cached value can not change whereas the killed status can
......@@ -742,81 +731,9 @@ int mysql_update(THD *thd,
};);
error= (killed_status == THD::NOT_KILLED)? error : 1;
>>>>>>>
if (!transactional_table && updated > 0)
thd->transaction.stmt.modified_non_trans_table= TRUE;
<<<<<<< gca sql/sql_update.cc 1.154.2.70
/*
todo bug#27571: to avoid asynchronization of `error' and
`error_code' of binlog event constructor
The concept, which is a bit different for insert(!), is to
replace `error' assignment with the following lines
killed_status= thd->killed; // get the status of the volatile
Notice: thd->killed is type of "state" whereas the lhs has
"status" the suffix which translates according to WordNet: a state
at a particular time - at the time of the end of per-row loop in
our case. Binlogging ops are conducted with the status.
error= (killed_status == THD::NOT_KILLED)? error : 1;
which applies to most mysql_$query functions.
Event's constructor will accept `killed_status' as an argument:
Query_log_event qinfo(..., killed_status);
thd->killed might be changed after killed_status had got cached and this
won't affect binlogging event but other effects remain.
Open issue: In a case the error happened not because of KILLED -
and then KILLED was caught later still within the loop - we shall
do something to avoid binlogging of incorrect ER_SERVER_SHUTDOWN
error_code.
*/
if (thd->killed && !error)
error= 1; // Aborted
<<<<<<< local sql/sql_update.cc 1.258
/*
todo bug#27571: to avoid asynchronization of `error' and
`error_code' of binlog event constructor
The concept, which is a bit different for insert(!), is to
replace `error' assignment with the following lines
killed_status= thd->killed; // get the status of the volatile
Notice: thd->killed is type of "state" whereas the lhs has
"status" the suffix which translates according to WordNet: a state
at a particular time - at the time of the end of per-row loop in
our case. Binlogging ops are conducted with the status.
error= (killed_status == THD::NOT_KILLED)? error : 1;
which applies to most mysql_$query functions.
Event's constructor will accept `killed_status' as an argument:
Query_log_event qinfo(..., killed_status);
thd->killed might be changed after killed_status had got cached and this
won't affect binlogging event but other effects remain.
Open issue: In a case the error happened not because of KILLED -
and then KILLED was caught later still within the loop - we shall
do something to avoid binlogging of incorrect ER_SERVER_SHUTDOWN
error_code.
*/
if (thd->killed && !error)
error= 1; // Aborted
else if (will_batch &&
(loc_error= table->file->exec_bulk_update(&dup_key_found)))
if (error &&
will_batch &&
(loc_error= table->file->exec_bulk_update(&dup_key_found)))
/*
An error has occurred when a batched update was performed and returned
an error indication. It cannot be an allowed duplicate key error since
......@@ -838,8 +755,10 @@ int mysql_update(THD *thd,
if (will_batch)
table->file->end_bulk_update();
table->file->try_semi_consistent_read(0);
<<<<<<< remote sql/sql_update.cc 1.154.2.71
>>>>>>>
if (!transactional_table && updated > 0)
thd->transaction.stmt.modified_non_trans_table= TRUE;
end_read_record(&info);
delete select;
thd->proc_info= "end";
......@@ -869,25 +788,13 @@ int mysql_update(THD *thd,
{
if (error < 0)
thd->clear_error();
<<<<<<< gca sql/sql_update.cc 1.154.2.70
Query_log_event qinfo(thd, thd->query, thd->query_length,
transactional_table, FALSE);
if (mysql_bin_log.write(&qinfo) && transactional_table)
error=1; // Rollback update
<<<<<<< local sql/sql_update.cc 1.258
if (thd->binlog_query(THD::ROW_QUERY_TYPE,
thd->query, thd->query_length,
transactional_table, FALSE) &&
transactional_table, FALSE, killed_status) &&
transactional_table)
{
error=1; // Rollback update
}
<<<<<<< remote sql/sql_update.cc 1.154.2.71
Query_log_event qinfo(thd, thd->query, thd->query_length,
transactional_table, FALSE, killed_status);
if (mysql_bin_log.write(&qinfo) && transactional_table)
error=1; // Rollback update
>>>>>>>
}
if (thd->transaction.stmt.modified_non_trans_table)
thd->transaction.all.modified_non_trans_table= TRUE;
......@@ -1829,24 +1736,14 @@ void multi_update::send_error(uint errcode,const char *err)
*/
if (mysql_bin_log.is_open())
{
<<<<<<< gca sql/sql_update.cc 1.154.2.70
Query_log_event qinfo(thd, thd->query, thd->query_length,
transactional_tables, FALSE);
mysql_bin_log.write(&qinfo);
<<<<<<< local sql/sql_update.cc 1.258
thd->binlog_query(THD::ROW_QUERY_TYPE,
thd->query, thd->query_length,
transactional_tables, FALSE);
<<<<<<< remote sql/sql_update.cc 1.154.2.71
/*
THD::killed status might not have been set ON at time of an error
got caught and if happens later the killed error is written
into repl event.
*/
Query_log_event qinfo(thd, thd->query, thd->query_length,
transactional_tables, FALSE);
mysql_bin_log.write(&qinfo);
>>>>>>>
thd->binlog_query(THD::ROW_QUERY_TYPE,
thd->query, thd->query_length,
transactional_tables, FALSE);
}
thd->transaction.all.modified_non_trans_table= TRUE;
}
......@@ -2039,13 +1936,9 @@ err2:
bool multi_update::send_eof()
{
char buff[STRING_BUFFER_USUAL_SIZE];
<<<<<<< gca sql/sql_update.cc 1.154.2.70
<<<<<<< local sql/sql_update.cc 1.258
ulonglong id;
DBUG_ENTER("multi_update::send_eof");
<<<<<<< remote sql/sql_update.cc 1.154.2.71
THD::killed_state killed_status= THD::NOT_KILLED;
>>>>>>>
DBUG_ENTER("multi_update::send_eof");
thd->proc_info="updating reference tables";
/*
......@@ -2084,25 +1977,13 @@ bool multi_update::send_eof()
{
if (local_error == 0)
thd->clear_error();
<<<<<<< gca sql/sql_update.cc 1.154.2.70
Query_log_event qinfo(thd, thd->query, thd->query_length,
transactional_tables, FALSE);
if (mysql_bin_log.write(&qinfo) && trans_safe)
local_error= 1; // Rollback update
<<<<<<< local sql/sql_update.cc 1.258
if (thd->binlog_query(THD::ROW_QUERY_TYPE,
thd->query, thd->query_length,
transactional_tables, FALSE) &&
transactional_tables, FALSE, killed_status) &&
trans_safe)
{
local_error= 1; // Rollback update
}
<<<<<<< remote sql/sql_update.cc 1.154.2.71
Query_log_event qinfo(thd, thd->query, thd->query_length,
transactional_tables, FALSE, killed_status);
if (mysql_bin_log.write(&qinfo) && trans_safe)
local_error= 1; // Rollback update
>>>>>>>
}
if (thd->transaction.stmt.modified_non_trans_table)
thd->transaction.all.modified_non_trans_table= TRUE;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment