Skip to content

Commit

Permalink
feat: support drop database/table if exists (#3348)
Browse files Browse the repository at this point in the history
  • Loading branch information
emo-coder authored Jul 14, 2023
1 parent e1d35fc commit 291ec6a
Show file tree
Hide file tree
Showing 7 changed files with 86 additions and 12 deletions.
18 changes: 18 additions & 0 deletions cases/plan/cmd.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,15 @@ cases:
+-node[CMD]
+-cmd_type: drop table
+-args: [db1, t1]
- id: 14-3
desc: DROP TABLE IF EXISTS
sql: DROP TABLE IF EXISTS t1;
expect:
node_tree_str: |
+-node[CMD]
+-cmd_type: drop table
+-if_exists: true
+-args: [t1]
- id: 15-1
desc: DROP INDEX
sql: DROP INDEX t1.index1
Expand Down Expand Up @@ -171,6 +180,15 @@ cases:
+-node[CMD]
+-cmd_type: drop database
+-args: [db1]
- id: 18
desc: DROP DATABASE IF EXISTS
sql: DROP DATABASE IF EXISTS db1
expect:
node_tree_str: |
+-node[CMD]
+-cmd_type: drop database
+-if_exists: true
+-args: [db1]
- id: show_deployments
desc: show deployments
sql: SHOW DEPLOYMENTS;
Expand Down
2 changes: 2 additions & 0 deletions hybridse/src/planv2/ast_node_converter.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2013,13 +2013,15 @@ base::Status ConvertDropStatement(const zetasql::ASTDropStatement* root, node::N
*output = dynamic_cast<node::CmdNode*>(
node_manager->MakeCmdNode(node::CmdType::kCmdDropTable, names[0], names[1]));
}
(*output)->SetIfExists(root->is_if_exists());
return base::Status::OK();
}
case zetasql::SchemaObjectKind::kDatabase: {
CHECK_TRUE(1 == names.size(), common::kSqlAstError, "Invalid database path expression ",
root->name()->ToIdentifierPathString())
*output =
dynamic_cast<node::CmdNode*>(node_manager->MakeCmdNode(node::CmdType::kCmdDropDatabase, names[0]));
(*output)->SetIfExists(root->is_if_exists());
return base::Status::OK();
}
case zetasql::SchemaObjectKind::kIndex: {
Expand Down
5 changes: 4 additions & 1 deletion src/client/ns_client.cc
Original file line number Diff line number Diff line change
Expand Up @@ -73,13 +73,16 @@ bool NsClient::ShowDatabase(std::vector<std::string>* dbs, std::string& msg) {
return ok && response.code() == 0;
}

bool NsClient::DropDatabase(const std::string& db, std::string& msg) {
bool NsClient::DropDatabase(const std::string& db, std::string& msg, bool if_exists) {
::openmldb::nameserver::DropDatabaseRequest request;
::openmldb::nameserver::GeneralResponse response;
request.set_db(db);
bool ok = client_.SendRequest(&::openmldb::nameserver::NameServer_Stub::DropDatabase, &request, &response,
FLAGS_request_timeout_ms, 1);
msg = response.msg();
if (if_exists) {
return ok && (response.code() == 0 || response.code() == ::openmldb::base::ReturnCode::kDatabaseNotFound);
}
return ok && response.code() == 0;
}

Expand Down
2 changes: 1 addition & 1 deletion src/client/ns_client.h
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ class NsClient : public Client {
bool ShowDatabase(std::vector<std::string>* dbs,
std::string& msg); // NOLINT

bool DropDatabase(const std::string& db, std::string& msg); // NOLINT
bool DropDatabase(const std::string& db, std::string& msg, bool if_exists = false); // NOLINT

bool ShowTablet(std::vector<TabletInfo>& tablets, // NOLINT
std::string& msg); // NOLINT
Expand Down
29 changes: 20 additions & 9 deletions src/sdk/sql_cluster_router.cc
Original file line number Diff line number Diff line change
Expand Up @@ -902,7 +902,8 @@ bool SQLClusterRouter::DropDB(const std::string& db, hybridse::sdk::Status* stat
return true;
}

bool SQLClusterRouter::DropTable(const std::string& db, const std::string& table, hybridse::sdk::Status* status) {
bool SQLClusterRouter::DropTable(const std::string& db, const std::string& table, const bool if_exists,
hybridse::sdk::Status* status) {
RET_FALSE_IF_NULL_AND_WARN(status, "output status is nullptr");
if (db.empty() || table.empty()) {
SET_STATUS_AND_WARN(status, StatusCode::kCmdError,
Expand All @@ -916,20 +917,30 @@ bool SQLClusterRouter::DropTable(const std::string& db, const std::string& table
return false;
}

auto tableInfo = GetTableInfo(db, table);
auto table_info = cluster_sdk_->GetTableInfo(db, table);

if (table_info == nullptr) {
if (if_exists) {
*status = {};
return true;
} else {
SET_STATUS_AND_WARN(status, StatusCode::kCmdError, "fail to drop, table does not exist!");
return false;
}
}

// delete pre-aggr meta info if need
if (tableInfo.base_table_tid() > 0) {
if (table_info->base_table_tid() > 0) {
std::string meta_db = openmldb::nameserver::INTERNAL_DB;
std::string meta_table = openmldb::nameserver::PRE_AGG_META_NAME;
std::string select_aggr_info =
absl::StrCat("select base_db,base_table,aggr_func,aggr_col,partition_cols,order_by_col,filter_col from ",
meta_db, ".", meta_table, " where aggr_table = '", tableInfo.name(), "';");
meta_db, ".", meta_table, " where aggr_table = '", table_info->name(), "';");
auto rs = ExecuteSQL("", select_aggr_info, true, true, 0, status);
WARN_NOT_OK_AND_RET(status, "get aggr info failed", false);
if (rs->Size() != 1) {
SET_STATUS_AND_WARN(status, StatusCode::kCmdError,
"duplicate records generate with aggr table name: " + tableInfo.name());
"duplicate records generate with aggr table name: " + table_info->name());
return false;
}
std::string idx_key;
Expand Down Expand Up @@ -961,15 +972,15 @@ bool SQLClusterRouter::DropTable(const std::string& db, const std::string& table
}
auto tid = cluster_sdk_->GetTableId(meta_db, meta_table);
std::string msg;
if (!tablet_client->Delete(tid, 0, tableInfo.name(), "aggr_table", msg) ||
if (!tablet_client->Delete(tid, 0, table_info->name(), "aggr_table", msg) ||
!tablet_client->Delete(tid, 0, idx_key, "unique_key", msg)) {
SET_STATUS_AND_WARN(status, StatusCode::kCmdError, "delete aggr meta failed");
return false;
}
}

// Check offline table info first
if (tableInfo.has_offline_table_info()) {
if (table_info->has_offline_table_info()) {
auto taskmanager_client_ptr = cluster_sdk_->GetTaskManagerClient();
if (!taskmanager_client_ptr) {
SET_STATUS_AND_WARN(status, StatusCode::kRuntimeError, "no taskmanager client");
Expand Down Expand Up @@ -1644,7 +1655,7 @@ std::shared_ptr<hybridse::sdk::ResultSet> SQLClusterRouter::HandleSQLCmd(const h
}
case hybridse::node::kCmdDropDatabase: {
std::string name = cmd_node->GetArgs()[0];
if (ns_ptr->DropDatabase(name, msg)) {
if (ns_ptr->DropDatabase(name, msg, cmd_node->IsIfExists())) {
*status = {};
} else {
*status = {StatusCode::kCmdError, msg};
Expand Down Expand Up @@ -1886,7 +1897,7 @@ std::shared_ptr<hybridse::sdk::ResultSet> SQLClusterRouter::HandleSQLCmd(const h
if (!CheckAnswerIfInteractive("table", table_name)) {
return {};
}
if (DropTable(db_name, table_name, status)) {
if (DropTable(db_name, table_name, cmd_node->IsIfExists(), status)) {
RefreshCatalog();
}
return {};
Expand Down
3 changes: 2 additions & 1 deletion src/sdk/sql_cluster_router.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,8 @@ class SQLClusterRouter : public SQLRouter {

bool DropDB(const std::string& db, hybridse::sdk::Status* status) override;

bool DropTable(const std::string& db, const std::string& table, hybridse::sdk::Status* status);
bool DropTable(const std::string& db, const std::string& table, const bool if_exists,
hybridse::sdk::Status* status);

bool ShowDB(std::vector<std::string>* dbs, hybridse::sdk::Status* status) override;

Expand Down
39 changes: 39 additions & 0 deletions src/sdk/sql_cluster_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,45 @@ class SQLClusterDDLTest : public SQLClusterTest {
std::shared_ptr<SQLRouter> router;
std::string db;
};

TEST_F(SQLClusterDDLTest, TestIfExists) {
std::string name = "test" + GenRand();
::hybridse::sdk::Status status;
std::string db2 = "db" + GenRand();

std::string ddl;
ddl = "create table " + db2 + "." + name +
"("
"col1 int, col2 bigint, col3 string,"
"index(key=col3, ts=col2));";

ASSERT_TRUE(router->ExecuteDDL(db, "create database " + db2 + ";", &status));

// drop database db2 & table name
ASSERT_TRUE(router->ExecuteDDL(db, ddl, &status));
ASSERT_TRUE(router->ExecuteDDL(db, "drop table " + db2 + "." + name + ";", &status));

// drop table name when name not exist
ASSERT_FALSE(router->ExecuteDDL(db, "drop table " + db2 + "." + name + ";", &status));
ASSERT_TRUE(router->ExecuteDDL(db, "drop database " + db2 + ";", &status));

// drop database db2 when db2 not exist
ASSERT_FALSE(router->ExecuteDDL(db, "drop database " + db2 + ";", &status));

ASSERT_TRUE(router->ExecuteDDL(db, "create database " + db2 + ";", &status));

// if exists drop database db2 & table name
ASSERT_TRUE(router->ExecuteDDL(db, ddl, &status));
ASSERT_TRUE(router->ExecuteDDL(db, "drop table if exists " + db2 + "." + name + ";", &status));

// drop table name when name not exist
ASSERT_TRUE(router->ExecuteDDL(db, "drop table if exists " + db2 + "." + name + ";", &status));
ASSERT_TRUE(router->ExecuteDDL(db, "drop database if exists " + db2 + ";", &status));

// drop database db2 when db2 not exist
ASSERT_TRUE(router->ExecuteDDL(db, "drop database if exists " + db2 + ";", &status));
}

TEST_F(SQLClusterDDLTest, CreateTableWithDatabase) {
std::string name = "test" + GenRand();
::hybridse::sdk::Status status;
Expand Down

0 comments on commit 291ec6a

Please sign in to comment.