diff --git a/src/dbms/inmemory/replication_handlers.cpp b/src/dbms/inmemory/replication_handlers.cpp index 3f7356a9b..4f3b90faa 100644 --- a/src/dbms/inmemory/replication_handlers.cpp +++ b/src/dbms/inmemory/replication_handlers.cpp @@ -660,19 +660,11 @@ uint64_t InMemoryReplicationHandlers::ReadAndApplyDelta(storage::InMemoryStorage break; } case WalDeltaData::Type::TEXT_INDEX_CREATE: { - const auto &info = delta.operation_text; - spdlog::trace(" Create text index {} on :{}", info.index_name, info.label); - auto *transaction = get_transaction(timestamp, kUniqueAccess); - if (transaction->CreateTextIndex(info.index_name, storage->NameToLabel(info.label), this).HasError()) - throw utils::BasicException("Invalid transaction! Please raise an issue, {}:{}", __FILE__, __LINE__); + // NOTE: Phase 1 of the text search feature doesn't have replication in scope break; } case WalDeltaData::Type::TEXT_INDEX_DROP: { - const auto &info = delta.operation_text; - spdlog::trace(" Drop text index {} on :{}", info.index_name, info.label); - auto *transaction = get_transaction(timestamp, kUniqueAccess); - if (transaction->DropTextIndex(info.index_name).HasError()) - throw utils::BasicException("Invalid transaction! Please raise an issue, {}:{}", __FILE__, __LINE__); + // NOTE: Phase 1 of the text search feature doesn't have replication in scope break; } case WalDeltaData::Type::EXISTENCE_CONSTRAINT_CREATE: { diff --git a/src/storage/v2/disk/durable_metadata.cpp b/src/storage/v2/disk/durable_metadata.cpp index fe2c558ae..bce8344c5 100644 --- a/src/storage/v2/disk/durable_metadata.cpp +++ b/src/storage/v2/disk/durable_metadata.cpp @@ -1,4 +1,4 @@ -// Copyright 2023 Memgraph Ltd. +// Copyright 2024 Memgraph Ltd. // // Use of this software is governed by the Business Source License // included in the file licenses/BSL.txt; by using this file, you agree to be bound by the terms of the Business Source @@ -26,6 +26,7 @@ constexpr const char *kVertexCountDescr = "vertex_count"; constexpr const char *kEdgeDountDescr = "edge_count"; constexpr const char *kLabelIndexStr = "label_index"; constexpr const char *kLabelPropertyIndexStr = "label_property_index"; +constexpr const char *kTextIndexStr = "label_property_index"; constexpr const char *kExistenceConstraintsStr = "existence_constraints"; constexpr const char *kUniqueConstraintsStr = "unique_constraints"; } // namespace @@ -144,6 +145,29 @@ bool DurableMetadata::PersistLabelPropertyIndexAndExistenceConstraintDeletion(La return true; } +bool DurableMetadata::PersistTextIndexCreation(std::string index_name) { + if (auto text_index_store = durability_kvstore_.Get(kTextIndexStr); text_index_store.has_value()) { + std::string &value = text_index_store.value(); + value += "|"; + value += index_name; + return durability_kvstore_.Put(kTextIndexStr, value); + } + return durability_kvstore_.Put(kTextIndexStr, index_name); +} + +bool DurableMetadata::PersistTextIndexDeletion(std::string index_name) { + if (auto text_index_store = durability_kvstore_.Get(kTextIndexStr); text_index_store.has_value()) { + const std::string &value = text_index_store.value(); + std::vector text_indices = utils::Split(value, "|"); + std::erase(text_indices, index_name); + if (text_indices.empty()) { + return durability_kvstore_.Delete(kTextIndexStr); + } + return durability_kvstore_.Put(kTextIndexStr, utils::Join(text_indices, "|")); + } + return true; +} + bool DurableMetadata::PersistUniqueConstraintCreation(LabelId label, const std::set &properties) { const std::string entry = utils::GetKeyForUniqueConstraintsDurability(label, properties); diff --git a/src/storage/v2/disk/durable_metadata.hpp b/src/storage/v2/disk/durable_metadata.hpp index 168cce469..6f2350c3c 100644 --- a/src/storage/v2/disk/durable_metadata.hpp +++ b/src/storage/v2/disk/durable_metadata.hpp @@ -1,4 +1,4 @@ -// Copyright 2023 Memgraph Ltd. +// Copyright 2024 Memgraph Ltd. // // Use of this software is governed by the Business Source License // included in the file licenses/BSL.txt; by using this file, you agree to be bound by the terms of the Business Source @@ -53,6 +53,10 @@ class DurableMetadata { bool PersistLabelPropertyIndexAndExistenceConstraintDeletion(LabelId label, PropertyId property, const std::string &key); + bool PersistTextIndexCreation(std::string index_name); + + bool PersistTextIndexDeletion(std::string index_name); + bool PersistUniqueConstraintCreation(LabelId label, const std::set &properties); bool PersistUniqueConstraintDeletion(LabelId label, const std::set &properties); diff --git a/src/storage/v2/disk/storage.cpp b/src/storage/v2/disk/storage.cpp index 5a61347d3..44ec89ece 100644 --- a/src/storage/v2/disk/storage.cpp +++ b/src/storage/v2/disk/storage.cpp @@ -1652,10 +1652,14 @@ utils::BasicResult DiskStorage::DiskAccessor::Co throw utils::NotYetImplemented("ClearIndexStats(stats) is not implemented for DiskStorage."); } break; case MetadataDelta::Action::TEXT_INDEX_CREATE: { - // TODO antepusic + if (!disk_storage->durable_metadata_.PersistTextIndexCreation(md_delta.text.index_name)) { + return StorageManipulationError{PersistenceError{}}; + } } break; case MetadataDelta::Action::TEXT_INDEX_DROP: { - // TODO antepusic + if (!disk_storage->durable_metadata_.PersistTextIndexDeletion(md_delta.text.index_name)) { + return StorageManipulationError{PersistenceError{}}; + } } break; case MetadataDelta::Action::EXISTENCE_CONSTRAINT_CREATE: { const auto &info = md_delta.label_property; @@ -1905,8 +1909,6 @@ utils::BasicResult DiskStorage::DiskAccessor: return {}; } -// TODO antepusic move text index creation here - utils::BasicResult DiskStorage::DiskAccessor::CreateIndex(LabelId label, PropertyId property) { MG_ASSERT(unique_guard_.owns_lock(), "Create index requires a unique access to the storage!"); @@ -1951,8 +1953,6 @@ utils::BasicResult DiskStorage::DiskAccessor: return {}; } -// TODO antepusic move text index deletion here - utils::BasicResult DiskStorage::DiskAccessor::CreateExistenceConstraint(LabelId label, PropertyId property) { MG_ASSERT(unique_guard_.owns_lock(), "Create existence constraint requires a unique access to the storage!"); diff --git a/src/storage/v2/inmemory/storage.cpp b/src/storage/v2/inmemory/storage.cpp index 2d54435d5..b38ce719c 100644 --- a/src/storage/v2/inmemory/storage.cpp +++ b/src/storage/v2/inmemory/storage.cpp @@ -1184,8 +1184,6 @@ utils::BasicResult InMemoryStorage::InMemoryA return {}; } -// TODO antepusic move text index creation here - utils::BasicResult InMemoryStorage::InMemoryAccessor::DropIndex(LabelId label) { MG_ASSERT(unique_guard_.owns_lock(), "Dropping label index requires a unique access to the storage!"); auto *in_memory = static_cast(storage_); @@ -1214,8 +1212,6 @@ utils::BasicResult InMemoryStorage::InMemoryA return {}; } -// TODO antepusic move text index deletion here - utils::BasicResult InMemoryStorage::InMemoryAccessor::CreateExistenceConstraint(LabelId label, PropertyId property) { MG_ASSERT(unique_guard_.owns_lock(), "Creating existence requires a unique access to the storage!"); diff --git a/src/storage/v2/replication/replication_client.cpp b/src/storage/v2/replication/replication_client.cpp index 6d47e67e9..ae0664bc4 100644 --- a/src/storage/v2/replication/replication_client.cpp +++ b/src/storage/v2/replication/replication_client.cpp @@ -316,7 +316,6 @@ void ReplicaStream::AppendOperation(durability::StorageMetadataOperation operati const std::set &properties, const LabelIndexStats &stats, const LabelPropertyIndexStats &property_stats, uint64_t timestamp) { replication::Encoder encoder(stream_.GetBuilder()); - // TODO antepusic EncodeOperation(&encoder, storage_->name_id_mapper_.get(), operation, label, properties, stats, property_stats, timestamp); }