summaryrefslogtreecommitdiff
path: root/sql/opt_range.cc
diff options
context:
space:
mode:
authorSergey Glukhov <Sergey.Glukhov@sun.com>2010-09-16 16:13:53 +0400
committerSergey Glukhov <Sergey.Glukhov@sun.com>2010-09-16 16:13:53 +0400
commit31a38c0fc5de01055183f642ce171b2f47d377f0 (patch)
tree36efe241298c8ea40f1190ffdece01eff20411e2 /sql/opt_range.cc
parentebd207baa84278759675bd97d8864d4cac94c6ed (diff)
downloadmariadb-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.cc11
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)
{