Commit cd7d837b authored by unknown's avatar unknown

BUG#21842: There was an inconsistency in the use of table->record[0] and

table->record[1] buffers inside Rows_log_event::find_row() function. 
The patch fixes this.


sql/log_event.cc:
  Use table->record[0] to read records from table and table->record[1] to
  store a copy of the original record for comparisons.
parent 642eda22
...@@ -7602,7 +7602,7 @@ int Rows_log_event::find_row(const RELAY_LOG_INFO *rli) ...@@ -7602,7 +7602,7 @@ int Rows_log_event::find_row(const RELAY_LOG_INFO *rli)
DBUG_RETURN(error); DBUG_RETURN(error);
} }
// We can't use pisition() - try other methods. // We can't use position() - try other methods.
/* /*
We need to retrieve all fields We need to retrieve all fields
...@@ -7610,6 +7610,12 @@ int Rows_log_event::find_row(const RELAY_LOG_INFO *rli) ...@@ -7610,6 +7610,12 @@ int Rows_log_event::find_row(const RELAY_LOG_INFO *rli)
*/ */
table->use_all_columns(); table->use_all_columns();
/*
Save copy of the record in table->record[1]. It might be needed
later if linear search is used to find exact match.
*/
store_record(table,record[1]);
if (table->s->keys > 0) if (table->s->keys > 0)
{ {
DBUG_PRINT("info",("locating record using primary key (index_read)")); DBUG_PRINT("info",("locating record using primary key (index_read)"));
...@@ -7643,8 +7649,9 @@ int Rows_log_event::find_row(const RELAY_LOG_INFO *rli) ...@@ -7643,8 +7649,9 @@ int Rows_log_event::find_row(const RELAY_LOG_INFO *rli)
*/ */
my_ptrdiff_t const pos= my_ptrdiff_t const pos=
table->s->null_bytes > 0 ? table->s->null_bytes - 1 : 0; table->s->null_bytes > 0 ? table->s->null_bytes - 1 : 0;
table->record[1][pos]= 0xFF; table->record[0][pos]= 0xFF;
if ((error= table->file->index_read_map(table->record[1], m_key,
if ((error= table->file->index_read_map(table->record[0], m_key,
HA_WHOLE_KEY, HA_WHOLE_KEY,
HA_READ_KEY_EXACT))) HA_READ_KEY_EXACT)))
{ {
...@@ -7684,8 +7691,8 @@ int Rows_log_event::find_row(const RELAY_LOG_INFO *rli) ...@@ -7684,8 +7691,8 @@ int Rows_log_event::find_row(const RELAY_LOG_INFO *rli)
/* /*
In case key is not unique, we still have to iterate over records found In case key is not unique, we still have to iterate over records found
and find the one which is identical to the row given. The row is unpacked and find the one which is identical to the row given. A copy of the
in record[1] where missing columns are filled with default values. record we are looking for is stored in record[1].
*/ */
DBUG_PRINT("info",("non-unique index, scanning it to find matching record")); DBUG_PRINT("info",("non-unique index, scanning it to find matching record"));
...@@ -7702,11 +7709,11 @@ int Rows_log_event::find_row(const RELAY_LOG_INFO *rli) ...@@ -7702,11 +7709,11 @@ int Rows_log_event::find_row(const RELAY_LOG_INFO *rli)
*/ */
if (table->s->null_bytes > 0) if (table->s->null_bytes > 0)
{ {
table->record[1][table->s->null_bytes - 1]|= table->record[0][table->s->null_bytes - 1]|=
256U - (1U << table->s->last_null_bit_pos); 256U - (1U << table->s->last_null_bit_pos);
} }
if ((error= table->file->index_next(table->record[1]))) if ((error= table->file->index_next(table->record[0])))
{ {
DBUG_PRINT("info",("no record matching the given row found")); DBUG_PRINT("info",("no record matching the given row found"));
table->file->print_error(error, MYF(0)); table->file->print_error(error, MYF(0));
...@@ -7738,13 +7745,11 @@ int Rows_log_event::find_row(const RELAY_LOG_INFO *rli) ...@@ -7738,13 +7745,11 @@ int Rows_log_event::find_row(const RELAY_LOG_INFO *rli)
/* Continue until we find the right record or have made a full loop */ /* Continue until we find the right record or have made a full loop */
do do
{ {
error= table->file->rnd_next(table->record[1]); error= table->file->rnd_next(table->record[0]);
switch (error) { switch (error) {
case 0: case 0:
DBUG_DUMP("record found", table->record[0], table->s->reclength);
case HA_ERR_RECORD_DELETED: case HA_ERR_RECORD_DELETED:
break; break;
...@@ -7773,6 +7778,8 @@ int Rows_log_event::find_row(const RELAY_LOG_INFO *rli) ...@@ -7773,6 +7778,8 @@ int Rows_log_event::find_row(const RELAY_LOG_INFO *rli)
*/ */
if (restart_count == 2) if (restart_count == 2)
DBUG_PRINT("info", ("Record not found")); DBUG_PRINT("info", ("Record not found"));
else
DBUG_DUMP("record found", table->record[0], table->s->reclength);
table->file->ha_rnd_end(); table->file->ha_rnd_end();
DBUG_ASSERT(error == HA_ERR_END_OF_FILE || error == 0); DBUG_ASSERT(error == HA_ERR_END_OF_FILE || error == 0);
......
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