Commit 9cb002b3 authored by Sergey Petrunya's avatar Sergey Petrunya

MDEV-6878: Use of uninitialized saved_primary_key in Mrr_ordered_index_reader::resume_read()

(Backport to 5.3)
(variant #2, with fixed coding style)
- Make Mrr_ordered_index_reader::resume_read() restore index position 
  only if it was saved before with Mrr_ordered_index_reader::interrupt_read().
parent 94c8f335
...@@ -149,3 +149,41 @@ set @@join_cache_level= @save_join_cache_level; ...@@ -149,3 +149,41 @@ set @@join_cache_level= @save_join_cache_level;
set storage_engine=@save_storage_engine; set storage_engine=@save_storage_engine;
set optimizer_switch=@innodb_mrr_cpk_tmp; set optimizer_switch=@innodb_mrr_cpk_tmp;
drop table t0; drop table t0;
#
# MDEV-6878: Use of uninitialized saved_primary_key in Mrr_ordered_index_reader::resume_read()
#
create table t0(a int);
insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
create table t1 (
pk varchar(32) character set utf8 primary key,
kp1 char(32) not null,
col1 varchar(32),
key (kp1)
) engine=innodb;
insert into t1
select
concat('pk-', 1000 +A.a),
concat('kp1-', 1000 +A.a),
concat('val-', 1000 +A.a)
from test.t0 A ;
create table t2 as select kp1 as a from t1;
set join_cache_level=8;
set optimizer_switch='mrr=on,mrr_sort_keys=on';
explain
select * from t2 straight_join t1 force index(kp1) where t1.kp1=t2.a;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t2 ALL NULL NULL NULL NULL 10
1 SIMPLE t1 ref kp1 kp1 32 test.t2.a 1 Using join buffer (flat, BKAH join); Key-ordered Rowid-ordered scan
select * from t2 straight_join t1 force index(kp1) where t1.kp1=t2.a;
a pk kp1 col1
kp1-1000 pk-1000 kp1-1000 val-1000
kp1-1001 pk-1001 kp1-1001 val-1001
kp1-1002 pk-1002 kp1-1002 val-1002
kp1-1003 pk-1003 kp1-1003 val-1003
kp1-1004 pk-1004 kp1-1004 val-1004
kp1-1005 pk-1005 kp1-1005 val-1005
kp1-1006 pk-1006 kp1-1006 val-1006
kp1-1007 pk-1007 kp1-1007 val-1007
kp1-1008 pk-1008 kp1-1008 val-1008
kp1-1009 pk-1009 kp1-1009 val-1009
drop table t0,t1,t2;
...@@ -139,3 +139,32 @@ set storage_engine=@save_storage_engine; ...@@ -139,3 +139,32 @@ set storage_engine=@save_storage_engine;
set optimizer_switch=@innodb_mrr_cpk_tmp; set optimizer_switch=@innodb_mrr_cpk_tmp;
drop table t0; drop table t0;
--echo #
--echo # MDEV-6878: Use of uninitialized saved_primary_key in Mrr_ordered_index_reader::resume_read()
--echo #
create table t0(a int);
insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
create table t1 (
pk varchar(32) character set utf8 primary key,
kp1 char(32) not null,
col1 varchar(32),
key (kp1)
) engine=innodb;
insert into t1
select
concat('pk-', 1000 +A.a),
concat('kp1-', 1000 +A.a),
concat('val-', 1000 +A.a)
from test.t0 A ;
create table t2 as select kp1 as a from t1;
set join_cache_level=8;
set optimizer_switch='mrr=on,mrr_sort_keys=on';
explain
select * from t2 straight_join t1 force index(kp1) where t1.kp1=t2.a;
select * from t2 straight_join t1 force index(kp1) where t1.kp1=t2.a;
drop table t0,t1,t2;
...@@ -410,6 +410,7 @@ bool Mrr_ordered_index_reader::set_interruption_temp_buffer(uint rowid_length, ...@@ -410,6 +410,7 @@ bool Mrr_ordered_index_reader::set_interruption_temp_buffer(uint rowid_length,
*space_start += key_len; *space_start += key_len;
have_saved_rowid= FALSE; have_saved_rowid= FALSE;
read_was_interrupted= FALSE;
return FALSE; return FALSE;
} }
...@@ -418,6 +419,7 @@ void Mrr_ordered_index_reader::set_no_interruption_temp_buffer() ...@@ -418,6 +419,7 @@ void Mrr_ordered_index_reader::set_no_interruption_temp_buffer()
support_scan_interruptions= FALSE; support_scan_interruptions= FALSE;
saved_key_tuple= saved_rowid= saved_primary_key= NULL; /* safety */ saved_key_tuple= saved_rowid= saved_primary_key= NULL; /* safety */
have_saved_rowid= FALSE; have_saved_rowid= FALSE;
read_was_interrupted= FALSE;
} }
void Mrr_ordered_index_reader::interrupt_read() void Mrr_ordered_index_reader::interrupt_read()
...@@ -435,6 +437,7 @@ void Mrr_ordered_index_reader::interrupt_read() ...@@ -435,6 +437,7 @@ void Mrr_ordered_index_reader::interrupt_read()
&table->key_info[table->s->primary_key], &table->key_info[table->s->primary_key],
table->key_info[table->s->primary_key].key_length); table->key_info[table->s->primary_key].key_length);
} }
read_was_interrupted= TRUE;
/* Save the last rowid */ /* Save the last rowid */
memcpy(saved_rowid, file->ref, file->ref_length); memcpy(saved_rowid, file->ref, file->ref_length);
...@@ -452,6 +455,10 @@ void Mrr_ordered_index_reader::position() ...@@ -452,6 +455,10 @@ void Mrr_ordered_index_reader::position()
void Mrr_ordered_index_reader::resume_read() void Mrr_ordered_index_reader::resume_read()
{ {
TABLE *table= file->get_table(); TABLE *table= file->get_table();
if (!read_was_interrupted)
return;
KEY *used_index= &table->key_info[file->active_index]; KEY *used_index= &table->key_info[file->active_index];
key_restore(table->record[0], saved_key_tuple, key_restore(table->record[0], saved_key_tuple,
used_index, used_index->key_length); used_index, used_index->key_length);
...@@ -541,8 +548,7 @@ int Mrr_ordered_index_reader::init(handler *h_arg, RANGE_SEQ_IF *seq_funcs, ...@@ -541,8 +548,7 @@ int Mrr_ordered_index_reader::init(handler *h_arg, RANGE_SEQ_IF *seq_funcs,
is_mrr_assoc= !test(mode & HA_MRR_NO_ASSOCIATION); is_mrr_assoc= !test(mode & HA_MRR_NO_ASSOCIATION);
mrr_funcs= *seq_funcs; mrr_funcs= *seq_funcs;
source_exhausted= FALSE; source_exhausted= FALSE;
if (support_scan_interruptions) read_was_interrupted= false;
bzero(saved_key_tuple, key_info->key_length);
have_saved_rowid= FALSE; have_saved_rowid= FALSE;
return 0; return 0;
} }
......
...@@ -324,6 +324,12 @@ class Mrr_ordered_index_reader : public Mrr_index_reader ...@@ -324,6 +324,12 @@ class Mrr_ordered_index_reader : public Mrr_index_reader
uchar *saved_key_tuple; /* Saved current key tuple */ uchar *saved_key_tuple; /* Saved current key tuple */
uchar *saved_primary_key; /* Saved current primary key tuple */ uchar *saved_primary_key; /* Saved current primary key tuple */
/*
TRUE<=> saved_key_tuple (and saved_primary_key when applicable) have
valid values.
*/
bool read_was_interrupted;
static int compare_keys(void* arg, uchar* key1, uchar* key2); static int compare_keys(void* arg, uchar* key1, uchar* key2);
static int compare_keys_reverse(void* arg, uchar* key1, uchar* key2); static int compare_keys_reverse(void* arg, uchar* key1, uchar* key2);
......
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