mirror of
https://github.com/MariaDB/server.git
synced 2025-07-29 05:21:33 +03:00
Bug#50402 Optimizer producing wrong results when using Index Merge on InnoDB
Subselect executes twice, at JOIN::optimize stage and at JOIN::execute stage. At optimize stage Innodb prebuilt struct which is used for the retrieval of column values is initialized in. ha_innobase::index_read(), prebuilt->sql_stat_start is true. After QUICK_ROR_INTERSECT_SELECT finished his job it restores read_set/write_set bitmaps with initial values and deactivates one of the handlers used by QUICK_ROR_INTERSECT_SELECT in JOIN::cleanup (it's the case when we reuse original handler as one of handlers required by QUICK_ROR_INTERSECT_SELECT object). On second subselect execution inactive handler is activated in QUICK_RANGE_SELECT::reset, file->ha_index_init(). In ha_index_init Innodb prebuilt struct is reinitialized with inappropriate read_set/write_set bitmaps. Further reinitialization in ha_innobase::index_read() does not happen as prebuilt->sql_stat_start is false. It leads to partial retrieval of required field values and we get a mix of field values from different records in the record buffer. The fix is to reset read_set/write_set bitmaps as these values are required for proper intialization of internal InnoDB struct which is used for the retrieval of column values (see build_template(), ha_innodb.cc) mysql-test/include/index_merge_ror_cpk.inc: test case mysql-test/r/index_merge_innodb.result: test case mysql-test/r/index_merge_myisam.result: test case sql/opt_range.cc: if ROR merge scan is used we need to reset read_set/write_set bitmaps as these values are required for proper intialization of internal InnoDB struct which is used for the retrieval of column values (see build_template(), ha_innodb.cc)
This commit is contained in:
@ -8451,9 +8451,14 @@ int QUICK_RANGE_SELECT::reset()
|
||||
in_range= FALSE;
|
||||
cur_range= (QUICK_RANGE**) ranges.buffer;
|
||||
|
||||
if (file->inited == handler::NONE && (error= file->ha_index_init(index,1)))
|
||||
DBUG_RETURN(error);
|
||||
|
||||
if (file->inited == handler::NONE)
|
||||
{
|
||||
if (in_ror_merged_scan)
|
||||
head->column_bitmaps_set_no_signal(&column_bitmap, &column_bitmap);
|
||||
if ((error= file->ha_index_init(index,1)))
|
||||
DBUG_RETURN(error);
|
||||
}
|
||||
|
||||
/* Do not allocate the buffers twice. */
|
||||
if (multi_range_length)
|
||||
{
|
||||
|
Reference in New Issue
Block a user