Decouple text indices from other index types
This commit is contained in:
parent
3114c69627
commit
3bc570ead8
@ -186,6 +186,9 @@ constexpr utils::TypeInfo query::ProfileQuery::kType{utils::TypeId::AST_PROFILE_
|
||||
|
||||
constexpr utils::TypeInfo query::IndexQuery::kType{utils::TypeId::AST_INDEX_QUERY, "IndexQuery", &query::Query::kType};
|
||||
|
||||
constexpr utils::TypeInfo query::TextIndexQuery::kType{utils::TypeId::AST_TEXT_INDEX_QUERY, "TextIndexQuery",
|
||||
&query::Query::kType};
|
||||
|
||||
constexpr utils::TypeInfo query::Create::kType{utils::TypeId::AST_CREATE, "Create", &query::Clause::kType};
|
||||
|
||||
constexpr utils::TypeInfo query::CallProcedure::kType{utils::TypeId::AST_CALL_PROCEDURE, "CallProcedure",
|
||||
|
@ -2196,39 +2196,59 @@ class IndexQuery : public memgraph::query::Query {
|
||||
|
||||
enum class Action { CREATE, DROP };
|
||||
|
||||
// IndexQuery distinguishes two types of indices. Lookup indices (label and label & property) make it faster to look
|
||||
// up nodes, whereas text indices enable text search.
|
||||
enum class Type { LOOKUP, TEXT };
|
||||
|
||||
IndexQuery() = default;
|
||||
|
||||
DEFVISITABLE(QueryVisitor<void>);
|
||||
|
||||
memgraph::query::IndexQuery::Action action_;
|
||||
memgraph::query::IndexQuery::Type type_;
|
||||
memgraph::query::LabelIx label_;
|
||||
std::vector<memgraph::query::PropertyIx> properties_;
|
||||
std::string index_name_;
|
||||
|
||||
IndexQuery *Clone(AstStorage *storage) const override {
|
||||
IndexQuery *object = storage->Create<IndexQuery>();
|
||||
object->action_ = action_;
|
||||
object->type_ = type_;
|
||||
object->label_ = storage->GetLabelIx(label_.name);
|
||||
object->properties_.resize(properties_.size());
|
||||
for (auto i = 0; i < object->properties_.size(); ++i) {
|
||||
object->properties_[i] = storage->GetPropertyIx(properties_[i].name);
|
||||
}
|
||||
return object;
|
||||
}
|
||||
|
||||
protected:
|
||||
IndexQuery(Action action, LabelIx label, std::vector<PropertyIx> properties)
|
||||
: action_(action), label_(std::move(label)), properties_(std::move(properties)) {}
|
||||
|
||||
private:
|
||||
friend class AstStorage;
|
||||
};
|
||||
|
||||
class TextIndexQuery : public memgraph::query::Query {
|
||||
public:
|
||||
static const utils::TypeInfo kType;
|
||||
const utils::TypeInfo &GetTypeInfo() const override { return kType; }
|
||||
|
||||
enum class Action { CREATE, DROP };
|
||||
|
||||
TextIndexQuery() = default;
|
||||
|
||||
DEFVISITABLE(QueryVisitor<void>);
|
||||
|
||||
memgraph::query::TextIndexQuery::Action action_;
|
||||
memgraph::query::LabelIx label_;
|
||||
std::string index_name_;
|
||||
|
||||
TextIndexQuery *Clone(AstStorage *storage) const override {
|
||||
TextIndexQuery *object = storage->Create<TextIndexQuery>();
|
||||
object->action_ = action_;
|
||||
object->label_ = storage->GetLabelIx(label_.name);
|
||||
object->index_name_ = index_name_;
|
||||
return object;
|
||||
}
|
||||
|
||||
protected:
|
||||
IndexQuery(Action action, Type type, LabelIx label, std::vector<PropertyIx> properties)
|
||||
: action_(action), type_(type), label_(label), properties_(properties) {}
|
||||
|
||||
IndexQuery(Action action, Type type, LabelIx label, std::vector<PropertyIx> properties, std::string index_name)
|
||||
: action_(action), type_(type), label_(label), properties_(properties), index_name_(index_name) {}
|
||||
TextIndexQuery(Action action, LabelIx label, std::string index_name)
|
||||
: action_(action), label_(std::move(label)), index_name_(index_name) {}
|
||||
|
||||
private:
|
||||
friend class AstStorage;
|
||||
|
@ -82,6 +82,7 @@ class AuthQuery;
|
||||
class ExplainQuery;
|
||||
class ProfileQuery;
|
||||
class IndexQuery;
|
||||
class TextIndexQuery;
|
||||
class DatabaseInfoQuery;
|
||||
class SystemInfoQuery;
|
||||
class ConstraintQuery;
|
||||
@ -143,11 +144,11 @@ class ExpressionVisitor
|
||||
|
||||
template <class TResult>
|
||||
class QueryVisitor
|
||||
: public utils::Visitor<TResult, CypherQuery, ExplainQuery, ProfileQuery, IndexQuery, AuthQuery, DatabaseInfoQuery,
|
||||
SystemInfoQuery, ConstraintQuery, DumpQuery, ReplicationQuery, LockPathQuery,
|
||||
FreeMemoryQuery, TriggerQuery, IsolationLevelQuery, CreateSnapshotQuery, StreamQuery,
|
||||
SettingQuery, VersionQuery, ShowConfigQuery, TransactionQueueQuery, StorageModeQuery,
|
||||
AnalyzeGraphQuery, MultiDatabaseQuery, ShowDatabasesQuery, EdgeImportModeQuery,
|
||||
CoordinatorQuery> {};
|
||||
: public utils::Visitor<TResult, CypherQuery, ExplainQuery, ProfileQuery, IndexQuery, TextIndexQuery, AuthQuery,
|
||||
DatabaseInfoQuery, SystemInfoQuery, ConstraintQuery, DumpQuery, ReplicationQuery,
|
||||
LockPathQuery, FreeMemoryQuery, TriggerQuery, IsolationLevelQuery, CreateSnapshotQuery,
|
||||
StreamQuery, SettingQuery, VersionQuery, ShowConfigQuery, TransactionQueueQuery,
|
||||
StorageModeQuery, AnalyzeGraphQuery, MultiDatabaseQuery, ShowDatabasesQuery,
|
||||
EdgeImportModeQuery, CoordinatorQuery> {};
|
||||
|
||||
} // namespace memgraph::query
|
||||
|
@ -243,10 +243,16 @@ antlrcpp::Any CypherMainVisitor::visitIndexQuery(MemgraphCypher::IndexQueryConte
|
||||
return index_query;
|
||||
}
|
||||
|
||||
antlrcpp::Any CypherMainVisitor::visitTextIndexQuery(MemgraphCypher::TextIndexQueryContext *ctx) {
|
||||
MG_ASSERT(ctx->children.size() == 1, "TextIndexQuery should have exactly one child!");
|
||||
auto *text_index_query = std::any_cast<TextIndexQuery *>(ctx->children[0]->accept(this));
|
||||
query_ = text_index_query;
|
||||
return text_index_query;
|
||||
}
|
||||
|
||||
antlrcpp::Any CypherMainVisitor::visitCreateIndex(MemgraphCypher::CreateIndexContext *ctx) {
|
||||
auto *index_query = storage_->Create<IndexQuery>();
|
||||
index_query->action_ = IndexQuery::Action::CREATE;
|
||||
index_query->type_ = IndexQuery::Type::LOOKUP;
|
||||
index_query->label_ = AddLabel(std::any_cast<std::string>(ctx->labelName()->accept(this)));
|
||||
if (ctx->propertyKeyName()) {
|
||||
auto name_key = std::any_cast<PropertyIx>(ctx->propertyKeyName()->accept(this));
|
||||
@ -256,10 +262,9 @@ antlrcpp::Any CypherMainVisitor::visitCreateIndex(MemgraphCypher::CreateIndexCon
|
||||
}
|
||||
|
||||
antlrcpp::Any CypherMainVisitor::visitCreateTextIndex(MemgraphCypher::CreateTextIndexContext *ctx) {
|
||||
auto *index_query = storage_->Create<IndexQuery>();
|
||||
auto *index_query = storage_->Create<TextIndexQuery>();
|
||||
index_query->index_name_ = std::any_cast<std::string>(ctx->indexName()->accept(this));
|
||||
index_query->action_ = IndexQuery::Action::CREATE;
|
||||
index_query->type_ = IndexQuery::Type::TEXT;
|
||||
index_query->action_ = TextIndexQuery::Action::CREATE;
|
||||
index_query->label_ = AddLabel(std::any_cast<std::string>(ctx->labelName()->accept(this)));
|
||||
return index_query;
|
||||
}
|
||||
@ -267,7 +272,6 @@ antlrcpp::Any CypherMainVisitor::visitCreateTextIndex(MemgraphCypher::CreateText
|
||||
antlrcpp::Any CypherMainVisitor::visitDropIndex(MemgraphCypher::DropIndexContext *ctx) {
|
||||
auto *index_query = storage_->Create<IndexQuery>();
|
||||
index_query->action_ = IndexQuery::Action::DROP;
|
||||
index_query->type_ = IndexQuery::Type::LOOKUP;
|
||||
if (ctx->propertyKeyName()) {
|
||||
auto key = std::any_cast<PropertyIx>(ctx->propertyKeyName()->accept(this));
|
||||
index_query->properties_ = {key};
|
||||
@ -277,10 +281,9 @@ antlrcpp::Any CypherMainVisitor::visitDropIndex(MemgraphCypher::DropIndexContext
|
||||
}
|
||||
|
||||
antlrcpp::Any CypherMainVisitor::visitDropTextIndex(MemgraphCypher::DropTextIndexContext *ctx) {
|
||||
auto *index_query = storage_->Create<IndexQuery>();
|
||||
auto *index_query = storage_->Create<TextIndexQuery>();
|
||||
index_query->index_name_ = std::any_cast<std::string>(ctx->indexName()->accept(this));
|
||||
index_query->action_ = IndexQuery::Action::DROP;
|
||||
index_query->type_ = IndexQuery::Type::TEXT;
|
||||
index_query->action_ = TextIndexQuery::Action::DROP;
|
||||
return index_query;
|
||||
}
|
||||
|
||||
|
@ -148,6 +148,11 @@ class CypherMainVisitor : public antlropencypher::MemgraphCypherBaseVisitor {
|
||||
*/
|
||||
antlrcpp::Any visitIndexQuery(MemgraphCypher::IndexQueryContext *ctx) override;
|
||||
|
||||
/**
|
||||
* @return TextIndexQuery*
|
||||
*/
|
||||
antlrcpp::Any visitTextIndexQuery(MemgraphCypher::TextIndexQueryContext *ctx) override;
|
||||
|
||||
/**
|
||||
* @return ExplainQuery*
|
||||
*/
|
||||
@ -489,7 +494,7 @@ class CypherMainVisitor : public antlropencypher::MemgraphCypherBaseVisitor {
|
||||
antlrcpp::Any visitCreateIndex(MemgraphCypher::CreateIndexContext *ctx) override;
|
||||
|
||||
/**
|
||||
* @return IndexQuery*
|
||||
* @return TextIndexQuery*
|
||||
*/
|
||||
antlrcpp::Any visitCreateTextIndex(MemgraphCypher::CreateTextIndexContext *ctx) override;
|
||||
|
||||
@ -499,7 +504,7 @@ class CypherMainVisitor : public antlropencypher::MemgraphCypherBaseVisitor {
|
||||
antlrcpp::Any visitDropIndex(MemgraphCypher::DropIndexContext *ctx) override;
|
||||
|
||||
/**
|
||||
* @return IndexQuery*
|
||||
* @return TextIndexQuery*
|
||||
*/
|
||||
antlrcpp::Any visitDropTextIndex(MemgraphCypher::DropTextIndexContext *ctx) override;
|
||||
|
||||
|
@ -25,6 +25,7 @@ statement : query ;
|
||||
|
||||
query : cypherQuery
|
||||
| indexQuery
|
||||
| textIndexQuery
|
||||
| explainQuery
|
||||
| profileQuery
|
||||
| databaseInfoQuery
|
||||
@ -63,7 +64,9 @@ profileQuery : PROFILE cypherQuery ;
|
||||
|
||||
cypherQuery : singleQuery ( cypherUnion )* ( queryMemoryLimit )? ;
|
||||
|
||||
indexQuery : createIndex | dropIndex | createTextIndex | dropTextIndex;
|
||||
indexQuery : createIndex | dropIndex;
|
||||
|
||||
textIndexQuery : createTextIndex | dropTextIndex;
|
||||
|
||||
singleQuery : clause ( clause )* ;
|
||||
|
||||
|
@ -133,6 +133,7 @@ symbolicName : UnescapedSymbolicName
|
||||
|
||||
query : cypherQuery
|
||||
| indexQuery
|
||||
| textIndexQuery
|
||||
| explainQuery
|
||||
| profileQuery
|
||||
| databaseInfoQuery
|
||||
|
@ -27,6 +27,8 @@ class PrivilegeExtractor : public QueryVisitor<void>, public HierarchicalTreeVis
|
||||
|
||||
void Visit(IndexQuery & /*unused*/) override { AddPrivilege(AuthQuery::Privilege::INDEX); }
|
||||
|
||||
void Visit(TextIndexQuery & /*unused*/) override { AddPrivilege(AuthQuery::Privilege::INDEX); }
|
||||
|
||||
void Visit(AnalyzeGraphQuery & /*unused*/) override { AddPrivilege(AuthQuery::Privilege::INDEX); }
|
||||
|
||||
void Visit(AuthQuery & /*unused*/) override { AddPrivilege(AuthQuery::Privilege::AUTH); }
|
||||
|
@ -2543,7 +2543,6 @@ PreparedQuery PrepareIndexQuery(ParsedQuery parsed_query, bool in_explicit_trans
|
||||
|
||||
auto *storage = db_acc->storage();
|
||||
auto label = storage->NameToLabel(index_query->label_.name);
|
||||
auto &index_name = index_query->index_name_;
|
||||
|
||||
std::vector<storage::PropertyId> properties;
|
||||
std::vector<std::string> properties_string;
|
||||
@ -2567,20 +2566,12 @@ PreparedQuery PrepareIndexQuery(ParsedQuery parsed_query, bool in_explicit_trans
|
||||
fmt::format("Created index on label {} on properties {}.", index_query->label_.name, properties_stringified);
|
||||
|
||||
// TODO: not just storage + invalidate_plan_cache. Need a DB transaction (for replication)
|
||||
handler = [dba, index_type = index_query->type_, label, index_name,
|
||||
properties_stringified = std::move(properties_stringified), label_name = index_query->label_.name,
|
||||
properties = std::move(properties),
|
||||
handler = [dba, label, properties_stringified = std::move(properties_stringified),
|
||||
label_name = index_query->label_.name, properties = std::move(properties),
|
||||
invalidate_plan_cache = std::move(invalidate_plan_cache)](Notification &index_notification) {
|
||||
MG_ASSERT(properties.size() <= 1U);
|
||||
std::optional<utils::BasicResult<storage::StorageIndexDefinitionError, void>> maybe_index_error;
|
||||
if (index_type == IndexQuery::Type::LOOKUP) {
|
||||
maybe_index_error = properties.empty() ? dba->CreateIndex(label) : dba->CreateIndex(label, properties[0]);
|
||||
} else if (index_type == IndexQuery::Type::TEXT) {
|
||||
if (!flags::run_time::GetExperimentalTextSearchEnabled()) {
|
||||
throw QueryException("To use text indices, enable the text search feature.");
|
||||
}
|
||||
maybe_index_error = dba->CreateTextIndex(index_name, label);
|
||||
}
|
||||
maybe_index_error = properties.empty() ? dba->CreateIndex(label) : dba->CreateIndex(label, properties[0]);
|
||||
utils::OnScopeExit invalidator(invalidate_plan_cache);
|
||||
|
||||
if (maybe_index_error.has_value() && maybe_index_error.value().HasError()) {
|
||||
@ -2597,20 +2588,12 @@ PreparedQuery PrepareIndexQuery(ParsedQuery parsed_query, bool in_explicit_trans
|
||||
index_notification.title = fmt::format("Dropped index on label {} on properties {}.", index_query->label_.name,
|
||||
utils::Join(properties_string, ", "));
|
||||
// TODO: not just storage + invalidate_plan_cache. Need a DB transaction (for replication)
|
||||
handler = [dba, index_type = index_query->type_, label, index_name,
|
||||
properties_stringified = std::move(properties_stringified), label_name = index_query->label_.name,
|
||||
properties = std::move(properties),
|
||||
handler = [dba, label, properties_stringified = std::move(properties_stringified),
|
||||
label_name = index_query->label_.name, properties = std::move(properties),
|
||||
invalidate_plan_cache = std::move(invalidate_plan_cache)](Notification &index_notification) {
|
||||
MG_ASSERT(properties.size() <= 1U);
|
||||
std::optional<utils::BasicResult<storage::StorageIndexDefinitionError, void>> maybe_index_error;
|
||||
if (index_type == IndexQuery::Type::LOOKUP) {
|
||||
maybe_index_error = properties.empty() ? dba->DropIndex(label) : dba->DropIndex(label, properties[0]);
|
||||
} else if (index_type == IndexQuery::Type::TEXT) {
|
||||
if (!flags::run_time::GetExperimentalTextSearchEnabled()) {
|
||||
throw QueryException("To use text indices, enable the text search feature.");
|
||||
}
|
||||
maybe_index_error = dba->DropTextIndex(index_name);
|
||||
}
|
||||
maybe_index_error = properties.empty() ? dba->DropIndex(label) : dba->DropIndex(label, properties[0]);
|
||||
utils::OnScopeExit invalidator(invalidate_plan_cache);
|
||||
|
||||
if (maybe_index_error.has_value() && maybe_index_error.value().HasError()) {
|
||||
@ -2635,6 +2618,89 @@ PreparedQuery PrepareIndexQuery(ParsedQuery parsed_query, bool in_explicit_trans
|
||||
RWType::W};
|
||||
}
|
||||
|
||||
PreparedQuery PrepareTextIndexQuery(ParsedQuery parsed_query, bool in_explicit_transaction,
|
||||
std::vector<Notification> *notifications, CurrentDB ¤t_db) {
|
||||
if (in_explicit_transaction) {
|
||||
throw IndexInMulticommandTxException();
|
||||
}
|
||||
|
||||
auto *text_index_query = utils::Downcast<TextIndexQuery>(parsed_query.query);
|
||||
std::function<void(Notification &)> handler;
|
||||
|
||||
// TODO: we will need transaction for replication
|
||||
MG_ASSERT(current_db.db_acc_, "Text index query expects a current DB");
|
||||
auto &db_acc = *current_db.db_acc_;
|
||||
|
||||
MG_ASSERT(current_db.db_transactional_accessor_, "Text index query expects a current DB transaction");
|
||||
auto *dba = &*current_db.execution_db_accessor_;
|
||||
|
||||
// Creating an index influences computed plan costs.
|
||||
auto invalidate_plan_cache = [plan_cache = db_acc->plan_cache()] {
|
||||
plan_cache->WithLock([&](auto &cache) { cache.reset(); });
|
||||
};
|
||||
|
||||
auto *storage = db_acc->storage();
|
||||
auto label = storage->NameToLabel(text_index_query->label_.name);
|
||||
auto &index_name = text_index_query->index_name_;
|
||||
|
||||
Notification index_notification(SeverityLevel::INFO);
|
||||
switch (text_index_query->action_) {
|
||||
case TextIndexQuery::Action::CREATE: {
|
||||
index_notification.code = NotificationCode::CREATE_INDEX;
|
||||
index_notification.title = fmt::format("Created text index on label {}.", text_index_query->label_.name);
|
||||
|
||||
// TODO: not just storage + invalidate_plan_cache. Need a DB transaction (for replication)
|
||||
handler = [dba, label, index_name, label_name = text_index_query->label_.name,
|
||||
invalidate_plan_cache = std::move(invalidate_plan_cache)](Notification &index_notification) {
|
||||
std::optional<utils::BasicResult<storage::StorageIndexDefinitionError, void>> maybe_index_error;
|
||||
if (!flags::run_time::GetExperimentalTextSearchEnabled()) {
|
||||
throw TextSearchDisabledException();
|
||||
}
|
||||
maybe_index_error = dba->CreateTextIndex(index_name, label);
|
||||
utils::OnScopeExit invalidator(invalidate_plan_cache);
|
||||
|
||||
if (maybe_index_error.has_value() && maybe_index_error.value().HasError()) {
|
||||
index_notification.code = NotificationCode::EXISTENT_INDEX;
|
||||
index_notification.title = fmt::format("Text index on label {} already exists.", label_name);
|
||||
// ABORT?
|
||||
}
|
||||
};
|
||||
break;
|
||||
}
|
||||
case TextIndexQuery::Action::DROP: {
|
||||
index_notification.code = NotificationCode::DROP_INDEX;
|
||||
index_notification.title = fmt::format("Dropped text index on label {}.", text_index_query->label_.name);
|
||||
// TODO: not just storage + invalidate_plan_cache. Need a DB transaction (for replication)
|
||||
handler = [dba, label, index_name, label_name = text_index_query->label_.name,
|
||||
invalidate_plan_cache = std::move(invalidate_plan_cache)](Notification &index_notification) {
|
||||
std::optional<utils::BasicResult<storage::StorageIndexDefinitionError, void>> maybe_index_error;
|
||||
if (!flags::run_time::GetExperimentalTextSearchEnabled()) {
|
||||
throw TextSearchDisabledException();
|
||||
}
|
||||
maybe_index_error = dba->DropTextIndex(index_name);
|
||||
utils::OnScopeExit invalidator(invalidate_plan_cache);
|
||||
|
||||
if (maybe_index_error.has_value() && maybe_index_error.value().HasError()) {
|
||||
index_notification.code = NotificationCode::NONEXISTENT_INDEX;
|
||||
index_notification.title = fmt::format("Text index on label {} doesn't exist.", label_name);
|
||||
}
|
||||
};
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return PreparedQuery{
|
||||
{},
|
||||
std::move(parsed_query.required_privileges),
|
||||
[handler = std::move(handler), notifications, index_notification = std::move(index_notification)](
|
||||
AnyStream * /*stream*/, std::optional<int> /*unused*/) mutable {
|
||||
handler(index_notification);
|
||||
notifications->push_back(index_notification);
|
||||
return QueryHandlerResult::COMMIT; // TODO: Will need to become COMMIT when we fix replication
|
||||
},
|
||||
RWType::W};
|
||||
}
|
||||
|
||||
PreparedQuery PrepareAuthQuery(ParsedQuery parsed_query, bool in_explicit_transaction,
|
||||
InterpreterContext *interpreter_context, Interpreter &interpreter) {
|
||||
if (in_explicit_transaction) {
|
||||
@ -4227,13 +4293,14 @@ Interpreter::PrepareResult Interpreter::Prepare(const std::string &query_string,
|
||||
utils::Downcast<CypherQuery>(parsed_query.query) || utils::Downcast<ExplainQuery>(parsed_query.query) ||
|
||||
utils::Downcast<ProfileQuery>(parsed_query.query) || utils::Downcast<DumpQuery>(parsed_query.query) ||
|
||||
utils::Downcast<TriggerQuery>(parsed_query.query) || utils::Downcast<AnalyzeGraphQuery>(parsed_query.query) ||
|
||||
utils::Downcast<IndexQuery>(parsed_query.query) || utils::Downcast<DatabaseInfoQuery>(parsed_query.query) ||
|
||||
utils::Downcast<ConstraintQuery>(parsed_query.query);
|
||||
utils::Downcast<IndexQuery>(parsed_query.query) || utils::Downcast<TextIndexQuery>(parsed_query.query) ||
|
||||
utils::Downcast<DatabaseInfoQuery>(parsed_query.query) || utils::Downcast<ConstraintQuery>(parsed_query.query);
|
||||
|
||||
if (!in_explicit_transaction_ && requires_db_transaction) {
|
||||
// TODO: ATM only a single database, will change when we have multiple database transactions
|
||||
bool could_commit = utils::Downcast<CypherQuery>(parsed_query.query) != nullptr;
|
||||
bool unique = utils::Downcast<IndexQuery>(parsed_query.query) != nullptr ||
|
||||
utils::Downcast<TextIndexQuery>(parsed_query.query) != nullptr ||
|
||||
utils::Downcast<ConstraintQuery>(parsed_query.query) != nullptr ||
|
||||
upper_case_query.find(kSchemaAssert) != std::string::npos;
|
||||
SetupDatabaseTransaction(could_commit, unique);
|
||||
@ -4270,6 +4337,9 @@ Interpreter::PrepareResult Interpreter::Prepare(const std::string &query_string,
|
||||
} else if (utils::Downcast<IndexQuery>(parsed_query.query)) {
|
||||
prepared_query = PrepareIndexQuery(std::move(parsed_query), in_explicit_transaction_,
|
||||
&query_execution->notifications, current_db_);
|
||||
} else if (utils::Downcast<TextIndexQuery>(parsed_query.query)) {
|
||||
prepared_query = PrepareTextIndexQuery(std::move(parsed_query), in_explicit_transaction_,
|
||||
&query_execution->notifications, current_db_);
|
||||
} else if (utils::Downcast<AnalyzeGraphQuery>(parsed_query.query)) {
|
||||
prepared_query = PrepareAnalyzeGraphQuery(std::move(parsed_query), in_explicit_transaction_, current_db_);
|
||||
} else if (utils::Downcast<AuthQuery>(parsed_query.query)) {
|
||||
|
@ -173,6 +173,7 @@ enum class TypeId : uint64_t {
|
||||
AST_EXPLAIN_QUERY,
|
||||
AST_PROFILE_QUERY,
|
||||
AST_INDEX_QUERY,
|
||||
AST_TEXT_INDEX_QUERY,
|
||||
AST_CREATE,
|
||||
AST_CALL_PROCEDURE,
|
||||
AST_MATCH,
|
||||
|
@ -563,9 +563,8 @@ auto GetForeach(AstStorage &storage, NamedExpression *named_expr, const std::vec
|
||||
memgraph::query::test_common::OnCreate { \
|
||||
std::vector<memgraph::query::Clause *> { __VA_ARGS__ } \
|
||||
}
|
||||
#define CREATE_INDEX_ON(label, property) \
|
||||
storage.Create<memgraph::query::IndexQuery>(memgraph::query::IndexQuery::Action::CREATE, \
|
||||
memgraph::query::IndexQuery::Type::LOOKUP, (label), \
|
||||
#define CREATE_INDEX_ON(label, property) \
|
||||
storage.Create<memgraph::query::IndexQuery>(memgraph::query::IndexQuery::Action::CREATE, (label), \
|
||||
std::vector<memgraph::query::PropertyIx>{(property)})
|
||||
#define QUERY(...) memgraph::query::test_common::GetQuery(this->storage, __VA_ARGS__)
|
||||
#define SINGLE_QUERY(...) \
|
||||
|
Loading…
Reference in New Issue
Block a user