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
commit86d7cbd450ab53012e4f4f892e4cdb6093a7313b (patch)
tree36efe241298c8ea40f1190ffdece01eff20411e2 /sql/opt_range.cc
parentf43d6c2b738b12b7ff20fb6558c8b99c13d447fc (diff)
downloadmariadb-git-86d7cbd450ab53012e4f4f892e4cdb6093a7313b.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)
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)
{