Heh, unfortunately comparing refs will not work in conjunction with KEYREAD: for innodb ref can be a primary key, if it has it, so index is not clustered. The index we're evaluating can be different from a primary key. In that case some values can be left unfetched with KEYREAD. All that is because if innodb has primary key, it just does key_copy On Wed, 4 Dec 2019 at 17:14, Nikita Malyavin <nikitamalyavin@gmail.com> wrote:
On Wed, 4 Dec 2019 at 05:04, Sergei Golubchik <serg@mariadb.org> wrote:
two rows are the same, if their "positions" are equal, not if their column values are equal. Also positions are much shorter to compare.
after ha_index_read_map or ha_index_next you do
handler->position(record_buffer)
and then you have a "position" stored in handler->ref, and it has the length of handler->ref_length bytes. For MyISAM it's usually the file offset, for InnoDB - PK value.
For UPDATE you can, I suppose, call this->position(old_data) to get the position.
old_data could have been even not fetched, and in some cases handler is not cloned, so it can't work in general.
In what cases? We're talking about UPDATE here, there's `this` handler that has already read old_data, so `this->position()` is well defined.
Hmm yes... I guess ha_update_row wouldn't even work correctly if old_data is not the last fetched row. I remember that was true for myisam at least -- ha_write_row was spoiling ref (when history row was inserted, or period row were split in FOR PORTION case), and that was worked around -- either by saving/restoring positions, or by having separate file with rowids
So both positions exist, can be read and compared. What's not general here, that it doesn't work for INSERT? It doesn't have to, this is special logic for UPDATE only.
Ok, I still think it is a little bit a hack but we can try and see if it'll work in long term.
-- Yours truly, Nikita Malyavin
-- Yours truly, Nikita Malyavin