diff --git a/sql/ha_partition.cc b/sql/ha_partition.cc index 42cbaa1cdb0..ac105855c02 100644 --- a/sql/ha_partition.cc +++ b/sql/ha_partition.cc @@ -3235,14 +3235,9 @@ end_dont_reset_start_part: void ha_partition::position(const uchar *record) { - handler *file; + handler *file= m_file[m_last_part]; DBUG_ENTER("ha_partition::position"); - if (unlikely(get_part_for_delete(record, m_rec0, m_part_info, &m_last_part))) - m_last_part= 0; - - file= m_file[m_last_part]; - file->position(record); int2store(ref, m_last_part); memcpy((ref + PARTITION_BYTES_IN_POS), file->ref, @@ -3300,6 +3295,36 @@ int ha_partition::rnd_pos(uchar * buf, uchar *pos) } +/* + Read row using position using given record to find + + SYNOPSIS + rnd_pos_by_record() + record Current record in MySQL Row Format + + RETURN VALUE + >0 Error code + 0 Success + + DESCRIPTION + this works as position()+rnd_pos() functions, but does some extra work, + calculating m_last_part - the partition to where the 'record' + should go. + + called from replication (log_event.cc) +*/ + +int ha_partition::rnd_pos_by_record(uchar *record) +{ + DBUG_ENTER("ha_partition::rnd_pos_by_record"); + + if (unlikely(get_part_for_delete(record, m_rec0, m_part_info, &m_last_part))) + DBUG_RETURN(1); + + DBUG_RETURN(handler::rnd_pos_by_record(record)); +} + + /**************************************************************************** MODULE index scan ****************************************************************************/ diff --git a/sql/ha_partition.h b/sql/ha_partition.h index 434d90a4487..8fe512fadb3 100644 --- a/sql/ha_partition.h +++ b/sql/ha_partition.h @@ -353,6 +353,7 @@ public: virtual int rnd_end(); virtual int rnd_next(uchar * buf); virtual int rnd_pos(uchar * buf, uchar * pos); + virtual int rnd_pos_by_record(uchar *record); virtual void position(const uchar * record); /* diff --git a/sql/handler.h b/sql/handler.h index 557b9fd7887..b91d8a39b88 100644 --- a/sql/handler.h +++ b/sql/handler.h @@ -1343,6 +1343,17 @@ public: virtual int ft_read(uchar *buf) { return HA_ERR_WRONG_COMMAND; } virtual int rnd_next(uchar *buf)=0; virtual int rnd_pos(uchar * buf, uchar *pos)=0; + /* + one has to use this method when to find + random position by record as the plain + position() call doesn't work for some + handlers for random position + */ + virtual int rnd_pos_by_record(uchar *record) + { + position(record); + return rnd_pos(record, ref); + } virtual int read_first_row(uchar *buf, uint primary_key); /* The following function is only needed for tables that may be temporary diff --git a/sql/log_event.cc b/sql/log_event.cc index 44898ca8639..9094a7c38b2 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -7501,8 +7501,7 @@ int Rows_log_event::find_row(const Relay_log_info *rli) */ DBUG_PRINT("info",("locating record using primary key (position)")); - table->file->position(table->record[0]); - error= table->file->rnd_pos(table->record[0], table->file->ref); + int error= table->file->rnd_pos_by_record(table->record[0]); if (error) { DBUG_PRINT("info",("rnd_pos returns error %d",error));