diff options
author | Sergey Glukhov <Sergey.Glukhov@sun.com> | 2010-09-16 16:13:53 +0400 |
---|---|---|
committer | Sergey Glukhov <Sergey.Glukhov@sun.com> | 2010-09-16 16:13:53 +0400 |
commit | 31a38c0fc5de01055183f642ce171b2f47d377f0 (patch) | |
tree | 36efe241298c8ea40f1190ffdece01eff20411e2 /sql/opt_range.cc | |
parent | ebd207baa84278759675bd97d8864d4cac94c6ed (diff) | |
download | mariadb-git-31a38c0fc5de01055183f642ce171b2f47d377f0.tar.gz |
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)
Diffstat (limited to 'sql/opt_range.cc')
-rw-r--r-- | sql/opt_range.cc | 11 |
1 files changed, 8 insertions, 3 deletions
diff --git a/sql/opt_range.cc b/sql/opt_range.cc index eae79e63c19..d4a2bc3b138 100644 --- a/sql/opt_range.cc +++ b/sql/opt_range.cc @@ -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) { |