From 125df80e9be90a749be43a1c05601f1f46a9586b Mon Sep 17 00:00:00 2001 From: "mskold/marty@mysql.com/linux.site" <> Date: Tue, 12 Sep 2006 16:04:52 +0200 Subject: [PATCH 1/5] Bug #21378 Alter table from X storage engine to NDB could cause data loss: Added warning if local table shadows ndb table --- mysql-test/r/ndb_multi.result | 32 ++++++++++++++++++++++++++++++++ mysql-test/t/ndb_multi.test | 22 ++++++++++++++++++++++ sql/ha_ndbcluster.cc | 17 +++++++++++++---- 3 files changed, 67 insertions(+), 4 deletions(-) diff --git a/mysql-test/r/ndb_multi.result b/mysql-test/r/ndb_multi.result index bd3af223a65..068d86b83e2 100644 --- a/mysql-test/r/ndb_multi.result +++ b/mysql-test/r/ndb_multi.result @@ -69,3 +69,35 @@ t3 t4 drop table t1, t2, t3, t4; drop table t1, t3, t4; +create table t1(c1 int key)ENGINE=MyISAM; +insert into t1 values(1),(3),(5); +select * from t1 order by c1; +c1 +1 +3 +5 +create table t1(c1 int key)ENGINE=MyISAM; +insert into t1 values(100),(344),(533); +select * from t1 order by c1; +c1 +100 +344 +533 +alter table t1 engine=ndb; +show tables; +Tables_in_test +t1 +Warnings: +Warning 1050 Local table t1 shadows cluster table +select * from t1 order by c1; +c1 +100 +344 +533 +drop table t1; +select * from t1 order by c1; +c1 +1 +3 +5 +drop table t1; diff --git a/mysql-test/t/ndb_multi.test b/mysql-test/t/ndb_multi.test index 1183f2b283f..ce8ce420793 100644 --- a/mysql-test/t/ndb_multi.test +++ b/mysql-test/t/ndb_multi.test @@ -69,4 +69,26 @@ drop table t1, t2, t3, t4; connection server2; drop table t1, t3, t4; +# bug#21378 +connection server1; +create table t1(c1 int key)ENGINE=MyISAM; +insert into t1 values(1),(3),(5); +select * from t1 order by c1; + +connection server2; +create table t1(c1 int key)ENGINE=MyISAM; +insert into t1 values(100),(344),(533); +select * from t1 order by c1; + +connection server1; +alter table t1 engine=ndb; + +connection server2; +show tables; +select * from t1 order by c1; +drop table t1; + +connection server1; +select * from t1 order by c1; +drop table t1; # End of 4.1 tests diff --git a/sql/ha_ndbcluster.cc b/sql/ha_ndbcluster.cc index e4c20de2390..987c96aed37 100644 --- a/sql/ha_ndbcluster.cc +++ b/sql/ha_ndbcluster.cc @@ -4715,16 +4715,16 @@ int ndbcluster_find_files(THD *thd,const char *db,const char *path, List delete_list; while ((file_name=it++)) { + bool file_on_disk= false; DBUG_PRINT("info", ("%s", file_name)); if (hash_search(&ndb_tables, file_name, strlen(file_name))) { DBUG_PRINT("info", ("%s existed in NDB _and_ on disk ", file_name)); // File existed in NDB and as frm file, put in ok_tables list - my_hash_insert(&ok_tables, (byte*)file_name); - continue; + file_on_disk= true; } - // File is not in NDB, check for .ndb file with this name + // Check for .ndb file with this name (void)strxnmov(name, FN_REFLEN, mysql_data_home,"/",db,"/",file_name,ha_ndb_ext,NullS); DBUG_PRINT("info", ("Check access for %s", name)); @@ -4732,9 +4732,18 @@ int ndbcluster_find_files(THD *thd,const char *db,const char *path, { DBUG_PRINT("info", ("%s did not exist on disk", name)); // .ndb file did not exist on disk, another table type + if (file_on_disk) + push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN, + ER_TABLE_EXISTS_ERROR, + "Local table %s.%s shadows ndb table", + db, file_name); + continue; + } + if (file_on_disk) + { + my_hash_insert(&ok_tables, (byte*)file_name); continue; } - DBUG_PRINT("info", ("%s existed on disk", name)); // The .ndb file exists on disk, but it's not in list of tables in ndb // Verify that handler agrees table is gone. From 4979d1526cb1076971c1a7b342870e5cf2e10d36 Mon Sep 17 00:00:00 2001 From: "mskold/marty@mysql.com/linux.site" <> Date: Wed, 13 Sep 2006 18:49:05 +0200 Subject: [PATCH 2/5] Bug #21378 Alter table from X storage engine to NDB could cause data loss: skip autodiscover of local tables --- sql/ha_ndbcluster.cc | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/sql/ha_ndbcluster.cc b/sql/ha_ndbcluster.cc index 987c96aed37..7398c15a9c8 100644 --- a/sql/ha_ndbcluster.cc +++ b/sql/ha_ndbcluster.cc @@ -4720,7 +4720,6 @@ int ndbcluster_find_files(THD *thd,const char *db,const char *path, if (hash_search(&ndb_tables, file_name, strlen(file_name))) { DBUG_PRINT("info", ("%s existed in NDB _and_ on disk ", file_name)); - // File existed in NDB and as frm file, put in ok_tables list file_on_disk= true; } @@ -4733,14 +4732,21 @@ int ndbcluster_find_files(THD *thd,const char *db,const char *path, DBUG_PRINT("info", ("%s did not exist on disk", name)); // .ndb file did not exist on disk, another table type if (file_on_disk) + { + // Ignore this ndb table + gptr record= hash_search(&ndb_tables, file_name, strlen(file_name)); + DBUG_ASSERT(record); + hash_delete(&ndb_tables, record); push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN, ER_TABLE_EXISTS_ERROR, "Local table %s.%s shadows ndb table", db, file_name); + } continue; } if (file_on_disk) { + // File existed in NDB and as frm file, put in ok_tables list my_hash_insert(&ok_tables, (byte*)file_name); continue; } From 4139849910dc5d2287252fce52ebd962701c10dc Mon Sep 17 00:00:00 2001 From: "mskold/marty@mysql.com/linux.site" <> Date: Wed, 13 Sep 2006 19:56:02 +0200 Subject: [PATCH 3/5] Bug #21378 Alter table from X storage engine to NDB could cause data loss: updated results --- mysql-test/r/ndb_multi.result | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mysql-test/r/ndb_multi.result b/mysql-test/r/ndb_multi.result index 068d86b83e2..351cd7e35c5 100644 --- a/mysql-test/r/ndb_multi.result +++ b/mysql-test/r/ndb_multi.result @@ -88,7 +88,7 @@ show tables; Tables_in_test t1 Warnings: -Warning 1050 Local table t1 shadows cluster table +Warning 1050 Local table test.t1 shadows ndb table select * from t1 order by c1; c1 100 From 42d64e427569b962057b4db2c92327924ac18c24 Mon Sep 17 00:00:00 2001 From: "mskold/marty@mysql.com/linux.site" <> Date: Thu, 21 Sep 2006 16:49:07 +0200 Subject: [PATCH 4/5] Bug #21072 Duplicate key error in NDB references wrong key: use MAX_KEY to signal unknown key --- mysql-test/r/ndb_charset.result | 4 ++-- mysql-test/r/ndb_index_unique.result | 10 +++++----- mysql-test/r/ndb_update.result | 2 +- sql/ha_ndbcluster.cc | 9 ++++++++- sql/handler.cc | 20 +++++++++++++++----- 5 files changed, 31 insertions(+), 14 deletions(-) diff --git a/mysql-test/r/ndb_charset.result b/mysql-test/r/ndb_charset.result index b8d881fca83..b014050b69f 100644 --- a/mysql-test/r/ndb_charset.result +++ b/mysql-test/r/ndb_charset.result @@ -78,9 +78,9 @@ unique key(a) ) engine=ndb; insert into t1 values(1, 'aAa'); insert into t1 values(2, 'aaa'); -ERROR 23000: Duplicate entry '2' for key 1 +ERROR 23000: Duplicate entry '' for key 0 insert into t1 values(3, 'AAA'); -ERROR 23000: Duplicate entry '3' for key 1 +ERROR 23000: Duplicate entry '' for key 0 select * from t1 order by p; p a 1 aAa diff --git a/mysql-test/r/ndb_index_unique.result b/mysql-test/r/ndb_index_unique.result index 598b9dcccf7..f9fb6f89aa2 100644 --- a/mysql-test/r/ndb_index_unique.result +++ b/mysql-test/r/ndb_index_unique.result @@ -22,7 +22,7 @@ select * from t1 where b = 4 order by a; a b c 3 4 6 insert into t1 values(8, 2, 3); -ERROR 23000: Duplicate entry '8' for key 1 +ERROR 23000: Duplicate entry '' for key 0 select * from t1 order by a; a b c 1 2 3 @@ -89,7 +89,7 @@ a b c 1 1 1 4 4 NULL insert into t1 values(5,1,1); -ERROR 23000: Duplicate entry '5' for key 1 +ERROR 23000: Duplicate entry '' for key 0 drop table t1; CREATE TABLE t2 ( a int unsigned NOT NULL PRIMARY KEY, @@ -112,7 +112,7 @@ select * from t2 where b = 4 order by a; a b c 3 4 6 insert into t2 values(8, 2, 3); -ERROR 23000: Duplicate entry '8' for key 1 +ERROR 23000: Duplicate entry '' for key 0 select * from t2 order by a; a b c 1 2 3 @@ -177,7 +177,7 @@ pk a 3 NULL 4 4 insert into t1 values (5,0); -ERROR 23000: Duplicate entry '5' for key 1 +ERROR 23000: Duplicate entry '' for key 0 select * from t1 order by pk; pk a -1 NULL @@ -210,7 +210,7 @@ pk a b c 0 NULL 18 NULL 1 3 19 abc insert into t2 values(2,3,19,'abc'); -ERROR 23000: Duplicate entry '2' for key 1 +ERROR 23000: Duplicate entry '' for key 0 select * from t2 order by pk; pk a b c -1 1 17 NULL diff --git a/mysql-test/r/ndb_update.result b/mysql-test/r/ndb_update.result index c2247564e65..164d1bd700c 100644 --- a/mysql-test/r/ndb_update.result +++ b/mysql-test/r/ndb_update.result @@ -18,7 +18,7 @@ pk1 b c 2 2 2 4 1 1 UPDATE t1 set pk1 = 1, c = 2 where pk1 = 4; -ERROR 23000: Duplicate entry '1' for key 1 +ERROR 23000: Duplicate entry '' for key 0 select * from t1 order by pk1; pk1 b c 0 0 0 diff --git a/sql/ha_ndbcluster.cc b/sql/ha_ndbcluster.cc index 7398c15a9c8..240030a5a5f 100644 --- a/sql/ha_ndbcluster.cc +++ b/sql/ha_ndbcluster.cc @@ -454,7 +454,14 @@ int ha_ndbcluster::ndb_err(NdbConnection *trans) if (res == HA_ERR_FOUND_DUPP_KEY) { if (m_rows_to_insert == 1) - m_dupkey= table->primary_key; + { + /* + We can only distinguish between primary and non-primary + violations here, so we need to return MAX_KEY for non-primary + to signal that key is unknown + */ + m_dupkey= err.code == 630 ? table->primary_key : MAX_KEY; + } else { /* We are batching inserts, offending key is not available */ diff --git a/sql/handler.cc b/sql/handler.cc index c05fc8ba0e7..be8d2e2aed3 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -1102,12 +1102,22 @@ void handler::print_error(int error, myf errflag) /* Write the dupplicated key in the error message */ char key[MAX_KEY_LENGTH]; String str(key,sizeof(key),system_charset_info); - key_unpack(&str,table,(uint) key_nr); - uint max_length=MYSQL_ERRMSG_SIZE-(uint) strlen(ER(ER_DUP_ENTRY)); - if (str.length() >= max_length) + + if (key_nr == MAX_KEY) { - str.length(max_length-4); - str.append("..."); + /* Key is unknown */ + str.length(0); + key_nr= -1; + } + else + { + key_unpack(&str,table,(uint) key_nr); + uint max_length=MYSQL_ERRMSG_SIZE-(uint) strlen(ER(ER_DUP_ENTRY)); + if (str.length() >= max_length) + { + str.length(max_length-4); + str.append("..."); + } } my_error(ER_DUP_ENTRY,MYF(0),str.c_ptr(),key_nr+1); DBUG_VOID_RETURN; From c854ecebf9efde74535f7756678f02d7beb95449 Mon Sep 17 00:00:00 2001 From: "mskold/marty@mysql.com/linux.site" <> Date: Thu, 21 Sep 2006 16:54:54 +0200 Subject: [PATCH 5/5] Bug #21072 Duplicate key error in NDB references wrong key: wrong indent for code block --- sql/handler.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sql/handler.cc b/sql/handler.cc index be8d2e2aed3..40f2af75c2f 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -1114,10 +1114,10 @@ void handler::print_error(int error, myf errflag) key_unpack(&str,table,(uint) key_nr); uint max_length=MYSQL_ERRMSG_SIZE-(uint) strlen(ER(ER_DUP_ENTRY)); if (str.length() >= max_length) - { + { str.length(max_length-4); str.append("..."); - } + } } my_error(ER_DUP_ENTRY,MYF(0),str.c_ptr(),key_nr+1); DBUG_VOID_RETURN;