BUG#671340: Diverging results in with mrr_sort_keys=ON|OFF and join_cache_level=5
- Make Mrr_ordered_index_reader() save the rowid across scan interruptions Also - Fix compiler warning for setup_buffer_sizes() - Add commented key_copy/key_restore for better handling of a similar issue with index record being destroyed by scan interruption (which causes incorrect evaluation of pushed index condition later on).
This commit is contained in:
parent
e2d2cdd7b8
commit
a86599e1e4
@ -576,3 +576,87 @@ count(*)
|
||||
480
|
||||
set join_cache_level= @my_save_join_cache_level;
|
||||
drop table t1;
|
||||
#
|
||||
# BUG#671340: Diverging results in with mrr_sort_keys=ON|OFF and join_cache_level=5
|
||||
#
|
||||
CREATE TABLE t1 (
|
||||
pk int(11) NOT NULL AUTO_INCREMENT,
|
||||
col_int_key int(11) NOT NULL,
|
||||
col_varchar_key varchar(1) NOT NULL,
|
||||
col_varchar_nokey varchar(1) NOT NULL,
|
||||
PRIMARY KEY (pk),
|
||||
KEY col_int_key (col_int_key),
|
||||
KEY col_varchar_key (col_varchar_key,col_int_key)
|
||||
) ENGINE=InnoDB;
|
||||
INSERT INTO t1 VALUES
|
||||
(10,8,'v','v'),
|
||||
(11,8,'f','f'),
|
||||
(12,5,'v','v'),
|
||||
(13,8,'s','s'),
|
||||
(14,8,'a','a'),
|
||||
(15,6,'p','p'),
|
||||
(16,7,'z','z'),
|
||||
(17,2,'a','a'),
|
||||
(18,5,'h','h'),
|
||||
(19,7,'h','h'),
|
||||
(20,2,'v','v'),
|
||||
(21,9,'v','v'),
|
||||
(22,142,'b','b'),
|
||||
(23,3,'y','y'),
|
||||
(24,0,'v','v'),
|
||||
(25,3,'m','m'),
|
||||
(26,5,'z','z'),
|
||||
(27,9,'n','n'),
|
||||
(28,1,'d','d'),
|
||||
(29,107,'a','a');
|
||||
CREATE TABLE t2 (
|
||||
pk int(11) NOT NULL AUTO_INCREMENT,
|
||||
col_int_key int(11) NOT NULL,
|
||||
col_varchar_key varchar(1) NOT NULL,
|
||||
col_varchar_nokey varchar(1) NOT NULL,
|
||||
PRIMARY KEY (pk),
|
||||
KEY col_int_key (col_int_key),
|
||||
KEY col_varchar_key (col_varchar_key,col_int_key)
|
||||
) ENGINE=InnoDB;
|
||||
INSERT INTO t2 VALUES
|
||||
(1,9,'x','x'),
|
||||
(2,5,'g','g'),
|
||||
(3,1,'o','o'),
|
||||
(4,0,'g','g'),
|
||||
(5,1,'v','v'),
|
||||
(6,190,'m','m'),
|
||||
(7,6,'x','x'),
|
||||
(8,3,'c','c'),
|
||||
(9,4,'z','z'),
|
||||
(10,3,'i','i'),
|
||||
(11,186,'x','x'),
|
||||
(12,1,'g','g'),
|
||||
(13,8,'q','q'),
|
||||
(14,226,'m','m'),
|
||||
(15,133,'p','p'),
|
||||
(16,6,'e','e'),
|
||||
(17,3,'t','t'),
|
||||
(18,8,'j','j'),
|
||||
(19,5,'h','h'),
|
||||
(20,7,'w','w');
|
||||
SELECT count(*), sum(table1.col_int_key*table2.pk)
|
||||
FROM
|
||||
t2 AS table1, t1 AS table2, t2 AS table3
|
||||
WHERE
|
||||
table3.col_varchar_nokey = table2.col_varchar_key AND table3.pk > table2.col_varchar_nokey ;
|
||||
count(*) sum(table1.col_int_key*table2.pk)
|
||||
240 185955
|
||||
set @my_save_join_cache_level= @@join_cache_level;
|
||||
set @my_save_join_buffer_size= @@join_buffer_size;
|
||||
set join_cache_level=6;
|
||||
set join_buffer_size=1500;
|
||||
SELECT count(*), sum(table1.col_int_key*table2.pk)
|
||||
FROM
|
||||
t2 AS table1, t1 AS table2, t2 AS table3
|
||||
WHERE
|
||||
table3.col_varchar_nokey = table2.col_varchar_key AND table3.pk > table2.col_varchar_nokey ;
|
||||
count(*) sum(table1.col_int_key*table2.pk)
|
||||
240 185955
|
||||
drop table t1,t2;
|
||||
set join_cache_level=@my_save_join_cache_level;
|
||||
set join_buffer_size=@my_save_join_buffer_size;
|
||||
|
@ -277,3 +277,90 @@ select count(*) from
|
||||
set join_cache_level= @my_save_join_cache_level;
|
||||
drop table t1;
|
||||
|
||||
|
||||
--echo #
|
||||
--echo # BUG#671340: Diverging results in with mrr_sort_keys=ON|OFF and join_cache_level=5
|
||||
--echo #
|
||||
CREATE TABLE t1 (
|
||||
pk int(11) NOT NULL AUTO_INCREMENT,
|
||||
col_int_key int(11) NOT NULL,
|
||||
col_varchar_key varchar(1) NOT NULL,
|
||||
col_varchar_nokey varchar(1) NOT NULL,
|
||||
PRIMARY KEY (pk),
|
||||
KEY col_int_key (col_int_key),
|
||||
KEY col_varchar_key (col_varchar_key,col_int_key)
|
||||
) ENGINE=InnoDB;
|
||||
INSERT INTO t1 VALUES
|
||||
(10,8,'v','v'),
|
||||
(11,8,'f','f'),
|
||||
(12,5,'v','v'),
|
||||
(13,8,'s','s'),
|
||||
(14,8,'a','a'),
|
||||
(15,6,'p','p'),
|
||||
(16,7,'z','z'),
|
||||
(17,2,'a','a'),
|
||||
(18,5,'h','h'),
|
||||
(19,7,'h','h'),
|
||||
(20,2,'v','v'),
|
||||
(21,9,'v','v'),
|
||||
(22,142,'b','b'),
|
||||
(23,3,'y','y'),
|
||||
(24,0,'v','v'),
|
||||
(25,3,'m','m'),
|
||||
(26,5,'z','z'),
|
||||
(27,9,'n','n'),
|
||||
(28,1,'d','d'),
|
||||
(29,107,'a','a');
|
||||
|
||||
CREATE TABLE t2 (
|
||||
pk int(11) NOT NULL AUTO_INCREMENT,
|
||||
col_int_key int(11) NOT NULL,
|
||||
col_varchar_key varchar(1) NOT NULL,
|
||||
col_varchar_nokey varchar(1) NOT NULL,
|
||||
PRIMARY KEY (pk),
|
||||
KEY col_int_key (col_int_key),
|
||||
KEY col_varchar_key (col_varchar_key,col_int_key)
|
||||
) ENGINE=InnoDB;
|
||||
INSERT INTO t2 VALUES
|
||||
(1,9,'x','x'),
|
||||
(2,5,'g','g'),
|
||||
(3,1,'o','o'),
|
||||
(4,0,'g','g'),
|
||||
(5,1,'v','v'),
|
||||
(6,190,'m','m'),
|
||||
(7,6,'x','x'),
|
||||
(8,3,'c','c'),
|
||||
(9,4,'z','z'),
|
||||
(10,3,'i','i'),
|
||||
(11,186,'x','x'),
|
||||
(12,1,'g','g'),
|
||||
(13,8,'q','q'),
|
||||
(14,226,'m','m'),
|
||||
(15,133,'p','p'),
|
||||
(16,6,'e','e'),
|
||||
(17,3,'t','t'),
|
||||
(18,8,'j','j'),
|
||||
(19,5,'h','h'),
|
||||
(20,7,'w','w');
|
||||
|
||||
SELECT count(*), sum(table1.col_int_key*table2.pk)
|
||||
FROM
|
||||
t2 AS table1, t1 AS table2, t2 AS table3
|
||||
WHERE
|
||||
table3.col_varchar_nokey = table2.col_varchar_key AND table3.pk > table2.col_varchar_nokey ;
|
||||
|
||||
set @my_save_join_cache_level= @@join_cache_level;
|
||||
set @my_save_join_buffer_size= @@join_buffer_size;
|
||||
set join_cache_level=6;
|
||||
set join_buffer_size=1500;
|
||||
|
||||
SELECT count(*), sum(table1.col_int_key*table2.pk)
|
||||
FROM
|
||||
t2 AS table1, t1 AS table2, t2 AS table3
|
||||
WHERE
|
||||
table3.col_varchar_nokey = table2.col_varchar_key AND table3.pk > table2.col_varchar_nokey ;
|
||||
|
||||
drop table t1,t2;
|
||||
set join_cache_level=@my_save_join_cache_level;
|
||||
set join_buffer_size=@my_save_join_buffer_size;
|
||||
|
||||
|
@ -372,6 +372,42 @@ int Mrr_ordered_index_reader::get_next(char **range_info)
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
|
||||
void Mrr_ordered_index_reader::set_temp_space(uchar *space)
|
||||
{
|
||||
//saved_key_tuple= space;
|
||||
saved_rowid= space;
|
||||
have_saved_rowid= FALSE;
|
||||
}
|
||||
|
||||
void Mrr_ordered_index_reader::interrupt_read()
|
||||
{
|
||||
/*
|
||||
key_copy(saved_key_tuple, file->get_table()->record[0],
|
||||
&file->get_table()->key_info[file->active_index],
|
||||
keypar.key_tuple_length);
|
||||
*/
|
||||
/* Save the last rowid */
|
||||
memcpy(saved_rowid, file->ref, file->ref_length);
|
||||
have_saved_rowid= TRUE;
|
||||
}
|
||||
|
||||
void Mrr_ordered_index_reader::position()
|
||||
{
|
||||
if (have_saved_rowid)
|
||||
memcpy(file->ref, saved_rowid, file->ref_length);
|
||||
else
|
||||
Mrr_index_reader::position();
|
||||
}
|
||||
|
||||
void Mrr_ordered_index_reader::resume_read()
|
||||
{
|
||||
/*
|
||||
key_restore(file->get_table()->record[0], saved_key_tuple,
|
||||
&file->get_table()->key_info[file->active_index],
|
||||
keypar.key_tuple_length);
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Fill the buffer with (lookup_tuple, range_id) pairs and sort
|
||||
@ -480,6 +516,8 @@ int Mrr_ordered_index_reader::init(handler *h_arg, RANGE_SEQ_IF *seq_funcs,
|
||||
|
||||
*/
|
||||
disallow_identical_key_handling= test(mrr_funcs.skip_index_tuple);
|
||||
/*bzero(saved_key_tuple, keypar.key_tuple_length);*/
|
||||
have_saved_rowid= FALSE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -571,6 +609,7 @@ int Mrr_ordered_rndpos_reader::refill_from_index_reader()
|
||||
|
||||
last_identical_rowid= NULL;
|
||||
|
||||
index_reader->resume_read();
|
||||
while (rowid_buffer->can_write())
|
||||
{
|
||||
res= index_reader->get_next(&range_info);
|
||||
@ -589,6 +628,7 @@ int Mrr_ordered_rndpos_reader::refill_from_index_reader()
|
||||
rowid_buffer->write();
|
||||
}
|
||||
|
||||
index_reader->interrupt_read();
|
||||
/* Sort the buffer contents by rowid */
|
||||
rowid_buffer->sort((qsort2_cmp)rowid_cmp_reverse, (void*)file);
|
||||
|
||||
@ -788,6 +828,16 @@ int DsMrr_impl::dsmrr_init(handler *h_arg, RANGE_SEQ_IF *seq_funcs,
|
||||
keypar.key_size_in_keybuf= keypar.use_key_pointers?
|
||||
sizeof(char*) : keypar.key_tuple_length;
|
||||
key_buff_elem_size= keypar.key_size_in_keybuf + (int)is_mrr_assoc * sizeof(void*);
|
||||
|
||||
/* Ordered index reader needs some space to store an index tuple */
|
||||
if (strategy != index_strategy)
|
||||
{
|
||||
if (full_buf_end - full_buf <= (ptrdiff_t)primary_file->ref_length/*keypar.key_tuple_length*/)
|
||||
goto use_default_impl;
|
||||
reader_factory.ordered_index_reader.set_temp_space(full_buf);
|
||||
//full_buf += keypar.key_tuple_length;
|
||||
full_buf += primary_file->ref_length;
|
||||
}
|
||||
}
|
||||
|
||||
if (strategy == index_strategy)
|
||||
@ -1039,7 +1089,7 @@ int Mrr_ordered_index_reader::compare_keys_reverse(void* arg, uchar* key1,
|
||||
bool DsMrr_impl::setup_buffer_sharing(uint key_size_in_keybuf,
|
||||
key_part_map key_tuple_map)
|
||||
{
|
||||
uint key_buff_elem_size= key_size_in_keybuf +
|
||||
long key_buff_elem_size= key_size_in_keybuf +
|
||||
(int)is_mrr_assoc * sizeof(void*);
|
||||
|
||||
KEY *key_info= &primary_file->get_table()->key_info[keyno];
|
||||
@ -1186,6 +1236,7 @@ int Key_value_records_iterator::init(Mrr_ordered_index_reader *owner_arg)
|
||||
move_to_next_key_value();
|
||||
return res;
|
||||
}
|
||||
owner->have_saved_rowid= FALSE;
|
||||
get_next_row= FALSE;
|
||||
return 0;
|
||||
}
|
||||
@ -1212,6 +1263,7 @@ int Key_value_records_iterator::get_next()
|
||||
return res;
|
||||
}
|
||||
identical_key_it.init(owner->key_buffer);
|
||||
owner->have_saved_rowid= FALSE;
|
||||
get_next_row= FALSE;
|
||||
}
|
||||
|
||||
|
@ -211,8 +211,11 @@ public:
|
||||
/* Get pointer to place where every get_next() call will put rowid */
|
||||
virtual uchar *get_rowid_ptr() = 0;
|
||||
/* Get the rowid (call this after get_next() call) */
|
||||
void position();
|
||||
virtual void position();
|
||||
virtual bool skip_record(char *range_id, uchar *rowid) = 0;
|
||||
|
||||
virtual void interrupt_read() {}
|
||||
virtual void resume_read() {}
|
||||
};
|
||||
|
||||
|
||||
@ -269,6 +272,10 @@ public:
|
||||
mrr_funcs.skip_index_tuple(mrr_iter, range_info));
|
||||
}
|
||||
|
||||
void set_temp_space(uchar *space);
|
||||
void interrupt_read();
|
||||
void resume_read();
|
||||
void position();
|
||||
private:
|
||||
Key_value_records_iterator kv_it;
|
||||
|
||||
@ -300,6 +307,11 @@ private:
|
||||
|
||||
/* TRUE == reached eof when enumerating ranges */
|
||||
bool source_exhausted;
|
||||
|
||||
/* TODO */
|
||||
/*uchar *saved_key_tuple;*/
|
||||
uchar *saved_rowid;
|
||||
bool have_saved_rowid;
|
||||
|
||||
static int compare_keys(void* arg, uchar* key1, uchar* key2);
|
||||
static int compare_keys_reverse(void* arg, uchar* key1, uchar* key2);
|
||||
|
Loading…
x
Reference in New Issue
Block a user