summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--mysql-test/r/innodb_mrr.result30
-rw-r--r--mysql-test/t/innodb_mrr.test31
-rw-r--r--sql/multi_range_read.cc17
-rw-r--r--sql/multi_range_read.h2
4 files changed, 71 insertions, 9 deletions
diff --git a/mysql-test/r/innodb_mrr.result b/mysql-test/r/innodb_mrr.result
index 7b1c18d2523..1e50a8b84ed 100644
--- a/mysql-test/r/innodb_mrr.result
+++ b/mysql-test/r/innodb_mrr.result
@@ -402,3 +402,33 @@ SELECT * FROM t1 WHERE parent_id IS NOT NULL ORDER BY id DESC LIMIT 1;
id parent_id name
60 40 F
drop table t1;
+#
+# BUG#628785: multi_range_read.cc:430: int DsMrr_impl::dsmrr_init(): Assertion `do_sort_keys || do_rowid_fetch' failed
+#
+set @save_join_cache_level= @@join_cache_level;
+set @save_optimizer_switch= @@optimizer_switch;
+SET SESSION join_cache_level=9;
+Warnings:
+Warning 1292 Truncated incorrect join_cache_level value: '9'
+SET SESSION optimizer_switch='mrr_sort_keys=off';
+CREATE TABLE `t1` (
+`pk` int(11) NOT NULL AUTO_INCREMENT,
+`col_int_nokey` int(11) DEFAULT NULL,
+`col_int_key` int(11) DEFAULT NULL,
+`col_varchar_key` varchar(1) DEFAULT NULL,
+`col_varchar_nokey` varchar(1) DEFAULT NULL,
+PRIMARY KEY (`pk`),
+KEY `col_varchar_key` (`col_varchar_key`,`col_int_key`)
+) ENGINE=InnoDB AUTO_INCREMENT=101 DEFAULT CHARSET=latin1;
+INSERT INTO `t1` VALUES (1,6,NULL,'r','r');
+INSERT INTO `t1` VALUES (2,8,0,'c','c');
+INSERT INTO `t1` VALUES (97,7,0,'z','z');
+INSERT INTO `t1` VALUES (98,1,1,'j','j');
+INSERT INTO `t1` VALUES (99,7,8,'c','c');
+INSERT INTO `t1` VALUES (100,2,5,'f','f');
+SELECT table1 .`col_varchar_key`
+FROM t1 table1 STRAIGHT_JOIN ( t1 table3 JOIN t1 table4 ON table4 .`pk` = table3 .`col_int_nokey` ) ON table4 .`col_varchar_nokey` ;
+col_varchar_key
+DROP TABLE t1;
+set join_cache_level=@save_join_cache_level;
+set optimizer_switch=@save_optimizer_switch;
diff --git a/mysql-test/t/innodb_mrr.test b/mysql-test/t/innodb_mrr.test
index 0f5b41cef27..f2c7a83e068 100644
--- a/mysql-test/t/innodb_mrr.test
+++ b/mysql-test/t/innodb_mrr.test
@@ -123,3 +123,34 @@ SELECT id FROM t1 WHERE parent_id IS NOT NULL ORDER BY id DESC LIMIT 1;
explain SELECT * FROM t1 FORCE INDEX (PRIMARY) WHERE parent_id IS NOT NULL ORDER BY id DESC LIMIT 1;
SELECT * FROM t1 WHERE parent_id IS NOT NULL ORDER BY id DESC LIMIT 1;
drop table t1;
+
+
+-- echo #
+-- echo # BUG#628785: multi_range_read.cc:430: int DsMrr_impl::dsmrr_init(): Assertion `do_sort_keys || do_rowid_fetch' failed
+-- echo #
+set @save_join_cache_level= @@join_cache_level;
+set @save_optimizer_switch= @@optimizer_switch;
+SET SESSION join_cache_level=9;
+SET SESSION optimizer_switch='mrr_sort_keys=off';
+
+CREATE TABLE `t1` (
+ `pk` int(11) NOT NULL AUTO_INCREMENT,
+ `col_int_nokey` int(11) DEFAULT NULL,
+ `col_int_key` int(11) DEFAULT NULL,
+ `col_varchar_key` varchar(1) DEFAULT NULL,
+ `col_varchar_nokey` varchar(1) DEFAULT NULL,
+ PRIMARY KEY (`pk`),
+ KEY `col_varchar_key` (`col_varchar_key`,`col_int_key`)
+) ENGINE=InnoDB AUTO_INCREMENT=101 DEFAULT CHARSET=latin1;
+INSERT INTO `t1` VALUES (1,6,NULL,'r','r');
+INSERT INTO `t1` VALUES (2,8,0,'c','c');
+INSERT INTO `t1` VALUES (97,7,0,'z','z');
+INSERT INTO `t1` VALUES (98,1,1,'j','j');
+INSERT INTO `t1` VALUES (99,7,8,'c','c');
+INSERT INTO `t1` VALUES (100,2,5,'f','f');
+SELECT table1 .`col_varchar_key`
+FROM t1 table1 STRAIGHT_JOIN ( t1 table3 JOIN t1 table4 ON table4 .`pk` = table3 .`col_int_nokey` ) ON table4 .`col_varchar_nokey` ;
+DROP TABLE t1;
+set join_cache_level=@save_join_cache_level;
+set optimizer_switch=@save_optimizer_switch;
+
diff --git a/sql/multi_range_read.cc b/sql/multi_range_read.cc
index 31d3faa3205..b6c9a5e16ab 100644
--- a/sql/multi_range_read.cc
+++ b/sql/multi_range_read.cc
@@ -474,8 +474,8 @@ int DsMrr_impl::dsmrr_init(handler *h_arg, RANGE_SEQ_IF *seq_funcs,
}
do_rowid_fetch= FALSE;
- doing_cpk_scan= check_cpk_scan(h->inited == handler::INDEX?
- h->active_index: h2->active_index, mode);
+ doing_cpk_scan= check_cpk_scan(thd, h->inited == handler::INDEX?
+ h->active_index: h2->active_index, mode);
if (!doing_cpk_scan /* && !index_only_read */)
{
/* Will use rowid buffer to store/sort rowids, etc */
@@ -1370,12 +1370,13 @@ bool key_uses_partial_cols(TABLE *table, uint keyno)
FALSE Otherwise
*/
-bool DsMrr_impl::check_cpk_scan(uint keyno, uint mrr_flags)
+bool DsMrr_impl::check_cpk_scan(THD *thd, uint keyno, uint mrr_flags)
{
return test((mrr_flags & HA_MRR_SINGLE_POINT) &&
!(mrr_flags & HA_MRR_SORTED) &&
keyno == table->s->primary_key &&
- h->primary_key_is_clustered());
+ h->primary_key_is_clustered() &&
+ optimizer_flag(thd, OPTIMIZER_SWITCH_MRR_SORT_KEYS));
}
@@ -1410,11 +1411,11 @@ bool DsMrr_impl::choose_mrr_impl(uint keyno, ha_rows rows, uint *flags,
bool res;
THD *thd= current_thd;
- doing_cpk_scan= check_cpk_scan(keyno, *flags);
+ doing_cpk_scan= check_cpk_scan(thd, keyno, *flags);
+ bool using_cpk= test(keyno == table->s->primary_key &&
+ h->primary_key_is_clustered());
if (thd->variables.optimizer_use_mrr == 2 || *flags & HA_MRR_INDEX_ONLY ||
- (keyno == table->s->primary_key && h->primary_key_is_clustered() &&
- !doing_cpk_scan) ||
- key_uses_partial_cols(table, keyno))
+ (using_cpk && !doing_cpk_scan) || key_uses_partial_cols(table, keyno))
{
/* Use the default implementation */
*flags |= HA_MRR_USE_DEFAULT_IMPL;
diff --git a/sql/multi_range_read.h b/sql/multi_range_read.h
index 5eaff483c47..9cd1503596f 100644
--- a/sql/multi_range_read.h
+++ b/sql/multi_range_read.h
@@ -384,7 +384,7 @@ private:
COST_VECT *cost);
bool get_disk_sweep_mrr_cost(uint keynr, ha_rows rows, uint flags,
uint *buffer_size, COST_VECT *cost);
- bool check_cpk_scan(uint keyno, uint mrr_flags);
+ bool check_cpk_scan(THD *thd, uint keyno, uint mrr_flags);
static int key_tuple_cmp(void* arg, uchar* key1, uchar* key2);
int dsmrr_fill_rowid_buffer();
void dsmrr_fill_key_buffer();