Commit 2061e00c authored by Varun Gupta's avatar Varun Gupta

MDEV-14440: Assertion `inited==RND' failed in handler::ha_rnd_end

In the function QUICK_RANGE_SELECT::init_ror_merged_scan we create a seperate handler if the handler in
head->file cannot be reused. The flag free_file tells us if we have a seperate handler or not.
There are cases where you might create a handler and then there might be a failure(running ALTER)
and then we have to revert the handler back to the original one. The code does that
but it does not reset the flag 'free_file' in this case.
Also backported f2c41807.
parent 19a7656f
...@@ -55,3 +55,27 @@ pk f1 f2 f3 pk f1 f2 f3 f4 f5 ...@@ -55,3 +55,27 @@ pk f1 f2 f3 pk f1 f2 f3 f4 f5
2 6 v NULL 14 1 q NULL 4 q 2 6 v NULL 14 1 q NULL 4 q
3 7 c NULL 14 1 q NULL 4 q 3 7 c NULL 14 1 q NULL 4 q
drop table t1,t2; drop table t1,t2;
#
# MDEV-14440: Server crash in in handler::ha_external_lock or Assertion `inited==RND'
# failed in handler::ha_rnd_end upon SELECT from partitioned table
#
set @optimizer_switch_save= @@optimizer_switch;
set optimizer_switch='index_merge_sort_intersection=off';
create table t0 (a int)engine=innodb;
insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
create table t1 (
a int, b int, c int,
key(a),key(b),key(c)
)engine=innodb;
insert into t1
select A.a+10*B.a, A.a+10*B.a, A.a+10*B.a+100*C.a
from t0 A, t0 B, t0 C, t0 D where D.a<5;
set @@global.debug_dbug="+d,ha_index_init_fail";
explain select * from t1 where a=10 and b=10;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 index_merge a,b a,b 5,5 NULL 1 Using intersect(a,b); Using where
select * from t1 where a=10 and b=10;
ERROR HY000: Table definition has changed, please retry transaction
DROP TABLE t0,t1;
set @@global.debug_dbug="-d";
set @@optimizer_switch= @optimizer_switch_save;
...@@ -3,6 +3,7 @@ ...@@ -3,6 +3,7 @@
--echo # --echo #
--source include/have_innodb.inc --source include/have_innodb.inc
--source include/have_debug.inc
--disable_warnings --disable_warnings
drop table if exists t0, t1, t2; drop table if exists t0, t1, t2;
...@@ -62,3 +63,27 @@ INSERT INTO t2 VALUES (4,'q'),(NULL,'j'); ...@@ -62,3 +63,27 @@ INSERT INTO t2 VALUES (4,'q'),(NULL,'j');
SELECT * FROM t1 AS t1_1, t1 AS t1_2, t2 SELECT * FROM t1 AS t1_1, t1 AS t1_2, t2
WHERE f5 = t1_2.f2 AND ( t1_1.f1 = 103 AND t1_1.f2 = 'o' OR t1_1.pk < f4 ); WHERE f5 = t1_2.f2 AND ( t1_1.f1 = 103 AND t1_1.f2 = 'o' OR t1_1.pk < f4 );
drop table t1,t2; drop table t1,t2;
--echo #
--echo # MDEV-14440: Server crash in in handler::ha_external_lock or Assertion `inited==RND'
--echo # failed in handler::ha_rnd_end upon SELECT from partitioned table
--echo #
set @optimizer_switch_save= @@optimizer_switch;
set optimizer_switch='index_merge_sort_intersection=off';
create table t0 (a int)engine=innodb;
insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
create table t1 (
a int, b int, c int,
key(a),key(b),key(c)
)engine=innodb;
insert into t1
select A.a+10*B.a, A.a+10*B.a, A.a+10*B.a+100*C.a
from t0 A, t0 B, t0 C, t0 D where D.a<5;
set @@global.debug_dbug="+d,ha_index_init_fail";
explain select * from t1 where a=10 and b=10;
--error ER_TABLE_DEF_CHANGED
select * from t1 where a=10 and b=10;
DROP TABLE t0,t1;
set @@global.debug_dbug="-d";
set @@optimizer_switch= @optimizer_switch_save;
...@@ -2161,6 +2161,7 @@ int QUICK_RANGE_SELECT::init_ror_merged_scan(bool reuse_handler, MEM_ROOT *alloc ...@@ -2161,6 +2161,7 @@ int QUICK_RANGE_SELECT::init_ror_merged_scan(bool reuse_handler, MEM_ROOT *alloc
head->column_bitmaps_set(save_read_set, save_write_set); head->column_bitmaps_set(save_read_set, save_write_set);
delete file; delete file;
file= save_file; file= save_file;
free_file= false;
DBUG_RETURN(1); DBUG_RETURN(1);
} }
...@@ -7140,6 +7141,8 @@ TRP_ROR_INTERSECT *get_best_ror_intersect(const PARAM *param, SEL_TREE *tree, ...@@ -7140,6 +7141,8 @@ TRP_ROR_INTERSECT *get_best_ror_intersect(const PARAM *param, SEL_TREE *tree,
if (ror_intersect_add(intersect, cpk_scan, TRUE) && if (ror_intersect_add(intersect, cpk_scan, TRUE) &&
(intersect->total_cost < min_cost)) (intersect->total_cost < min_cost))
intersect_best= intersect; //just set pointer here intersect_best= intersect; //just set pointer here
else
cpk_scan= 0; // Don't use cpk_scan
} }
else else
cpk_scan= 0; // Don't use cpk_scan cpk_scan= 0; // Don't use cpk_scan
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment