Skip to content

Commit 619b01f

Browse files
authored
Implement edge type indices (#1542)
Implement edge type indices (#1542 )
1 parent 5ca98f9 commit 619b01f

File tree

96 files changed

+3379
-51
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

96 files changed

+3379
-51
lines changed

src/communication/result_stream_faker.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Copyright 2023 Memgraph Ltd.
1+
// Copyright 2024 Memgraph Ltd.
22
//
33
// Use of this software is governed by the Business Source License
44
// included in the file licenses/BSL.txt; by using this file, you agree to be bound by the terms of the Business Source

src/dbms/database_handler.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Copyright 2023 Memgraph Ltd.
1+
// Copyright 2024 Memgraph Ltd.
22
//
33
// Use of this software is governed by the Business Source License
44
// included in the file licenses/BSL.txt; by using this file, you agree to be bound by the terms of the Business Source

src/dbms/inmemory/replication_handlers.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -840,6 +840,20 @@ uint64_t InMemoryReplicationHandlers::ReadAndApplyDelta(storage::InMemoryStorage
840840
transaction->DeleteLabelPropertyIndexStats(storage->NameToLabel(info.label));
841841
break;
842842
}
843+
case WalDeltaData::Type::EDGE_INDEX_CREATE: {
844+
spdlog::trace(" Create edge index on :{}", delta.operation_edge_type.edge_type);
845+
auto *transaction = get_transaction(timestamp, kUniqueAccess);
846+
if (transaction->CreateIndex(storage->NameToEdgeType(delta.operation_label.label)).HasError())
847+
throw utils::BasicException("Invalid transaction! Please raise an issue, {}:{}", __FILE__, __LINE__);
848+
break;
849+
}
850+
case WalDeltaData::Type::EDGE_INDEX_DROP: {
851+
spdlog::trace(" Drop edge index on :{}", delta.operation_edge_type.edge_type);
852+
auto *transaction = get_transaction(timestamp, kUniqueAccess);
853+
if (transaction->DropIndex(storage->NameToEdgeType(delta.operation_label.label)).HasError())
854+
throw utils::BasicException("Invalid transaction! Please raise an issue, {}:{}", __FILE__, __LINE__);
855+
break;
856+
}
843857
case WalDeltaData::Type::EXISTENCE_CONSTRAINT_CREATE: {
844858
spdlog::trace(" Create existence constraint on :{} ({})", delta.operation_label_property.label,
845859
delta.operation_label_property.property);

src/glue/communication.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Copyright 2023 Memgraph Ltd.
1+
// Copyright 2024 Memgraph Ltd.
22
//
33
// Use of this software is governed by the Business Source License
44
// included in the file licenses/BSL.txt; by using this file, you agree to be bound by the terms of the Business Source

src/query/db_accessor.hpp

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -371,6 +371,62 @@ class VerticesIterable final {
371371
}
372372
};
373373

374+
class EdgesIterable final {
375+
std::variant<storage::EdgesIterable, std::unordered_set<EdgeAccessor, std::hash<EdgeAccessor>, std::equal_to<void>,
376+
utils::Allocator<EdgeAccessor>> *>
377+
iterable_;
378+
379+
public:
380+
class Iterator final {
381+
std::variant<storage::EdgesIterable::Iterator,
382+
std::unordered_set<EdgeAccessor, std::hash<EdgeAccessor>, std::equal_to<void>,
383+
utils::Allocator<EdgeAccessor>>::iterator>
384+
it_;
385+
386+
public:
387+
explicit Iterator(storage::EdgesIterable::Iterator it) : it_(std::move(it)) {}
388+
explicit Iterator(std::unordered_set<EdgeAccessor, std::hash<EdgeAccessor>, std::equal_to<void>,
389+
utils::Allocator<EdgeAccessor>>::iterator it)
390+
: it_(it) {}
391+
392+
EdgeAccessor operator*() const {
393+
return std::visit([](auto &it_) { return EdgeAccessor(*it_); }, it_);
394+
}
395+
396+
Iterator &operator++() {
397+
std::visit([](auto &it_) { ++it_; }, it_);
398+
return *this;
399+
}
400+
401+
bool operator==(const Iterator &other) const { return it_ == other.it_; }
402+
403+
bool operator!=(const Iterator &other) const { return !(other == *this); }
404+
};
405+
406+
explicit EdgesIterable(storage::EdgesIterable iterable) : iterable_(std::move(iterable)) {}
407+
explicit EdgesIterable(std::unordered_set<EdgeAccessor, std::hash<EdgeAccessor>, std::equal_to<void>,
408+
utils::Allocator<EdgeAccessor>> *edges)
409+
: iterable_(edges) {}
410+
411+
Iterator begin() {
412+
return std::visit(
413+
memgraph::utils::Overloaded{
414+
[](storage::EdgesIterable &iterable_) { return Iterator(iterable_.begin()); },
415+
[](std::unordered_set<EdgeAccessor, std::hash<EdgeAccessor>, std::equal_to<void>,
416+
utils::Allocator<EdgeAccessor>> *iterable_) { return Iterator(iterable_->begin()); }},
417+
iterable_);
418+
}
419+
420+
Iterator end() {
421+
return std::visit(
422+
memgraph::utils::Overloaded{
423+
[](storage::EdgesIterable &iterable_) { return Iterator(iterable_.end()); },
424+
[](std::unordered_set<EdgeAccessor, std::hash<EdgeAccessor>, std::equal_to<void>,
425+
utils::Allocator<EdgeAccessor>> *iterable_) { return Iterator(iterable_->end()); }},
426+
iterable_);
427+
}
428+
};
429+
374430
class DbAccessor final {
375431
storage::Storage::Accessor *accessor_;
376432

@@ -416,6 +472,10 @@ class DbAccessor final {
416472
return VerticesIterable(accessor_->Vertices(label, property, lower, upper, view));
417473
}
418474

475+
EdgesIterable Edges(storage::View view, storage::EdgeTypeId edge_type) {
476+
return EdgesIterable(accessor_->Edges(edge_type, view));
477+
}
478+
419479
VertexAccessor InsertVertex() { return VertexAccessor(accessor_->CreateVertex()); }
420480

421481
storage::Result<EdgeAccessor> InsertEdge(VertexAccessor *from, VertexAccessor *to,
@@ -572,6 +632,8 @@ class DbAccessor final {
572632
return accessor_->LabelPropertyIndexExists(label, prop);
573633
}
574634

635+
bool EdgeTypeIndexExists(storage::EdgeTypeId edge_type) const { return accessor_->EdgeTypeIndexExists(edge_type); }
636+
575637
std::optional<storage::LabelIndexStats> GetIndexStats(const storage::LabelId &label) const {
576638
return accessor_->GetIndexStats(label);
577639
}
@@ -638,6 +700,10 @@ class DbAccessor final {
638700
return accessor_->CreateIndex(label, property);
639701
}
640702

703+
utils::BasicResult<storage::StorageIndexDefinitionError, void> CreateIndex(storage::EdgeTypeId edge_type) {
704+
return accessor_->CreateIndex(edge_type);
705+
}
706+
641707
utils::BasicResult<storage::StorageIndexDefinitionError, void> DropIndex(storage::LabelId label) {
642708
return accessor_->DropIndex(label);
643709
}
@@ -647,6 +713,10 @@ class DbAccessor final {
647713
return accessor_->DropIndex(label, property);
648714
}
649715

716+
utils::BasicResult<storage::StorageIndexDefinitionError, void> DropIndex(storage::EdgeTypeId edge_type) {
717+
return accessor_->DropIndex(edge_type);
718+
}
719+
650720
utils::BasicResult<storage::StorageExistenceConstraintDefinitionError, void> CreateExistenceConstraint(
651721
storage::LabelId label, storage::PropertyId property) {
652722
return accessor_->CreateExistenceConstraint(label, property);

src/query/dump.cpp

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -242,6 +242,10 @@ void DumpLabelIndex(std::ostream *os, query::DbAccessor *dba, const storage::Lab
242242
*os << "CREATE INDEX ON :" << EscapeName(dba->LabelToName(label)) << ";";
243243
}
244244

245+
void DumpEdgeTypeIndex(std::ostream *os, query::DbAccessor *dba, const storage::EdgeTypeId edge_type) {
246+
*os << "CREATE EDGE INDEX ON :" << EscapeName(dba->EdgeTypeToName(edge_type)) << ";";
247+
}
248+
245249
void DumpLabelPropertyIndex(std::ostream *os, query::DbAccessor *dba, storage::LabelId label,
246250
storage::PropertyId property) {
247251
*os << "CREATE INDEX ON :" << EscapeName(dba->LabelToName(label)) << "(" << EscapeName(dba->PropertyToName(property))
@@ -297,7 +301,9 @@ PullPlanDump::PullPlanDump(DbAccessor *dba, dbms::DatabaseAccess db_acc)
297301
// Internal index cleanup
298302
CreateInternalIndexCleanupPullChunk(),
299303
// Dump all triggers
300-
CreateTriggersPullChunk()} {}
304+
CreateTriggersPullChunk(),
305+
// Dump all edge-type indices
306+
CreateEdgeTypeIndicesPullChunk()} {}
301307

302308
bool PullPlanDump::Pull(AnyStream *stream, std::optional<int> n) {
303309
// Iterate all functions that stream some results.
@@ -352,6 +358,33 @@ PullPlanDump::PullChunk PullPlanDump::CreateLabelIndicesPullChunk() {
352358
};
353359
}
354360

361+
PullPlanDump::PullChunk PullPlanDump::CreateEdgeTypeIndicesPullChunk() {
362+
// Dump all label indices
363+
return [this, global_index = 0U](AnyStream *stream, std::optional<int> n) mutable -> std::optional<size_t> {
364+
// Delay the construction of indices vectors
365+
if (!indices_info_) {
366+
indices_info_.emplace(dba_->ListAllIndices());
367+
}
368+
const auto &edge_type = indices_info_->edge_type;
369+
370+
size_t local_counter = 0;
371+
while (global_index < edge_type.size() && (!n || local_counter < *n)) {
372+
std::ostringstream os;
373+
DumpEdgeTypeIndex(&os, dba_, edge_type[global_index]);
374+
stream->Result({TypedValue(os.str())});
375+
376+
++global_index;
377+
++local_counter;
378+
}
379+
380+
if (global_index == edge_type.size()) {
381+
return local_counter;
382+
}
383+
384+
return std::nullopt;
385+
};
386+
}
387+
355388
PullPlanDump::PullChunk PullPlanDump::CreateLabelPropertyIndicesPullChunk() {
356389
return [this, global_index = 0U](AnyStream *stream, std::optional<int> n) mutable -> std::optional<size_t> {
357390
// Delay the construction of indices vectors

src/query/dump.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,5 +63,6 @@ struct PullPlanDump {
6363
PullChunk CreateDropInternalIndexPullChunk();
6464
PullChunk CreateInternalIndexCleanupPullChunk();
6565
PullChunk CreateTriggersPullChunk();
66+
PullChunk CreateEdgeTypeIndicesPullChunk();
6667
};
6768
} // namespace memgraph::query

src/query/frontend/ast/ast.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,9 @@ constexpr utils::TypeInfo query::ProfileQuery::kType{utils::TypeId::AST_PROFILE_
186186

187187
constexpr utils::TypeInfo query::IndexQuery::kType{utils::TypeId::AST_INDEX_QUERY, "IndexQuery", &query::Query::kType};
188188

189+
constexpr utils::TypeInfo query::EdgeIndexQuery::kType{utils::TypeId::AST_EDGE_INDEX_QUERY, "EdgeIndexQuery",
190+
&query::Query::kType};
191+
189192
constexpr utils::TypeInfo query::Create::kType{utils::TypeId::AST_CREATE, "Create", &query::Clause::kType};
190193

191194
constexpr utils::TypeInfo query::CallProcedure::kType{utils::TypeId::AST_CALL_PROCEDURE, "CallProcedure",

src/query/frontend/ast/ast.hpp

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2224,6 +2224,34 @@ class IndexQuery : public memgraph::query::Query {
22242224
friend class AstStorage;
22252225
};
22262226

2227+
class EdgeIndexQuery : public memgraph::query::Query {
2228+
public:
2229+
static const utils::TypeInfo kType;
2230+
const utils::TypeInfo &GetTypeInfo() const override { return kType; }
2231+
2232+
enum class Action { CREATE, DROP };
2233+
2234+
EdgeIndexQuery() = default;
2235+
2236+
DEFVISITABLE(QueryVisitor<void>);
2237+
2238+
memgraph::query::EdgeIndexQuery::Action action_;
2239+
memgraph::query::EdgeTypeIx edge_type_;
2240+
2241+
EdgeIndexQuery *Clone(AstStorage *storage) const override {
2242+
EdgeIndexQuery *object = storage->Create<EdgeIndexQuery>();
2243+
object->action_ = action_;
2244+
object->edge_type_ = storage->GetEdgeTypeIx(edge_type_.name);
2245+
return object;
2246+
}
2247+
2248+
protected:
2249+
EdgeIndexQuery(Action action, EdgeTypeIx edge_type) : action_(action), edge_type_(edge_type) {}
2250+
2251+
private:
2252+
friend class AstStorage;
2253+
};
2254+
22272255
class Create : public memgraph::query::Clause {
22282256
public:
22292257
static const utils::TypeInfo kType;

src/query/frontend/ast/ast_visitor.hpp

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@ class AuthQuery;
8282
class ExplainQuery;
8383
class ProfileQuery;
8484
class IndexQuery;
85+
class EdgeIndexQuery;
8586
class DatabaseInfoQuery;
8687
class SystemInfoQuery;
8788
class ConstraintQuery;
@@ -143,11 +144,11 @@ class ExpressionVisitor
143144

144145
template <class TResult>
145146
class QueryVisitor
146-
: public utils::Visitor<TResult, CypherQuery, ExplainQuery, ProfileQuery, IndexQuery, AuthQuery, DatabaseInfoQuery,
147-
SystemInfoQuery, ConstraintQuery, DumpQuery, ReplicationQuery, LockPathQuery,
148-
FreeMemoryQuery, TriggerQuery, IsolationLevelQuery, CreateSnapshotQuery, StreamQuery,
149-
SettingQuery, VersionQuery, ShowConfigQuery, TransactionQueueQuery, StorageModeQuery,
150-
AnalyzeGraphQuery, MultiDatabaseQuery, ShowDatabasesQuery, EdgeImportModeQuery,
151-
CoordinatorQuery> {};
147+
: public utils::Visitor<TResult, CypherQuery, ExplainQuery, ProfileQuery, IndexQuery, EdgeIndexQuery, AuthQuery,
148+
DatabaseInfoQuery, SystemInfoQuery, ConstraintQuery, DumpQuery, ReplicationQuery,
149+
LockPathQuery, FreeMemoryQuery, TriggerQuery, IsolationLevelQuery, CreateSnapshotQuery,
150+
StreamQuery, SettingQuery, VersionQuery, ShowConfigQuery, TransactionQueueQuery,
151+
StorageModeQuery, AnalyzeGraphQuery, MultiDatabaseQuery, ShowDatabasesQuery,
152+
EdgeImportModeQuery, CoordinatorQuery> {};
152153

153154
} // namespace memgraph::query

0 commit comments

Comments
 (0)