diff --git a/CHANGELOG.md b/CHANGELOG.md index 1d4e9a29af..85cd3cfe58 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -25,6 +25,7 @@ Please mark all change in change log and use the issue from GitHub - \#2196 Fix server start failed if wal is disabled - \#2203 0.8.0 id=-1 is returned when total count < topk - \#2231 Use server_config to define hard-delete delay time for segment files +- \#2261 Re-define result returned by has_collection if collection in delete state ## Feature - \#1751 Add api SearchByID diff --git a/core/src/db/DB.h b/core/src/db/DB.h index 94057ccb5d..3cc00d5eab 100644 --- a/core/src/db/DB.h +++ b/core/src/db/DB.h @@ -56,10 +56,10 @@ class DB { DescribeCollection(meta::CollectionSchema& table_schema_) = 0; virtual Status - HasCollection(const std::string& collection_id, bool& has_or_not_) = 0; + HasCollection(const std::string& collection_id, bool& has_or_not) = 0; virtual Status - HasNativeCollection(const std::string& collection_id, bool& has_or_not_) = 0; + HasNativeCollection(const std::string& collection_id, bool& has_or_not) = 0; virtual Status AllCollections(std::vector& table_schema_array) = 0; diff --git a/core/src/db/DBImpl.cpp b/core/src/db/DBImpl.cpp index 999f76a678..b3fe65c516 100644 --- a/core/src/db/DBImpl.cpp +++ b/core/src/db/DBImpl.cpp @@ -275,30 +275,16 @@ DBImpl::HasCollection(const std::string& collection_id, bool& has_or_not) { return SHUTDOWN_ERROR; } - return meta_ptr_->HasCollection(collection_id, has_or_not); + return meta_ptr_->HasCollection(collection_id, has_or_not, false); } Status -DBImpl::HasNativeCollection(const std::string& collection_id, bool& has_or_not_) { +DBImpl::HasNativeCollection(const std::string& collection_id, bool& has_or_not) { if (!initialized_.load(std::memory_order_acquire)) { return SHUTDOWN_ERROR; } - engine::meta::CollectionSchema collection_schema; - collection_schema.collection_id_ = collection_id; - auto status = DescribeCollection(collection_schema); - if (!status.ok()) { - has_or_not_ = false; - return status; - } else { - if (!collection_schema.owner_collection_.empty()) { - has_or_not_ = false; - return Status(DB_NOT_FOUND, ""); - } - - has_or_not_ = true; - return Status::OK(); - } + return meta_ptr_->HasCollection(collection_id, has_or_not, true); } Status diff --git a/core/src/db/meta/Meta.h b/core/src/db/meta/Meta.h index 1bea3af863..a010c037b1 100644 --- a/core/src/db/meta/Meta.h +++ b/core/src/db/meta/Meta.h @@ -55,7 +55,7 @@ class Meta { DescribeCollection(CollectionSchema& table_schema) = 0; virtual Status - HasCollection(const std::string& collection_id, bool& has_or_not) = 0; + HasCollection(const std::string& collection_id, bool& has_or_not, bool is_root = false) = 0; virtual Status AllCollections(std::vector& table_schema_array) = 0; diff --git a/core/src/db/meta/MySQLMetaImpl.cpp b/core/src/db/meta/MySQLMetaImpl.cpp index 18d61e4e1c..561f0127b8 100644 --- a/core/src/db/meta/MySQLMetaImpl.cpp +++ b/core/src/db/meta/MySQLMetaImpl.cpp @@ -541,7 +541,7 @@ MySQLMetaImpl::DescribeCollection(CollectionSchema& collection_schema) { } Status -MySQLMetaImpl::HasCollection(const std::string& collection_id, bool& has_or_not) { +MySQLMetaImpl::HasCollection(const std::string& collection_id, bool& has_or_not, bool is_root) { try { server::MetricCollector metric; mysqlpp::StoreQueryResult res; @@ -557,20 +557,23 @@ MySQLMetaImpl::HasCollection(const std::string& collection_id, bool& has_or_not) mysqlpp::Query HasCollectionQuery = connectionPtr->query(); // since collection_id is a unique column we just need to check whether it exists or not - HasCollectionQuery << "SELECT EXISTS" - << " (SELECT 1 FROM " << META_TABLES << " WHERE table_id = " << mysqlpp::quote - << collection_id << " AND state <> " << std::to_string(CollectionSchema::TO_DELETE) - << ")" - << " AS " << mysqlpp::quote << "check" - << ";"; + if (is_root) { + HasCollectionQuery << "SELECT id FROM " << META_TABLES << " WHERE table_id = " << mysqlpp::quote + << collection_id << " AND state <> " << std::to_string(CollectionSchema::TO_DELETE) + << " AND owner_table = " << mysqlpp::quote << "" + << ";"; + } else { + HasCollectionQuery << "SELECT id FROM " << META_TABLES << " WHERE table_id = " << mysqlpp::quote + << collection_id << " AND state <> " << std::to_string(CollectionSchema::TO_DELETE) + << ";"; + } LOG_ENGINE_DEBUG_ << "HasCollection: " << HasCollectionQuery.str(); res = HasCollectionQuery.store(); } // Scoped Connection - int check = res[0]["check"]; - has_or_not = (check == 1); + has_or_not = (res.num_rows() > 0); } catch (std::exception& e) { return HandleException("Failed to check collection existence", e.what()); } diff --git a/core/src/db/meta/MySQLMetaImpl.h b/core/src/db/meta/MySQLMetaImpl.h index a6412c97dd..0a1084d8c7 100644 --- a/core/src/db/meta/MySQLMetaImpl.h +++ b/core/src/db/meta/MySQLMetaImpl.h @@ -38,7 +38,7 @@ class MySQLMetaImpl : public Meta { DescribeCollection(CollectionSchema& collection_schema) override; Status - HasCollection(const std::string& collection_id, bool& has_or_not) override; + HasCollection(const std::string& collection_id, bool& has_or_not, bool is_root = false) override; Status AllCollections(std::vector& collection_schema_array) override; diff --git a/core/src/db/meta/SqliteMetaImpl.cpp b/core/src/db/meta/SqliteMetaImpl.cpp index f677fae364..c50f2054a6 100644 --- a/core/src/db/meta/SqliteMetaImpl.cpp +++ b/core/src/db/meta/SqliteMetaImpl.cpp @@ -272,7 +272,7 @@ SqliteMetaImpl::DescribeCollection(CollectionSchema& collection_schema) { } Status -SqliteMetaImpl::HasCollection(const std::string& collection_id, bool& has_or_not) { +SqliteMetaImpl::HasCollection(const std::string& collection_id, bool& has_or_not, bool is_root) { has_or_not = false; try { @@ -281,11 +281,21 @@ SqliteMetaImpl::HasCollection(const std::string& collection_id, bool& has_or_not // multi-threads call sqlite update may get exception('bad logic', etc), so we add a lock here std::lock_guard meta_lock(meta_mutex_); - auto collections = ConnectorPtr->select( - columns(&CollectionSchema::id_), - where(c(&CollectionSchema::collection_id_) == collection_id - and c(&CollectionSchema::state_) != (int)CollectionSchema::TO_DELETE)); - if (collections.size() == 1) { + + auto select_columns = columns(&CollectionSchema::id_, &CollectionSchema::owner_collection_); + decltype(ConnectorPtr->select(select_columns)) selected; + if (is_root) { + selected = ConnectorPtr->select(select_columns, + where(c(&CollectionSchema::collection_id_) == collection_id + and c(&CollectionSchema::state_) != (int)CollectionSchema::TO_DELETE + and c(&CollectionSchema::owner_collection_) == "")); + } else { + selected = ConnectorPtr->select(select_columns, + where(c(&CollectionSchema::collection_id_) == collection_id + and c(&CollectionSchema::state_) != (int)CollectionSchema::TO_DELETE)); + } + + if (selected.size() == 1) { has_or_not = true; } else { has_or_not = false; diff --git a/core/src/db/meta/SqliteMetaImpl.h b/core/src/db/meta/SqliteMetaImpl.h index 67a0e688b0..82b30861b9 100644 --- a/core/src/db/meta/SqliteMetaImpl.h +++ b/core/src/db/meta/SqliteMetaImpl.h @@ -40,7 +40,7 @@ class SqliteMetaImpl : public Meta { DescribeCollection(CollectionSchema& collection_schema) override; Status - HasCollection(const std::string& collection_id, bool& has_or_not) override; + HasCollection(const std::string& collection_id, bool& has_or_not, bool is_root = false) override; Status AllCollections(std::vector& collection_schema_array) override; diff --git a/core/src/server/delivery/request/HasCollectionRequest.cpp b/core/src/server/delivery/request/HasCollectionRequest.cpp index 5e16a4f345..10f4c7d5d2 100644 --- a/core/src/server/delivery/request/HasCollectionRequest.cpp +++ b/core/src/server/delivery/request/HasCollectionRequest.cpp @@ -50,20 +50,10 @@ HasCollectionRequest::OnExecute() { status = DBWrapper::DB()->HasNativeCollection(collection_name_, has_collection_); fiu_do_on("HasCollectionRequest.OnExecute.throw_std_exception", throw std::exception()); - // only process root collection, ignore partition collection - if (has_collection_) { - engine::meta::CollectionSchema collection_schema; - collection_schema.collection_id_ = collection_name_; - status = DBWrapper::DB()->DescribeCollection(collection_schema); - if (!collection_schema.owner_collection_.empty()) { - has_collection_ = false; - } - } + return status; } catch (std::exception& ex) { return Status(SERVER_UNEXPECTED_ERROR, ex.what()); } - - return Status::OK(); } } // namespace server