diff --git a/src/sdk/db_sdk.cc b/src/sdk/db_sdk.cc index 6b78d4069ec..c04e86d4f03 100644 --- a/src/sdk/db_sdk.cc +++ b/src/sdk/db_sdk.cc @@ -426,6 +426,15 @@ bool ClusterSDK::BuildCatalog() { return UpdateCatalog(table_datas, sp_datas); } +std::vector DBSDK::GetAllDbs() { + std::lock_guard<::openmldb::base::SpinMutex> lock(mu_); + std::vector all_dbs; + for (auto db_name_iter = table_to_tablets_.begin(); db_name_iter != table_to_tablets_.end(); db_name_iter++) { + all_dbs.push_back(db_name_iter->first); + } + return all_dbs; +} + uint32_t DBSDK::GetTableId(const std::string& db, const std::string& tname) { auto table_handler = GetCatalog()->GetTable(db, tname); auto* sdk_table_handler = dynamic_cast<::openmldb::catalog::SDKTableHandler*>(table_handler.get()); diff --git a/src/sdk/db_sdk.h b/src/sdk/db_sdk.h index 48bb1ea80ab..71e3e321241 100644 --- a/src/sdk/db_sdk.h +++ b/src/sdk/db_sdk.h @@ -77,6 +77,7 @@ class DBSDK { std::shared_ptr<::openmldb::client::TaskManagerClient> GetTaskManagerClient(); + std::vector GetAllDbs(); uint32_t GetTableId(const std::string& db, const std::string& tname); std::shared_ptr<::openmldb::nameserver::TableInfo> GetTableInfo(const std::string& db, const std::string& tname); std::vector> GetTables(const std::string& db); diff --git a/src/sdk/sql_cluster_router.cc b/src/sdk/sql_cluster_router.cc index 768c4d897c6..bd48caf2c81 100644 --- a/src/sdk/sql_cluster_router.cc +++ b/src/sdk/sql_cluster_router.cc @@ -1930,11 +1930,12 @@ base::Status SQLClusterRouter::HandleSQLCreateTable(hybridse::node::CreatePlanNo return base::Status(base::ReturnCode::kSQLCmdRunError, "fail to execute plan : null pointer"); } - if (create_node->like_clause_ == nullptr) { - std::string db_name = create_node->GetDatabase().empty() ? db : create_node->GetDatabase(); - if (db_name.empty()) { - return base::Status(base::ReturnCode::kSQLCmdRunError, "ERROR: Please use database first"); + std::string db_name = create_node->GetDatabase().empty() ? db : create_node->GetDatabase(); + if (db_name.empty()) { + return base::Status(base::ReturnCode::kSQLCmdRunError, "ERROR: Please use database first"); } + + if (create_node->like_clause_ == nullptr) { ::openmldb::nameserver::TableInfo table_info; table_info.set_db(db_name); @@ -1955,6 +1956,12 @@ base::Status SQLClusterRouter::HandleSQLCreateTable(hybridse::node::CreatePlanNo return base::Status(base::ReturnCode::kSQLCmdRunError, msg); } } else { + auto dbs = cluster_sdk_->GetAllDbs(); + auto it = std::find(dbs.begin(), dbs.end(), db_name); + if (it == dbs.end()) { + return base::Status(base::ReturnCode::kSQLCmdRunError, "fail to create, database does not exist!"); + } + LOG(WARNING) << "CREATE TABLE LIKE will run in offline job, please wait."; std::map config; diff --git a/src/sdk/sql_cluster_test.cc b/src/sdk/sql_cluster_test.cc index 41623c5fc79..b7ef300fee1 100644 --- a/src/sdk/sql_cluster_test.cc +++ b/src/sdk/sql_cluster_test.cc @@ -98,6 +98,13 @@ class SQLClusterDDLTest : public SQLClusterTest { std::string db; }; +TEST_F(SQLClusterDDLTest, TestCreateTableLike) { + ::hybridse::sdk::Status status; + + ASSERT_FALSE(router->ExecuteDDL(db, "create table db2.tb like hive 'hive://db.tb';", &status)); + ASSERT_FALSE(router->ExecuteDDL(db, "drop table db2.tb;", &status)); +} + TEST_F(SQLClusterDDLTest, TestIfExists) { std::string name = "test" + GenRand(); ::hybridse::sdk::Status status;