Commit 2e6d41d1 authored by unknown's avatar unknown
Browse files

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.


include/my_global.h:
  Auto merged
mysql-test/t/heap_hash.test:
  Auto merged
sql/ha_heap.h:
  Auto merged
sql/item_timefunc.cc:
  Auto merged
mysql-test/r/func_time.result:
  Manual merge.
  Used local for the backported fix for Bug#10568.
mysql-test/r/heap_hash.result:
  Bug#10178 - failure to find a row in heap table by concurrent UPDATEs
  Manual merge.
mysql-test/t/func_time.test:
  Manual merge.
  Used local for the backported fix for Bug#10568.
sql/ha_heap.cc:
  Bug#10178 - failure to find a row in heap table by concurrent UPDATEs
  Manual merge.
parents be3d7091 a7e66efc
Loading
Loading
Loading
Loading
+0 −2
Original line number Diff line number Diff line
@@ -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
+12 −11
Original line number Diff line number Diff line
@@ -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;
+2 −0
Original line number Diff line number Diff line
@@ -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';
+25 −5
Original line number Diff line number Diff line
@@ -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];
}

+3 −1
Original line number Diff line number Diff line
@@ -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
  {