=== modified file 'mysql-test/suite/ndb/r/ndb_database.result' --- mysql-test/suite/ndb/r/ndb_database.result 2007-06-27 12:28:02 +0000 +++ mysql-test/suite/ndb/r/ndb_database.result 2010-07-06 16:28:30 +0000 @@ -11,3 +11,45 @@ use mysqltest; show tables; Tables_in_mysqltest drop database mysqltest; +create database newdb; +create table newdb.t1 (a int primary key) engine=myisam; +create table newdb.t1 (a int primary key, +b1 blob, +b2 blob, +b3 blob, +b4 blob, +b5 blob, +b6 blob, +b7 blob, +b8 blob, +b9 blob, +b10 blob, +b11 blob, +b12 blob, +b13 blob, +b14 blob, +b15 blob, +b16 blob, +b17 blob, +b18 blob, +b19 blob, +b20 blob, +b21 blob, +b22 blob, +b23 blob, +b24 blob, +b25 blob, +b26 blob, +b27 blob, +b28 blob, +b29 blob) engine = ndb; +drop database newdb; +create database newdb; +use newdb; +show tables; +Tables_in_newdb +create table newdb.t1(a int primary key) engine=ndb; +show tables; +Tables_in_newdb +t1 +drop database newdb; === modified file 'mysql-test/suite/ndb/t/ndb_database.test' --- mysql-test/suite/ndb/t/ndb_database.test 2007-07-04 20:38:53 +0000 +++ mysql-test/suite/ndb/t/ndb_database.test 2010-07-06 16:27:01 +0000 @@ -22,3 +22,66 @@ show tables; drop database mysqltest; # End of 4.1 tests + + + +# +# bug# 54788 DROP DATABASE can remove hidden blob tables without removing parent tables +# +# Dropping a database on a server where Ndb tables with Blobs were +# 'occluded' by a local table can result in Blob part tables being +# deleted, but the main table not being deleted. +# +--connection server1 +# Create database with occluding table t1 +create database newdb; +create table newdb.t1 (a int primary key) engine=myisam; + +--connection server2 +# Create Ndb table with Blobs +# Lots of Blobs to increase prob. that Ndb-list-objects returns a +# Blob part table before the main table. +create table newdb.t1 (a int primary key, + b1 blob, + b2 blob, + b3 blob, + b4 blob, + b5 blob, + b6 blob, + b7 blob, + b8 blob, + b9 blob, + b10 blob, + b11 blob, + b12 blob, + b13 blob, + b14 blob, + b15 blob, + b16 blob, + b17 blob, + b18 blob, + b19 blob, + b20 blob, + b21 blob, + b22 blob, + b23 blob, + b24 blob, + b25 blob, + b26 blob, + b27 blob, + b28 blob, + b29 blob) engine = ndb; + +--connection server1 +drop database newdb; + +--connection server2 +# Now check that the table is gone +create database newdb; +use newdb; +show tables; + +# Check that we can reuse the table name etc. +create table newdb.t1(a int primary key) engine=ndb; +show tables; +drop database newdb; \ No newline at end of file === modified file 'sql/ha_ndbcluster.cc' --- sql/ha_ndbcluster.cc 2010-02-09 13:15:32 +0000 +++ sql/ha_ndbcluster.cc 2010-07-06 15:18:45 +0000 @@ -7290,7 +7290,11 @@ int ndbcluster_drop_database_impl(THD *t DBUG_PRINT("info", ("Found %s/%s in NDB", elmt.database, elmt.name)); // Add only tables that belongs to db - if (my_strcasecmp(system_charset_info, elmt.database, dbname)) + // Ignore Blob part tables - they are deleted when their table + // is deleted. + if (my_strcasecmp(system_charset_info, elmt.database, dbname) || + IS_NDB_BLOB_PREFIX(elmt.name)) + // TODO : Should we also ignore temporary tables here? continue; DBUG_PRINT("info", ("%s must be dropped", elmt.name)); drop_list.push_back(thd->strdup(elmt.name)); === modified file 'storage/ndb/src/ndbapi/NdbDictionary.cpp' --- storage/ndb/src/ndbapi/NdbDictionary.cpp 2010-03-01 13:15:18 +0000 +++ storage/ndb/src/ndbapi/NdbDictionary.cpp 2010-07-06 15:26:12 +0000 @@ -1649,22 +1649,54 @@ int NdbDictionary::Dictionary::createTable(const Table & t) { DBUG_ENTER("NdbDictionary::Dictionary::createTable"); - DBUG_RETURN(m_impl.createTable(NdbTableImpl::getImpl(t))); + if (likely(! is_ndb_blob_table(t.getName()))) + { + DBUG_RETURN(m_impl.createTable(NdbTableImpl::getImpl(t))); + } + else + { + /* 4307 : Invalid table name */ + DBUG_RETURN(4307); + } } int NdbDictionary::Dictionary::dropTable(Table & t){ - return m_impl.dropTable(NdbTableImpl::getImpl(t)); + if (likely(! is_ndb_blob_table(t.getName()))) + { + return m_impl.dropTable(NdbTableImpl::getImpl(t)); + } + else + { + /* 4249 : Invalid table */ + return 4249; + } } int NdbDictionary::Dictionary::dropTableGlobal(const Table & t){ - return m_impl.dropTableGlobal(NdbTableImpl::getImpl(t)); + if (likely(! is_ndb_blob_table(t.getName()))) + { + return m_impl.dropTableGlobal(NdbTableImpl::getImpl(t)); + } + else + { + /* 4249 : Invalid table */ + return 4249; + } } int NdbDictionary::Dictionary::dropTable(const char * name){ - return m_impl.dropTable(name); + if (likely(! is_ndb_blob_table(name))) + { + return m_impl.dropTable(name); + } + else + { + /* 4249 : Invalid table */ + return 4249; + } } bool === modified file 'storage/ndb/src/ndbapi/NdbDictionaryImpl.cpp' --- storage/ndb/src/ndbapi/NdbDictionaryImpl.cpp 2010-03-01 13:15:18 +0000 +++ storage/ndb/src/ndbapi/NdbDictionaryImpl.cpp 2010-07-06 15:27:46 +0000 @@ -2601,13 +2601,24 @@ NdbDictInterface::compChangeMask(const N DBUG_ENTER("compChangeMask"); bool found_varpart; change_mask= 0; + Uint32 old_sz= old_impl.m_columns.size(); + Uint32 sz= impl.m_columns.size(); /* These are the supported properties that may be altered. */ DBUG_PRINT("info", ("old_impl.m_internalName='%s' impl.m_internalName='%s'", old_impl.m_internalName.c_str(), impl.m_internalName.c_str())); if(impl.m_internalName != old_impl.m_internalName) + { + if (unlikely(is_ndb_blob_table(old_impl.m_externalName.c_str()) || + is_ndb_blob_table(impl.m_externalName.c_str()))) + { + /* Attempt to alter to/from Blob part table name */ + DBUG_PRINT("info", ("Attempt to alter to/from Blob part table name")); + goto invalid_alter_table; + } AlterTableReq::setNameFlag(change_mask, true); + } if(!impl.m_frm.equal(old_impl.m_frm)) AlterTableReq::setFrmFlag(change_mask, true); if(!impl.m_fd.equal(old_impl.m_fd)) @@ -2620,8 +2631,6 @@ NdbDictInterface::compChangeMask(const N AlterTableReq::setTsFlag(change_mask, true); /* No other property can be changed in alter table. */ - Uint32 old_sz= old_impl.m_columns.size(); - Uint32 sz= impl.m_columns.size(); if(impl.m_fragmentCount != old_impl.m_fragmentCount || impl.m_logging != old_impl.m_logging || impl.m_temporary != old_impl.m_temporary || === modified file 'storage/ndb/src/ndbapi/NdbDictionaryImpl.hpp' --- storage/ndb/src/ndbapi/NdbDictionaryImpl.hpp 2010-03-01 13:15:18 +0000 +++ storage/ndb/src/ndbapi/NdbDictionaryImpl.hpp 2010-07-06 15:18:45 +0000 @@ -1139,6 +1139,21 @@ inline NdbTableImpl * NdbDictionaryImpl::getTableGlobal(const char * table_name) { + if (unlikely(strchr(table_name, '$') != 0)) { + if (is_ndb_blob_table(table_name)) + { + /* Could attempt to get the Blob table here, but + * instead we will generate an error. + * The non-global getTable() calls can fetch Blob + * tables correctly if necessary. + * + * 4307 Invalid Table name + */ + m_error.code = 4307; + return NULL; + } + } + const BaseString internal_tabname(m_ndb.internalize_table_name(table_name)); return fetchGlobalTableImplRef(InitTable(internal_tabname)); }