-
Jorgen Loland authored
PREFIX IN SEARCH When UPDATE creates a duplicate out of columns defined as unique, an error is issued. The error message needs info about the column values to make this error message, and if this info is not available in the offended index a table read is done through ha_rnd_pos(). The were multiple problems in this code. 1) the error-creation code in mysql_update() called ha_rnd_pos() without calling ha_rnd_init() first. This was OK for InnoDB in MySQL 5.5 because InnoDB noticed it and called change_active_index() internally. In 5.6 InnoDB no longer automatically switches index, resulting in this bug report. 2) When doing an UPDATE, InnoDB reads all columns of the row to update. For this reason, mysql_update() does not even have to call ha_rnd_pos() to get the info. Furthermore, MyISAM always reads all rows anyway. Due to 2), the simplest bug fix would have been to not read additional columns from the table if the SE is InnoDB. However, the problem would persist for other SEs. An alternative patch would be to open another handler that calls ha_rnd_init();ha_rnd_pos();ha_rnd_end() and is then destroyed, but it makes more sense to change the contract with the handler slightly: If ha_update_row() returns duplicate key error, all columns relevant for the error message must have been read. The need for an extra ha_rnd_pos() is therefore eliminated. MyISAM and InnoDB already obeys this new contract. NDB Cluster (Magnus) has agreed to fix this in their codebase.
Jorgen Loland authoredPREFIX IN SEARCH When UPDATE creates a duplicate out of columns defined as unique, an error is issued. The error message needs info about the column values to make this error message, and if this info is not available in the offended index a table read is done through ha_rnd_pos(). The were multiple problems in this code. 1) the error-creation code in mysql_update() called ha_rnd_pos() without calling ha_rnd_init() first. This was OK for InnoDB in MySQL 5.5 because InnoDB noticed it and called change_active_index() internally. In 5.6 InnoDB no longer automatically switches index, resulting in this bug report. 2) When doing an UPDATE, InnoDB reads all columns of the row to update. For this reason, mysql_update() does not even have to call ha_rnd_pos() to get the info. Furthermore, MyISAM always reads all rows anyway. Due to 2), the simplest bug fix would have been to not read additional columns from the table if the SE is InnoDB. However, the problem would persist for other SEs. An alternative patch would be to open another handler that calls ha_rnd_init();ha_rnd_pos();ha_rnd_end() and is then destroyed, but it makes more sense to change the contract with the handler slightly: If ha_update_row() returns duplicate key error, all columns relevant for the error message must have been read. The need for an extra ha_rnd_pos() is therefore eliminated. MyISAM and InnoDB already obeys this new contract. NDB Cluster (Magnus) has agreed to fix this in their codebase.
Loading