summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorunknown <mskold@mysql.com>2006-05-31 10:28:42 +0200
committerunknown <mskold@mysql.com>2006-05-31 10:28:42 +0200
commitbf6d480aab57f01be4749eeb73cb5ea6be552e06 (patch)
tree5ce2855d1defbd1d9471933ef5a460da4755934c
parentd4aa0b8d92405de8776582117de3faba2ec7a6e6 (diff)
downloadmariadb-git-bf6d480aab57f01be4749eeb73cb5ea6be552e06.tar.gz
Bug #16997 Table rename that changes database does not rename indexes: Moved index tables to system database
-rw-r--r--mysql-test/r/ndb_rename.result24
-rw-r--r--mysql-test/t/ndb_rename.test36
-rw-r--r--sql/ha_ndbcluster.cc35
-rw-r--r--storage/ndb/include/ndbapi/Ndb.hpp5
-rw-r--r--storage/ndb/include/ndbapi/NdbDictionary.hpp10
-rw-r--r--storage/ndb/src/ndbapi/Ndb.cpp33
-rw-r--r--storage/ndb/src/ndbapi/NdbDictionary.cpp8
-rw-r--r--storage/ndb/src/ndbapi/NdbDictionaryImpl.cpp14
-rw-r--r--storage/ndb/src/ndbapi/NdbDictionaryImpl.hpp55
-rw-r--r--storage/ndb/src/ndbapi/NdbImpl.hpp2
-rw-r--r--storage/ndb/src/ndbapi/Ndbinit.cpp3
11 files changed, 220 insertions, 5 deletions
diff --git a/mysql-test/r/ndb_rename.result b/mysql-test/r/ndb_rename.result
new file mode 100644
index 00000000000..2cc2dfb3ff1
--- /dev/null
+++ b/mysql-test/r/ndb_rename.result
@@ -0,0 +1,24 @@
+DROP TABLE IF EXISTS t1,t2;
+drop database if exists mysqltest;
+CREATE TABLE t1 (
+pk1 INT NOT NULL PRIMARY KEY,
+attr1 INT NOT NULL,
+attr2 INT,
+attr3 VARCHAR(10),
+INDEX i1(attr1)
+) ENGINE=ndbcluster;
+INSERT INTO t1 VALUES (0,0,0,"zero"),(1,1,1,"one"),(2,2,2,"two");
+SELECT * FROM t1 WHERE attr1 = 1;
+pk1 attr1 attr2 attr3
+1 1 1 one
+alter table t1 rename t2;
+SELECT * FROM t2 WHERE attr1 = 1;
+pk1 attr1 attr2 attr3
+1 1 1 one
+create database ndbtest;
+alter table t2 rename ndbtest.t2;
+SELECT * FROM ndbtest.t2 WHERE attr1 = 1;
+pk1 attr1 attr2 attr3
+1 1 1 one
+drop table ndbtest.t2;
+drop database ndbtest;
diff --git a/mysql-test/t/ndb_rename.test b/mysql-test/t/ndb_rename.test
new file mode 100644
index 00000000000..7f9fd0e6984
--- /dev/null
+++ b/mysql-test/t/ndb_rename.test
@@ -0,0 +1,36 @@
+-- source include/have_ndb.inc
+-- source include/not_embedded.inc
+
+--disable_warnings
+DROP TABLE IF EXISTS t1,t2;
+drop database if exists mysqltest;
+--enable_warnings
+
+#
+# Table rename tests
+#
+
+#
+# Create a normal table with primary key
+#
+CREATE TABLE t1 (
+ pk1 INT NOT NULL PRIMARY KEY,
+ attr1 INT NOT NULL,
+ attr2 INT,
+ attr3 VARCHAR(10),
+ INDEX i1(attr1)
+) ENGINE=ndbcluster;
+
+INSERT INTO t1 VALUES (0,0,0,"zero"),(1,1,1,"one"),(2,2,2,"two");
+SELECT * FROM t1 WHERE attr1 = 1;
+alter table t1 rename t2;
+SELECT * FROM t2 WHERE attr1 = 1;
+
+create database ndbtest;
+alter table t2 rename ndbtest.t2;
+SELECT * FROM ndbtest.t2 WHERE attr1 = 1;
+
+drop table ndbtest.t2;
+drop database ndbtest;
+
+# End of 4.1 tests
diff --git a/sql/ha_ndbcluster.cc b/sql/ha_ndbcluster.cc
index f46a5eccabf..8634a30eae9 100644
--- a/sql/ha_ndbcluster.cc
+++ b/sql/ha_ndbcluster.cc
@@ -4922,13 +4922,17 @@ int ha_ndbcluster::rename_table(const char *from, const char *to)
{
NDBDICT *dict;
char old_dbname[FN_HEADLEN];
+ char new_dbname[FN_HEADLEN];
char new_tabname[FN_HEADLEN];
const NDBTAB *orig_tab;
int result;
+ bool recreate_indexes= FALSE;
+ NDBDICT::List index_list;
DBUG_ENTER("ha_ndbcluster::rename_table");
DBUG_PRINT("info", ("Renaming %s to %s", from, to));
set_dbname(from, old_dbname);
+ set_dbname(to, new_dbname);
set_tabname(from);
set_tabname(to, new_tabname);
@@ -4953,6 +4957,11 @@ int ha_ndbcluster::rename_table(const char *from, const char *to)
DBUG_ASSERT(r == 0);
}
#endif
+ if (my_strcasecmp(system_charset_info, new_dbname, old_dbname))
+ {
+ dict->listIndexes(index_list, *orig_tab);
+ recreate_indexes= TRUE;
+ }
// Change current database to that of target table
set_dbname(to);
ndb->setDatabaseName(m_dbname);
@@ -5033,6 +5042,32 @@ int ha_ndbcluster::rename_table(const char *from, const char *to)
SOT_RENAME_TABLE,
m_dbname, new_tabname);
}
+
+ // If we are moving tables between databases, we need to recreate
+ // indexes
+ if (recreate_indexes)
+ {
+ for (unsigned i = 0; i < index_list.count; i++)
+ {
+ NDBDICT::List::Element& index_el = index_list.elements[i];
+ // Recreate any indexes not stored in the system database
+ if (my_strcasecmp(system_charset_info,
+ index_el.database, NDB_SYSTEM_DATABASE))
+ {
+ set_dbname(from);
+ ndb->setDatabaseName(m_dbname);
+ const NDBINDEX * index= dict->getIndexGlobal(index_el.name, new_tab);
+ DBUG_PRINT("info", ("Creating index %s/%s",
+ index_el.database, index->getName()));
+ dict->createIndex(*index, new_tab);
+ DBUG_PRINT("info", ("Dropping index %s/%s",
+ index_el.database, index->getName()));
+ set_dbname(from);
+ ndb->setDatabaseName(m_dbname);
+ dict->dropIndexGlobal(*index);
+ }
+ }
+ }
if (share)
free_share(&share);
#endif
diff --git a/storage/ndb/include/ndbapi/Ndb.hpp b/storage/ndb/include/ndbapi/Ndb.hpp
index f6f313e9224..5c7a0cf30a9 100644
--- a/storage/ndb/include/ndbapi/Ndb.hpp
+++ b/storage/ndb/include/ndbapi/Ndb.hpp
@@ -1001,6 +1001,9 @@ typedef void (* NdbEventCallback)(NdbEventOperation*, Ndb*, void*);
#define WAITFOR_RESPONSE_TIMEOUT 120000 // Milliseconds
#endif
+#define NDB_SYSTEM_DATABASE "sys"
+#define NDB_SYSTEM_SCHEMA "def"
+
/**
* @class Ndb
* @brief Represents the NDB kernel and is the main class of the NDB API.
@@ -1648,6 +1651,8 @@ private:
const char * externalizeIndexName(const char * internalIndexName,
bool fullyQualifiedNames);
const char * externalizeIndexName(const char * internalIndexName);
+ const BaseString old_internalize_index_name(const NdbTableImpl * table,
+ const char * external_name) const;
const BaseString internalize_index_name(const NdbTableImpl * table,
const char * external_name) const;
diff --git a/storage/ndb/include/ndbapi/NdbDictionary.hpp b/storage/ndb/include/ndbapi/NdbDictionary.hpp
index 865fb506f05..27e0aede36d 100644
--- a/storage/ndb/include/ndbapi/NdbDictionary.hpp
+++ b/storage/ndb/include/ndbapi/NdbDictionary.hpp
@@ -1635,6 +1635,16 @@ public:
int listIndexes(List & list, const char * tableName);
int listIndexes(List & list, const char * tableName) const;
+#ifndef DOXYGEN_SHOULD_SKIP_INTERNAL
+ /**
+ * Fetch list of indexes of given table.
+ * @param list Reference to list where to store the listed indexes
+ * @param table Reference to table that index belongs to.
+ * @return 0 if successful, otherwise -1
+ */
+ int listIndexes(List & list, const Table &table) const;
+#endif
+
/** @} *******************************************************************/
/**
* @name Events
diff --git a/storage/ndb/src/ndbapi/Ndb.cpp b/storage/ndb/src/ndbapi/Ndb.cpp
index 0b0749c835e..ee121708cea 100644
--- a/storage/ndb/src/ndbapi/Ndb.cpp
+++ b/storage/ndb/src/ndbapi/Ndb.cpp
@@ -1196,6 +1196,35 @@ Ndb::internalize_table_name(const char *external_name) const
DBUG_RETURN(ret);
}
+const BaseString
+Ndb::old_internalize_index_name(const NdbTableImpl * table,
+ const char * external_name) const
+{
+ BaseString ret;
+ DBUG_ENTER("old_internalize_index_name");
+ DBUG_PRINT("enter", ("external_name: %s, table_id: %d",
+ external_name, table ? table->m_id : ~0));
+ if (!table)
+ {
+ DBUG_PRINT("error", ("!table"));
+ DBUG_RETURN(ret);
+ }
+
+ if (fullyQualifiedNames)
+ {
+ /* Internal index name format <db>/<schema>/<tabid>/<table> */
+ ret.assfmt("%s%d%c%s",
+ theImpl->m_prefix.c_str(),
+ table->m_id,
+ table_name_separator,
+ external_name);
+ }
+ else
+ ret.assign(external_name);
+
+ DBUG_PRINT("exit", ("internal_name: %s", ret.c_str()));
+ DBUG_RETURN(ret);
+}
const BaseString
Ndb::internalize_index_name(const NdbTableImpl * table,
@@ -1213,9 +1242,9 @@ Ndb::internalize_index_name(const NdbTableImpl * table,
if (fullyQualifiedNames)
{
- /* Internal index name format <db>/<schema>/<tabid>/<table> */
+ /* Internal index name format sys/def/<tabid>/<table> */
ret.assfmt("%s%d%c%s",
- theImpl->m_prefix.c_str(),
+ theImpl->m_systemPrefix.c_str(),
table->m_id,
table_name_separator,
external_name);
diff --git a/storage/ndb/src/ndbapi/NdbDictionary.cpp b/storage/ndb/src/ndbapi/NdbDictionary.cpp
index e844dc3369e..c71689d2e81 100644
--- a/storage/ndb/src/ndbapi/NdbDictionary.cpp
+++ b/storage/ndb/src/ndbapi/NdbDictionary.cpp
@@ -1618,6 +1618,14 @@ NdbDictionary::Dictionary::listIndexes(List& list,
return m_impl.listIndexes(list, tab->getTableId());
}
+int
+NdbDictionary::Dictionary::listIndexes(List& list,
+ const NdbDictionary::Table &table) const
+{
+ return m_impl.listIndexes(list, table.getTableId());
+}
+
+
const struct NdbError &
NdbDictionary::Dictionary::getNdbError() const {
return m_impl.getNdbError();
diff --git a/storage/ndb/src/ndbapi/NdbDictionaryImpl.cpp b/storage/ndb/src/ndbapi/NdbDictionaryImpl.cpp
index d2d8c43a064..250e7207ee7 100644
--- a/storage/ndb/src/ndbapi/NdbDictionaryImpl.cpp
+++ b/storage/ndb/src/ndbapi/NdbDictionaryImpl.cpp
@@ -1512,9 +1512,21 @@ NdbTableImpl *
NdbDictionaryImpl::getIndexTable(NdbIndexImpl * index,
NdbTableImpl * table)
{
+ const char *current_db= m_ndb.getDatabaseName();
+ NdbTableImpl *index_table;
const BaseString internalName(
m_ndb.internalize_index_name(table, index->getName()));
- return getTable(m_ndb.externalizeTableName(internalName.c_str()));
+ // Get index table in system database
+ m_ndb.setDatabaseName(NDB_SYSTEM_DATABASE);
+ index_table= getTable(m_ndb.externalizeTableName(internalName.c_str()));
+ m_ndb.setDatabaseName(current_db);
+ if (!index_table)
+ {
+ // Index table not found
+ // Try geting index table in current database (old format)
+ index_table= getTable(m_ndb.externalizeTableName(internalName.c_str()));
+ }
+ return index_table;
}
#if 0
diff --git a/storage/ndb/src/ndbapi/NdbDictionaryImpl.hpp b/storage/ndb/src/ndbapi/NdbDictionaryImpl.hpp
index cf30abc6c3f..41647cea10d 100644
--- a/storage/ndb/src/ndbapi/NdbDictionaryImpl.hpp
+++ b/storage/ndb/src/ndbapi/NdbDictionaryImpl.hpp
@@ -1022,6 +1022,33 @@ NdbDictionaryImpl::getIndexGlobal(const char * index_name,
}
break;
}
+ {
+ // Index not found, try old format
+ const BaseString
+ old_internal_indexname(m_ndb.old_internalize_index_name(&ndbtab,
+ index_name));
+ retry= 2;
+ while (retry)
+ {
+ NdbTableImpl *tab=
+ fetchGlobalTableImplRef(InitIndex(old_internal_indexname,
+ index_name, ndbtab));
+ if (tab)
+ {
+ // tab->m_index sould be set. otherwise tab == 0
+ NdbIndexImpl *idx= tab->m_index;
+ if (idx->m_table_id != (unsigned)ndbtab.getObjectId() ||
+ idx->m_table_version != (unsigned)ndbtab.getObjectVersion())
+ {
+ releaseIndexGlobal(*idx, 1);
+ retry--;
+ continue;
+ }
+ DBUG_RETURN(idx);
+ }
+ break;
+ }
+ }
m_error.code= 4243;
DBUG_RETURN(0);
}
@@ -1088,17 +1115,41 @@ NdbDictionaryImpl::getIndex(const char* index_name,
index_name,
prim));
if (!tab)
- goto err;
+ goto retry;
info= Ndb_local_table_info::create(tab, 0);
if (!info)
- goto err;
+ goto retry;
m_localHash.put(internal_indexname.c_str(), info);
}
else
tab= info->m_table_impl;
return tab->m_index;
+
+retry:
+ // Index not found, try fetching it from current database
+ const BaseString
+ old_internal_indexname(m_ndb.old_internalize_index_name(&prim, index_name));
+
+ info= m_localHash.get(old_internal_indexname.c_str());
+ if (info == 0)
+ {
+ tab= fetchGlobalTableImplRef(InitIndex(old_internal_indexname,
+ index_name,
+ prim));
+ if (!tab)
+ goto err;
+
+ info= Ndb_local_table_info::create(tab, 0);
+ if (!info)
+ goto err;
+ m_localHash.put(old_internal_indexname.c_str(), info);
+ }
+ else
+ tab= info->m_table_impl;
+
+ return tab->m_index;
err:
m_error.code= 4243;
diff --git a/storage/ndb/src/ndbapi/NdbImpl.hpp b/storage/ndb/src/ndbapi/NdbImpl.hpp
index 82795550381..3b7b8cf44fb 100644
--- a/storage/ndb/src/ndbapi/NdbImpl.hpp
+++ b/storage/ndb/src/ndbapi/NdbImpl.hpp
@@ -93,6 +93,8 @@ public:
m_schemaname.c_str(), table_name_separator);
}
+ BaseString m_systemPrefix; // Buffer for preformatted for <sys>/<def>/
+
/**
* NOTE free lists must be _after_ theNdbObjectIdMap take
* assure that destructors are run in correct order
diff --git a/storage/ndb/src/ndbapi/Ndbinit.cpp b/storage/ndb/src/ndbapi/Ndbinit.cpp
index e41380e6484..a21f82676d9 100644
--- a/storage/ndb/src/ndbapi/Ndbinit.cpp
+++ b/storage/ndb/src/ndbapi/Ndbinit.cpp
@@ -223,6 +223,9 @@ NdbImpl::NdbImpl(Ndb_cluster_connection *ndb_cluster_connection,
}
m_optimized_node_selection=
m_ndb_cluster_connection.m_optimized_node_selection;
+
+ m_systemPrefix.assfmt("%s%c%s%c", NDB_SYSTEM_DATABASE, table_name_separator,
+ NDB_SYSTEM_SCHEMA, table_name_separator);
}
NdbImpl::~NdbImpl()