Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[flash-369]support ddl for partition tables. #168

Merged
merged 6 commits into from
Aug 14, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions dbms/src/Common/ErrorCodes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -392,6 +392,7 @@ namespace ErrorCodes
extern const int REGION_MISS = 10002;
extern const int SCHEMA_SYNC_ERROR = 10003;
extern const int SCHEMA_VERSION_ERROR = 10004;
extern const int DDL_ERROR = 10005;
}

}
2 changes: 1 addition & 1 deletion dbms/src/Debug/DBGInvoker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ DBGInvoker::DBGInvoker()
regFunc("mock_tidb_table", MockTiDBTable::dbgFuncMockTiDBTable);
regFunc("mock_tidb_db", MockTiDBTable::dbgFuncMockTiDBDB);
regFunc("mock_tidb_partition", MockTiDBTable::dbgFuncMockTiDBPartition);
regFunc("rename_table_for_partition", MockTiDBTable::dbgFuncRenameTableForPartition);
regFunc("drop_tidb_partition", MockTiDBTable::dbgFuncDropTiDBPartition);
regFunc("drop_tidb_table", MockTiDBTable::dbgFuncDropTiDBTable);
regFunc("drop_tidb_db", MockTiDBTable::dbgFuncDropTiDBDB);
regFunc("add_column_to_tidb_table", MockTiDBTable::dbgFuncAddColumnToTiDBTable);
Expand Down
51 changes: 41 additions & 10 deletions dbms/src/Debug/MockTiDB.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -234,34 +234,65 @@ TableID MockTiDB::newTable(const String & database_name, const String & table_na
return table->table_info.id;
}

TableID MockTiDB::newPartition(const String & database_name, const String & table_name, const String & partition_name, Timestamp tso)
void MockTiDB::newPartition(const String & database_name, const String & table_name, TableID partition_id, Timestamp tso, bool is_add_part)
{
std::lock_guard lock(tables_mutex);

TablePtr table = getTableByNameInternal(database_name, table_name);
TableInfo & table_info = table->table_info;

const auto & part_def = find_if(table_info.partition.definitions.begin(), table_info.partition.definitions.end(),
[&partition_name](PartitionDefinition & part_def) { return part_def.name == partition_name; });
[&partition_id](PartitionDefinition & part_def) { return part_def.id == partition_id; });
if (part_def != table_info.partition.definitions.end())
throw Exception(
"Mock TiDB table " + database_name + "." + table_name + " already has partition " + partition_name, ErrorCodes::LOGICAL_ERROR);
throw Exception("Mock TiDB table " + database_name + "." + table_name + " already has partition " + std::to_string(partition_id),
ErrorCodes::LOGICAL_ERROR);

table_info.is_partition_table = true;
table_info.partition.enable = true;
table_info.partition.num++;
TableID partition_id = table_info.id + table_info.partition.num;
PartitionDefinition partition_def;
partition_def.id = partition_id;
partition_def.name = partition_name;
partition_def.name = std::to_string(partition_id);
table_info.partition.definitions.emplace_back(partition_def);
table_info.update_timestamp = tso;

// Map the same table object with partition ID as key, so mock schema syncer behaves the same as TiDB,
// i.e. gives the table info by partition ID.
tables_by_id.emplace(partition_id, table);
if (is_add_part)
{
version++;

SchemaDiff diff;
diff.type = SchemaActionAddTablePartition;
diff.schema_id = table->table_info.db_id;
diff.table_id = table->id();
diff.version = version;
version_diff[version] = diff;
}
}

void MockTiDB::dropPartition(const String & database_name, const String & table_name, TableID partition_id)
{
std::lock_guard lock(tables_mutex);

return partition_id;
TablePtr table = getTableByNameInternal(database_name, table_name);
TableInfo & table_info = table->table_info;

const auto & part_def = find_if(table_info.partition.definitions.begin(), table_info.partition.definitions.end(),
[&partition_id](PartitionDefinition & part_def) { return part_def.id == partition_id; });
if (part_def == table_info.partition.definitions.end())
throw Exception("Mock TiDB table " + database_name + "." + table_name + " already drop partition " + std::to_string(partition_id),
ErrorCodes::LOGICAL_ERROR);

table_info.partition.num--;
table_info.partition.definitions.erase(part_def);

version++;

SchemaDiff diff;
diff.type = SchemaActionDropTablePartition;
diff.schema_id = table->table_info.db_id;
diff.table_id = table->id();
diff.version = version;
version_diff[version] = diff;
}

void MockTiDB::addColumnToTable(const String & database_name, const String & table_name, const NameAndTypePair & column)
Expand Down
16 changes: 3 additions & 13 deletions dbms/src/Debug/MockTiDB.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,18 +35,6 @@ class MockTiDB : public ext::singleton<MockTiDB>

