Bug#10178 - failure to find a row in heap table by concurrent UPDATEs
Bug#10568 - Function 'LAST_DAY(date)' does not return NULL for invalid argument. Manual merge.
This commit is contained in:
commit
1c33fbc4c1
@ -295,10 +295,8 @@ C_MODE_END
|
||||
#include <alloca.h>
|
||||
#endif
|
||||
#ifdef HAVE_ATOMIC_ADD
|
||||
#if defined(__ia64__)
|
||||
#define new my_arg_new
|
||||
#define need_to_restore_new 1
|
||||
#endif
|
||||
C_MODE_START
|
||||
#include <asm/atomic.h>
|
||||
C_MODE_END
|
||||
|
@ -231,18 +231,19 @@ explain select * from t1 where a='aaad';
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE t1 ref a a 8 const 1 Using where
|
||||
insert into t1 select * from t1;
|
||||
flush tables;
|
||||
explain select * from t1 where a='aaaa';
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE t1 ref a a 8 const 1 Using where
|
||||
1 SIMPLE t1 ref a a 8 const 2 Using where
|
||||
explain select * from t1 where a='aaab';
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE t1 ref a a 8 const 1 Using where
|
||||
1 SIMPLE t1 ref a a 8 const 2 Using where
|
||||
explain select * from t1 where a='aaac';
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE t1 ref a a 8 const 1 Using where
|
||||
1 SIMPLE t1 ref a a 8 const 2 Using where
|
||||
explain select * from t1 where a='aaad';
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE t1 ref a a 8 const 1 Using where
|
||||
1 SIMPLE t1 ref a a 8 const 2 Using where
|
||||
flush tables;
|
||||
explain select * from t1 where a='aaaa';
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
@ -261,16 +262,16 @@ delete from t1;
|
||||
insert into t1 select * from t2;
|
||||
explain select * from t1 where a='aaaa';
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE t1 ref a a 8 const 1 Using where
|
||||
1 SIMPLE t1 ref a a 8 const 2 Using where
|
||||
explain select * from t1 where a='aaab';
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE t1 ref a a 8 const 1 Using where
|
||||
1 SIMPLE t1 ref a a 8 const 2 Using where
|
||||
explain select * from t1 where a='aaac';
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE t1 ref a a 8 const 1 Using where
|
||||
1 SIMPLE t1 ref a a 8 const 2 Using where
|
||||
explain select * from t1 where a='aaad';
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE t1 ref a a 8 const 1 Using where
|
||||
1 SIMPLE t1 ref a a 8 const 2 Using where
|
||||
drop table t1, t2;
|
||||
create table t1 (
|
||||
id int unsigned not null primary key auto_increment,
|
||||
@ -345,14 +346,14 @@ insert into t3 select name, name from t1;
|
||||
show index from t3;
|
||||
Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment
|
||||
t3 1 a 1 a NULL NULL NULL NULL HASH
|
||||
t3 1 a 2 b NULL 15 NULL NULL HASH
|
||||
t3 1 a 2 b NULL 13 NULL NULL HASH
|
||||
show index from t3;
|
||||
Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment
|
||||
t3 1 a 1 a NULL NULL NULL NULL HASH
|
||||
t3 1 a 2 b NULL 15 NULL NULL HASH
|
||||
t3 1 a 2 b NULL 13 NULL NULL HASH
|
||||
explain select * from t1 ignore key(btree_idx), t3 where t1.name='matt' and t3.a = concat('',t1.name) and t3.b=t1.name;
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE t3 ref a a 44 const,const 6 Using where
|
||||
1 SIMPLE t3 ref a a 44 const,const 7 Using where
|
||||
1 SIMPLE t1 ref heap_idx heap_idx 22 const 7 Using where
|
||||
drop table t1, t2, t3;
|
||||
create temporary table t1 ( a int, index (a) ) engine=memory;
|
||||
|
@ -169,6 +169,8 @@ explain select * from t1 where a='aaac';
|
||||
explain select * from t1 where a='aaad';
|
||||
insert into t1 select * from t1;
|
||||
|
||||
# avoid statistics differences between normal and ps-protocol tests
|
||||
flush tables;
|
||||
explain select * from t1 where a='aaaa';
|
||||
explain select * from t1 where a='aaab';
|
||||
explain select * from t1 where a='aaac';
|
||||
|
@ -65,7 +65,15 @@ int ha_heap::open(const char *name, int mode, uint test_if_locked)
|
||||
{
|
||||
/* Initialize variables for the opened table */
|
||||
set_keys_for_scanning();
|
||||
update_key_stats();
|
||||
/*
|
||||
We cannot run update_key_stats() here because we do not have a
|
||||
lock on the table. The 'records' count might just be changed
|
||||
temporarily at this moment and we might get wrong statistics (Bug
|
||||
#10178). Instead we request for update. This will be done in
|
||||
ha_heap::info(), which is always called before key statistics are
|
||||
used.
|
||||
*/
|
||||
key_stats_ok= FALSE;
|
||||
}
|
||||
return (file ? 0 : 1);
|
||||
}
|
||||
@ -118,6 +126,8 @@ void ha_heap::update_key_stats()
|
||||
}
|
||||
}
|
||||
records_changed= 0;
|
||||
/* At the end of update_key_stats() we can proudly claim they are OK. */
|
||||
key_stats_ok= TRUE;
|
||||
}
|
||||
|
||||
|
||||
@ -132,7 +142,7 @@ int ha_heap::write_row(byte * buf)
|
||||
res= heap_write(file,buf);
|
||||
if (!res && (++records_changed*HEAP_STATS_UPDATE_THRESHOLD >
|
||||
file->s->records))
|
||||
update_key_stats();
|
||||
key_stats_ok= FALSE;
|
||||
return res;
|
||||
}
|
||||
|
||||
@ -145,7 +155,7 @@ int ha_heap::update_row(const byte * old_data, byte * new_data)
|
||||
res= heap_update(file,old_data,new_data);
|
||||
if (!res && ++records_changed*HEAP_STATS_UPDATE_THRESHOLD >
|
||||
file->s->records)
|
||||
update_key_stats();
|
||||
key_stats_ok= FALSE;
|
||||
return res;
|
||||
}
|
||||
|
||||
@ -156,7 +166,7 @@ int ha_heap::delete_row(const byte * buf)
|
||||
res= heap_delete(file,buf);
|
||||
if (!res && table->s->tmp_table == NO_TMP_TABLE &&
|
||||
++records_changed*HEAP_STATS_UPDATE_THRESHOLD > file->s->records)
|
||||
update_key_stats();
|
||||
key_stats_ok= FALSE;
|
||||
return res;
|
||||
}
|
||||
|
||||
@ -278,6 +288,13 @@ void ha_heap::info(uint flag)
|
||||
delete_length= info.deleted * info.reclength;
|
||||
if (flag & HA_STATUS_AUTO)
|
||||
auto_increment_value= info.auto_increment;
|
||||
/*
|
||||
If info() is called for the first time after open(), we will still
|
||||
have to update the key statistics. Hoping that a table lock is now
|
||||
in place.
|
||||
*/
|
||||
if (! key_stats_ok)
|
||||
update_key_stats();
|
||||
}
|
||||
|
||||
int ha_heap::extra(enum ha_extra_function operation)
|
||||
@ -289,7 +306,7 @@ int ha_heap::delete_all_rows()
|
||||
{
|
||||
heap_clear(file);
|
||||
if (table->s->tmp_table == NO_TMP_TABLE)
|
||||
update_key_stats();
|
||||
key_stats_ok= FALSE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -448,6 +465,9 @@ ha_rows ha_heap::records_in_range(uint inx, key_range *min_key,
|
||||
min_key->flag != HA_READ_KEY_EXACT ||
|
||||
max_key->flag != HA_READ_AFTER_KEY)
|
||||
return HA_POS_ERROR; // Can only use exact keys
|
||||
|
||||
/* Assert that info() did run. We need current statistics here. */
|
||||
DBUG_ASSERT(key_stats_ok);
|
||||
return key->rec_per_key[key->key_parts-1];
|
||||
}
|
||||
|
||||
|
@ -29,8 +29,10 @@ class ha_heap: public handler
|
||||
key_map btree_keys;
|
||||
/* number of records changed since last statistics update */
|
||||
uint records_changed;
|
||||
bool key_stats_ok;
|
||||
public:
|
||||
ha_heap(TABLE *table): handler(table), file(0), records_changed(0) {}
|
||||
ha_heap(TABLE *table): handler(table), file(0), records_changed(0),
|
||||
key_stats_ok(0) {}
|
||||
~ha_heap() {}
|
||||
const char *table_type() const
|
||||
{
|
||||
|
Loading…
x
Reference in New Issue
Block a user