From 48e446688f7ef4104253dde8238b492894ca156c Mon Sep 17 00:00:00 2001 From: florijan <florijan@memgraph.io> Date: Sat, 16 Sep 2017 14:08:52 +0200 Subject: [PATCH] IndexInfo function added Summary: - Keys() functions in the indices can't be const because ConcurrentMap doesn't provide const accessors (and they are broken in skiplist) :D - no cucumber tests because many tests create indices so it's hard to say what's inside and what not Reviewers: buda, mislav.bradac Reviewed By: mislav.bradac Subscribers: pullbot Differential Revision: https://phabricator.memgraph.io/D797 --- CHANGELOG.md | 1 + docs/user_technical/open-cypher.md | 1 + src/database/graph_db_accessor.cpp | 16 ++++++++++++++++ src/database/graph_db_accessor.hpp | 5 +++++ src/database/indexes/key_index.hpp | 10 ++++++++++ src/database/indexes/label_property_index.hpp | 10 ++++++++++ .../interpret/awesome_memgraph_functions.cpp | 10 ++++++++++ tests/unit/query_expression_evaluator.cpp | 19 +++++++++++++++++++ 8 files changed, 72 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index d329e9163..dfa931945 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,7 @@ * `assert` function added. * Use \u to specify 4 digit codepoint and \U for 8 digit * `counter` and `counterSet` functions added. +* `indexInfo` function added. ### Bug Fixes and Other Changes diff --git a/docs/user_technical/open-cypher.md b/docs/user_technical/open-cypher.md index 4059927df..0488e3325 100644 --- a/docs/user_technical/open-cypher.md +++ b/docs/user_technical/open-cypher.md @@ -502,6 +502,7 @@ functions. `assert` | Raises an exception reported to the client if the given argument is not `true`. `counter` | Generates integers that are guaranteed to be unique on the database level, for the given counter name. `counterSet` | Sets the counter with the given name to the given value. + `indexInfo` | Returns a list of all the indexes available in the database. The list includes indexes that are not yet ready for use (they are concurrently being built by another transaction). #### String Operators diff --git a/src/database/graph_db_accessor.cpp b/src/database/graph_db_accessor.cpp index 7d96f7e01..01cb7b1a6 100644 --- a/src/database/graph_db_accessor.cpp +++ b/src/database/graph_db_accessor.cpp @@ -341,3 +341,19 @@ void GraphDbAccessor::CounterSet(const std::string &name, int64_t value) { if (!name_counter_pair.second) name_counter_pair.first->second.store(value); } + +std::vector<std::string> GraphDbAccessor::IndexInfo() const { + std::vector<std::string> info; + for (GraphDbTypes::Label label : db_.labels_index_.Keys()) { + info.emplace_back(":" + LabelName(label)); + } + + // Edge indices are not shown because they are never used. + + for (LabelPropertyIndex::Key key : db_.label_property_index_.Keys()) { + info.emplace_back(fmt::format(":{}({})", LabelName(key.label_), + PropertyName(key.property_))); + } + + return info; +} diff --git a/src/database/graph_db_accessor.hpp b/src/database/graph_db_accessor.hpp index 19c3d131a..5423f79df 100644 --- a/src/database/graph_db_accessor.hpp +++ b/src/database/graph_db_accessor.hpp @@ -575,6 +575,11 @@ class GraphDbAccessor { */ void CounterSet(const std::string &name, int64_t value); + /* + * Returns a list of index names present in the database. + */ + std::vector<std::string> IndexInfo() const; + private: /** * Insert this vertex into corresponding label and label+property (if it diff --git a/src/database/indexes/key_index.hpp b/src/database/indexes/key_index.hpp index 8d44869f5..19365e8a5 100644 --- a/src/database/indexes/key_index.hpp +++ b/src/database/indexes/key_index.hpp @@ -96,6 +96,16 @@ class KeyIndex { }); } + /** + * Returns a vector of keys present in this index. + */ + std::vector<TKey> Keys() { + std::vector<TKey> keys; + for (auto &kv : indices_.access()) + keys.push_back(kv.first); + return keys; + } + private: /** * @brief - Contains vlist and record pointers. diff --git a/src/database/indexes/label_property_index.hpp b/src/database/indexes/label_property_index.hpp index d75b8dda3..008df6ace 100644 --- a/src/database/indexes/label_property_index.hpp +++ b/src/database/indexes/label_property_index.hpp @@ -389,6 +389,16 @@ class LabelPropertyIndex { return indices; } + /** + * Returns a vector of keys present in this index. + */ + std::vector<Key> Keys() { + std::vector<Key> keys; + for (auto &kv : indices_.access()) + keys.push_back(kv.first); + return keys; + } + private: /** * @brief - Contains value, vlist and vertex record to distinguish between diff --git a/src/query/interpret/awesome_memgraph_functions.cpp b/src/query/interpret/awesome_memgraph_functions.cpp index 14dcf7e2d..00a044046 100644 --- a/src/query/interpret/awesome_memgraph_functions.cpp +++ b/src/query/interpret/awesome_memgraph_functions.cpp @@ -545,6 +545,15 @@ TypedValue CounterSet(const std::vector<TypedValue> &args, GraphDbAccessor &dba) dba.CounterSet(args[0].ValueString(), args[1].ValueInt()); return TypedValue::Null; } + +TypedValue IndexInfo(const std::vector<TypedValue> &args, + GraphDbAccessor &dba) { + if (args.size() != 0U) + throw QueryRuntimeException("indexInfo takes zero arguments"); + + auto info = dba.IndexInfo(); + return std::vector<TypedValue>(info.begin(), info.end()); +} } // annonymous namespace std::function<TypedValue(const std::vector<TypedValue> &, GraphDbAccessor &)> @@ -590,6 +599,7 @@ NameToFunction(const std::string &function_name) { if (function_name == "ASSERT") return Assert; if (function_name == "COUNTER") return Counter; if (function_name == "COUNTERSET") return CounterSet; + if (function_name == "INDEXINFO") return IndexInfo; return nullptr; } } // namespace query diff --git a/tests/unit/query_expression_evaluator.cpp b/tests/unit/query_expression_evaluator.cpp index e61f9f6de..123d34ea2 100644 --- a/tests/unit/query_expression_evaluator.cpp +++ b/tests/unit/query_expression_evaluator.cpp @@ -1235,4 +1235,23 @@ TEST(ExpressionEvaluator, FunctionCounterSet) { EXPECT_EQ(EvaluateFunction("COUNTER", {"c1"}, dbms).ValueInt(), 13); EXPECT_EQ(EvaluateFunction("COUNTER", {"c2"}, dbms).ValueInt(), 43); } + +TEST(ExpressionEvaluator, FunctionIndexInfo) { + Dbms dbms; + EXPECT_THROW(EvaluateFunction("INDEXINFO", {1}, dbms), QueryRuntimeException); + EXPECT_EQ(EvaluateFunction("INDEXINFO", {}, dbms).ValueList().size(), 0); + auto dba = dbms.active(); + dba->InsertVertex().add_label(dba->Label("l1")); + { + auto info = ToList<std::string>(EvaluateFunction("INDEXINFO", {}, dbms)); + EXPECT_EQ(info.size(), 1); + EXPECT_EQ(info[0], ":l1"); + } + { + dba->BuildIndex(dba->Label("l1"), dba->Property("prop")); + auto info = ToList<std::string>(EvaluateFunction("INDEXINFO", {}, dbms)); + EXPECT_EQ(info.size(), 2); + EXPECT_THAT(info, testing::UnorderedElementsAre(":l1", ":l1(prop)")); + } +} } // namespace