From bba73a091031e9c324fedd6ad1bb26bcd4e635f9 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 8 Nov 2005 00:26:37 -0500 Subject: [PATCH 01/52] 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/52] 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/52] 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 601cfeab34f4415b3295f78a60ac94e4afc7a6a8 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 1 Dec 2005 23:17:00 +0300 Subject: [PATCH 04/52] Fixes bug #6536. When MyODBC or any other client do my_init()/my_end() several times, it was causing corruption of charset data stored in once_mem_pool. my_end() deallocated once_mem pool, but did not put a flag that charsets have to be reloaded. The fix addresses this problem. --- mysys/my_init.c | 1 + 1 file changed, 1 insertion(+) diff --git a/mysys/my_init.c b/mysys/my_init.c index 3e5130ec670..d68c76bef1b 100644 --- a/mysys/my_init.c +++ b/mysys/my_init.c @@ -152,6 +152,7 @@ void my_end(int infoflag) DBUG_PRINT("error",("%s",errbuff[0])); } } + free_charsets(); my_once_free(); if ((infoflag & MY_GIVE_INFO) || print_info) From e7c25ed4a1b086e208a6fa6b7ee1ab0cc50c41b6 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 18 Jan 2006 13:48:57 +0200 Subject: [PATCH 05/52] 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 06/52] 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 6cc16c50191951e1d4fe3eb657fa53eb3f44da9d Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 24 Jan 2006 13:54:34 +0100 Subject: [PATCH 07/52] Test "ctype_ucs": Disable warnings if "InnoDB" is not configured ("classic" build) (bug#16730). mysql-test/t/ctype_ucs.test: Disable warnings if "InnoDB" is not configured ("classic" build) (bug#16730). --- mysql-test/t/ctype_ucs.test | 2 ++ 1 file changed, 2 insertions(+) diff --git a/mysql-test/t/ctype_ucs.test b/mysql-test/t/ctype_ucs.test index ed55287ca05..bd37d008173 100644 --- a/mysql-test/t/ctype_ucs.test +++ b/mysql-test/t/ctype_ucs.test @@ -422,7 +422,9 @@ drop table t1; # # Bug #14583 Bug on query using a LIKE on indexed field with ucs2_bin collation # +--disable_warnings create table t1(f1 varchar(5) CHARACTER SET ucs2 COLLATE ucs2_bin NOT NULL) engine=InnoDB; +--enable_warnings insert into t1 values('a'); create index t1f1 on t1(f1); select f1 from t1 where f1 like 'a%'; From d33ac37ba68cb26c11fe7c44d08ca16b6e7c5480 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 25 Jan 2006 23:25:23 +0300 Subject: [PATCH 08/52] 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 09/52] 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 10/52] 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 11/52] 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 12/52] 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 13/52] 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 14/52] 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 15/52] 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 16/52] 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 17/52] 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 a73b7dc2439879e36ee522d29f76f229f70213d2 Mon Sep 17 00:00:00 2001 From: unknown Date: Sat, 28 Jan 2006 12:35:46 +0100 Subject: [PATCH 18/52] mysql-test-run.sh: Bug#16780: Extend port range to make space for 5.1 NDBCLUSTER_PORT_SLAVE mysql-test/mysql-test-run.sh: Bug#16780: Extend port range to make space for 5.1 NDBCLUSTER_PORT_SLAVE --- mysql-test/mysql-test-run.sh | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/mysql-test/mysql-test-run.sh b/mysql-test/mysql-test-run.sh index 296bbecc843..3488c308536 100644 --- a/mysql-test/mysql-test-run.sh +++ b/mysql-test/mysql-test-run.sh @@ -207,8 +207,13 @@ MYSQL_MANAGER_USER=root # an environment variable can be used to control all ports. A small # number is to be used, 0 - 16 or similar. # +# Note the MASTER_MYPORT has to be set the same in all 4.x and 5.x +# versions of this script, else a 4.0 test run might conflict with a +# 5.1 test run, even if different MTR_BUILD_THREAD is used. This means +# all port numbers might not be used in this version of the script. +# if [ -n "$MTR_BUILD_THREAD" ] ; then - MASTER_MYPORT=`expr $MTR_BUILD_THREAD '*' 5 + 10000` + MASTER_MYPORT=`expr $MTR_BUILD_THREAD '*' 10 + 10000` MYSQL_MANAGER_PORT=`expr $MASTER_MYPORT + 2` SLAVE_MYPORT=`expr $MASTER_MYPORT + 3` From 13896eaa84aa2cad93e96fb09fd22a32f709b846 Mon Sep 17 00:00:00 2001 From: unknown Date: Sat, 28 Jan 2006 13:04:01 +0100 Subject: [PATCH 19/52] mysql-test-run.pl: Aligned the MTR_BUILD_THREAD policy to shell version mysql-test/mysql-test-run.pl: Aligned the MTR_BUILD_THREAD policy to shell version --- mysql-test/mysql-test-run.pl | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl index 58308f0ccdd..c9478534fee 100755 --- a/mysql-test/mysql-test-run.pl +++ b/mysql-test/mysql-test-run.pl @@ -463,11 +463,21 @@ sub command_line_setup () { my $opt_slave_myport= 9308; $opt_ndbcluster_port= 9350; + # + # To make it easier for different devs to work on the same host, + # an environment variable can be used to control all ports. A small + # number is to be used, 0 - 16 or similar. + # + # Note the MASTER_MYPORT has to be set the same in all 4.x and 5.x + # versions of this script, else a 4.0 test run might conflict with a + # 5.1 test run, even if different MTR_BUILD_THREAD is used. This means + # all port numbers might not be used in this version of the script. + # if ( $ENV{'MTR_BUILD_THREAD'} ) { - $opt_master_myport= $ENV{'MTR_BUILD_THREAD'} * 40 + 8120; - $opt_slave_myport= $opt_master_myport + 16; - $opt_ndbcluster_port= $opt_master_myport + 24; + $opt_master_myport= $ENV{'MTR_BUILD_THREAD'} * 10 + 10000; + $opt_slave_myport= $opt_master_myport + 3; + $opt_ndbcluster_port= $opt_master_myport + 4; } # Read the command line From cc47eb77913aa40fc7642ccf5d372675059ec8f2 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 30 Jan 2006 15:17:33 +0300 Subject: [PATCH 20/52] Fixed BUG#16387. Applied innodb-4.1-ss17 snapshot. Do not mistake TABLENAME_ibfk_0 for auto-generated id. innobase/dict/dict0dict.c: Applied innodb-4.1-ss17 snapshot. dict_table_get_highest_foreign_id(): Ignore foreign constraint identifiers starting with the pattern TABLENAME_ibfk_0 (BUG#16387). mysql-test/r/innodb.result: Applied innodb-4.1-ss17 snapshot. Fixed results for added test case. mysql-test/t/innodb.test: Applied innodb-4.1-ss17 snapshot. Added test case. --- innobase/dict/dict0dict.c | 3 ++- mysql-test/r/innodb.result | 13 +++++++++++++ mysql-test/t/innodb.test | 13 +++++++++++++ 3 files changed, 28 insertions(+), 1 deletion(-) diff --git a/innobase/dict/dict0dict.c b/innobase/dict/dict0dict.c index 0cdd593b678..093df5118af 100644 --- a/innobase/dict/dict0dict.c +++ b/innobase/dict/dict0dict.c @@ -2755,7 +2755,8 @@ dict_table_get_highest_foreign_id( if (ut_strlen(foreign->id) > ((sizeof dict_ibfk) - 1) + len && 0 == ut_memcmp(foreign->id, table->name, len) && 0 == ut_memcmp(foreign->id + len, - dict_ibfk, (sizeof dict_ibfk) - 1)) { + dict_ibfk, (sizeof dict_ibfk) - 1) + && foreign->id[len + ((sizeof dict_ibfk) - 1)] != '0') { /* It is of the >= 4.0.18 format */ id = strtoul(foreign->id + len + ((sizeof dict_ibfk) - 1), diff --git a/mysql-test/r/innodb.result b/mysql-test/r/innodb.result index 3ec78c518fc..c4fae109bd4 100644 --- a/mysql-test/r/innodb.result +++ b/mysql-test/r/innodb.result @@ -1794,3 +1794,16 @@ a hex(b) 7 D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B2 update t1 set b = 'three' where a = 6; drop table t1; +CREATE TABLE t1(a INT, PRIMARY KEY(a)) ENGINE=InnoDB; +CREATE TABLE t2(a INT) ENGINE=InnoDB; +ALTER TABLE t2 ADD FOREIGN KEY (a) REFERENCES t1(a); +ALTER TABLE t2 DROP FOREIGN KEY t2_ibfk_1; +ALTER TABLE t2 ADD CONSTRAINT t2_ibfk_0 FOREIGN KEY (a) REFERENCES t1(a); +ALTER TABLE t2 DROP FOREIGN KEY t2_ibfk_0; +SHOW CREATE TABLE t2; +Table Create Table +t2 CREATE TABLE `t2` ( + `a` int(11) default NULL, + KEY `t2_ibfk_0` (`a`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +DROP TABLE t2,t1; diff --git a/mysql-test/t/innodb.test b/mysql-test/t/innodb.test index e2c12eedcae..ee411a1bb37 100644 --- a/mysql-test/t/innodb.test +++ b/mysql-test/t/innodb.test @@ -1365,4 +1365,17 @@ insert into t1 values(7,_utf8 0xD0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1 select a,hex(b) from t1 order by b; update t1 set b = 'three' where a = 6; drop table t1; + +# Ensure that _ibfk_0 is not mistreated as a +# generated foreign key identifier. (Bug #16387) + +CREATE TABLE t1(a INT, PRIMARY KEY(a)) ENGINE=InnoDB; +CREATE TABLE t2(a INT) ENGINE=InnoDB; +ALTER TABLE t2 ADD FOREIGN KEY (a) REFERENCES t1(a); +ALTER TABLE t2 DROP FOREIGN KEY t2_ibfk_1; +ALTER TABLE t2 ADD CONSTRAINT t2_ibfk_0 FOREIGN KEY (a) REFERENCES t1(a); +ALTER TABLE t2 DROP FOREIGN KEY t2_ibfk_0; +SHOW CREATE TABLE t2; +DROP TABLE t2,t1; + # End of 4.1 tests From 8eaf6f11774dfdb2b61e7cebfdc7db78293f0feb Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 30 Jan 2006 22:33:02 +0300 Subject: [PATCH 21/52] Fixed BUG#15653, BUG#16582. Applied innodb-4.1-ss20 snapshot. innobase/btr/btr0sea.c: Applied innodb-4.1-ss20 snapshot. Account for a race condition when dropping the adaptive hash index for a B-tree page (Bug #16582). btr_search_drop_page_hash_index(): Retry the operation if a hash index with different parameters was built meanwhile. Add diagnostics for the case that hash node pointers to the page remain. This fix is from Heikki. btr_search_info_update_hash(), btr_search_info_update_slow(): Document the parameter "info" as in/out. innobase/fil/fil0fil.c: Applied innodb-4.1-ss20 snapshot. Keep track on unflushed modifications to file spaces. When there are tens of thousnads of file spaces, flushing all files in fil_flush_file_spaces() would be very slow (Bug #16582). fil_flush_file_spaces(): Only flush unflushed file spaces. fil_space_t, fil_system_t: Add a list of unflushed spaces. innobase/include/btr0sea.ic: Applied innodb-4.1-ss20 snapshot. btr_search_info_update_hash(), btr_search_info_update_slow(): Document the parameter "info" as in/out. --- innobase/btr/btr0sea.c | 41 ++++++++++++-- innobase/fil/fil0fil.c | 103 +++++++++++++++++++++++++++++++----- innobase/include/btr0sea.ic | 2 +- 3 files changed, 129 insertions(+), 17 deletions(-) diff --git a/innobase/btr/btr0sea.c b/innobase/btr/btr0sea.c index 9384168df88..c7da695859b 100644 --- a/innobase/btr/btr0sea.c +++ b/innobase/btr/btr0sea.c @@ -191,7 +191,7 @@ static void btr_search_info_update_hash( /*========================*/ - btr_search_t* info, /* in: search info */ + btr_search_t* info, /* in/out: search info */ btr_cur_t* cursor) /* in: cursor which was just positioned */ { dict_index_t* index; @@ -443,7 +443,7 @@ Updates the search info. */ void btr_search_info_update_slow( /*========================*/ - btr_search_t* info, /* in: search info */ + btr_search_t* info, /* in/out: search info */ btr_cur_t* cursor) /* in: cursor which was just positioned */ { buf_block_t* block; @@ -931,7 +931,7 @@ btr_search_drop_page_hash_index( ut_ad(!rw_lock_own(&btr_search_latch, RW_LOCK_SHARED)); ut_ad(!rw_lock_own(&btr_search_latch, RW_LOCK_EX)); #endif /* UNIV_SYNC_DEBUG */ - +retry: rw_lock_s_lock(&btr_search_latch); block = buf_block_align(page); @@ -1007,6 +1007,24 @@ next_rec: rw_lock_x_lock(&btr_search_latch); + if (!block->is_hashed) { + /* Someone else has meanwhile dropped the hash index */ + + goto cleanup; + } + + if (block->curr_n_fields != n_fields + || block->curr_n_bytes != n_bytes) { + + /* Someone else has meanwhile built a new hash index on the + page, with different parameters */ + + rw_lock_x_unlock(&btr_search_latch); + + mem_free(folds); + goto retry; + } + for (i = 0; i < n_cached; i++) { ha_remove_all_nodes_to_page(table, folds[i], page); @@ -1014,7 +1032,22 @@ next_rec: block->is_hashed = FALSE; - rw_lock_x_unlock(&btr_search_latch); +cleanup: + if (block->n_pointers) { + /* Corruption */ + ut_print_timestamp(stderr); + fprintf(stderr, +" InnoDB: Corruption of adaptive hash index. After dropping\n" +"InnoDB: the hash index to a page of %lu %lu, still %lu hash nodes remain.\n", + (ulong) ut_dulint_get_high(tree_id), + (ulong) ut_dulint_get_low(tree_id), + (ulong) block->n_pointers); + rw_lock_x_unlock(&btr_search_latch); + + btr_search_validate(); + } else { + rw_lock_x_unlock(&btr_search_latch); + } mem_free(folds); } diff --git a/innobase/fil/fil0fil.c b/innobase/fil/fil0fil.c index e83d2fcde32..c696c940790 100644 --- a/innobase/fil/fil0fil.c +++ b/innobase/fil/fil0fil.c @@ -179,6 +179,11 @@ struct fil_space_struct { hash_node_t name_hash;/* hash chain the name_hash table */ rw_lock_t latch; /* latch protecting the file space storage allocation */ + UT_LIST_NODE_T(fil_space_t) unflushed_spaces; + /* list of spaces with at least one unflushed + file we have written to */ + ibool is_in_unflushed_spaces; /* TRUE if this space is + currently in the list above */ UT_LIST_NODE_T(fil_space_t) space_list; /* list of all spaces */ ibuf_data_t* ibuf_data; @@ -211,6 +216,12 @@ struct fil_system_struct { not put to this list: they are opened after the startup, and kept open until shutdown */ + UT_LIST_BASE_NODE_T(fil_space_t) unflushed_spaces; + /* base node for the list of those + tablespaces whose files contain + unflushed writes; those spaces have + at least one file node where + modification_counter > flush_counter */ ulint n_open; /* number of files currently open */ ulint max_n_open; /* n_open is not allowed to exceed this */ @@ -387,6 +398,36 @@ fil_space_get_ibuf_data( return(space->ibuf_data); } +/************************************************************************** +Checks if all the file nodes in a space are flushed. The caller must hold +the fil_system mutex. */ +static +ibool +fil_space_is_flushed( +/*=================*/ + /* out: TRUE if all are flushed */ + fil_space_t* space) /* in: space */ +{ + fil_node_t* node; + +#ifdef UNIV_SYNC_DEBUG + ut_ad(mutex_own(&(fil_system->mutex))); +#endif /* UNIV_SYNC_DEBUG */ + + node = UT_LIST_GET_FIRST(space->chain); + + while (node) { + if (node->modification_counter > node->flush_counter) { + + return(FALSE); + } + + node = UT_LIST_GET_NEXT(chain, node); + } + + return(TRUE); +} + /*********************************************************************** Appends a new file to the chain of files of a space. File must be closed. */ @@ -517,7 +558,7 @@ fil_node_open_file( if (size_bytes < FIL_IBD_FILE_INITIAL_SIZE * UNIV_PAGE_SIZE) { fprintf(stderr, "InnoDB: Error: the size of single-table tablespace file %s\n" -"InnoDB: is only %lu %lu, should be at least %lu!", node->name, +"InnoDB: is only %lu %lu, should be at least %lu!\n", node->name, (ulong) size_high, (ulong) size_low, (ulong) (4 * UNIV_PAGE_SIZE)); @@ -687,8 +728,8 @@ fil_try_to_close_file_in_LRU( ut_print_filename(stderr, node->name); fprintf(stderr, ", because mod_count %ld != fl_count %ld\n", - (ulong) node->modification_counter, - (ulong) node->flush_counter); + (long) node->modification_counter, + (long) node->flush_counter); } node = UT_LIST_GET_PREV(LRU, node); @@ -839,6 +880,16 @@ fil_node_free( node->modification_counter = node->flush_counter; + if (space->is_in_unflushed_spaces + && fil_space_is_flushed(space)) { + + space->is_in_unflushed_spaces = FALSE; + + UT_LIST_REMOVE(unflushed_spaces, + system->unflushed_spaces, + space); + } + fil_node_close_file(node, system); } @@ -1002,6 +1053,8 @@ try_again: HASH_INSERT(fil_space_t, name_hash, system->name_hash, ut_fold_string(name), space); + space->is_in_unflushed_spaces = FALSE; + UT_LIST_ADD_LAST(space_list, system->space_list, space); mutex_exit(&(system->mutex)); @@ -1097,6 +1150,13 @@ fil_space_free( HASH_DELETE(fil_space_t, name_hash, system->name_hash, ut_fold_string(space->name), space); + if (space->is_in_unflushed_spaces) { + space->is_in_unflushed_spaces = FALSE; + + UT_LIST_REMOVE(unflushed_spaces, system->unflushed_spaces, + space); + } + UT_LIST_REMOVE(space_list, system->space_list, space); ut_a(space->magic_n == FIL_SPACE_MAGIC_N); @@ -1248,6 +1308,7 @@ fil_system_create( system->tablespace_version = 0; + UT_LIST_INIT(system->unflushed_spaces); UT_LIST_INIT(system->space_list); return(system); @@ -2612,12 +2673,12 @@ fil_open_single_table_tablespace( fputs("!\n" "InnoDB: Have you moved InnoDB .ibd files around without using the\n" "InnoDB: commands DISCARD TABLESPACE and IMPORT TABLESPACE?\n" -"InnoDB: It is also possible that this is a table created with\n" -"InnoDB: CREATE TEMPORARY TABLE, and MySQL removed the .ibd file for this.\n" +"InnoDB: It is also possible that this is a temporary table #sql...,\n" +"InnoDB: and MySQL removed the .ibd file for this.\n" "InnoDB: Please refer to\n" "InnoDB:" " http://dev.mysql.com/doc/mysql/en/InnoDB_troubleshooting_datadict.html\n" -"InnoDB: how to resolve the issue.\n", stderr); +"InnoDB: for how to resolve the issue.\n", stderr); mem_free(filepath); @@ -2657,7 +2718,7 @@ fil_open_single_table_tablespace( "InnoDB: Please refer to\n" "InnoDB:" " http://dev.mysql.com/doc/mysql/en/InnoDB_troubleshooting_datadict.html\n" -"InnoDB: how to resolve the issue.\n", (ulong) space_id, (ulong) id); +"InnoDB: for how to resolve the issue.\n", (ulong) space_id, (ulong) id); ret = FALSE; @@ -3292,7 +3353,7 @@ fil_space_for_table_exists_in_mem( ut_print_filename(stderr, name); fprintf(stderr, "\n" "InnoDB: in InnoDB data dictionary has tablespace id %lu,\n" -"InnoDB: but tablespace with that id does not exist. There is\n" +"InnoDB: but a tablespace with that id does not exist. There is\n" "InnoDB: a tablespace of name %s and id %lu, though. Have\n" "InnoDB: you deleted or moved .ibd files?\n", (ulong) id, namespace->name, @@ -3303,7 +3364,7 @@ fil_space_for_table_exists_in_mem( "InnoDB: Please refer to\n" "InnoDB:" " http://dev.mysql.com/doc/mysql/en/InnoDB_troubleshooting_datadict.html\n" -"InnoDB: how to resolve the issue.\n", stderr); +"InnoDB: for how to resolve the issue.\n", stderr); mem_free(path); mutex_exit(&(system->mutex)); @@ -3317,7 +3378,7 @@ fil_space_for_table_exists_in_mem( ut_print_filename(stderr, name); fprintf(stderr, "\n" "InnoDB: in InnoDB data dictionary has tablespace id %lu,\n" -"InnoDB: but tablespace with that id has name %s.\n" +"InnoDB: but the tablespace with that id has name %s.\n" "InnoDB: Have you deleted or moved .ibd files?\n", (ulong) id, space->name); if (namespace != NULL) { @@ -3732,6 +3793,14 @@ fil_node_complete_io( if (type == OS_FILE_WRITE) { system->modification_counter++; node->modification_counter = system->modification_counter; + + if (!node->space->is_in_unflushed_spaces) { + + node->space->is_in_unflushed_spaces = TRUE; + UT_LIST_ADD_FIRST(unflushed_spaces, + system->unflushed_spaces, + node->space); + } } if (node->n_pending == 0 && node->space->purpose == FIL_TABLESPACE @@ -4145,6 +4214,16 @@ retry: skip_flush: if (node->flush_counter < old_mod_counter) { node->flush_counter = old_mod_counter; + + if (space->is_in_unflushed_spaces + && fil_space_is_flushed(space)) { + + space->is_in_unflushed_spaces = FALSE; + + UT_LIST_REMOVE(unflushed_spaces, + system->unflushed_spaces, + space); + } } if (space->purpose == FIL_TABLESPACE) { @@ -4176,7 +4255,7 @@ fil_flush_file_spaces( mutex_enter(&(system->mutex)); - space = UT_LIST_GET_FIRST(system->space_list); + space = UT_LIST_GET_FIRST(system->unflushed_spaces); while (space) { if (space->purpose == purpose && !space->is_being_deleted) { @@ -4192,7 +4271,7 @@ fil_flush_file_spaces( space->n_pending_flushes--; } - space = UT_LIST_GET_NEXT(space_list, space); + space = UT_LIST_GET_NEXT(unflushed_spaces, space); } mutex_exit(&(system->mutex)); diff --git a/innobase/include/btr0sea.ic b/innobase/include/btr0sea.ic index 8a41042f713..f4e33027c25 100644 --- a/innobase/include/btr0sea.ic +++ b/innobase/include/btr0sea.ic @@ -16,7 +16,7 @@ Updates the search info. */ void btr_search_info_update_slow( /*========================*/ - btr_search_t* info, /* in: search info */ + btr_search_t* info, /* in/out: search info */ btr_cur_t* cursor);/* in: cursor which was just positioned */ /************************************************************************ From 97deac8b8c4651536978c7f5ec7bcb1463ac4868 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 31 Jan 2006 08:13:42 +0100 Subject: [PATCH 22/52] 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 c35be281497edaef66fa139071cd6c7062cb3153 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 31 Jan 2006 12:47:22 +0100 Subject: [PATCH 23/52] Bug #15302 LOAD DATA FROM MASTER -> Packets out of order (Found: 2, expected 1) - Change "mysql_create_db" to not call "send_ok" if in silent mode i.e. called from "load_master_data" - Change mysqltest to detect when there aren't as many warnings available as was reported. client/mysqltest.c: Call "die" if warnings were reported but there weren't any warnings to retrieve sql/sql_db.cc: Don't call "send_ok" if in silent mode. --- client/mysqltest.c | 8 ++++---- sql/sql_db.cc | 13 ++++++++++--- 2 files changed, 14 insertions(+), 7 deletions(-) diff --git a/client/mysqltest.c b/client/mysqltest.c index d10ad054798..613c4e12763 100644 --- a/client/mysqltest.c +++ b/client/mysqltest.c @@ -2966,8 +2966,8 @@ static int run_query_normal(MYSQL* mysql, struct st_query* q, int flags) warn_res= mysql_store_result(mysql); } if (!warn_res) - verbose_msg("Warning count is %u but didn't get any warnings\n", - count); + die("Warning count is %u but didn't get any warnings\n", + count); else { dynstr_append_mem(ds, "Warnings:\n", 10); @@ -3446,8 +3446,8 @@ static void run_query_stmt_handle_warnings(MYSQL *mysql, DYNAMIC_STRING *ds) { MYSQL_RES *warn_res= mysql_store_result(mysql); if (!warn_res) - verbose_msg("Warning count is %u but didn't get any warnings\n", - count); + die("Warning count is %u but didn't get any warnings\n", + count); else { dynstr_append_mem(ds, "Warnings:\n", 10); diff --git a/sql/sql_db.cc b/sql/sql_db.cc index 7c834c91183..035a0b22a6b 100644 --- a/sql/sql_db.cc +++ b/sql/sql_db.cc @@ -388,6 +388,12 @@ bool load_db_opt(THD *thd, const char *path, HA_CREATE_INFO *create) silent Used by replication when internally creating a database. In this case the entry should not be logged. + SIDE-EFFECTS + 1. Report back to client that command succeeded (send_ok) + 2. Report errors to client + 3. Log event to binary log + (The 'silent' flags turns off 1 and 3.) + RETURN VALUES 0 ok -1 Error @@ -421,16 +427,17 @@ int mysql_create_db(THD *thd, char *db, HA_CREATE_INFO *create_info, if (my_stat(path,&stat_info,MYF(0))) { - if (!(create_options & HA_LEX_CREATE_IF_NOT_EXISTS)) + if (!(create_options & HA_LEX_CREATE_IF_NOT_EXISTS)) { my_error(ER_DB_CREATE_EXISTS,MYF(0),db); error= -1; goto exit; } push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE, - ER_DB_CREATE_EXISTS, ER(ER_DB_CREATE_EXISTS), db); + ER_DB_CREATE_EXISTS, ER(ER_DB_CREATE_EXISTS), db); + if (!silent) + send_ok(thd); error= 0; - send_ok(thd); goto exit; } else From e3c3086304c6574a7b9d32e4acd339269a4f1749 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 1 Feb 2006 20:40:12 +0400 Subject: [PATCH 24/52] BUG#14496: Crash or strange results with prepared statement, MATCH and FULLTEXT Fixed that fulltext query using PS results in unexpected behaviour when executed 2 or more times. mysql-test/r/fulltext.result: Testcase for BUG#14496. mysql-test/t/fulltext.test: Testcase for BUG#14496. sql/item_func.h: In Item_func_match::cleanup() always reset ft_handler to 0. --- mysql-test/r/fulltext.result | 11 +++++++++++ mysql-test/t/fulltext.test | 12 ++++++++++++ sql/item_func.h | 2 +- 3 files changed, 24 insertions(+), 1 deletion(-) diff --git a/mysql-test/r/fulltext.result b/mysql-test/r/fulltext.result index ebd6880a10e..c1dd5f80d5c 100644 --- a/mysql-test/r/fulltext.result +++ b/mysql-test/r/fulltext.result @@ -436,3 +436,14 @@ SELECT a FROM t1 WHERE MATCH a AGAINST('testword\'\'' IN BOOLEAN MODE); a testword'' DROP TABLE t1; +CREATE TABLE t1 (a TEXT, FULLTEXT KEY(a)); +INSERT INTO t1 VALUES('test'),('test1'),('test'); +PREPARE stmt from "SELECT a, MATCH(a) AGAINST('test1 test') FROM t1 WHERE MATCH(a) AGAINST('test1 test')"; +EXECUTE stmt; +a MATCH(a) AGAINST('test1 test') +test1 0.68526661396027 +EXECUTE stmt; +a MATCH(a) AGAINST('test1 test') +test1 0.68526661396027 +DEALLOCATE PREPARE stmt; +DROP TABLE t1; diff --git a/mysql-test/t/fulltext.test b/mysql-test/t/fulltext.test index 1399b9bfdff..d5ce6241490 100644 --- a/mysql-test/t/fulltext.test +++ b/mysql-test/t/fulltext.test @@ -357,4 +357,16 @@ SELECT a FROM t1 WHERE MATCH a AGAINST('testword' IN BOOLEAN MODE); SELECT a FROM t1 WHERE MATCH a AGAINST('testword\'\'' IN BOOLEAN MODE); DROP TABLE t1; +# +# BUG#14496: Crash or strange results with prepared statement, +# MATCH and FULLTEXT +# +CREATE TABLE t1 (a TEXT, FULLTEXT KEY(a)); +INSERT INTO t1 VALUES('test'),('test1'),('test'); +PREPARE stmt from "SELECT a, MATCH(a) AGAINST('test1 test') FROM t1 WHERE MATCH(a) AGAINST('test1 test')"; +EXECUTE stmt; +EXECUTE stmt; +DEALLOCATE PREPARE stmt; +DROP TABLE t1; + # End of 4.1 tests diff --git a/sql/item_func.h b/sql/item_func.h index 2c4976d1152..53d113c8b6f 100644 --- a/sql/item_func.h +++ b/sql/item_func.h @@ -1056,7 +1056,6 @@ public: if (!master && ft_handler) { ft_handler->please->close_search(ft_handler); - ft_handler=0; if (join_key) table->file->ft_handler=0; table->fulltext_searched=0; @@ -1066,6 +1065,7 @@ public: delete concat; concat= 0; } + ft_handler= 0; DBUG_VOID_RETURN; } enum Functype functype() const { return FT_FUNC; } From 1e686ae7702d297cc9fd261c42864653f4fdd7b3 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 1 Feb 2006 20:35:16 +0100 Subject: [PATCH 25/52] 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 }, From f7a6e249346826cad72f54df8acf9435cb01627b Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 1 Feb 2006 12:28:39 -0800 Subject: [PATCH 26/52] Fix mysqldump crash when encountering a VIEW (when used against a 5.0 or later server, obviously). (Bug #16389) client/mysqldump.c: Prevent dumping data from a view (and crashing when we see one) --- client/mysqldump.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/client/mysqldump.c b/client/mysqldump.c index 7ff9504607f..64629bcf608 100644 --- a/client/mysqldump.c +++ b/client/mysqldump.c @@ -2557,8 +2557,11 @@ static const char *check_if_ignore_table(const char *table_name) mysql_free_result(res); return 0; /* assume table is ok */ } - if (strcmp(row[1], (result= "MRG_MyISAM")) && - strcmp(row[1], (result= "MRG_ISAM"))) + /* Some forward-compatibility: don't dump data from a VIEW */ + if (!row[1]) + result= "VIEW"; + else if (strcmp(row[1], (result= "MRG_MyISAM")) && + strcmp(row[1], (result= "MRG_ISAM"))) result= 0; mysql_free_result(res); return result; From 394c88df3acd71730e004c84ca7ee64f4ed3fdec Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 3 Feb 2006 14:09:33 +0400 Subject: [PATCH 27/52] BUG#16893: Crash in test 'fulltext_order_by' Fixed that fulltext query + union results in unexpected behaviour. sql/item_func.h: Remove access to table object from cleanup() as the table object may have been dropped earlier (In case of temporary tables or of close_thread_tables() is run before cleanup()) This fixed a bug with access to already freed memory sql/sql_base.cc: Reset variables used by fulltext --- sql/item_func.h | 3 --- sql/sql_base.cc | 2 ++ 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/sql/item_func.h b/sql/item_func.h index 2c4976d1152..5bf57a713c4 100644 --- a/sql/item_func.h +++ b/sql/item_func.h @@ -1057,9 +1057,6 @@ public: { ft_handler->please->close_search(ft_handler); ft_handler=0; - if (join_key) - table->file->ft_handler=0; - table->fulltext_searched=0; } if (concat) { diff --git a/sql/sql_base.cc b/sql/sql_base.cc index ea013bb4e1e..223e8482f49 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -988,6 +988,8 @@ TABLE *open_table(THD *thd,const char *db,const char *table_name, table->status=STATUS_NO_RECORD; table->keys_in_use_for_query= table->keys_in_use; table->used_keys= table->keys_for_keyread; + table->file->ft_handler=0; + table->fulltext_searched=0; if (table->timestamp_field) table->timestamp_field_type= table->timestamp_field->get_auto_set_type(); DBUG_ASSERT(table->key_read == 0); From b301e658839f6d5e8eaced201a4ca17f100a569d Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 3 Feb 2006 15:23:58 +0100 Subject: [PATCH 28/52] ndb - replace+tinyblob back-patch from 5.0 [ discard on 4.1->5.0 merge ] mysql-test/r/ndb_blob.result: replace+tinyblob back-patch from 5.0 mysql-test/t/ndb_blob.test: replace+tinyblob back-patch from 5.0 ndb/src/ndbapi/NdbBlob.cpp: replace+tinyblob back-patch from 5.0 --- mysql-test/r/ndb_blob.result | 7 +++++++ mysql-test/t/ndb_blob.test | 6 +++++- ndb/src/ndbapi/NdbBlob.cpp | 2 ++ 3 files changed, 14 insertions(+), 1 deletion(-) diff --git a/mysql-test/r/ndb_blob.result b/mysql-test/r/ndb_blob.result index 6f25ec95c80..bcf867a4edd 100644 --- a/mysql-test/r/ndb_blob.result +++ b/mysql-test/r/ndb_blob.result @@ -428,6 +428,13 @@ delete from t1; select * from t1; a b commit; +replace t1 set a=2, b='y'; +select * from t1; +a b +2 y +delete from t1; +select * from t1; +a b drop table t1; set autocommit=0; create table t1 ( diff --git a/mysql-test/t/ndb_blob.test b/mysql-test/t/ndb_blob.test index a12ebee2f0d..f80b7f71281 100644 --- a/mysql-test/t/ndb_blob.test +++ b/mysql-test/t/ndb_blob.test @@ -338,7 +338,7 @@ select * from t1 order by a; drop table t1; drop database test2; -# -- bug-5252 tinytext crashes plus no-commit result -- +# -- bug-5252 tinytext crashes + no-commit result + replace -- set autocommit=0; create table t1 ( @@ -352,6 +352,10 @@ select * from t1; delete from t1; select * from t1; commit; +replace t1 set a=2, b='y'; +select * from t1; +delete from t1; +select * from t1; drop table t1; # -- bug-5013 insert empty string to text -- diff --git a/ndb/src/ndbapi/NdbBlob.cpp b/ndb/src/ndbapi/NdbBlob.cpp index c5692d79e83..416e983ec14 100644 --- a/ndb/src/ndbapi/NdbBlob.cpp +++ b/ndb/src/ndbapi/NdbBlob.cpp @@ -959,6 +959,8 @@ int NdbBlob::deletePartsUnknown(Uint32 part) { DBG("deletePartsUnknown [in] part=" << part << " count=all"); + if (thePartSize == 0) // tinyblob + return 0; static const unsigned maxbat = 256; static const unsigned minbat = 1; unsigned bat = minbat; From 1076e176ce965a9d37fcdc71e6eb3447c3931005 Mon Sep 17 00:00:00 2001 From: unknown Date: Sun, 5 Feb 2006 22:12:06 +0100 Subject: [PATCH 29/52] ndb - bug#16693 (4.1) test + workaround, analyze later ndb/test/ndbapi/testBlobs.cpp: do batched deletes + list commit across open cursor test cases ndb/tools/delete_all.cpp: if blobs, no commit across open cursor (single trans) cases listed in testBlobs.cpp, analyze later (in 5.0 maybe) --- ndb/test/ndbapi/testBlobs.cpp | 82 +++++++++++++++++++++++++++-------- ndb/tools/delete_all.cpp | 30 ++++++++++--- 2 files changed, 88 insertions(+), 24 deletions(-) diff --git a/ndb/test/ndbapi/testBlobs.cpp b/ndb/test/ndbapi/testBlobs.cpp index cd2287df876..4c82f718788 100644 --- a/ndb/test/ndbapi/testBlobs.cpp +++ b/ndb/test/ndbapi/testBlobs.cpp @@ -841,9 +841,6 @@ insertPk(int style) CHK(g_con->execute(NoCommit) == 0); CHK(writeBlobData(tup) == 0); } - // just another trap - if (urandom(10) == 0) - CHK(g_con->execute(NoCommit) == 0); if (++n == g_opt.m_batch) { CHK(g_con->execute(Commit) == 0); g_ndb->closeTransaction(g_con); @@ -965,21 +962,31 @@ static int deletePk() { DBG("--- deletePk ---"); + unsigned n = 0; + CHK((g_con = g_ndb->startTransaction()) != 0); for (unsigned k = 0; k < g_opt.m_rows; k++) { Tup& tup = g_tups[k]; DBG("deletePk pk1=" << hex << tup.m_pk1); - CHK((g_con = g_ndb->startTransaction()) != 0); CHK((g_opr = g_con->getNdbOperation(g_opt.m_tname)) != 0); CHK(g_opr->deleteTuple() == 0); CHK(g_opr->equal("PK1", tup.m_pk1) == 0); if (g_opt.m_pk2len != 0) CHK(g_opr->equal("PK2", tup.m_pk2) == 0); - CHK(g_con->execute(Commit) == 0); - g_ndb->closeTransaction(g_con); + if (++n == g_opt.m_batch) { + CHK(g_con->execute(Commit) == 0); + g_ndb->closeTransaction(g_con); + CHK((g_con = g_ndb->startTransaction()) != 0); + n = 0; + } g_opr = 0; - g_con = 0; tup.m_exists = false; } + if (n != 0) { + CHK(g_con->execute(Commit) == 0); + n = 0; + } + g_ndb->closeTransaction(g_con); + g_con = 0; return 0; } @@ -1082,19 +1089,27 @@ static int deleteIdx() { DBG("--- deleteIdx ---"); + unsigned n = 0; + CHK((g_con = g_ndb->startTransaction()) != 0); for (unsigned k = 0; k < g_opt.m_rows; k++) { Tup& tup = g_tups[k]; DBG("deleteIdx pk1=" << hex << tup.m_pk1); - CHK((g_con = g_ndb->startTransaction()) != 0); CHK((g_opx = g_con->getNdbIndexOperation(g_opt.m_x1name, g_opt.m_tname)) != 0); CHK(g_opx->deleteTuple() == 0); CHK(g_opx->equal("PK2", tup.m_pk2) == 0); - CHK(g_con->execute(Commit) == 0); - g_ndb->closeTransaction(g_con); + if (++n == g_opt.m_batch) { + CHK(g_con->execute(Commit) == 0); + g_ndb->closeTransaction(g_con); + CHK((g_con = g_ndb->startTransaction()) != 0); + n = 0; + } g_opx = 0; - g_con = 0; tup.m_exists = false; } + if (n != 0) { + CHK(g_con->execute(Commit) == 0); + n = 0; + } return 0; } @@ -1225,20 +1240,49 @@ deleteScan(bool idx) CHK(g_ops->getValue("PK2", tup.m_pk2) != 0); CHK(g_con->execute(NoCommit) == 0); unsigned rows = 0; + unsigned n = 0; while (1) { int ret; tup.m_pk1 = (Uint32)-1; memset(tup.m_pk2, 'x', g_opt.m_pk2len); - CHK((ret = rs->nextResult()) == 0 || ret == 1); + CHK((ret = rs->nextResult(true)) == 0 || ret == 1); if (ret == 1) break; - DBG("deleteScan" << (idx ? "Idx" : "") << " pk1=" << hex << tup.m_pk1); - CHK(rs->deleteTuple() == 0); - CHK(g_con->execute(NoCommit) == 0); - Uint32 k = tup.m_pk1 - g_opt.m_pk1off; - CHK(k < g_opt.m_rows && g_tups[k].m_exists); - g_tups[k].m_exists = false; - rows++; + while (1) { + DBG("deleteScan" << (idx ? "Idx" : "") << " pk1=" << hex << tup.m_pk1); + Uint32 k = tup.m_pk1 - g_opt.m_pk1off; + CHK(k < g_opt.m_rows && g_tups[k].m_exists); + g_tups[k].m_exists = false; + CHK(rs->deleteTuple() == 0); + rows++; + tup.m_pk1 = (Uint32)-1; + memset(tup.m_pk2, 'x', g_opt.m_pk2len); + CHK((ret = rs->nextResult(false)) == 0 || ret == 1 || ret == 2); + if (++n == g_opt.m_batch || ret == 2) { + DBG("execute batch: n=" << n << " ret=" << ret); + switch (0) { + case 0: // works normally + CHK(g_con->execute(NoCommit) == 0); + CHK(true || g_con->restart() == 0); + break; + case 1: // nonsense - g_con is invalid for 2nd batch + CHK(g_con->execute(Commit) == 0); + CHK(true || g_con->restart() == 0); + break; + case 2: // DBTC sendSignalErrorRefuseLab + CHK(g_con->execute(NoCommit) == 0); + CHK(g_con->restart() == 0); + break; + case 3: // 266 time-out + CHK(g_con->execute(Commit) == 0); + CHK(g_con->restart() == 0); + break; + } + n = 0; + } + if (ret == 2) + break; + } } CHK(g_con->execute(Commit) == 0); g_ndb->closeTransaction(g_con); diff --git a/ndb/tools/delete_all.cpp b/ndb/tools/delete_all.cpp index 21e0c2ac089..d4a07fdf505 100644 --- a/ndb/tools/delete_all.cpp +++ b/ndb/tools/delete_all.cpp @@ -22,7 +22,8 @@ #include #include -static int clear_table(Ndb* pNdb, const NdbDictionary::Table* pTab, int parallelism=240); +static int clear_table(Ndb* pNdb, const NdbDictionary::Table* pTab, + bool commit_across_open_cursor, int parallelism=240); NDB_STD_OPTS_VARS; @@ -81,8 +82,18 @@ int main(int argc, char** argv){ ndbout << " Table " << argv[i] << " does not exist!" << endl; return NDBT_ProgramExit(NDBT_WRONGARGS); } + // Check if we have any blobs + bool commit_across_open_cursor = true; + for (int j = 0; j < pTab->getNoOfColumns(); j++) { + NdbDictionary::Column::Type t = pTab->getColumn(j)->getType(); + if (t == NdbDictionary::Column::Blob || + t == NdbDictionary::Column::Text) { + commit_across_open_cursor = false; + break; + } + } ndbout << "Deleting all from " << argv[i] << "..."; - if(clear_table(&MyNdb, pTab) == NDBT_FAILED){ + if(clear_table(&MyNdb, pTab, commit_across_open_cursor) == NDBT_FAILED){ res = NDBT_FAILED; ndbout << "FAILED" << endl; } @@ -91,7 +102,8 @@ int main(int argc, char** argv){ } -int clear_table(Ndb* pNdb, const NdbDictionary::Table* pTab, int parallelism) +int clear_table(Ndb* pNdb, const NdbDictionary::Table* pTab, + bool commit_across_open_cursor, int parallelism) { // Scan all records exclusive and delete // them one by one @@ -153,8 +165,12 @@ int clear_table(Ndb* pNdb, const NdbDictionary::Table* pTab, int parallelism) } while((check = rs->nextResult(false)) == 0); if(check != -1){ - check = pTrans->execute(Commit); - pTrans->restart(); + if (commit_across_open_cursor) { + check = pTrans->execute(Commit); + pTrans->restart(); // new tx id + } else { + check = pTrans->execute(NoCommit); + } } err = pTrans->getNdbError(); @@ -180,6 +196,10 @@ int clear_table(Ndb* pNdb, const NdbDictionary::Table* pTab, int parallelism) } goto failed; } + if (! commit_across_open_cursor && pTrans->execute(Commit) != 0) { + err = pTrans->getNdbError(); + goto failed; + } pNdb->closeTransaction(pTrans); return NDBT_OK; } From c9147c5ecb121e7f2be951100ba91fe83ccb1a65 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 6 Feb 2006 11:30:56 +0100 Subject: [PATCH 30/52] bug#13965 ndb - error while restarting in dict improve error message when changed config leads to failed restart ndb/src/kernel/blocks/dbdict/Dbdict.cpp: improve error message --- ndb/src/kernel/blocks/dbdict/Dbdict.cpp | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/ndb/src/kernel/blocks/dbdict/Dbdict.cpp b/ndb/src/kernel/blocks/dbdict/Dbdict.cpp index 6564963f61a..6f1e9fee3be 100644 --- a/ndb/src/kernel/blocks/dbdict/Dbdict.cpp +++ b/ndb/src/kernel/blocks/dbdict/Dbdict.cpp @@ -2397,7 +2397,19 @@ Dbdict::restartCreateTab_readTableConf(Signal* signal, Uint32 sz = c_readTableRecord.noOfPages * ZSIZE_OF_PAGES_IN_WORDS; SimplePropertiesLinearReader r(&pageRecPtr.p->word[0], sz); handleTabInfoInit(r, &parseRecord); - ndbrequire(parseRecord.errorCode == 0); + if (parseRecord.errorCode != 0) + { + char buf[255]; + BaseString::snprintf(buf, sizeof(buf), + "Unable to restart, fail while creating table %d" + " error: %d. Most likely change of configution", + c_readTableRecord.tableId, + parseRecord.errorCode); + progError(__LINE__, + ERR_INVALID_CONFIG, + buf); + ndbrequire(parseRecord.errorCode == 0); + } /* ---------------------------------------------------------------- */ // We have read the table description from disk as part of system restart. From db4d82bad49a5c1b69c4b3134ad9c2f25b9e3221 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 6 Feb 2006 11:42:44 +0100 Subject: [PATCH 31/52] bug#13966 - ndb better error message on invalid config change ndb/src/kernel/blocks/dbdict/Dbdict.cpp: fix typo ndb/src/kernel/blocks/dblqh/DblqhMain.cpp: Change error message...note that this is a guess --- ndb/src/kernel/blocks/dbdict/Dbdict.cpp | 2 +- ndb/src/kernel/blocks/dblqh/DblqhMain.cpp | 14 ++++++++++++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/ndb/src/kernel/blocks/dbdict/Dbdict.cpp b/ndb/src/kernel/blocks/dbdict/Dbdict.cpp index 6f1e9fee3be..2bb429aeabc 100644 --- a/ndb/src/kernel/blocks/dbdict/Dbdict.cpp +++ b/ndb/src/kernel/blocks/dbdict/Dbdict.cpp @@ -2402,7 +2402,7 @@ Dbdict::restartCreateTab_readTableConf(Signal* signal, char buf[255]; BaseString::snprintf(buf, sizeof(buf), "Unable to restart, fail while creating table %d" - " error: %d. Most likely change of configution", + " error: %d. Most likely change of configuration", c_readTableRecord.tableId, parseRecord.errorCode); progError(__LINE__, diff --git a/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp b/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp index c8460630d62..80a8805697e 100644 --- a/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp +++ b/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp @@ -16096,8 +16096,22 @@ void Dblqh::findLogfile(Signal* signal, }//if locLogFilePtr.i = locLogFilePtr.p->nextLogFile; loopCount++; + if (loopCount >= flfLogPartPtr.p->noLogFiles && + getNodeState().startLevel != NodeState::SL_STARTED) + { + goto error; + } ndbrequire(loopCount < flfLogPartPtr.p->noLogFiles); }//while + +error: + char buf[255]; + BaseString::snprintf(buf, sizeof(buf), + "Unable to restart, failed while reading redo." + " Likely invalid change of configuration"); + progError(__LINE__, + ERR_INVALID_CONFIG, + buf); }//Dblqh::findLogfile() /* ------------------------------------------------------------------------- */ From 8deb6616bc80eb883b6243077acd9a01ae5fae03 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 7 Feb 2006 00:03:39 +0100 Subject: [PATCH 32/52] Bug #17154 load data infile of char values into a table of char(PK) hangs Bug #17158 load data infile of char values into table of char with no (PK) fails to load Bug #17081 Doing "LOAD DATA INFILE" directly after delete can cause missing data mysql-test/r/ndb_load.result: New BitKeeper file ``mysql-test/r/ndb_load.result'' mysql-test/t/ndb_load.test: New BitKeeper file ``mysql-test/t/ndb_load.test'' --- mysql-test/r/ndb_load.result | 80 ++++++++++++++++++++++++++++++++++++ mysql-test/t/ndb_load.test | 24 +++++++++++ sql/ha_ndbcluster.cc | 22 ++++++++-- sql/sql_load.cc | 7 +++- 4 files changed, 127 insertions(+), 6 deletions(-) create mode 100644 mysql-test/r/ndb_load.result create mode 100644 mysql-test/t/ndb_load.test diff --git a/mysql-test/r/ndb_load.result b/mysql-test/r/ndb_load.result new file mode 100644 index 00000000000..76da5b2a215 --- /dev/null +++ b/mysql-test/r/ndb_load.result @@ -0,0 +1,80 @@ +DROP TABLE IF EXISTS t1; +CREATE TABLE t1 (word CHAR(20) NOT NULL PRIMARY KEY) ENGINE=NDB; +LOAD DATA INFILE '../../std_data/words.dat' INTO TABLE t1 ; +ERROR 23000: Can't write; duplicate key in table 't1' +DROP TABLE t1; +CREATE TABLE t1 (word CHAR(20) NOT NULL) ENGINE=NDB; +LOAD DATA INFILE '../../std_data/words.dat' INTO TABLE t1 ; +SELECT * FROM t1 ORDER BY word; +word +Aarhus +Aarhus +Aaron +Aaron +Ababa +Ababa +aback +aback +abaft +abaft +abandon +abandon +abandoned +abandoned +abandoning +abandoning +abandonment +abandonment +abandons +abandons +abase +abased +abasement +abasements +abases +abash +abashed +abashes +abashing +abasing +abate +abated +abatement +abatements +abater +abates +abating +Abba +abbe +abbey +abbeys +abbot +abbots +Abbott +abbreviate +abbreviated +abbreviates +abbreviating +abbreviation +abbreviations +Abby +abdomen +abdomens +abdominal +abduct +abducted +abduction +abductions +abductor +abductors +abducts +Abe +abed +Abel +Abelian +Abelson +Aberdeen +Abernathy +aberrant +aberration +DROP TABLE t1; diff --git a/mysql-test/t/ndb_load.test b/mysql-test/t/ndb_load.test new file mode 100644 index 00000000000..72a5b53eaad --- /dev/null +++ b/mysql-test/t/ndb_load.test @@ -0,0 +1,24 @@ +-- source include/have_ndb.inc +-- source include/not_embedded.inc + +--disable_warnings +DROP TABLE IF EXISTS t1; +--enable_warnings + +# +# Basic test for different types of loading data +# + +# should give duplicate key +CREATE TABLE t1 (word CHAR(20) NOT NULL PRIMARY KEY) ENGINE=NDB; +--error 1022 +LOAD DATA INFILE '../../std_data/words.dat' INTO TABLE t1 ; +DROP TABLE t1; + +# now without a primary key we should be ok +CREATE TABLE t1 (word CHAR(20) NOT NULL) ENGINE=NDB; +LOAD DATA INFILE '../../std_data/words.dat' INTO TABLE t1 ; +SELECT * FROM t1 ORDER BY word; +DROP TABLE t1; + +# End of 4.1 tests diff --git a/sql/ha_ndbcluster.cc b/sql/ha_ndbcluster.cc index 594551b918a..f5c0f3dc173 100644 --- a/sql/ha_ndbcluster.cc +++ b/sql/ha_ndbcluster.cc @@ -3046,9 +3046,23 @@ int ha_ndbcluster::end_bulk_insert() "rows_inserted:%d, bulk_insert_rows: %d", (int) m_rows_inserted, (int) m_bulk_insert_rows)); m_bulk_insert_not_flushed= FALSE; - if (execute_no_commit(this,trans) != 0) { - no_uncommitted_rows_execute_failure(); - my_errno= error= ndb_err(trans); + if (m_transaction_on) + { + if (execute_no_commit(this, trans) != 0) + { + no_uncommitted_rows_execute_failure(); + my_errno= error= ndb_err(trans); + } + } + else + { + if (execute_commit(this, trans) != 0) + { + no_uncommitted_rows_execute_failure(); + my_errno= error= ndb_err(trans); + } + int res= trans->restart(); + DBUG_ASSERT(res == 0); } } @@ -4867,7 +4881,7 @@ bool ha_ndbcluster::low_byte_first() const } bool ha_ndbcluster::has_transactions() { - return m_transaction_on; + return TRUE; } const char* ha_ndbcluster::index_type(uint key_number) { diff --git a/sql/sql_load.cc b/sql/sql_load.cc index aa4ea3e6c8c..4e6c458cc43 100644 --- a/sql/sql_load.cc +++ b/sql/sql_load.cc @@ -285,8 +285,11 @@ int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list, else error=read_sep_field(thd,info,table,fields,read_info,*enclosed, skip_lines); - if (table->file->end_bulk_insert()) - error=1; /* purecov: inspected */ + if (table->file->end_bulk_insert() && !error) + { + table->file->print_error(my_errno, MYF(0)); + error= 1; + } table->file->extra(HA_EXTRA_NO_IGNORE_DUP_KEY); table->next_number_field=0; } From 523d97f4ddfe695ca6134a65d93a24f388e52a4c Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 7 Feb 2006 11:30:42 +0100 Subject: [PATCH 33/52] Bug #17081 "LOAD DATA INFILE" may not load all the data --- sql/ha_ndbcluster.cc | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/sql/ha_ndbcluster.cc b/sql/ha_ndbcluster.cc index f5c0f3dc173..6a80ba83017 100644 --- a/sql/ha_ndbcluster.cc +++ b/sql/ha_ndbcluster.cc @@ -3061,8 +3061,11 @@ int ha_ndbcluster::end_bulk_insert() no_uncommitted_rows_execute_failure(); my_errno= error= ndb_err(trans); } - int res= trans->restart(); - DBUG_ASSERT(res == 0); + else + { + int res= trans->restart(); + DBUG_ASSERT(res == 0); + } } } From 26f7afaf35d0ec874598fcb2b039090aa617daf7 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 7 Feb 2006 13:45:16 +0200 Subject: [PATCH 34/52] kill.test fixed for kill on Mac OS X (which do not send OK) mysql-test/r/kill.result: This result chenged because of the correspondent test change. mysql-test/t/kill.test: This test fixed for kill on Mac OS X (which do not send OK) --- mysql-test/r/kill.result | 2 +- mysql-test/t/kill.test | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/mysql-test/r/kill.result b/mysql-test/r/kill.result index 828c7fcf9b0..239f9d24e9e 100644 --- a/mysql-test/r/kill.result +++ b/mysql-test/r/kill.result @@ -27,5 +27,5 @@ select ((@id := kill_id) - kill_id) from t3; ((@id := kill_id) - kill_id) 0 kill @id; -ERROR 08S01: Server shutdown in progress +Got one of the listed errors drop table t1, t2, t3; diff --git a/mysql-test/t/kill.test b/mysql-test/t/kill.test index ebe4673beb3..9ef5e272d46 100644 --- a/mysql-test/t/kill.test +++ b/mysql-test/t/kill.test @@ -78,7 +78,7 @@ select ((@id := kill_id) - kill_id) from t3; kill @id; connection conn1; --- error 1053 +-- error 1053,2013 reap; disconnect conn1; From 1a27a433fc6e3eb50b995cd52c11edcb2364d362 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 8 Feb 2006 16:00:39 +0400 Subject: [PATCH 35/52] Removed 'delayed' to make the test deterministic (as the bug itself has nothing to do with 'delayed'). --- mysql-test/r/heap.result | 4 ++-- mysql-test/t/heap.test | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/mysql-test/r/heap.result b/mysql-test/r/heap.result index e3b9f7db984..6bb9d0c87ee 100644 --- a/mysql-test/r/heap.result +++ b/mysql-test/r/heap.result @@ -297,11 +297,11 @@ insert into t1 values ("abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcd 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); +insert into t1 values (0); delete from t1; select * from t1; a -insert delayed into t1 values (0), (1); +insert into t1 values (0), (1); select * from t1 where a = 0; a 0 diff --git a/mysql-test/t/heap.test b/mysql-test/t/heap.test index a8128b79e3b..50147b4182d 100644 --- a/mysql-test/t/heap.test +++ b/mysql-test/t/heap.test @@ -238,10 +238,10 @@ 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); +insert into t1 values (0); delete from t1; select * from t1; -insert delayed into t1 values (0), (1); +insert into t1 values (0), (1); select * from t1 where a = 0; drop table t1; From bbcb4a567a298edf6c7a8846f4a57377702f5d9c Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 10 Feb 2006 09:17:53 +0100 Subject: [PATCH 36/52] bug#17295 - ndb - error while reading REDO log fix corruption due to page 0, file 0 gets released ndb/src/kernel/blocks/dblqh/DblqhMain.cpp: Make sure that page 0, file 0 isnt released --- ndb/src/kernel/blocks/dblqh/DblqhMain.cpp | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp b/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp index 80a8805697e..fb6aa026b3b 100644 --- a/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp +++ b/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp @@ -14767,7 +14767,9 @@ void Dblqh::execSr(Signal* signal) signal->theData[4] = logFilePtr.p->currentFilepage; signal->theData[5] = logFilePtr.p->currentMbyte; signal->theData[6] = logPagePtr.p->logPageWord[ZCURR_PAGE_INDEX]; - sendSignal(cownref, GSN_DEBUG_SIG, signal, 7, JBA); + signal->theData[7] = ~0; + signal->theData[8] = __LINE__; + sendSignal(cownref, GSN_DEBUG_SIG, signal, 9, JBA); return; }//if }//if @@ -14833,7 +14835,8 @@ void Dblqh::execSr(Signal* signal) signal->theData[5] = logFilePtr.p->currentFilepage; signal->theData[6] = logPagePtr.p->logPageWord[ZCURR_PAGE_INDEX]; signal->theData[7] = logWord; - sendSignal(cownref, GSN_DEBUG_SIG, signal, 8, JBA); + signal->theData[8] = __LINE__; + sendSignal(cownref, GSN_DEBUG_SIG, signal, 9, JBA); return; break; }//switch @@ -14862,8 +14865,9 @@ void Dblqh::execDEBUG_SIG(Signal* signal) char buf[100]; BaseString::snprintf(buf, 100, - "Error while reading REDO log.\n" + "Error while reading REDO log. from %d\n" "D=%d, F=%d Mb=%d FP=%d W1=%d W2=%d", + signal->theData[8], signal->theData[2], signal->theData[3], signal->theData[4], signal->theData[5], signal->theData[6], signal->theData[7]); @@ -15439,6 +15443,10 @@ void Dblqh::readSrFourthZeroLab(Signal* signal) // to read a page from file. lfoPtr.p->lfoState = LogFileOperationRecord::WRITE_SR_INVALIDATE_PAGES; + /** + * Make sure we dont release zero page + */ + seizeLogpage(signal); invalidateLogAfterLastGCI(signal); return; }//Dblqh::readSrFourthZeroLab() From 165d5390698c66217d0614afa097cb61bd859af1 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 10 Feb 2006 09:37:36 +0100 Subject: [PATCH 37/52] bug#10987 - ndb - unable to find restorable replica Introduce new variable c_newest_restorable_gci which is set _after_ both GCP_SAVE and COPY_GCI This variable is used when cutting redo (calcKeepGci) Also make sure complete GCI is run inbetween LCP's ndb/src/kernel/blocks/dbdih/Dbdih.hpp: Introduce new variable c_newest_restorable_gci which is set _after_ both GCP_SAVE and COPY_GCI This variable is used when cutting redo (calcKeepGci) Also make sure complete GCI is run inbetween LCP's ndb/src/kernel/blocks/dbdih/DbdihMain.cpp: Introduce new variable c_newest_restorable_gci which is set _after_ both GCP_SAVE and COPY_GCI This variable is used when cutting redo (calcKeepGci) Also make sure complete GCI is run inbetween LCP's --- ndb/src/kernel/blocks/dbdih/Dbdih.hpp | 7 +++--- ndb/src/kernel/blocks/dbdih/DbdihMain.cpp | 28 ++++++++++++++--------- 2 files changed, 21 insertions(+), 14 deletions(-) diff --git a/ndb/src/kernel/blocks/dbdih/Dbdih.hpp b/ndb/src/kernel/blocks/dbdih/Dbdih.hpp index ee67bf47d7b..0c107e35603 100644 --- a/ndb/src/kernel/blocks/dbdih/Dbdih.hpp +++ b/ndb/src/kernel/blocks/dbdih/Dbdih.hpp @@ -774,7 +774,7 @@ private: //------------------------------------ // Methods for LCP functionality //------------------------------------ - void checkKeepGci(Uint32 replicaStartIndex); + void checkKeepGci(TabRecordPtr, Uint32, Fragmentstore*, Uint32); void checkLcpStart(Signal *, Uint32 lineNo); void checkStartMoreLcp(Signal *, Uint32 nodeId); bool reportLcpCompletion(const class LcpFragRep *); @@ -1292,7 +1292,7 @@ private: } Uint32 lcpStart; - Uint32 lcpStartGcp; + Uint32 lcpStopGcp; Uint32 keepGci; /* USED TO CALCULATE THE GCI TO KEEP AFTER A LCP */ Uint32 oldestRestorableGci; @@ -1361,7 +1361,8 @@ private: Uint32 cstarttype; Uint32 csystemnodes; Uint32 currentgcp; - + Uint32 c_newest_restorable_gci; + enum GcpMasterTakeOverState { GMTOS_IDLE = 0, GMTOS_INITIAL = 1, diff --git a/ndb/src/kernel/blocks/dbdih/DbdihMain.cpp b/ndb/src/kernel/blocks/dbdih/DbdihMain.cpp index 97cd8c374c6..1d2124e1b32 100644 --- a/ndb/src/kernel/blocks/dbdih/DbdihMain.cpp +++ b/ndb/src/kernel/blocks/dbdih/DbdihMain.cpp @@ -674,6 +674,7 @@ void Dbdih::execCOPY_GCIREQ(Signal* signal) jam(); coldgcp = SYSFILE->newestRestorableGCI; crestartGci = SYSFILE->newestRestorableGCI; + c_newest_restorable_gci = SYSFILE->newestRestorableGCI; Sysfile::setRestartOngoing(SYSFILE->systemRestartBits); currentgcp = coldgcp + 1; cnewgcp = coldgcp + 1; @@ -692,6 +693,7 @@ void Dbdih::execCOPY_GCIREQ(Signal* signal) ok = true; jam(); cgcpParticipantState = GCP_PARTICIPANT_COPY_GCI_RECEIVED; + c_newest_restorable_gci = SYSFILE->newestRestorableGCI; setNodeInfo(signal); break; }//if @@ -7749,6 +7751,8 @@ void Dbdih::execCOPY_GCICONF(Signal* signal) signal->theData[1] = coldgcp; sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 2, JBB); + c_newest_restorable_gci = coldgcp; + CRASH_INSERTION(7004); emptyWaitGCPMasterQueue(signal); cgcpStatus = GCP_READY; @@ -9155,7 +9159,7 @@ void Dbdih::checkTcCounterLab(Signal* signal) }//if c_lcpState.ctimer += 32; if ((c_nodeStartMaster.blockLcp == true) || - ((c_lcpState.lcpStartGcp + 1) > currentgcp)) { + (c_lcpState.lcpStopGcp >= c_newest_restorable_gci)) { jam(); /* --------------------------------------------------------------------- */ // No reason to start juggling the states and checking for start of LCP if @@ -9238,7 +9242,6 @@ void Dbdih::execTCGETOPSIZECONF(Signal* signal) /* ----------------------------------------------------------------------- */ c_lcpState.ctimer = 0; c_lcpState.keepGci = coldgcp; - c_lcpState.lcpStartGcp = currentgcp; /* ----------------------------------------------------------------------- */ /* UPDATE THE NEW LATEST LOCAL CHECKPOINT ID. */ /* ----------------------------------------------------------------------- */ @@ -9310,7 +9313,7 @@ void Dbdih::calculateKeepGciLab(Signal* signal, Uint32 tableId, Uint32 fragId) cnoOfActiveTables++; FragmentstorePtr fragPtr; getFragstore(tabPtr.p, fragId, fragPtr); - checkKeepGci(fragPtr.p->storedReplicas); + checkKeepGci(tabPtr, fragId, fragPtr.p, fragPtr.p->storedReplicas); fragId++; if (fragId >= tabPtr.p->totalfragments) { jam(); @@ -10168,6 +10171,7 @@ void Dbdih::allNodesLcpCompletedLab(Signal* signal) signal->theData[0] = EventReport::LocalCheckpointCompleted; //Event type signal->theData[1] = SYSFILE->latestLCP_ID; sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 2, JBB); + c_lcpState.lcpStopGcp = c_newest_restorable_gci; /** * Start checking for next LCP @@ -10522,7 +10526,8 @@ void Dbdih::checkEscalation() /* DESCRIPTION: CHECK FOR MINIMUM GCI RESTORABLE WITH NEW LOCAL */ /* CHECKPOINT. */ /*************************************************************************/ -void Dbdih::checkKeepGci(Uint32 replicaStartIndex) +void Dbdih::checkKeepGci(TabRecordPtr tabPtr, Uint32 fragId, Fragmentstore*, + Uint32 replicaStartIndex) { ReplicaRecordPtr ckgReplicaPtr; ckgReplicaPtr.i = replicaStartIndex; @@ -10544,7 +10549,6 @@ void Dbdih::checkKeepGci(Uint32 replicaStartIndex) if (oldestRestorableGci > c_lcpState.oldestRestorableGci) { jam(); c_lcpState.oldestRestorableGci = oldestRestorableGci; - ndbrequire(((int)c_lcpState.oldestRestorableGci) >= 0); }//if ckgReplicaPtr.i = ckgReplicaPtr.p->nextReplica; }//while @@ -10838,7 +10842,7 @@ void Dbdih::findMinGci(ReplicaRecordPtr fmgReplicaPtr, do { ndbrequire(lcpNo < MAX_LCP_STORED); if (fmgReplicaPtr.p->lcpStatus[lcpNo] == ZVALID && - fmgReplicaPtr.p->maxGciStarted[lcpNo] <= coldgcp) + fmgReplicaPtr.p->maxGciStarted[lcpNo] < c_newest_restorable_gci) { jam(); keepGci = fmgReplicaPtr.p->maxGciCompleted[lcpNo]; @@ -10960,7 +10964,7 @@ void Dbdih::initCommonData() c_lcpState.clcpDelay = 0; c_lcpState.lcpStart = ZIDLE; - c_lcpState.lcpStartGcp = 0; + c_lcpState.lcpStopGcp = 0; c_lcpState.setLcpStatus(LCP_STATUS_IDLE, __LINE__); c_lcpState.currentFragment.tableId = 0; c_lcpState.currentFragment.fragmentId = 0; @@ -10996,6 +11000,7 @@ void Dbdih::initCommonData() csystemnodes = 0; c_updateToLock = RNIL; currentgcp = 0; + c_newest_restorable_gci = 0; cverifyQueueCounter = 0; cwaitLcpSr = false; @@ -11067,6 +11072,7 @@ void Dbdih::initRestartInfo() currentgcp = 2; cnewgcp = 2; crestartGci = 1; + c_newest_restorable_gci = 1; SYSFILE->keepGCI = 1; SYSFILE->oldestRestorableGCI = 1; @@ -13038,9 +13044,9 @@ Dbdih::execDUMP_STATE_ORD(Signal* signal) if (signal->theData[0] == 7001) { infoEvent("c_lcpState.keepGci = %d", c_lcpState.keepGci); - infoEvent("c_lcpState.lcpStatus = %d, clcpStartGcp = %d", + infoEvent("c_lcpState.lcpStatus = %d, clcpStopGcp = %d", c_lcpState.lcpStatus, - c_lcpState.lcpStartGcp); + c_lcpState.lcpStopGcp); infoEvent("cgcpStartCounter = %d, cimmediateLcpStart = %d", cgcpStartCounter, c_lcpState.immediateLcpStart); }//if @@ -13221,8 +13227,8 @@ Dbdih::execDUMP_STATE_ORD(Signal* signal) infoEvent("lcpStatus = %d (update place = %d) ", c_lcpState.lcpStatus, c_lcpState.lcpStatusUpdatedPlace); infoEvent - ("lcpStart = %d lcpStartGcp = %d keepGci = %d oldestRestorable = %d", - c_lcpState.lcpStart, c_lcpState.lcpStartGcp, + ("lcpStart = %d lcpStopGcp = %d keepGci = %d oldestRestorable = %d", + c_lcpState.lcpStart, c_lcpState.lcpStopGcp, c_lcpState.keepGci, c_lcpState.oldestRestorableGci); infoEvent From a68f171585da08a855df1958caab3264a4b74006 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 10 Feb 2006 15:12:27 +0200 Subject: [PATCH 38/52] BUG#16217 fix partly backported from 5.0. It is different in mysqlbinlog part. This changeset is assumed to stay in 4.1. client/mysql.cc: BUG#16217 forced to introduce a separate mysql client command. Feature is backported from 5.0, precisely ChangeSet 1.2034 06/02/09 16:23:09 aelkin@mysql.com (under second review at the moment) mysql-test/r/mysqlbinlog.result: changed in 5.0 mysql-test/t/mysqlbinlog.test: backported from 5.0. The last part of the test to mimic bug#16217 sql/log_event.cc: Inserting exclaiming comment command for mysql client made differently than in 5.0. Parsing still is cheap enough not to think to modify server code instead. --- client/mysql.cc | 26 +++++++++++++++++++++++++- mysql-test/r/mysqlbinlog.result | 19 ++++++++++++++++++- mysql-test/t/mysqlbinlog.test | 19 ++++++++++++++++++- sql/log_event.cc | 12 ++++++++++++ 4 files changed, 73 insertions(+), 3 deletions(-) diff --git a/client/mysql.cc b/client/mysql.cc index d76195535a3..2f9031b84b8 100644 --- a/client/mysql.cc +++ b/client/mysql.cc @@ -190,7 +190,7 @@ static int com_quit(String *str,char*), com_connect(String *str,char*), com_status(String *str,char*), com_use(String *str,char*), com_source(String *str, char*), com_rehash(String *str, char*), com_tee(String *str, char*), - com_notee(String *str, char*), + com_notee(String *str, char*), com_charset(String *str,char*), com_prompt(String *str, char*), com_delimiter(String *str, char*); #ifdef USE_POPEN @@ -263,6 +263,8 @@ static COMMANDS commands[] = { "Set outfile [to_outfile]. Append everything into given outfile." }, { "use", 'u', com_use, 1, "Use another database. Takes database name as argument." }, + { "charset_name", 'C', com_charset, 1, + "Switch to another charset. Might be needed for processing binlog." }, /* Get bash-like expansion for some commands */ { "create table", 0, 0, 0, ""}, { "create database", 0, 0, 0, ""}, @@ -1850,6 +1852,28 @@ com_clear(String *buffer,char *line __attribute__((unused))) return 0; } + /* ARGSUSED */ +static int +com_charset(String *buffer __attribute__((unused)), char *line) +{ + char buff[256], *param; + CHARSET_INFO * new_cs; + strmake(buff, line, sizeof(buff) - 1); + param= get_arg(buff, 0); + if (!param || !*param) + { + return put_info("Usage: \\C char_setname | charset charset_name", + INFO_ERROR, 0); + } + new_cs= get_charset_by_csname(param, MY_CS_PRIMARY, MYF(MY_WME)); + if (new_cs) + { + charset_info= new_cs; + put_info("Charset changed", INFO_INFO); + } + else put_info("Charset is not found", INFO_INFO); + return 0; +} /* Execute command diff --git a/mysql-test/r/mysqlbinlog.result b/mysql-test/r/mysqlbinlog.result index e88ece6b361..adaf0dad56b 100644 --- a/mysql-test/r/mysqlbinlog.result +++ b/mysql-test/r/mysqlbinlog.result @@ -84,4 +84,21 @@ SET INSERT_ID=1; use test; SET TIMESTAMP=1000000000; insert into t1 values ("Alas"); -drop table t1, t2; +flush logs; +create table t3 (f text character set utf8); +create table t4 (f text character set cp932); +flush logs; +rename table t3 to t03, t4 to t04; +select HEX(f) from t03; +HEX(f) +E382BD +select HEX(f) from t3; +HEX(f) +E382BD +select HEX(f) from t04; +HEX(f) +835C +select HEX(f) from t4; +HEX(f) +835C +drop table t1, t2, t03, t04, t3, t4; diff --git a/mysql-test/t/mysqlbinlog.test b/mysql-test/t/mysqlbinlog.test index 0f9faa5c337..871886331f6 100644 --- a/mysql-test/t/mysqlbinlog.test +++ b/mysql-test/t/mysqlbinlog.test @@ -98,7 +98,24 @@ select "--- --position --" as ""; --replace_result $MYSQL_TEST_DIR MYSQL_TEST_DIR --exec $MYSQL_BINLOG --short-form --local-load=$MYSQL_TEST_DIR/var/tmp/ --read-from-remote-server --position=27 --user=root --host=127.0.0.1 --port=$MASTER_MYPORT master-bin.000002 + +# Bug#16217 (mysql client did not know how not switch its internal charset) +flush logs; +create table t3 (f text character set utf8); +create table t4 (f text character set cp932); +--exec $MYSQL --default-character-set=utf8 test -e "insert into t3 values(_utf8'ソ')" +--exec $MYSQL --default-character-set=cp932 test -e "insert into t4 values(_cp932'ƒ\');" +flush logs; +rename table t3 to t03, t4 to t04; +--exec $MYSQL_BINLOG --short-form $MYSQL_TEST_DIR/var/log/master-bin.000004 | $MYSQL --default-character-set=utf8 +# original and recovered data must be equal +select HEX(f) from t03; +select HEX(f) from t3; +select HEX(f) from t04; +select HEX(f) from t4; + + # clean up -drop table t1, t2; +drop table t1, t2, t03, t04, t3, t4; # End of 4.1 tests diff --git a/sql/log_event.cc b/sql/log_event.cc index 3f545df5776..19c32b2d28e 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -949,6 +949,7 @@ Query_log_event::Query_log_event(const char* buf, int event_len, void Query_log_event::print(FILE* file, bool short_form, char* last_db) { char buff[40],*end; // Enough for SET TIMESTAMP + const uint set_len= sizeof("SET ONE_SHOT CHARACTER_SET_CLIENT=") - 1; if (!short_form) { print_header(file); @@ -978,6 +979,17 @@ void Query_log_event::print(FILE* file, bool short_form, char* last_db) my_fwrite(file, (byte*) buff, (uint) (end-buff),MYF(MY_NABP | MY_WME)); if (flags & LOG_EVENT_THREAD_SPECIFIC_F) fprintf(file,"SET @@session.pseudo_thread_id=%lu;\n",(ulong)thread_id); + /* charset_name command for mysql client */ + if (!strncmp(query, "SET ONE_SHOT CHARACTER_SET_CLIENT=", set_len)) + { + char * endptr; + int cs_number= strtoul(query + set_len, &endptr, 10); + DBUG_ASSERT(*endptr == ','); + CHARSET_INFO *cs_info= get_charset(cs_number, MYF(MY_WME)); + if (cs_info) { + fprintf(file, "/*!\\C %s */;\n", cs_info->csname); + } + } my_fwrite(file, (byte*) query, q_len, MYF(MY_NABP | MY_WME)); fprintf(file, ";\n"); } From b4d38aa0c66a1c3f83f61e35e007c3a6f03185a9 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 10 Feb 2006 17:40:04 +0100 Subject: [PATCH 39/52] support-files/mysql.spec.sh : Use "-i" on "make test-force", essential for log file evaluation. support-files/mysql.spec.sh: Use "-i" on "make test-force"; this will prevent "make" from writing "***" which in turn was treated as a _build_ error by the log evaluation tool, causing it not to list the failing tests. --- support-files/mysql.spec.sh | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/support-files/mysql.spec.sh b/support-files/mysql.spec.sh index 7afdae69439..42958a3a871 100644 --- a/support-files/mysql.spec.sh +++ b/support-files/mysql.spec.sh @@ -309,7 +309,7 @@ BuildMySQL "--enable-shared \ --with-comment=\"MySQL Community Edition - Max (GPL)\" \ --with-server-suffix='-Max'" -make test-force || true +make -i test-force || true # Save mysqld-max mv sql/mysqld sql/mysqld-max @@ -363,7 +363,7 @@ BuildMySQL "--disable-shared \ --without-openssl" nm --numeric-sort sql/mysqld > sql/mysqld.sym -make test-force || true +make -i test-force || true %install RBR=$RPM_BUILD_ROOT @@ -689,6 +689,11 @@ fi # itself - note that they must be ordered by date (important when # merging BK trees) %changelog +* Fri Jan 10 2006 Joerg Bruehe + +- Use "-i" on "make test-force"; + this is essential for later evaluation of this log file. + * Mon Dec 05 2005 Joerg Bruehe - Avoid using the "bundled" zlib on "shared" builds: From 26287714d5c2096ad04375769d49e0d972e4be59 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 10 Feb 2006 17:40:22 +0100 Subject: [PATCH 40/52] Bug #17249 ndb, delete statement with join where clause fails when table do not have pk Bug #17257 ndb, update fails for inner joins if tables do not have Primary Key change: the allocated area by setValue may not be around for later, store hidden key in special member variable instead mysql-test/r/ndb_basic.result: Bug #17249 delete statement with join where clause fails when table do not have pk Bug #17257 update fails for inner joins if tables do not have Primary Key mysql-test/t/ndb_basic.test: Bug #17249 delete statement with join where clause fails when table do not have pk Bug #17257 update fails for inner joins if tables do not have Primary Key sql/ha_ndbcluster.cc: Bug #17249 delete statement with join where clause fails when table do not have pk Bug #17257 update fails for inner joins if tables do not have Primary Key change: the allocated area by setValue may not be around for later, store hidden key in special member variable instead sql/ha_ndbcluster.h: Bug #17249 delete statement with join where clause fails when table do not have pk Bug #17257 update fails for inner joins if tables do not have Primary Key change: the allocated area by setValue may not be around for later, store hidden key in special member variable instead --- mysql-test/r/ndb_basic.result | 55 +++++++++++++++++++++++++++++ mysql-test/t/ndb_basic.test | 66 +++++++++++++++++++++++++++++++++++ sql/ha_ndbcluster.cc | 20 ++++------- sql/ha_ndbcluster.h | 3 ++ 4 files changed, 130 insertions(+), 14 deletions(-) diff --git a/mysql-test/r/ndb_basic.result b/mysql-test/r/ndb_basic.result index 42b5a39d3d8..68c8bc01a14 100644 --- a/mysql-test/r/ndb_basic.result +++ b/mysql-test/r/ndb_basic.result @@ -671,3 +671,58 @@ CREATE TABLE t1 ( b INT ) PACK_KEYS = 0 ENGINE = ndb; select * from t1; b drop table t1; +create table t1 (a int) engine=ndb; +create table t2 (a int) engine=ndb; +insert into t1 values (1); +insert into t2 values (1); +delete t1.* from t1, t2 where t1.a = t2.a; +select * from t1; +a +select * from t2; +a +1 +drop table t1; +drop table t2; +CREATE TABLE t1 ( +i INT, +j INT, +x INT, +y INT, +z INT +) engine=ndb; +CREATE TABLE t2 ( +i INT, +k INT, +x INT, +y INT, +z INT +) engine=ndb; +CREATE TABLE t3 ( +j INT, +k INT, +x INT, +y INT, +z INT +) engine=ndb; +INSERT INTO t1 VALUES ( 1, 2,13,14,15); +INSERT INTO t2 VALUES ( 1, 3,23,24,25); +INSERT INTO t3 VALUES ( 2, 3, 1,34,35), ( 2, 3, 1,34,36); +UPDATE t1 AS a +INNER JOIN t2 AS b +ON a.i = b.i +INNER JOIN t3 AS c +ON a.j = c.j AND b.k = c.k +SET a.x = b.x, +a.y = b.y, +a.z = ( +SELECT sum(z) +FROM t3 +WHERE y = 34 +) +WHERE b.x = 23; +select * from t1; +i j x y z +1 2 23 24 71 +drop table t1; +drop table t2; +drop table t3; diff --git a/mysql-test/t/ndb_basic.test b/mysql-test/t/ndb_basic.test index c8cf5823500..fdc87382308 100644 --- a/mysql-test/t/ndb_basic.test +++ b/mysql-test/t/ndb_basic.test @@ -614,4 +614,70 @@ CREATE TABLE t1 ( b INT ) PACK_KEYS = 0 ENGINE = ndb; select * from t1; drop table t1; +# +# Bug #17249 delete statement with join where clause fails +# when table do not have pk +# + +create table t1 (a int) engine=ndb; +create table t2 (a int) engine=ndb; +insert into t1 values (1); +insert into t2 values (1); +delete t1.* from t1, t2 where t1.a = t2.a; +select * from t1; +select * from t2; +drop table t1; +drop table t2; + +# +# Bug #17257 update fails for inner joins if tables +# do not have Primary Key +# + +CREATE TABLE t1 ( + i INT, + j INT, + x INT, + y INT, + z INT +) engine=ndb; + +CREATE TABLE t2 ( + i INT, + k INT, + x INT, + y INT, + z INT +) engine=ndb; + +CREATE TABLE t3 ( + j INT, + k INT, + x INT, + y INT, + z INT +) engine=ndb; + +INSERT INTO t1 VALUES ( 1, 2,13,14,15); +INSERT INTO t2 VALUES ( 1, 3,23,24,25); +INSERT INTO t3 VALUES ( 2, 3, 1,34,35), ( 2, 3, 1,34,36); + +UPDATE t1 AS a +INNER JOIN t2 AS b + ON a.i = b.i +INNER JOIN t3 AS c + ON a.j = c.j AND b.k = c.k +SET a.x = b.x, + a.y = b.y, + a.z = ( + SELECT sum(z) + FROM t3 + WHERE y = 34 + ) +WHERE b.x = 23; +select * from t1; +drop table t1; +drop table t2; +drop table t3; + # End of 4.1 tests diff --git a/sql/ha_ndbcluster.cc b/sql/ha_ndbcluster.cc index 6a80ba83017..876d5d2f8fd 100644 --- a/sql/ha_ndbcluster.cc +++ b/sql/ha_ndbcluster.cc @@ -45,8 +45,6 @@ static const int max_transactions= 256; static const char *ha_ndb_ext=".ndb"; -#define NDB_HIDDEN_PRIMARY_KEY_LENGTH 8 - #define NDB_FAILED_AUTO_INCREMENT ~(Uint64)0 #define NDB_AUTO_INCREMENT_RETRIES 10 @@ -747,7 +745,7 @@ int ha_ndbcluster::get_ndb_value(NdbOperation *ndb_op, Field *field, } // Used for hidden key only - m_value[fieldnr].rec= ndb_op->getValue(fieldnr, NULL); + m_value[fieldnr].rec= ndb_op->getValue(fieldnr, m_ref); DBUG_RETURN(m_value[fieldnr].rec == NULL); } @@ -2098,13 +2096,10 @@ int ha_ndbcluster::update_row(const byte *old_data, byte *new_data) DBUG_PRINT("info", ("Using hidden key")); // Require that the PK for this record has previously been - // read into m_value - uint no_fields= table->fields; - NdbRecAttr* rec= m_value[no_fields].rec; - DBUG_ASSERT(rec); - DBUG_DUMP("key", (char*)rec->aRef(), NDB_HIDDEN_PRIMARY_KEY_LENGTH); + // read into m_ref + DBUG_DUMP("key", m_ref, NDB_HIDDEN_PRIMARY_KEY_LENGTH); - if (set_hidden_key(op, no_fields, rec->aRef())) + if (set_hidden_key(op, table->fields, m_ref)) ERR_RETURN(op->getNdbError()); } else @@ -2181,11 +2176,8 @@ int ha_ndbcluster::delete_row(const byte *record) { // This table has no primary key, use "hidden" primary key DBUG_PRINT("info", ("Using hidden key")); - uint no_fields= table->fields; - NdbRecAttr* rec= m_value[no_fields].rec; - DBUG_ASSERT(rec != NULL); - if (set_hidden_key(op, no_fields, rec->aRef())) + if (set_hidden_key(op, table->fields, m_ref)) ERR_RETURN(op->getNdbError()); } else @@ -2792,7 +2784,7 @@ void ha_ndbcluster::position(const byte *record) hidden_col->getAutoIncrement() && rec != NULL && ref_length == NDB_HIDDEN_PRIMARY_KEY_LENGTH); - memcpy(ref, (const void*)rec->aRef(), ref_length); + memcpy(ref, m_ref, ref_length); } DBUG_DUMP("ref", (char*)ref, ref_length); diff --git a/sql/ha_ndbcluster.h b/sql/ha_ndbcluster.h index 90d5d59cabe..83d9d87777a 100644 --- a/sql/ha_ndbcluster.h +++ b/sql/ha_ndbcluster.h @@ -27,6 +27,8 @@ #include +#define NDB_HIDDEN_PRIMARY_KEY_LENGTH 8 + class Ndb; // Forward declaration class NdbOperation; // Forward declaration class NdbConnection; // Forward declaration @@ -226,6 +228,7 @@ class ha_ndbcluster: public handler // NdbRecAttr has no reference to blob typedef union { NdbRecAttr *rec; NdbBlob *blob; void *ptr; } NdbValue; NdbValue m_value[NDB_MAX_ATTRIBUTES_IN_TABLE]; + byte m_ref[NDB_HIDDEN_PRIMARY_KEY_LENGTH]; bool m_use_write; bool m_ignore_dup_key; bool m_primary_key_update; From 503193867ef8ee460b03ebfa9cb8e0409624c257 Mon Sep 17 00:00:00 2001 From: unknown Date: Sat, 11 Feb 2006 22:50:59 +0100 Subject: [PATCH 41/52] Fix a race on some platforms in mysql-test-run.pl, where it would sometimes errorneously abort reporting failure to kill child processes, where in reality the problem was merely that the child had become a zombie because of missing waitpid() call. mysql-test/lib/mtr_process.pl: Fix race (on some platforms) when killing processes. --- mysql-test/lib/mtr_process.pl | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/mysql-test/lib/mtr_process.pl b/mysql-test/lib/mtr_process.pl index 177665cf578..4da608ad345 100644 --- a/mysql-test/lib/mtr_process.pl +++ b/mysql-test/lib/mtr_process.pl @@ -770,7 +770,15 @@ sub mtr_record_dead_children () { } sub start_reap_all { - $SIG{CHLD}= 'IGNORE'; # FIXME is this enough? + # This causes terminating processes to not become zombies, avoiding + # the need for (or possibility of) explicit waitpid(). + $SIG{CHLD}= 'IGNORE'; + + # On some platforms (Linux, QNX, OSX, ...) there is potential race + # here. If a process terminated before setting $SIG{CHLD} (but after + # any attempt to waitpid() it), it will still be a zombie. So we + # have to handle any such process here. + while(waitpid(-1, &WNOHANG) > 0) { }; } sub stop_reap_all { From 18faf0026256aecaea5ed7df8ef025c985958966 Mon Sep 17 00:00:00 2001 From: unknown Date: Sat, 11 Feb 2006 23:35:23 +0100 Subject: [PATCH 42/52] mysql-test-run.{pl,sh}: Give space for second and third slave port mysql-test/mysql-test-run.pl: Give space for second and third slave port Define shell variables for all ports, and list these at startup mysql-test/mysql-test-run.sh: Give space for second and third slave port --- mysql-test/mysql-test-run.pl | 14 ++++++++++---- mysql-test/mysql-test-run.sh | 2 +- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl index c9478534fee..addacab8f9a 100755 --- a/mysql-test/mysql-test-run.pl +++ b/mysql-test/mysql-test-run.pl @@ -476,8 +476,8 @@ sub command_line_setup () { if ( $ENV{'MTR_BUILD_THREAD'} ) { $opt_master_myport= $ENV{'MTR_BUILD_THREAD'} * 10 + 10000; - $opt_slave_myport= $opt_master_myport + 3; - $opt_ndbcluster_port= $opt_master_myport + 4; + $opt_slave_myport= $opt_master_myport + 2; # and 3 4 + $opt_ndbcluster_port= $opt_master_myport + 5; } # Read the command line @@ -985,12 +985,14 @@ sub environment_setup () { $ENV{'USE_RUNNING_SERVER'}= $glob_use_running_server; $ENV{'MYSQL_TEST_DIR'}= $glob_mysql_test_dir; $ENV{'MYSQL_TEST_WINDIR'}= $glob_mysql_test_dir; - $ENV{'MASTER_MYSOCK'}= $master->[0]->{'path_mysock'}; $ENV{'MASTER_WINMYSOCK'}= $master->[0]->{'path_mysock'}; + $ENV{'MASTER_MYSOCK'}= $master->[0]->{'path_mysock'}; $ENV{'MASTER_MYSOCK1'}= $master->[1]->{'path_mysock'}; $ENV{'MASTER_MYPORT'}= $master->[0]->{'path_myport'}; $ENV{'MASTER_MYPORT1'}= $master->[1]->{'path_myport'}; $ENV{'SLAVE_MYPORT'}= $slave->[0]->{'path_myport'}; + $ENV{'SLAVE_MYPORT1'}= $slave->[1]->{'path_myport'}; + $ENV{'SLAVE_MYPORT2'}= $slave->[2]->{'path_myport'}; # $ENV{'MYSQL_TCP_PORT'}= '@MYSQL_TCP_PORT@'; # FIXME $ENV{'MYSQL_TCP_PORT'}= 3306; @@ -1004,11 +1006,15 @@ sub environment_setup () { } } + $ENV{MTR_BUILD_THREAD}= 0 unless $ENV{MTR_BUILD_THREAD}; # Set if not set + # We are nice and report a bit about our settings - print "Using MTR_BUILD_THREAD = ",$ENV{MTR_BUILD_THREAD} || 0,"\n"; + print "Using MTR_BUILD_THREAD = $ENV{MTR_BUILD_THREAD}\n"; print "Using MASTER_MYPORT = $ENV{MASTER_MYPORT}\n"; print "Using MASTER_MYPORT1 = $ENV{MASTER_MYPORT1}\n"; print "Using SLAVE_MYPORT = $ENV{SLAVE_MYPORT}\n"; + print "Using SLAVE_MYPORT1 = $ENV{SLAVE_MYPORT1}\n"; + print "Using SLAVE_MYPORT2 = $ENV{SLAVE_MYPORT2}\n"; print "Using NDBCLUSTER_PORT = $opt_ndbcluster_port\n"; } diff --git a/mysql-test/mysql-test-run.sh b/mysql-test/mysql-test-run.sh index 546c581025b..9fcdacb22cb 100644 --- a/mysql-test/mysql-test-run.sh +++ b/mysql-test/mysql-test-run.sh @@ -224,7 +224,7 @@ if [ -n "$MTR_BUILD_THREAD" ] ; then MASTER_MYPORT=`expr $MTR_BUILD_THREAD '*' 10 + 10000` MYSQL_MANAGER_PORT=`expr $MASTER_MYPORT + 2` SLAVE_MYPORT=`expr $MASTER_MYPORT + 3` - NDBCLUSTER_PORT=`expr $MASTER_MYPORT + 4` + NDBCLUSTER_PORT=`expr $MASTER_MYPORT + 6` echo "Using MTR_BUILD_THREAD = $MTR_BUILD_THREAD" echo "Using MASTER_MYPORT = $MASTER_MYPORT" From cd93a5aafa2d89f3c6baa27aff0ffb73afd2a622 Mon Sep 17 00:00:00 2001 From: unknown Date: Sun, 12 Feb 2006 01:33:43 +0100 Subject: [PATCH 43/52] make_binary_distribution.sh: print => echo in shell script scripts/make_binary_distribution.sh: print => echo in shell script --- scripts/make_binary_distribution.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/make_binary_distribution.sh b/scripts/make_binary_distribution.sh index 0236d8b8bfe..f372762c05d 100644 --- a/scripts/make_binary_distribution.sh +++ b/scripts/make_binary_distribution.sh @@ -279,7 +279,7 @@ then gcclib=`@CC@ --print-libgcc-file` if test $? -ne 0 then - print "Warning: Couldn't find libgcc.a!" + echo "Warning: Couldn't find libgcc.a!" else $CP $gcclib libmygcc.a fi From 46c82ab153f5b19a5c55ef214bd60fb5ba76829a Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 28 Feb 2006 12:01:24 -0600 Subject: [PATCH 44/52] mysqltest.c: Fix typos. client/mysqltest.c: Fix typos. --- client/mysqltest.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/client/mysqltest.c b/client/mysqltest.c index 613c4e12763..805c9330c6a 100644 --- a/client/mysqltest.c +++ b/client/mysqltest.c @@ -115,8 +115,8 @@ enum {OPT_MANAGER_USER=256,OPT_MANAGER_HOST,OPT_MANAGER_PASSWD, The list of error codes to --error are stored in an internal array of structs. This struct can hold numeric SQL error codes or SQLSTATE codes as strings. The element next to the last active element in the list is - set to type ERR_EMPTY. When an SQL statement return an error we use - this list to check if this is an expected error. + set to type ERR_EMPTY. When an SQL statement returns an error, we use + this list to check if this is an expected error. */ enum match_err_type @@ -986,8 +986,8 @@ int do_source(struct st_query *query) *p++= 0; query->last_argument= p; /* - If this file has already been sourced, dont source it again. - It's already available in the q_lines cache + If this file has already been sourced, don't source it again. + It's already available in the q_lines cache. */ if (parser.current_line < (parser.read_lines - 1)) return 0; @@ -2151,7 +2151,7 @@ my_bool end_of_query(int c) Normally that means it will read lines until it reaches the "delimiter" that marks end of query. Default delimiter is ';' The function should be smart enough not to detect delimiter's - found inside strings sorrounded with '"' and '\'' escaped strings. + found inside strings surrounded with '"' and '\'' escaped strings. If the first line in a query starts with '#' or '-' this line is treated as a comment. A comment is always terminated when end of line '\n' is @@ -2485,7 +2485,7 @@ static struct my_option my_long_options[] = {"result-file", 'R', "Read/Store result from/in this file.", (gptr*) &result_file, (gptr*) &result_file, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, - {"server-arg", 'A', "Send enbedded server this as a paramenter.", + {"server-arg", 'A', "Send option value to embedded server as a parameter.", 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, {"server-file", 'F', "Read embedded server arguments from file.", 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, @@ -4074,8 +4074,8 @@ int main(int argc, char **argv) /* my_stat() successful on result file. Check if we have not run a single query, but we do have a result file that contains data. - Note that we don't care, if my_stat() fails. For example for - non-existing or non-readable file we assume it's fine to have + Note that we don't care, if my_stat() fails. For example, for a + non-existing or non-readable file, we assume it's fine to have no query output from the test file, e.g. regarded as no error. */ if (res_info.st_size) From 9099fb2d063b537f7a8c94d18dbe163d4945f955 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 28 Feb 2006 14:00:17 -0600 Subject: [PATCH 45/52] mysqltest.c: Correct/clarify comments. client/mysqltest.c: Correct/clarify comments. --- client/mysqltest.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/client/mysqltest.c b/client/mysqltest.c index 805c9330c6a..83be283a050 100644 --- a/client/mysqltest.c +++ b/client/mysqltest.c @@ -320,13 +320,6 @@ const char *command_names[]= "connection", "query", "connect", - /* the difference between sleep and real_sleep is that sleep will use - the delay from command line (--sleep) if there is one. - real_sleep always uses delay from mysqltest's command line argument. - the logic is that sometimes delays are cpu-dependent (and --sleep - can be used to set this delay. real_sleep is used for cpu-independent - delays - */ "sleep", "real_sleep", "inc", @@ -1536,11 +1529,19 @@ int do_disable_rpl_parse(struct st_query *query __attribute__((unused))) do_sleep() q called command real_sleep use the value from opt_sleep as number of seconds to sleep + if real_sleep is false DESCRIPTION sleep - real_sleep + real_sleep + The difference between the sleep and real_sleep commands is that sleep + uses the delay from the --sleep command-line option if there is one. + (If the --sleep option is not given, the sleep command uses the delay + specified by its argument.) The real_sleep command always uses the + delay specified by its argument. The logic is that sometimes delays are + cpu-dependent, and --sleep can be used to set this delay. real_sleep is + used for cpu-independent delays. */ int do_sleep(struct st_query *query, my_bool real_sleep) From 8d5f0fcddcb7b3c5dd7d2f79dd04ba95c61779e9 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 28 Feb 2006 15:08:16 -0600 Subject: [PATCH 46/52] mysql-test-run.sh: Fix URLs. README: Fix URL. mysqltest.result: Update test result for real_sleep error message. mysqltest.c: Fix do_sleep() to print correct command name for real_sleep. client/mysqltest.c: Fix do_sleep() to print correct command name for real_sleep. mysql-test/r/mysqltest.result: Update test result for real_sleep error message. mysql-test/README: Fix URL. mysql-test/mysql-test-run.sh: Fix URLs. --- client/mysqltest.c | 7 ++++--- mysql-test/README | 2 +- mysql-test/mysql-test-run.sh | 4 ++-- mysql-test/r/mysqltest.result | 2 ++ 4 files changed, 9 insertions(+), 6 deletions(-) diff --git a/client/mysqltest.c b/client/mysqltest.c index 83be283a050..a525adfd819 100644 --- a/client/mysqltest.c +++ b/client/mysqltest.c @@ -1550,18 +1550,19 @@ int do_sleep(struct st_query *query, my_bool real_sleep) char *p= query->first_argument; char *sleep_start, *sleep_end= query->end; double sleep_val; + char *cmd = (real_sleep ? "real_sleep" : "sleep"); while (my_isspace(charset_info, *p)) p++; if (!*p) - die("Missing argument to sleep"); + die("Missing argument to %s", cmd); sleep_start= p; /* Check that arg starts with a digit, not handled by my_strtod */ if (!my_isdigit(charset_info, *sleep_start)) - die("Invalid argument to sleep \"%s\"", query->first_argument); + die("Invalid argument to %s \"%s\"", cmd, query->first_argument); sleep_val= my_strtod(sleep_start, &sleep_end, &error); if (error) - die("Invalid argument to sleep \"%s\"", query->first_argument); + die("Invalid argument to %s \"%s\"", cmd, query->first_argument); /* Fixed sleep time selected by --sleep option */ if (opt_sleep && !real_sleep) diff --git a/mysql-test/README b/mysql-test/README index 10d64784ed4..0e20ca884a3 100644 --- a/mysql-test/README +++ b/mysql-test/README @@ -21,7 +21,7 @@ conflict with it. All tests must pass. If one or more of them fail on your system, please read the following manual section of how to report the problem: -http://dev.mysql.com/doc/mysql/en/MySQL_test_suite.html +http://dev.mysql.com/doc/mysql/en/mysql-test-suite.html You can create your own test cases. To create a test case: diff --git a/mysql-test/mysql-test-run.sh b/mysql-test/mysql-test-run.sh index 9fcdacb22cb..b9512f7dd79 100644 --- a/mysql-test/mysql-test-run.sh +++ b/mysql-test/mysql-test-run.sh @@ -789,7 +789,7 @@ show_failed_diff () $DIFF -c $result_file $reject_file echo "-------------------------------------------------------" echo "Please follow the instructions outlined at" - echo "http://www.mysql.com/doc/en/Reporting_mysqltest_bugs.html" + echo "http://dev.mysql.com/doc/mysql/en/reporting-mysqltest-bugs.html" echo "to find the reason to this problem and how to report this." echo "" fi @@ -884,7 +884,7 @@ report_stats () { $ECHO "The log files in $MY_LOG_DIR may give you some hint" $ECHO "of what when wrong." $ECHO "If you want to report this error, please read first the documentation at" - $ECHO "http://www.mysql.com/doc/en/MySQL_test_suite.html" + $ECHO "http://dev.mysql.com/doc/mysql/en/mysql-test-suite.html" fi if test -z "$USE_RUNNING_SERVER" diff --git a/mysql-test/r/mysqltest.result b/mysql-test/r/mysqltest.result index 0e3d3812781..990f04e5ba9 100644 --- a/mysql-test/r/mysqltest.result +++ b/mysql-test/r/mysqltest.result @@ -280,7 +280,9 @@ here is the sourced script In loop here is the sourced script mysqltest: At line 1: Missing argument to sleep +mysqltest: At line 1: Missing argument to real_sleep mysqltest: At line 1: Invalid argument to sleep "abc" +mysqltest: At line 1: Invalid argument to real_sleep "abc" 1 2 101 From bf912125a39edbad5f66f8cd53950ae8c43c36fd Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 28 Feb 2006 17:54:11 -0600 Subject: [PATCH 47/52] mysqltest.test: Add real_sleep tests. mysql-test/t/mysqltest.test: Add real_sleep tests. --- mysql-test/t/mysqltest.test | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/mysql-test/t/mysqltest.test b/mysql-test/t/mysqltest.test index 7ed204fc6d3..f5c6a7617c5 100644 --- a/mysql-test/t/mysqltest.test +++ b/mysql-test/t/mysqltest.test @@ -605,10 +605,14 @@ real_sleep 1; # Missing parameter --error 1 --exec echo "sleep ;" | $MYSQL_TEST 2>&1 +--error 1 +--exec echo "real_sleep ;" | $MYSQL_TEST 2>&1 # Illegal parameter --error 1 --exec echo "sleep abc;" | $MYSQL_TEST 2>&1 +--error 1 +--exec echo "real_sleep abc;" | $MYSQL_TEST 2>&1 # ---------------------------------------------------------------------------- # Test inc From 6e0d2e41cccb9223b50212dfecf56e43f19df11e Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 1 Mar 2006 12:21:44 +0100 Subject: [PATCH 48/52] mysql-test/mysql-test-run.sh : Add a "--comment=" option, to get it logged when the test is run. mysql-test/mysql-test-run.sh: Add a "--comment=" option, to get it logged when the test is run. The purpose is to allow a better analysis when generating the status page ("gen-build-status-page"). See "Do-compile" for how it is used. --- mysql-test/mysql-test-run.sh | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/mysql-test/mysql-test-run.sh b/mysql-test/mysql-test-run.sh index 3488c308536..5853ffa201c 100644 --- a/mysql-test/mysql-test-run.sh +++ b/mysql-test/mysql-test-run.sh @@ -410,6 +410,13 @@ while test $# -gt 0; do --fast) FAST_START=1 ;; + --comment=*) + TMP=`$ECHO "$1" | $SED -e "s;--comment=;;"` + echo + echo '############################################' + echo "# $TMP" + echo '############################################' + ;; -- ) shift; break ;; --* ) $ECHO "Unrecognized option: $1"; exit 1 ;; * ) break ;; From ca3dd7f01aae783c2f8efea6adbf446e2c410c42 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 1 Mar 2006 13:15:37 +0100 Subject: [PATCH 49/52] mysql-test/mysql-test-run.pl : Add a "--comment=" option (backport from 5.1). mysql-test/mysql-test-run.pl: Add a "--comment=" option (backport from 5.1). Its sole purpose is to get logged, so that test evaluation gets easier. See "Do-compile" for how it is called, and "gen-build-status-page" for its effect. --- mysql-test/mysql-test-run.pl | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl index addacab8f9a..09c3dff9749 100755 --- a/mysql-test/mysql-test-run.pl +++ b/mysql-test/mysql-test-run.pl @@ -184,6 +184,7 @@ our $opt_big_test= 0; # Send --big-test to mysqltest our @opt_extra_mysqld_opt; +our $opt_comment; our $opt_compress; our $opt_current_test; our $opt_ddd; @@ -536,6 +537,7 @@ sub command_line_setup () { # Misc 'big-test' => \$opt_big_test, + 'comment=s' => \$opt_comment, 'compress' => \$opt_compress, 'debug' => \$opt_debug, 'fast' => \$opt_fast, @@ -571,6 +573,14 @@ sub command_line_setup () { usage(""); } + if ( $opt_comment ) + { + print "\n"; + print '#' x 78, "\n"; + print "# $opt_comment\n"; + print '#' x 78, "\n\n"; + } + foreach my $arg ( @ARGV ) { if ( $arg =~ /^--skip-/ ) @@ -2398,6 +2408,7 @@ Misc options verbose Verbose output from this script script-debug Debug this script itself + comment=STR Write STR to the output compress Use the compressed protocol between client and server timer Show test case execution time start-and-exit Only initiate and start the "mysqld" servers, use the startup From 7526342706bb18601e4a1e19c75fbbd95be210de Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 1 Mar 2006 17:37:07 -0600 Subject: [PATCH 50/52] README: Revise mysql-test README. mysql-test/README: Revise mysql-test README. --- mysql-test/README | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/mysql-test/README b/mysql-test/README index 6ad97adbd2b..0e20ca884a3 100644 --- a/mysql-test/README +++ b/mysql-test/README @@ -1,6 +1,19 @@ This directory contains a test suite for mysql daemon. To run the currently existing test cases, simply execute ./mysql-test-run in this directory. It will fire up the newly built mysqld and test it. + +If you want to run a test with a running MySQL server use the --extern +option to mysql-test-run. Please note that in this mode the test suite +expects user to specify test names to run. Otherwise it falls back to the +normal "non-extern" behaviour. The reason is that some tests +could not run with external server. Here is the sample command +to test "alias" and "analyze" tests on external server: + +mysql-test-run --extern alias analyze + +To match your setup you might also need to provide --socket, --user and +other relevant options. + Note that you do not have to have to do make install, and you could actually have a co-existing MySQL installation - the tests will not conflict with it. @@ -8,13 +21,12 @@ conflict with it. All tests must pass. If one or more of them fail on your system, please read the following manual section of how to report the problem: -http://dev.mysql.com/doc/mysql/en/MySQL_test_suite.html +http://dev.mysql.com/doc/mysql/en/mysql-test-suite.html You can create your own test cases. To create a test case: - cd t - vi test_case_name.test + xemacs t/test_case_name.test in the file, put a set of SQL commands that will create some tables, load test data, run some queries to manipulate it. From 79faaddce79e91d5ed1e88e05d3c337de77d4087 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 1 Mar 2006 17:55:10 -0600 Subject: [PATCH 51/52] README.gcov: Revise README.gcov. mysql-test/README.gcov: Revise README.gcov. --- mysql-test/README.gcov | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/mysql-test/README.gcov b/mysql-test/README.gcov index 83ddd6df2e1..6d2852e8ca0 100644 --- a/mysql-test/README.gcov +++ b/mysql-test/README.gcov @@ -1,11 +1,13 @@ To be able to see the level of coverage with the current test suite, do the following: - - make sure gcov is installed - - compile with BUILD/compile-pentium-gcov ( if your machine is not pentium, hack -this script, or just live with the pentium-specific stuff) - - ./mysql-test-run -gcov - - to see the level of coverage for a given source file: + - Make sure gcov is installed + - Compile the MySQL distribution with BUILD/compile-pentium-gcov (if your + machine does not have a pentium CPU, hack this script, or just live with + the pentium-specific stuff) + - In the mysql-test directory, run this command: ./mysql-test-run -gcov + - To see the level of coverage for a given source file: grep source_file_name /tmp/gcov.out - - to see which lines are not yet covered, look at source_file_name.gcov in the source tree. Then think hard about a test case that will cover those -lines, and write one! + - To see which lines are not yet covered, look at source_file_name.gcov in + the source tree. Then think hard about a test case that will cover those + lines, and write one! From aa9a497d7ad44dbeda7100b71916d3af9bfd5c0c Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 1 Mar 2006 18:37:41 -0600 Subject: [PATCH 52/52] README: revise README. mysql-test/README: revise README. --- mysql-test/README | 60 ++++++++++++++++++++++++++--------------------- 1 file changed, 33 insertions(+), 27 deletions(-) diff --git a/mysql-test/README b/mysql-test/README index 0e20ca884a3..77b398ebf39 100644 --- a/mysql-test/README +++ b/mysql-test/README @@ -1,45 +1,51 @@ -This directory contains a test suite for mysql daemon. To run +This directory contains a test suite for the MySQL daemon. To run the currently existing test cases, simply execute ./mysql-test-run in this directory. It will fire up the newly built mysqld and test it. -If you want to run a test with a running MySQL server use the --extern -option to mysql-test-run. Please note that in this mode the test suite -expects user to specify test names to run. Otherwise it falls back to the -normal "non-extern" behaviour. The reason is that some tests -could not run with external server. Here is the sample command -to test "alias" and "analyze" tests on external server: - -mysql-test-run --extern alias analyze - -To match your setup you might also need to provide --socket, --user and -other relevant options. - -Note that you do not have to have to do make install, and you could -actually have a co-existing MySQL installation - the tests will not +Note that you do not have to have to do "make install", and you could +actually have a co-existing MySQL installation. The tests will not conflict with it. All tests must pass. If one or more of them fail on your system, please -read the following manual section of how to report the problem: +read the following manual section for instructions on how to report the +problem: http://dev.mysql.com/doc/mysql/en/mysql-test-suite.html +If you want to use an already running MySQL server for specific tests, +use the --extern option to mysql-test-run. Please note that in this mode, +the test suite expects you to provide the names of the tests to run. +For example, here is the command to run the "alias" and "analyze" tests +with an external server: -You can create your own test cases. To create a test case: +mysql-test-run --extern alias analyze + +To match your setup, you might also need to provide --socket, --user, and +other relevant options. + +With no test cases named on the command line, mysql-test-run falls back +to the normal "non-extern" behavior. The reason for this is that some +tests cannot run with an external server. + + +You can create your own test cases. To create a test case, create a new +file in the t subdirectory using a text editor. The file should have a .test +extension. For example: xemacs t/test_case_name.test - in the file, put a set of SQL commands that will create some tables, - load test data, run some queries to manipulate it. + In the file, put a set of SQL statements that create some tables, + load test data, and run some queries to manipulate it. - We would appreciate if the test tables were called t1, t2, t3 ... (to not + We would appreciate it if you name your test tables t1, t2, t3 ... (to not conflict too much with existing tables). Your test should begin by dropping the tables you are going to create and - end by dropping them again. This will ensure that one can run the test - over and over again. + end by dropping them again. This ensures that you can run the test over + and over again. If you are using mysqltest commands (like result file names) in your - test case you should do create the result file as follows: + test case, you should create the result file as follows: mysql-test-run --record test_case_name @@ -47,8 +53,8 @@ You can create your own test cases. To create a test case: mysqltest --record < t/test_case_name.test - If you only have a simple test cases consistent of SQL commands and comments - you can create the test case one of the following ways: + If you only have a simple test cases consisting of SQL statements and + comments, you can create the test case in one of the following ways: mysql-test-run --record test_case_name @@ -57,11 +63,11 @@ You can create your own test cases. To create a test case: mysqltest --record --record-file=r/test_case_name.result < t/test_case_name.test When this is done, take a look at r/test_case_name.result - - If the result is wrong, you have found a bug; In this case you should + - If the result is incorrect, you have found a bug. In this case, you should edit the test result to the correct results so that we can verify that the bug is corrected in future releases. To submit your test case, put your .test file and .result file(s) into a tar.gz archive, add a README that explains the problem, ftp the -archive to ftp://support.mysql.com/pub/mysql/secret/ and send a mail +archive to ftp://support.mysql.com/pub/mysql/secret/ and send a mail to bugs@lists.mysql.com