From bba73a091031e9c324fedd6ad1bb26bcd4e635f9 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 8 Nov 2005 00:26:37 -0500 Subject: [PATCH 01/21] Bug #12796: Record lost in HEAP table Two handler objects were present, one was used for an insert and the other for a select The state of the statistics was local to the handler object and thus the other handler object didn't notice the insert. Fix included: 1) Add a new variable key_stat_version added to whenever statistics was considered in need of update (previously key_stats_ok= FALSE in those places) 2) Add a new handler variable key_stat_version assigned whenever key_stats_ok= TRUE was set previously 3) Fix records_in_range to return records if records <= 1 4) Fix records_in_range to add 2 to rec_per_key to ensure we don't specify 0 or 1 when it isn't and thus invoking incorrect optimisations. 5) Fix unique key handling for HEAP table in records_in_range --- heap/hp_create.c | 1 + include/heap.h | 1 + mysql-test/r/heap.result | 12 +++++++++++- mysql-test/t/heap.test | 11 +++++++++++ mysql-test/t/test_heap.test | 20 +++++++++++++++++++ sql/ha_heap.cc | 38 ++++++++++++++++++++++++------------- sql/ha_heap.h | 4 ++-- 7 files changed, 71 insertions(+), 16 deletions(-) create mode 100644 mysql-test/t/test_heap.test diff --git a/heap/hp_create.c b/heap/hp_create.c index 2b811dac89b..acd4447fe5c 100644 --- a/heap/hp_create.c +++ b/heap/hp_create.c @@ -104,6 +104,7 @@ int heap_create(const char *name, uint keys, HP_KEYDEF *keydef, DBUG_RETURN(1); } share->keydef= (HP_KEYDEF*) (share + 1); + share->key_stat_version= 1; keyseg= (HA_KEYSEG*) (share->keydef + keys); init_block(&share->block, reclength + 1, min_records, max_records); /* Fix keys */ diff --git a/include/heap.h b/include/heap.h index badec9ce2ef..cfbb6113f86 100644 --- a/include/heap.h +++ b/include/heap.h @@ -136,6 +136,7 @@ typedef struct st_heap_share HP_KEYDEF *keydef; ulong min_records,max_records; /* Params to open */ ulong data_length,index_length,max_table_size; + uint key_stat_version; /* version to indicate insert/delete */ uint records; /* records */ uint blength; /* records rounded up to 2^n */ uint deleted; /* Deleted records in database */ diff --git a/mysql-test/r/heap.result b/mysql-test/r/heap.result index 53dec294ef8..e3b9f7db984 100644 --- a/mysql-test/r/heap.result +++ b/mysql-test/r/heap.result @@ -182,7 +182,7 @@ SELECT * FROM t1 WHERE a=NULL; a b explain SELECT * FROM t1 WHERE a IS NULL; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 ref a a 5 const 1 Using where +1 SIMPLE t1 ref a a 5 const 2 Using where SELECT * FROM t1 WHERE a<=>NULL; a b NULL 99 @@ -296,3 +296,13 @@ insert into t1 values ("abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcd insert into t1 values ("abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz"); ERROR 23000: Duplicate entry 'abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijkl' for key 1 drop table t1; +CREATE TABLE t1 (a int, key(a)) engine=heap; +insert delayed into t1 values (0); +delete from t1; +select * from t1; +a +insert delayed into t1 values (0), (1); +select * from t1 where a = 0; +a +0 +drop table t1; diff --git a/mysql-test/t/heap.test b/mysql-test/t/heap.test index 270b8a1df6f..a8128b79e3b 100644 --- a/mysql-test/t/heap.test +++ b/mysql-test/t/heap.test @@ -234,4 +234,15 @@ insert into t1 values ("abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcd insert into t1 values ("abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz"); drop table t1; +# +# Bug 12796: Record doesn't show when selecting through index +# +CREATE TABLE t1 (a int, key(a)) engine=heap; +insert delayed into t1 values (0); +delete from t1; +select * from t1; +insert delayed into t1 values (0), (1); +select * from t1 where a = 0; +drop table t1; + # End of 4.1 tests diff --git a/mysql-test/t/test_heap.test b/mysql-test/t/test_heap.test new file mode 100644 index 00000000000..851c376ba38 --- /dev/null +++ b/mysql-test/t/test_heap.test @@ -0,0 +1,20 @@ +# +# Test of heap tables. +# + +--disable_warnings +drop table if exists t1; +--enable_warnings + +# +# Bug 12796: Record doesn't show when selecting through index +# +CREATE TABLE t1 (a int, key(a)) engine=heap; +insert delayed into t1 values (0); +delete from t1; +select * from t1; +insert delayed into t1 values (0), (1); +select * from t1 where a = 0; +drop table t1; + +# End of 4.1 tests diff --git a/sql/ha_heap.cc b/sql/ha_heap.cc index f8c2e6cc338..61e5ce89693 100644 --- a/sql/ha_heap.cc +++ b/sql/ha_heap.cc @@ -68,7 +68,7 @@ int ha_heap::open(const char *name, int mode, uint test_if_locked) ha_heap::info(), which is always called before key statistics are used. */ - key_stats_ok= FALSE; + key_stat_version= file->s->key_stat_version-1; } return (file ? 0 : 1); } @@ -114,14 +114,21 @@ void ha_heap::update_key_stats() continue; if (key->algorithm != HA_KEY_ALG_BTREE) { - ha_rows hash_buckets= file->s->keydef[i].hash_buckets; - key->rec_per_key[key->key_parts-1]= - hash_buckets ? file->s->records/hash_buckets : 0; + if (key->flags & HA_NOSAME) + key->rec_per_key[key->key_parts-1]= 1; + else + { + ha_rows hash_buckets= file->s->keydef[i].hash_buckets; + uint no_records= hash_buckets ? file->s->records/hash_buckets : 2; + if (no_records < 2) + no_records= 2; + key->rec_per_key[key->key_parts-1]= no_records; + } } } records_changed= 0; /* At the end of update_key_stats() we can proudly claim they are OK. */ - key_stats_ok= TRUE; + key_stat_version= file->s->key_stat_version; } int ha_heap::write_row(byte * buf) @@ -135,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) - key_stats_ok= FALSE; + file->s->key_stat_version++; return res; } @@ -148,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) - key_stats_ok= FALSE; + file->s->key_stat_version++; return res; } @@ -159,7 +166,7 @@ int ha_heap::delete_row(const byte * buf) res= heap_delete(file,buf); if (!res && table->tmp_table == NO_TMP_TABLE && ++records_changed*HEAP_STATS_UPDATE_THRESHOLD > file->s->records) - key_stats_ok= FALSE; + file->s->key_stat_version++; return res; } @@ -277,7 +284,7 @@ void ha_heap::info(uint flag) have to update the key statistics. Hoping that a table lock is now in place. */ - if (! key_stats_ok) + if (key_stat_version != file->s->key_stat_version) update_key_stats(); } @@ -290,7 +297,7 @@ int ha_heap::delete_all_rows() { heap_clear(file); if (table->tmp_table == NO_TMP_TABLE) - key_stats_ok= FALSE; + file->s->key_stat_version++; return 0; } @@ -451,9 +458,14 @@ ha_rows ha_heap::records_in_range(uint inx, key_range *min_key, return HA_POS_ERROR; // Can only use exact keys else { - /* Assert that info() did run. We need current statistics here. */ - DBUG_ASSERT(key_stats_ok); - return key->rec_per_key[key->key_parts-1]; + if (records <= 1) + return records; + else + { + /* Assert that info() did run. We need current statistics here. */ + DBUG_ASSERT(key_stat_version == file->s->key_stat_version); + return key->rec_per_key[key->key_parts-1]; + } } } diff --git a/sql/ha_heap.h b/sql/ha_heap.h index cbe2474492d..0a087fde1b0 100644 --- a/sql/ha_heap.h +++ b/sql/ha_heap.h @@ -29,10 +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; + uint key_stat_version; public: ha_heap(TABLE *table): handler(table), file(0), records_changed(0), - key_stats_ok(0) {} + key_stat_version(0) {} ~ha_heap() {} const char *table_type() const { return "HEAP"; } const char *index_type(uint inx) From 09c4976c1986ee40683f8aa7be4055d81418b6bd Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 22 Nov 2005 12:58:55 -0500 Subject: [PATCH 02/21] Changed report of records to 2 from 1 previously in records_in_range in certain situations causes change of test behaviour --- mysql-test/r/heap_hash.result | 20 ++++++++++---------- mysql-test/r/myisam.result | 2 +- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/mysql-test/r/heap_hash.result b/mysql-test/r/heap_hash.result index e5098ab8c87..11b280997e5 100644 --- a/mysql-test/r/heap_hash.result +++ b/mysql-test/r/heap_hash.result @@ -182,7 +182,7 @@ SELECT * FROM t1 WHERE a=NULL; a b explain SELECT * FROM t1 WHERE a IS NULL; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 ref a a 5 const 1 Using where +1 SIMPLE t1 ref a a 5 const 2 Using where SELECT * FROM t1 WHERE a<=>NULL; a b NULL 99 @@ -220,16 +220,16 @@ insert into t1 values ('aaag', 'prefill-hash=3',0); insert into t1 values ('aaah', 'prefill-hash=6',0); 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 insert into t1 select * from t1; flush tables; explain select * from t1 where a='aaaa'; @@ -291,25 +291,25 @@ insert into t1 (name) values ('Matt'), ('Lilu'), ('Corbin'), ('Carly'), insert into t2 select * from t1; explain select * from t1 where name='matt'; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 ref heap_idx,btree_idx heap_idx 20 const 1 Using where +1 SIMPLE t1 ref heap_idx,btree_idx btree_idx 20 const 1 Using where explain select * from t2 where name='matt'; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t2 ref btree_idx,heap_idx btree_idx 20 const 1 Using where explain select * from t1 where name='Lilu'; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 ref heap_idx,btree_idx heap_idx 20 const 1 Using where +1 SIMPLE t1 ref heap_idx,btree_idx btree_idx 20 const 1 Using where explain select * from t2 where name='Lilu'; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t2 ref btree_idx,heap_idx btree_idx 20 const 1 Using where explain select * from t1 where name='Phil'; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 ref heap_idx,btree_idx heap_idx 20 const 1 Using where +1 SIMPLE t1 ref heap_idx,btree_idx btree_idx 20 const 1 Using where explain select * from t2 where name='Phil'; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t2 ref btree_idx,heap_idx btree_idx 20 const 1 Using where explain select * from t1 where name='Lilu'; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 ref heap_idx,btree_idx heap_idx 20 const 1 Using where +1 SIMPLE t1 ref heap_idx,btree_idx btree_idx 20 const 1 Using where explain select * from t2 where name='Lilu'; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t2 ref btree_idx,heap_idx btree_idx 20 const 1 Using where @@ -364,5 +364,5 @@ a 3 explain select a from t1 where a in (1,3); id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range a a 5 NULL 2 Using where +1 SIMPLE t1 range a a 5 NULL 4 Using where drop table t1; diff --git a/mysql-test/r/myisam.result b/mysql-test/r/myisam.result index d2d0417f6e6..c269cbadca3 100644 --- a/mysql-test/r/myisam.result +++ b/mysql-test/r/myisam.result @@ -554,7 +554,7 @@ Warnings: Note 1031 Table storage engine for 't1' doesn't have this option show keys from t1; Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment -t1 1 a 1 a NULL 1000 NULL NULL YES HASH +t1 1 a 1 a NULL 500 NULL NULL YES HASH drop table t1,t2; create table t1 ( a tinytext, b char(1), index idx (a(1),b) ); insert into t1 values (null,''), (null,''); From a2991b9e1d123584670869fb0b2fe4555d259edd Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 22 Nov 2005 13:04:51 -0500 Subject: [PATCH 03/21] Delete: mysql-test/t/test_heap.test --- mysql-test/t/test_heap.test | 20 -------------------- 1 file changed, 20 deletions(-) delete mode 100644 mysql-test/t/test_heap.test diff --git a/mysql-test/t/test_heap.test b/mysql-test/t/test_heap.test deleted file mode 100644 index 851c376ba38..00000000000 --- a/mysql-test/t/test_heap.test +++ /dev/null @@ -1,20 +0,0 @@ -# -# Test of heap tables. -# - ---disable_warnings -drop table if exists t1; ---enable_warnings - -# -# Bug 12796: Record doesn't show when selecting through index -# -CREATE TABLE t1 (a int, key(a)) engine=heap; -insert delayed into t1 values (0); -delete from t1; -select * from t1; -insert delayed into t1 values (0), (1); -select * from t1 where a = 0; -drop table t1; - -# End of 4.1 tests From 25e32d83d6d5fdce25ba4ef68885ffbf9f7a934f Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 13 Jan 2006 14:42:46 +0100 Subject: [PATCH 04/21] fix for bug#15828 problem was not checking 2nd parameter of str_to_date against NULL mysql-test/r/date_formats.result: bk commit --- mysql-test/r/date_formats.result | 6 ++++++ mysql-test/t/date_formats.test | 7 +++++++ sql/item_timefunc.cc | 2 +- 3 files changed, 14 insertions(+), 1 deletion(-) diff --git a/mysql-test/r/date_formats.result b/mysql-test/r/date_formats.result index 34a2dedd976..b2dc1f7a67b 100644 --- a/mysql-test/r/date_formats.result +++ b/mysql-test/r/date_formats.result @@ -464,3 +464,9 @@ d1 d2 02 February 01 January drop table t1; +select str_to_date( 1, NULL ); +str_to_date( 1, NULL ) +NULL +select str_to_date( NULL, 1 ); +str_to_date( NULL, 1 ) +NULL diff --git a/mysql-test/t/date_formats.test b/mysql-test/t/date_formats.test index 6d501865d2c..dd31f1509c0 100644 --- a/mysql-test/t/date_formats.test +++ b/mysql-test/t/date_formats.test @@ -268,4 +268,11 @@ insert into t1 (f1) values ("2005-01-01"); insert into t1 (f1) values ("2005-02-01"); select date_format(f1, "%m") as d1, date_format(f1, "%M") as d2 from t1 order by date_format(f1, "%M"); drop table t1; + +# +# Bug #15828 +# +select str_to_date( 1, NULL ); +select str_to_date( NULL, 1 ); + # End of 4.1 tests diff --git a/sql/item_timefunc.cc b/sql/item_timefunc.cc index eb58b180ed7..d060612c9f6 100644 --- a/sql/item_timefunc.cc +++ b/sql/item_timefunc.cc @@ -2750,7 +2750,7 @@ void Item_func_str_to_date::fix_length_and_dec() cached_field_type= MYSQL_TYPE_STRING; max_length= MAX_DATETIME_FULL_WIDTH*MY_CHARSET_BIN_MB_MAXLEN; cached_timestamp_type= MYSQL_TIMESTAMP_NONE; - if ((const_item= args[1]->const_item())) + if ((const_item= args[1]->const_item()) && !args[1]->null_value) { format= args[1]->val_str(&format_str); cached_format_type= get_date_time_result_type(format->ptr(), From f36a0feed7232cbb4ca1cbc9e669edb39e714a78 Mon Sep 17 00:00:00 2001 From: unknown Date: Sat, 14 Jan 2006 09:53:12 +0100 Subject: [PATCH 05/21] item_timefunc.cc: fix for bug#15828 after review sql/item_timefunc.cc: fix for bug#15828 after review --- sql/item_timefunc.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sql/item_timefunc.cc b/sql/item_timefunc.cc index d060612c9f6..be8c5d2ad15 100644 --- a/sql/item_timefunc.cc +++ b/sql/item_timefunc.cc @@ -2750,7 +2750,8 @@ void Item_func_str_to_date::fix_length_and_dec() cached_field_type= MYSQL_TYPE_STRING; max_length= MAX_DATETIME_FULL_WIDTH*MY_CHARSET_BIN_MB_MAXLEN; cached_timestamp_type= MYSQL_TIMESTAMP_NONE; - if ((const_item= args[1]->const_item()) && !args[1]->null_value) + if (!args[1]->null_value && (const_item= args[1]->const_item())) + //if ((const_item= args[1]->const_item()) && !args[1]->null_value) { format= args[1]->val_str(&format_str); cached_format_type= get_date_time_result_type(format->ptr(), From 37b104b8ec45d842831c4854a3ddb3443c7bc642 Mon Sep 17 00:00:00 2001 From: unknown Date: Sat, 14 Jan 2006 16:06:51 +0100 Subject: [PATCH 06/21] item_timefunc.cc: fix for bug #15828 after review sql/item_timefunc.cc: fix for bug #15828 after review --- sql/item_timefunc.cc | 1 - 1 file changed, 1 deletion(-) diff --git a/sql/item_timefunc.cc b/sql/item_timefunc.cc index be8c5d2ad15..b5a9064c960 100644 --- a/sql/item_timefunc.cc +++ b/sql/item_timefunc.cc @@ -2751,7 +2751,6 @@ void Item_func_str_to_date::fix_length_and_dec() max_length= MAX_DATETIME_FULL_WIDTH*MY_CHARSET_BIN_MB_MAXLEN; cached_timestamp_type= MYSQL_TIMESTAMP_NONE; if (!args[1]->null_value && (const_item= args[1]->const_item())) - //if ((const_item= args[1]->const_item()) && !args[1]->null_value) { format= args[1]->val_str(&format_str); cached_format_type= get_date_time_result_type(format->ptr(), From e5f077f79a7872147a8858d353060ee08ffa5dcd Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 16 Jan 2006 15:46:37 +0100 Subject: [PATCH 07/21] date_formats.test: fix for bug #15828 after review doing val_str now before testing of null value secures the function for null values returned by dynamic functions - the fix before was incomplete andy covered constant null values mysql-test/t/date_formats.test: fix for bug #15828 after review doing val_str now before testing of null value secures the function for null values returned by dynamic functions - the fix before was incomplete andy covered constant null values --- mysql-test/r/date_formats.result | 3 +++ mysql-test/t/date_formats.test | 2 +- sql/item_timefunc.cc | 2 +- 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/mysql-test/r/date_formats.result b/mysql-test/r/date_formats.result index b2dc1f7a67b..014eeed27e7 100644 --- a/mysql-test/r/date_formats.result +++ b/mysql-test/r/date_formats.result @@ -470,3 +470,6 @@ NULL select str_to_date( NULL, 1 ); str_to_date( NULL, 1 ) NULL +select str_to_date( 1, IF(1=1,NULL,NULL) ); +str_to_date( 1, IF(1=1,NULL,NULL) ) +NULL diff --git a/mysql-test/t/date_formats.test b/mysql-test/t/date_formats.test index dd31f1509c0..78b4482a94a 100644 --- a/mysql-test/t/date_formats.test +++ b/mysql-test/t/date_formats.test @@ -274,5 +274,5 @@ drop table t1; # select str_to_date( 1, NULL ); select str_to_date( NULL, 1 ); - +select str_to_date( 1, IF(1=1,NULL,NULL) ); # End of 4.1 tests diff --git a/sql/item_timefunc.cc b/sql/item_timefunc.cc index b5a9064c960..d6b57464d59 100644 --- a/sql/item_timefunc.cc +++ b/sql/item_timefunc.cc @@ -2750,9 +2750,9 @@ void Item_func_str_to_date::fix_length_and_dec() cached_field_type= MYSQL_TYPE_STRING; max_length= MAX_DATETIME_FULL_WIDTH*MY_CHARSET_BIN_MB_MAXLEN; cached_timestamp_type= MYSQL_TIMESTAMP_NONE; + format= args[1]->val_str(&format_str); if (!args[1]->null_value && (const_item= args[1]->const_item())) { - format= args[1]->val_str(&format_str); cached_format_type= get_date_time_result_type(format->ptr(), format->length()); switch (cached_format_type) { From e7c25ed4a1b086e208a6fa6b7ee1ab0cc50c41b6 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 18 Jan 2006 13:48:57 +0200 Subject: [PATCH 08/21] Excluded posibility of tmp_table_param.copy_field double deletion (BUG#14851). mysql-test/r/kill.result: BUG#14851 test mysql-test/t/kill.test: BUG#14851 test sql/sql_class.cc: Debug prints are added. sql/sql_select.cc: Allocation of tmp_join fixed to involve constructor (it is not related to the bug directly but might cause other problems). Excluded posibility of tmp_table_param.copy_field double deletion (BUG#14851). sql/sql_select.h: JOINs constructor added, initialization of them fixed (it is not related to the bug directly but might cause other problems). --- mysql-test/r/kill.result | 14 +++++++++++- mysql-test/t/kill.test | 49 +++++++++++++++++++++++++++++++++++++++- sql/sql_class.cc | 3 +++ sql/sql_select.cc | 14 ++++++++++++ sql/sql_select.h | 11 +++++++-- 5 files changed, 87 insertions(+), 4 deletions(-) diff --git a/mysql-test/r/kill.result b/mysql-test/r/kill.result index ba9ba2833f6..828c7fcf9b0 100644 --- a/mysql-test/r/kill.result +++ b/mysql-test/r/kill.result @@ -1,4 +1,4 @@ -drop table if exists t1; +drop table if exists t1, t2, t3; create table t1 (kill_id int); insert into t1 values(connection_id()); select ((@id := kill_id) - kill_id) from t1; @@ -17,3 +17,15 @@ select 4; 4 4 drop table t1; +create table t1 (id int primary key); +create table t2 (id int unsigned not null); +insert into t2 select id from t1; +create table t3 (kill_id int); +insert into t3 values(connection_id()); + select id from t1 where id in (select distinct id from t2); +select ((@id := kill_id) - kill_id) from t3; +((@id := kill_id) - kill_id) +0 +kill @id; +ERROR 08S01: Server shutdown in progress +drop table t1, t2, t3; diff --git a/mysql-test/t/kill.test b/mysql-test/t/kill.test index aada8dd2ef3..ebe4673beb3 100644 --- a/mysql-test/t/kill.test +++ b/mysql-test/t/kill.test @@ -12,7 +12,7 @@ connect (con2, localhost, root,,); #remember id of con1 connection con1; --disable_warnings -drop table if exists t1; +drop table if exists t1, t2, t3; --enable_warnings create table t1 (kill_id int); @@ -40,4 +40,51 @@ connection con2; select 4; drop table t1; +disconnect con2; +connection default; +# +# BUG#14851: killing long running subquery processed via a temporary table. +# +create table t1 (id int primary key); +create table t2 (id int unsigned not null); + +connect (conn1, localhost, root,,); +connection conn1; + +-- disable_result_log +-- disable_query_log +let $1 = 4096; +while ($1) +{ + eval insert into t1 values ($1); + dec $1; +} +-- enable_query_log +-- enable_result_log + +insert into t2 select id from t1; + +create table t3 (kill_id int); +insert into t3 values(connection_id()); + +-- disable_result_log +send select id from t1 where id in (select distinct id from t2); +-- enable_result_log + +connect (conn2, localhost, root,,); +connection conn2; +select ((@id := kill_id) - kill_id) from t3; +-- sleep 1 +kill @id; + +connection conn1; +-- error 1053 +reap; + +disconnect conn1; +disconnect conn2; +connection default; + +drop table t1, t2, t3; + # End of 4.1 tests diff --git a/sql/sql_class.cc b/sql/sql_class.cc index 947da6b10d6..cdce9b6c7bc 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -1681,7 +1681,10 @@ bool select_dumpvar::send_eof() void TMP_TABLE_PARAM::init() { + DBUG_ENTER("TMP_TABLE_PARAM::init"); + DBUG_PRINT("enter", ("this: 0x%lx", (ulong)this)); field_count= sum_func_count= func_count= hidden_field_count= 0; group_parts= group_length= group_null_parts= 0; quick_group= 1; + DBUG_VOID_RETURN; } diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 5ef3f4d9fda..aca2c72f1ea 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -4107,6 +4107,20 @@ JOIN::join_free(bool full) problems in free_elements() as some of the elements are then deleted. */ tmp_table_param.copy_funcs.empty(); + /* + If we have tmp_join and 'this' JOIN is not tmp_join and + tmp_table_param.copy_field's of them are equal then we have to remove + pointer to tmp_table_param.copy_field from tmp_join, because it qill + be removed in tmp_table_param.cleanup(). + */ + if (tmp_join && + tmp_join != this && + tmp_join->tmp_table_param.copy_field == + tmp_table_param.copy_field) + { + tmp_join->tmp_table_param.copy_field= + tmp_join->tmp_table_param.save_copy_field= 0; + } tmp_table_param.cleanup(); } DBUG_VOID_RETURN; diff --git a/sql/sql_select.h b/sql/sql_select.h index 636ee967645..94cc8839466 100644 --- a/sql/sql_select.h +++ b/sql/sql_select.h @@ -227,7 +227,14 @@ class JOIN :public Sql_alloc { init(thd_arg, fields_arg, select_options_arg, result_arg); } - + + JOIN(JOIN &join) + :fields_list(join.fields_list) + { + init(join.thd, join.fields_list, join.select_options, + join.result); + } + void init(THD *thd_arg, List &fields_arg, ulong select_options_arg, select_result *result_arg) { @@ -272,7 +279,7 @@ class JOIN :public Sql_alloc fields_list= fields_arg; bzero((char*) &keyuse,sizeof(keyuse)); - tmp_table_param.copy_field=0; + tmp_table_param.init(); tmp_table_param.end_write_records= HA_POS_ERROR; rollup.state= ROLLUP::STATE_NONE; } From e14c9c5d9c82666118a1384853ec0a57c3d1cd61 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 23 Jan 2006 21:51:32 +0300 Subject: [PATCH 09/21] Fixed bug #16510: Updating field named like '*name' caused server crash. When setup_fields() function finds field named '*' it expands it to the list of all table fields. It does so by checking that the first char of field_name is '*', but it doesn't checks that the '* is the only char. Due to this, when updating table with a field named like '*name', such field is wrongly treated as '*' and expanded. This leads to making list of fields to update being longer than list of the new values. Later, the fill_record() function crashes by dereferencing null when there is left fields to update, but no more values. Added check in the setup_fields() function which ensures that the field expanding will be done only when '*' is the only char in the field name. mysql-test/t/update.test: Added test case for bug#16510: Updating field named like '*name' caused server crash mysql-test/r/update.result: Added test case for bug#16510: Updating field named like '*name' caused server crash sql/sql_base.cc: Fixed bug #16510: Updating field named like '*name' caused server crash. Added check in the setup_fields() function which ensures that the field expanding will be done only when '*' is the only char in the field name. --- mysql-test/r/update.result | 4 ++++ mysql-test/t/update.test | 8 ++++++++ sql/sql_base.cc | 1 + 3 files changed, 13 insertions(+) diff --git a/mysql-test/r/update.result b/mysql-test/r/update.result index 9ca92fe75df..46cf2d161ef 100644 --- a/mysql-test/r/update.result +++ b/mysql-test/r/update.result @@ -216,3 +216,7 @@ select * from t1; a b 0 2 drop table t1; +create table t1(f1 int, `*f2` int); +insert into t1 values (1,1); +update t1 set `*f2`=1; +drop table t1; diff --git a/mysql-test/t/update.test b/mysql-test/t/update.test index 6c7b450f763..fcd17dc75f0 100644 --- a/mysql-test/t/update.test +++ b/mysql-test/t/update.test @@ -174,3 +174,11 @@ insert into t1 values (0, '1'); update t1 set b = b + 1 where a = 0; select * from t1; drop table t1; + +# +# Bug #16510 Updating field named like '*name' caused server crash +# +create table t1(f1 int, `*f2` int); +insert into t1 values (1,1); +update t1 set `*f2`=1; +drop table t1; diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 4f52904a61e..42a2e692d21 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -1983,6 +1983,7 @@ int setup_fields(THD *thd, TABLE_LIST *tables, List &fields, */ if (item->type() == Item::FIELD_ITEM && ((Item_field*) item)->field_name[0] == '*' && + ((Item_field*) item)->field_name[1] == 0 && !((Item_field*) item)->field) { uint elem=fields.elements; From d33ac37ba68cb26c11fe7c44d08ca16b6e7c5480 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 25 Jan 2006 23:25:23 +0300 Subject: [PATCH 10/21] BUG#15935: In mysql_update, don't use full index scan when we could have used quick select scan. mysql-test/r/update.result: Testcase for BUG#15935 mysql-test/t/update.test: Testcase for BUG#15935 sql/sql_update.cc: BUG#15935: - Do account for the fact that used_index!=MAX_KEY is also true for cases when quick select is used, and use quick select then (and not full index scan). - Also removed the redundant "used_index= MAX_KEY" statement --- mysql-test/r/update.result | 15 +++++++++++++++ mysql-test/t/update.test | 12 ++++++++++++ sql/sql_update.cc | 3 +-- 3 files changed, 28 insertions(+), 2 deletions(-) diff --git a/mysql-test/r/update.result b/mysql-test/r/update.result index 7854fd773a1..995c76615d3 100644 --- a/mysql-test/r/update.result +++ b/mysql-test/r/update.result @@ -358,3 +358,18 @@ update t2,t1 set f1=3,f2=3 where f1=f2 and f1=1; affected rows: 3 info: Rows matched: 3 Changed: 3 Warnings: 0 drop table t1,t2; +create table t1 (a int); +insert into t1 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9); +create table t2 (a int, filler1 char(200), filler2 char(200), key(a)); +insert into t2 select A.a + 10*B.a, 'filler','filler' from t1 A, t1 B; +flush status; +update t2 set a=3 where a=2; +show status like 'handler_read%'; +Variable_name Value +Handler_read_first 0 +Handler_read_key 1 +Handler_read_next 1 +Handler_read_prev 0 +Handler_read_rnd 1 +Handler_read_rnd_next 0 +drop table t1, t2; diff --git a/mysql-test/t/update.test b/mysql-test/t/update.test index 95adb40962c..55015075db7 100644 --- a/mysql-test/t/update.test +++ b/mysql-test/t/update.test @@ -287,4 +287,16 @@ update t1 set f1=1 where f1=3; update t2,t1 set f1=3,f2=3 where f1=f2 and f1=1; --disable_info drop table t1,t2; + + +# BUG#15935 +create table t1 (a int); +insert into t1 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9); +create table t2 (a int, filler1 char(200), filler2 char(200), key(a)); +insert into t2 select A.a + 10*B.a, 'filler','filler' from t1 A, t1 B; +flush status; +update t2 set a=3 where a=2; +show status like 'handler_read%'; +drop table t1, t2; + # End of 4.1 tests diff --git a/sql/sql_update.cc b/sql/sql_update.cc index 24c7a278e79..edd16bb4bee 100644 --- a/sql/sql_update.cc +++ b/sql/sql_update.cc @@ -212,7 +212,6 @@ int mysql_update(THD *thd, SORT_FIELD *sortorder; ha_rows examined_rows; - used_index= MAX_KEY; // For call to init_read_record() table->sort.io_cache = (IO_CACHE *) my_malloc(sizeof(IO_CACHE), MYF(MY_FAE | MY_ZEROFILL)); if (!(sortorder=make_unireg_sortorder(order, &length)) || @@ -244,7 +243,7 @@ int mysql_update(THD *thd, DISK_BUFFER_SIZE, MYF(MY_WME))) goto err; - if (used_index == MAX_KEY) + if (used_index == MAX_KEY || (select && select->quick)) init_read_record(&info,thd,table,select,0,1); else init_read_record_idx(&info, thd, table, 1, used_index); From 042d5c1a18236241e6872d1845ac962ee45e3c02 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 25 Jan 2006 23:28:39 +0300 Subject: [PATCH 11/21] sql_base.cc: Small fix after merge of fix for bug#16510 sql/sql_base.cc: Small fix after merge of fix for bug#16510 --- sql/sql_base.cc | 1 - 1 file changed, 1 deletion(-) diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 9bc4008d86f..ea013bb4e1e 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -2390,7 +2390,6 @@ int setup_wild(THD *thd, TABLE_LIST *tables, List &fields, if (item->type() == Item::FIELD_ITEM && ((Item_field*) item)->field_name && ((Item_field*) item)->field_name[0] == '*' && - ((Item_field*) item)->field_name[1] == 0 && !((Item_field*) item)->field) { uint elem= fields.elements; From 7dd2ec0f1b3cc4b6cfb192b314e246d12350c5f0 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 26 Jan 2006 00:09:04 +0300 Subject: [PATCH 12/21] BUG#15935: post-review fixes: added comment --- sql/sql_update.cc | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/sql/sql_update.cc b/sql/sql_update.cc index edd16bb4bee..48a8cf93917 100644 --- a/sql/sql_update.cc +++ b/sql/sql_update.cc @@ -243,6 +243,16 @@ int mysql_update(THD *thd, DISK_BUFFER_SIZE, MYF(MY_WME))) goto err; + /* + When we get here, we have one of the following options: + A. used_index == MAX_KEY + This means we should use full table scan, and start it with + init_read_record call + B. used_index != MAX_KEY + B.1 quick select is used, start the scan with init_read_record + B.2 quick select is not used, this is full index scan (with LIMIT) + Full index scan must be started with init_read_record_idx + */ if (used_index == MAX_KEY || (select && select->quick)) init_read_record(&info,thd,table,select,0,1); else From 4c6d256b90c3312c7c9b6421902af98922973d2b Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 26 Jan 2006 10:16:28 +0100 Subject: [PATCH 13/21] reserved config numbers in ndb --- ndb/include/mgmapi/mgmapi_config_parameters.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/ndb/include/mgmapi/mgmapi_config_parameters.h b/ndb/include/mgmapi/mgmapi_config_parameters.h index 2e3b47eb42e..9076f18c5ac 100644 --- a/ndb/include/mgmapi/mgmapi_config_parameters.h +++ b/ndb/include/mgmapi/mgmapi_config_parameters.h @@ -85,6 +85,11 @@ #define CFG_DB_BACKUP_DATADIR 158 #define CFG_DB_MAX_OPEN_FILES 159 +#define CFG_DB_DISK_PAGE_BUFFER_MEMORY 160 /* used from 5.1 */ +#define CFG_DB_STRING_MEMORY 161 /* used from 5.1 */ +#define CFG_DB_INITIAL_OPEN_FILES 162 /* used from 5.1 */ + +#define CFG_DB_DATA_MEM_2 199 /* used in special build in 5.1 */ #define CFG_NODE_ARBIT_RANK 200 #define CFG_NODE_ARBIT_DELAY 201 From 956a5b6dfafe63ce7810aebc643205e0864ee8f1 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 26 Jan 2006 12:49:55 +0200 Subject: [PATCH 14/21] BUG#15699 importing the fix from 5.0 sql/sql_parse.cc: BUG#15699,16487 merge of the fix made in 5.0 mysql-test/r/rpl_multi_update4.result: New BitKeeper file ``mysql-test/r/rpl_multi_update4.result'' mysql-test/t/rpl_multi_update4-slave.opt: New BitKeeper file ``mysql-test/t/rpl_multi_update4-slave.opt'' mysql-test/t/rpl_multi_update4.test: New BitKeeper file ``mysql-test/t/rpl_multi_update4.test'' mysql-test/r/rpl_ignore_table.result: New BitKeeper file ``mysql-test/r/rpl_ignore_table.result'' --- mysql-test/r/rpl_ignore_table.result | 16 +++++++++ mysql-test/r/rpl_multi_update4.result | 25 ++++++++++++++ mysql-test/t/rpl_multi_update4-slave.opt | 1 + mysql-test/t/rpl_multi_update4.test | 44 ++++++++++++++++++++++++ sql/sql_parse.cc | 15 +++++--- 5 files changed, 96 insertions(+), 5 deletions(-) create mode 100644 mysql-test/r/rpl_ignore_table.result create mode 100644 mysql-test/r/rpl_multi_update4.result create mode 100644 mysql-test/t/rpl_multi_update4-slave.opt create mode 100644 mysql-test/t/rpl_multi_update4.test diff --git a/mysql-test/r/rpl_ignore_table.result b/mysql-test/r/rpl_ignore_table.result new file mode 100644 index 00000000000..356a9dcb2f8 --- /dev/null +++ b/mysql-test/r/rpl_ignore_table.result @@ -0,0 +1,16 @@ +stop slave; +drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; +reset master; +reset slave; +drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; +start slave; +**** Test case for BUG#16487 **** +**** Master **** +CREATE TABLE test.t4 (a int); +CREATE TABLE test.t1 (a int); +UPDATE test.t4 NATURAL JOIN test.t1 SET t1.a=5; +**** Slave **** +SELECT * FROM t4; +a +DROP TABLE t1; +DROP TABLE t4; diff --git a/mysql-test/r/rpl_multi_update4.result b/mysql-test/r/rpl_multi_update4.result new file mode 100644 index 00000000000..f6dde65a35d --- /dev/null +++ b/mysql-test/r/rpl_multi_update4.result @@ -0,0 +1,25 @@ +stop slave; +drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; +reset master; +reset slave; +drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; +start slave; +drop database if exists d1; +drop database if exists d2; +drop database if exists d2; +create database d1; +create table d1.t0 (id int); +create database d2; +use d2; +create table t1 (id int); +create table t2 (id int); +insert into t1 values (1), (2), (3), (4), (5); +insert into t2 select id + 3 from t1; +update t1 join t2 using (id) set t1.id = 0; +insert into d1.t0 values (0); +use d1; +select * from t0 where id=0; +id +0 +drop database d1; +drop database d2; diff --git a/mysql-test/t/rpl_multi_update4-slave.opt b/mysql-test/t/rpl_multi_update4-slave.opt new file mode 100644 index 00000000000..fea27db43ee --- /dev/null +++ b/mysql-test/t/rpl_multi_update4-slave.opt @@ -0,0 +1 @@ +--replicate-wild-do-table=d1.% diff --git a/mysql-test/t/rpl_multi_update4.test b/mysql-test/t/rpl_multi_update4.test new file mode 100644 index 00000000000..3d909b8e5cd --- /dev/null +++ b/mysql-test/t/rpl_multi_update4.test @@ -0,0 +1,44 @@ +# Let's verify that multi-update is not always skipped by slave if +# some replicate-* rules exist. +# (BUG#15699) + +source include/master-slave.inc; + +### Clean-up + +connection master; +--disable_warnings +drop database if exists d1; +drop database if exists d2; + +connection slave; +drop database if exists d2; +--enable_warnings + +### Test + +connection master; +create database d1; # accepted by slave +create table d1.t0 (id int); +create database d2; # ignored by slave +use d2; +create table t1 (id int); +create table t2 (id int); +insert into t1 values (1), (2), (3), (4), (5); +insert into t2 select id + 3 from t1; +# a problematic query which must be filter out by slave +update t1 join t2 using (id) set t1.id = 0; +insert into d1.t0 values (0); # replication works + +sync_slave_with_master; +use d1; +#connection slave; +select * from t0 where id=0; # must find + +### Clean-up +connection master; +drop database d1; +drop database d2; + + +# End of test diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 90de630da60..1daa0a5ffec 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -2840,21 +2840,26 @@ unsent_create_error: if ((res= multi_update_precheck(thd, tables))) break; - if ((res= mysql_multi_update_lock(thd, tables, &select_lex->item_list, - select_lex))) - break; - + res= mysql_multi_update_lock(thd, tables, &select_lex->item_list, + select_lex); #ifdef HAVE_REPLICATION /* Check slave filtering rules */ if (thd->slave_thread) if (all_tables_not_ok(thd,tables)) { + if (res!= 0) + { + res= 0; /* don't care of prev failure */ + thd->clear_error(); /* filters are of highest prior */ + } /* we warn the slave SQL thread */ my_error(ER_SLAVE_IGNORED_TABLE, MYF(0)); break; } #endif /* HAVE_REPLICATION */ - + if (res) + break; + res= mysql_multi_update(thd,tables, &select_lex->item_list, &lex->value_list, From e0412c55b3fd278f7135fc530988bb2d39795b7a Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 26 Jan 2006 12:51:34 +0200 Subject: [PATCH 15/21] BUG#16487 importing the test case from 5.0 (the fix is done in BUG#15699) mysql-test/t/rpl_ignore_table-slave.opt: New BitKeeper file ``mysql-test/t/rpl_ignore_table-slave.opt'' mysql-test/t/rpl_ignore_table.test: New BitKeeper file ``mysql-test/t/rpl_ignore_table.test'' --- mysql-test/t/rpl_ignore_table-slave.opt | 1 + mysql-test/t/rpl_ignore_table.test | 28 +++++++++++++++++++++++++ 2 files changed, 29 insertions(+) create mode 100644 mysql-test/t/rpl_ignore_table-slave.opt create mode 100644 mysql-test/t/rpl_ignore_table.test diff --git a/mysql-test/t/rpl_ignore_table-slave.opt b/mysql-test/t/rpl_ignore_table-slave.opt new file mode 100644 index 00000000000..cb49119bfcb --- /dev/null +++ b/mysql-test/t/rpl_ignore_table-slave.opt @@ -0,0 +1 @@ +--replicate-ignore-table=test.t1 --replicate-ignore-table=test.t2 --replicate-ignore-table=test.t3 diff --git a/mysql-test/t/rpl_ignore_table.test b/mysql-test/t/rpl_ignore_table.test new file mode 100644 index 00000000000..bc651779208 --- /dev/null +++ b/mysql-test/t/rpl_ignore_table.test @@ -0,0 +1,28 @@ +source include/master-slave.inc; + +# +# BUG#16487 +# +# Requirement: +# Multi-updates on ignored tables should not fail even if the slave does +# not have the ignored tables. +# +# Note table t1, t2, and t3 are ignored in the option file to this test. +# + +--echo **** Test case for BUG#16487 **** +--echo **** Master **** +connection master; +CREATE TABLE test.t4 (a int); +CREATE TABLE test.t1 (a int); + +# Expect: The row must *not* by updated on slave, since t1 is ignored +UPDATE test.t4 NATURAL JOIN test.t1 SET t1.a=5; + +--echo **** Slave **** +sync_slave_with_master; +SELECT * FROM t4; + +connection master; +DROP TABLE t1; +DROP TABLE t4; From 5681e7f657dbc7a0bc6b6821340b9d87b2572004 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 27 Jan 2006 01:38:05 +0100 Subject: [PATCH 16/21] configure.in: Generated "libmysql.ver" will be in \$(top_builddir) configure.in: Generated "libmysql.ver" will be in \$(top_builddir) --- configure.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.in b/configure.in index 24d6900a5f9..d752061e11b 100644 --- a/configure.in +++ b/configure.in @@ -435,7 +435,7 @@ fi # libmysqlclient versioning when linked with GNU ld. if $LD --version 2>/dev/null|grep -q GNU; then - LD_VERSION_SCRIPT="-Wl,--version-script=\$(top_srcdir)/libmysql/libmysql.ver" + LD_VERSION_SCRIPT="-Wl,--version-script=\$(top_builddir)/libmysql/libmysql.ver" AC_CONFIG_FILES(libmysql/libmysql.ver) fi AC_SUBST(LD_VERSION_SCRIPT) From 67b1ea248623670086e779855b101137dd7fe17e Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 27 Jan 2006 12:10:40 +0100 Subject: [PATCH 17/21] configure.in: Cloned off 4.1.18, new release number 4.1.19 configure.in: New release number --- configure.in | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/configure.in b/configure.in index d752061e11b..b230b7f042e 100644 --- a/configure.in +++ b/configure.in @@ -5,7 +5,7 @@ AC_INIT(sql/mysqld.cc) AC_CANONICAL_SYSTEM # The Docs Makefile.am parses this line! # remember to also change ndb version below and update version.c in ndb -AM_INIT_AUTOMAKE(mysql, 4.1.18) +AM_INIT_AUTOMAKE(mysql, 4.1.19) AM_CONFIG_HEADER(config.h) PROTOCOL_VERSION=10 @@ -17,7 +17,7 @@ SHARED_LIB_VERSION=$SHARED_LIB_MAJOR_VERSION:0:0 # ndb version NDB_VERSION_MAJOR=4 NDB_VERSION_MINOR=1 -NDB_VERSION_BUILD=18 +NDB_VERSION_BUILD=19 NDB_VERSION_STATUS="" # Set all version vars based on $VERSION. How do we do this more elegant ? From 7cdbff971199a85eac1bad6f8f4c5296ca0dc3a1 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 27 Jan 2006 13:23:10 +0100 Subject: [PATCH 18/21] Enable kill test mysql-test/t/disabled.def: Enable the kill test --- mysql-test/t/disabled.def | 1 - 1 file changed, 1 deletion(-) diff --git a/mysql-test/t/disabled.def b/mysql-test/t/disabled.def index ddb79205357..3eae8d230d8 100644 --- a/mysql-test/t/disabled.def +++ b/mysql-test/t/disabled.def @@ -13,4 +13,3 @@ rpl_relayrotate : Unstable test case, bug#12429 rpl_until : Unstable test case, bug#12429 rpl_deadlock : Unstable test case, bug#12429 -kill : Unstable test case, bug#9712 From 7f3f9027d9361f1601f258875d32053b7bf40055 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 27 Jan 2006 12:44:33 -0500 Subject: [PATCH 19/21] Added comments to specify why no much mutex is needed. --- sql/ha_heap.cc | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/sql/ha_heap.cc b/sql/ha_heap.cc index 61e5ce89693..ab0ab5d8b64 100644 --- a/sql/ha_heap.cc +++ b/sql/ha_heap.cc @@ -142,7 +142,13 @@ int ha_heap::write_row(byte * buf) res= heap_write(file,buf); if (!res && ++records_changed*HEAP_STATS_UPDATE_THRESHOLD > file->s->records) + { + /* + We can perform this safely since only one writer at the time is + allowed on the table. + */ file->s->key_stat_version++; + } return res; } @@ -155,7 +161,13 @@ 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) + { + /* + We can perform this safely since only one writer at the time is + allowed on the table. + */ file->s->key_stat_version++; + } return res; } @@ -166,7 +178,13 @@ int ha_heap::delete_row(const byte * buf) res= heap_delete(file,buf); if (!res && table->tmp_table == NO_TMP_TABLE && ++records_changed*HEAP_STATS_UPDATE_THRESHOLD > file->s->records) + { + /* + We can perform this safely since only one writer at the time is + allowed on the table. + */ file->s->key_stat_version++; + } return res; } @@ -297,7 +315,13 @@ int ha_heap::delete_all_rows() { heap_clear(file); if (table->tmp_table == NO_TMP_TABLE) + { + /* + We can perform this safely since only one writer at the time is + allowed on the table. + */ file->s->key_stat_version++; + } return 0; } From 97deac8b8c4651536978c7f5ec7bcb1463ac4868 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 31 Jan 2006 08:13:42 +0100 Subject: [PATCH 20/21] ndb - testBlobs 'perf test' fix ndb/test/ndbapi/testBlobs.cpp: setValue buffer was not fullsize --- ndb/test/ndbapi/testBlobs.cpp | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/ndb/test/ndbapi/testBlobs.cpp b/ndb/test/ndbapi/testBlobs.cpp index efbdceac5a6..cd2287df876 100644 --- a/ndb/test/ndbapi/testBlobs.cpp +++ b/ndb/test/ndbapi/testBlobs.cpp @@ -1488,13 +1488,16 @@ testperf() // insert char (one trans) { DBG("--- insert char ---"); + char b[20]; t1.on(); CHK((g_con = g_ndb->startTransaction()) != 0); for (Uint32 k = 0; k < g_opt.m_rowsperf; k++) { CHK((g_opr = g_con->getNdbOperation(tab.getName())) != 0); CHK(g_opr->insertTuple() == 0); CHK(g_opr->equal(cA, (char*)&k) == 0); - CHK(g_opr->setValue(cB, "b") == 0); + memset(b, 0x20, sizeof(b)); + b[0] = 'b'; + CHK(g_opr->setValue(cB, b) == 0); CHK(g_con->execute(NoCommit) == 0); } t1.off(g_opt.m_rowsperf); @@ -1531,12 +1534,15 @@ testperf() { DBG("--- insert for read test ---"); unsigned n = 0; + char b[20]; CHK((g_con = g_ndb->startTransaction()) != 0); for (Uint32 k = 0; k < g_opt.m_rowsperf; k++) { CHK((g_opr = g_con->getNdbOperation(tab.getName())) != 0); CHK(g_opr->insertTuple() == 0); CHK(g_opr->equal(cA, (char*)&k) == 0); - CHK(g_opr->setValue(cB, "b") == 0); + memset(b, 0x20, sizeof(b)); + b[0] = 'b'; + CHK(g_opr->setValue(cB, b) == 0); CHK((g_bh1 = g_opr->getBlobHandle(cC)) != 0); CHK((g_bh1->setValue("c", 1) == 0)); if (++n == g_opt.m_batch) { @@ -1570,7 +1576,7 @@ testperf() a = (Uint32)-1; b[0] = 0; CHK(g_con->execute(NoCommit) == 0); - CHK(a == k && strcmp(b, "b") == 0); + CHK(a == k && b[0] == 'b'); } CHK(g_con->execute(Commit) == 0); t1.off(g_opt.m_rowsperf); @@ -1596,7 +1602,7 @@ testperf() CHK(g_con->execute(NoCommit) == 0); Uint32 m = 20; CHK(g_bh1->readData(c, m) == 0); - CHK(a == k && m == 1 && strcmp(c, "c") == 0); + CHK(a == k && m == 1 && c[0] == 'c'); } CHK(g_con->execute(Commit) == 0); t2.off(g_opt.m_rowsperf); @@ -1629,7 +1635,7 @@ testperf() CHK((ret = rs->nextResult(true)) == 0 || ret == 1); if (ret == 1) break; - CHK(a < g_opt.m_rowsperf && strcmp(b, "b") == 0); + CHK(a < g_opt.m_rowsperf && b[0] == 'b'); n++; } CHK(n == g_opt.m_rowsperf); @@ -1661,7 +1667,7 @@ testperf() break; Uint32 m = 20; CHK(g_bh1->readData(c, m) == 0); - CHK(a < g_opt.m_rowsperf && m == 1 && strcmp(c, "c") == 0); + CHK(a < g_opt.m_rowsperf && m == 1 && c[0] == 'c'); n++; } CHK(n == g_opt.m_rowsperf); From 1e686ae7702d297cc9fd261c42864653f4fdd7b3 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 1 Feb 2006 20:35:16 +0100 Subject: [PATCH 21/21] fix for bug #12744 (MYSQL_STMT operations cause seg fault after connection reset) libmysql/libmysql.c: stmt->mysql could be 0x0 if the connection has failed between prepare and execute or any other operation. thus if the user decides to use mysql_stmt_reset() we should not segfault. tests/mysql_client_test.c: test for bug #12744 (MYSQL_STMT operations cause seg fault after connection reset) --- libmysql/libmysql.c | 6 ++++++ tests/mysql_client_test.c | 32 ++++++++++++++++++++++++++++++++ 2 files changed, 38 insertions(+) diff --git a/libmysql/libmysql.c b/libmysql/libmysql.c index 921f042922a..498881aa947 100644 --- a/libmysql/libmysql.c +++ b/libmysql/libmysql.c @@ -4628,6 +4628,12 @@ my_bool STDCALL mysql_stmt_reset(MYSQL_STMT *stmt) /* If statement hasnt been prepared there is nothing to reset */ if ((int) stmt->state < (int) MYSQL_STMT_PREPARE_DONE) DBUG_RETURN(0); + if (!stmt->mysql) + { + /* mysql can be reset in mysql_close called from mysql_reconnect */ + set_stmt_error(stmt, CR_SERVER_LOST, unknown_sqlstate); + DBUG_RETURN(1); + } mysql= stmt->mysql->last_used_con; int4store(buff, stmt->stmt_id); /* Send stmt id to server */ diff --git a/tests/mysql_client_test.c b/tests/mysql_client_test.c index 91c2ab9205d..dbc2f582466 100644 --- a/tests/mysql_client_test.c +++ b/tests/mysql_client_test.c @@ -11706,6 +11706,37 @@ static void test_bug12001() DIE_UNLESS(res==1); } +static void test_bug12744() +{ + MYSQL_STMT *prep_stmt = NULL; + int rc; + myheader("test_bug12744"); + + prep_stmt= mysql_stmt_init(mysql); + rc= mysql_stmt_prepare(prep_stmt, "SELECT 1", 8); + DIE_UNLESS(rc==0); + + rc= mysql_kill(mysql, mysql_thread_id(mysql)); + DIE_UNLESS(rc==0); + + if (rc= mysql_stmt_execute(prep_stmt)) + { + if (rc= mysql_stmt_reset(prep_stmt)) + printf("OK!\n"); + else + { + printf("Error!"); + DIE_UNLESS(1==0); + } + } + else + { + fprintf(stderr, "expected error but no error occured\n"); + DIE_UNLESS(1==0); + } + rc= mysql_stmt_close(prep_stmt); +} + /* Bug#11718: query with function, join and order by returns wrong type */ @@ -12054,6 +12085,7 @@ static struct my_tests_st my_tests[]= { { "test_bug8378", test_bug8378 }, { "test_bug9735", test_bug9735 }, { "test_bug11183", test_bug11183 }, + { "test_bug12744", test_bug12744 }, { "test_bug12001", test_bug12001 }, { "test_bug11718", test_bug11718 }, { "test_bug12925", test_bug12925 },