bool isPartitionTable() { return table_info.is_partition_table; }

TableID getPartitionIDByName(const String & partition_name)
{
const auto & partition_def = std::find_if(table_info.partition.definitions.begin(), table_info.partition.definitions.end(),
[&partition_name](const TiDB::PartitionDefinition & part_def) { return part_def.name == partition_name; });

if (partition_def == table_info.partition.definitions.end())
throw Exception("Mock TiDB table " + database_name + "." + table_name + " does not have partition " + partition_name,
ErrorCodes::LOGICAL_ERROR);

return partition_def->id;
}

std::vector<TableID> getPartitionIDs()
{
std::vector<TableID> partition_ids;
Expand All @@ -68,7 +56,9 @@ class MockTiDB : public ext::singleton<MockTiDB>

DatabaseID newDataBase(const String & database_name);

TableID newPartition(const String & database_name, const String & table_name, const String & partition_name, Timestamp tso);
void newPartition(const String & database_name, const String & table_name, TableID partition_id, Timestamp tso, bool);

void dropPartition(const String & database_name, const String & table_name, TableID partition_id);

void dropTable(Context & context, const String & database_name, const String & table_name, bool drop_regions);

Expand Down
39 changes: 15 additions & 24 deletions dbms/src/Debug/dbgFuncMockTiDBTable.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -65,48 +65,39 @@ void MockTiDBTable::dbgFuncMockTiDBDB(Context &, const ASTs & args, DBGInvoker::

void MockTiDBTable::dbgFuncMockTiDBPartition(Context & context, const ASTs & args, DBGInvoker::Printer output)
{
if (args.size() != 3)
if (args.size() != 3 && args.size() != 4)
throw Exception("Args not matched, should be: database-name, table-name, partition-name", ErrorCodes::BAD_ARGUMENTS);

const String & database_name = typeid_cast<const ASTIdentifier &>(*args[0]).name;
const String & table_name = typeid_cast<const ASTIdentifier &>(*args[1]).name;
const String & partition_name = typeid_cast<const ASTIdentifier &>(*args[2]).name;
TableID partition_id = safeGet<UInt64>(typeid_cast<const ASTLiteral &>(*args[2]).value);
bool is_add_part = false;
if (args.size() == 4)
{
is_add_part = typeid_cast<const ASTIdentifier &>(*args[3]).name == "true";
}
auto tso = context.getTMTContext().getPDClient()->getTS();

TableID partition_id = MockTiDB::instance().newPartition(database_name, table_name, partition_name, tso);
MockTiDB::instance().newPartition(database_name, table_name, partition_id, tso, is_add_part);

std::stringstream ss;
ss << "mock partition #" << partition_id;
output(ss.str());
}

void MockTiDBTable::dbgFuncRenameTableForPartition(Context & context, const ASTs & args, DBGInvoker::Printer output)
void MockTiDBTable::dbgFuncDropTiDBPartition(Context &, const ASTs & args, DBGInvoker::Printer output)
{
if (args.size() != 4)
throw Exception("Args not matched, should be: database-name, table-name, partition-name, view-name", ErrorCodes::BAD_ARGUMENTS);
if (args.size() != 3)
throw Exception("Args not matched, should be: database-name, table-name, partition-name", ErrorCodes::BAD_ARGUMENTS);

const String & database_name = typeid_cast<const ASTIdentifier &>(*args[0]).name;
const String & table_name = typeid_cast<const ASTIdentifier &>(*args[1]).name;
const String & partition_name = typeid_cast<const ASTIdentifier &>(*args[2]).name;
const String & new_name = typeid_cast<const ASTIdentifier &>(*args[3]).name;
TableID partition_id = safeGet<UInt64>(typeid_cast<const ASTLiteral &>(*args[2]).value);

const auto & table = MockTiDB::instance().getTableByName(database_name, table_name);

if (!table->isPartitionTable())
throw Exception("Table " + database_name + "." + table_name + " is not partition table.", ErrorCodes::LOGICAL_ERROR);
TableID partition_id = table->getPartitionIDByName(partition_name);
String physical_name = table_name + "_" + std::to_string(partition_id);
String rename_stmt = "RENAME TABLE " + database_name + "." + physical_name + " TO " + database_name + "." + new_name;

ParserRenameQuery parser;
ASTPtr ast = parseQuery(parser, rename_stmt.data(), rename_stmt.data() + rename_stmt.size(),
"from rename table for partition " + database_name + "." + table_name + "." + partition_name, 0);

InterpreterRenameQuery interpreter(ast, context);
interpreter.execute();
MockTiDB::instance().dropPartition(database_name, table_name, partition_id);

std::stringstream ss;
ss << "table " << physical_name << " renamed to " << new_name;
ss << "drop partition #" << partition_id;
output(ss.str());
}

Expand All @@ -117,7 +108,7 @@ void MockTiDBTable::dbgFuncDropTiDBDB(Context & context, const ASTs & args, DBGI

const String & database_name = typeid_cast<const ASTIdentifier &>(*args[0]).name;
bool drop_regions = true;
if (args.size() == 3)
if (args.size() == 2)
drop_regions = typeid_cast<const ASTIdentifier &>(*args[1]).name == "true";

MockTiDB::instance().dropDB(context, database_name, drop_regions);
Expand Down
10 changes: 4 additions & 6 deletions dbms/src/Debug/dbgFuncMockTiDBTable.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,15 +24,13 @@ struct MockTiDBTable

// Inject a partition into mocked TiDB table.
// Usage:
// ./storages-client.sh "DBGInvoke mock_tidb_partition(database_name, table_name, partition_name)"
// ./storages-client.sh "DBGInvoke mock_tidb_partition(database_name, table_name, partition_id [, is_add_part])"
static void dbgFuncMockTiDBPartition(Context & context, const ASTs & args, DBGInvoker::Printer output);

// Rename the physical table of a partition of a TiDB partition table.
// The physical table of a partition is named as table-name + '_' + partition-id, which is invisible by tests.
// Rename to expose it to tests to making query to.
// Inject a partition into mocked TiDB table.
// Usage:
// ./storages-client.sh "DBGInvoke rename_table_for_partition(database_name, table_name, partition_name, new_name)"
static void dbgFuncRenameTableForPartition(Context & context, const ASTs & args, DBGInvoker::Printer output);
// ./storages-client.sh "DBGInvoke drop_tidb_partition(database_name, table_name, partition_id)"
static void dbgFuncDropTiDBPartition(Context & context, const ASTs & args, DBGInvoker::Printer output);

// Drop a mocked TiDB table.
// Usage:
Expand Down
12 changes: 6 additions & 6 deletions dbms/src/Debug/dbgFuncRegion.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,15 +24,15 @@ extern const int BAD_ARGUMENTS;
extern const int UNKNOWN_TABLE;
} // namespace ErrorCodes

TableID getTableID(Context & context, const std::string & database_name, const std::string & table_name, const std::string & partition_name)
TableID getTableID(Context & context, const std::string & database_name, const std::string & table_name, const std::string & partition_id)
{
try
{
using TablePtr = MockTiDB::TablePtr;
TablePtr table = MockTiDB::instance().getTableByName(database_name, table_name);

if (table->isPartitionTable())
return table->getPartitionIDByName(partition_name);
return std::atoi(partition_id.c_str());

return table->id();
}
Expand Down Expand Up @@ -61,9 +61,9 @@ void dbgFuncPutRegion(Context & context, const ASTs & args, DBGInvoker::Printer
HandleID end = (HandleID)safeGet<UInt64>(typeid_cast<const ASTLiteral &>(*args[2]).value);
const String & database_name = typeid_cast<const ASTIdentifier &>(*args[3]).name;
const String & table_name = typeid_cast<const ASTIdentifier &>(*args[4]).name;
const String & partition_name = args.size() == 6 ? typeid_cast<const ASTIdentifier &>(*args[5]).name : "";
const String & partition_id = args.size() == 6 ? std::to_string(safeGet<UInt64>(typeid_cast<const ASTLiteral &>(*args[5]).value)) : "";

TableID table_id = getTableID(context, database_name, table_name, partition_name);
TableID table_id = getTableID(context, database_name, table_name, partition_id);

TMTContext & tmt = context.getTMTContext();
RegionPtr region = RegionBench::createRegion(table_id, region_id, start, end);
Expand Down Expand Up @@ -179,9 +179,9 @@ void dbgFuncRegionSnapshot(Context & context, const ASTs & args, DBGInvoker::Pri
HandleID end = (HandleID)safeGet<UInt64>(typeid_cast<const ASTLiteral &>(*args[2]).value);
const String & database_name = typeid_cast<const ASTIdentifier &>(*args[3]).name;
const String & table_name = typeid_cast<const ASTIdentifier &>(*args[4]).name;
const String & partition_name = args.size() == 6 ? typeid_cast<const ASTIdentifier &>(*args[5]).name : "";
const String & partition_id = args.size() == 6 ? typeid_cast<const ASTIdentifier &>(*args[5]).name : "";

TableID table_id = getTableID(context, database_name, table_name, partition_name);
TableID table_id = getTableID(context, database_name, table_name, partition_id);

TMTContext & tmt = context.getTMTContext();

Expand Down
Loading