Bug#27044 replicated with unique field ndb table allows duplkey inserts

The bug in that slave version of a table with unique field still was
able to execute INSERT query as replace whereas it's impossible on master.

The reason of this artifact is wrong usage of ndb->extra:s.

Fixed with resetting flags at do_after.
There is open issue with symmetrical resetting
   table->file->extra(HA_EXTRA_NO_IGNORE_NO_KEY)
which i had to hand to bug#27077.
The test for the current bug was committed in a cset for bug#27320.
parent d445d5e4
...@@ -6601,10 +6601,23 @@ int Write_rows_log_event::do_before_row_operations(TABLE *table) ...@@ -6601,10 +6601,23 @@ int Write_rows_log_event::do_before_row_operations(TABLE *table)
lex->duplicates flag. lex->duplicates flag.
*/ */
thd->lex->sql_command= SQLCOM_REPLACE; thd->lex->sql_command= SQLCOM_REPLACE;
/*
table->file->extra(HA_EXTRA_IGNORE_DUP_KEY); // Needed for ndbcluster Do not raise the error flag in case of hitting to an unique attribute
table->file->extra(HA_EXTRA_WRITE_CAN_REPLACE); // Needed for ndbcluster */
table->file->extra(HA_EXTRA_IGNORE_NO_KEY); // Needed for ndbcluster table->file->extra(HA_EXTRA_IGNORE_DUP_KEY);
/*
NDB specific: update from ndb master wrapped as Write_rows
*/
/*
so that the event should be applied to replace slave's row
*/
table->file->extra(HA_EXTRA_WRITE_CAN_REPLACE);
/*
NDB specific: if update from ndb master wrapped as Write_rows
does not find the row it's assumed idempotent binlog applying
is taking place; don't raise the error.
*/
table->file->extra(HA_EXTRA_IGNORE_NO_KEY);
/* /*
TODO: the cluster team (Tomas?) says that it's better if the engine knows TODO: the cluster team (Tomas?) says that it's better if the engine knows
how many rows are going to be inserted, then it can allocate needed memory how many rows are going to be inserted, then it can allocate needed memory
...@@ -6632,9 +6645,20 @@ int Write_rows_log_event::do_before_row_operations(TABLE *table) ...@@ -6632,9 +6645,20 @@ int Write_rows_log_event::do_before_row_operations(TABLE *table)
int Write_rows_log_event::do_after_row_operations(TABLE *table, int error) int Write_rows_log_event::do_after_row_operations(TABLE *table, int error)
{ {
if (error == 0) int local_error= 0;
error= table->file->ha_end_bulk_insert(); table->file->extra(HA_EXTRA_NO_IGNORE_DUP_KEY);
return error; table->file->extra(HA_EXTRA_WRITE_CANNOT_REPLACE);
/*
reseting the extra with
table->file->extra(HA_EXTRA_NO_IGNORE_NO_KEY);
fires bug#27077
todo: explain or fix
*/
if (local_error= table->file->ha_end_bulk_insert())
{
table->file->print_error(local_error, MYF(0));
}
return error? error : local_error;
} }
int Write_rows_log_event::do_prepare_row(THD *thd, RELAY_LOG_INFO *rli, int Write_rows_log_event::do_prepare_row(THD *thd, RELAY_LOG_INFO *rli,
......
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