diff --git a/src/io/address.hpp b/src/io/address.hpp index 0d1d396ad..3506f0523 100644 --- a/src/io/address.hpp +++ b/src/io/address.hpp @@ -36,14 +36,20 @@ struct Address { } bool operator==(const Address &other) const { - return (last_known_ip == other.last_known_ip) && (last_known_port == other.last_known_port); + return ((unique_id == other.unique_id) && last_known_ip == other.last_known_ip) && + (last_known_port == other.last_known_port); } + /// unique_id is most dominant for ordering, then last_known_ip, then last_known_port bool operator<(const Address &other) const { - if (last_known_ip == other.last_known_ip) { - return last_known_port < other.last_known_port; + if (unique_id == other.unique_id) { + if (last_known_ip == other.last_known_ip) { + return last_known_port < other.last_known_port; + } else { + return last_known_ip < other.last_known_ip; + } } else { - return last_known_ip < other.last_known_ip; + return unique_id < other.unique_id; } } }; diff --git a/src/io/future.hpp b/src/io/future.hpp index 0f47bb05e..83503f28d 100644 --- a/src/io/future.hpp +++ b/src/io/future.hpp @@ -18,9 +18,8 @@ #include #include -#include "utils/logging.hpp" - #include "io/errors.hpp" +#include "utils/logging.hpp" namespace memgraph::io { @@ -36,7 +35,7 @@ class Shared { std::optional item_; bool consumed_ = false; bool waiting_ = false; - std::optional> simulator_notifier_; + std::function simulator_notifier_ = nullptr; public: explicit Shared(std::function simulator_notifier) : simulator_notifier_(simulator_notifier) {} @@ -47,13 +46,27 @@ class Shared { Shared &operator=(const Shared &) = delete; ~Shared() = default; + /// Takes the item out of our optional item_ and returns it. + /// Requires caller holds mutex, proving it by passing reference. + T Take(std::unique_lock &) { + MG_ASSERT(item_, "Take called without item_ being present"); + MG_ASSERT(!consumed_, "Take called on already-consumed Future"); + + T ret = std::move(item_).value(); + item_.reset(); + + consumed_ = true; + + return ret; + } + T Wait() { std::unique_lock lock(mu_); waiting_ = true; while (!item_) { bool simulator_progressed = false; - if (simulator_notifier_) { + if (simulator_notifier_) [[unlikely]] { // We can't hold our own lock while notifying // the simulator because notifying the simulator // involves acquiring the simulator's mutex @@ -65,7 +78,7 @@ class Shared { // so we have to get out of its way to avoid // a cyclical deadlock. lock.unlock(); - simulator_progressed = (*simulator_notifier_)(); + simulator_progressed = (simulator_notifier_)(); lock.lock(); if (item_) { // item may have been filled while we @@ -80,13 +93,9 @@ class Shared { MG_ASSERT(!consumed_, "Future consumed twice!"); } - T ret = std::move(item_).value(); - item_.reset(); - waiting_ = false; - consumed_ = true; - return ret; + return Take(lock); } bool IsReady() { @@ -98,13 +107,7 @@ class Shared { std::unique_lock lock(mu_); if (item_) { - T ret = std::move(item_).value(); - item_.reset(); - - waiting_ = false; - consumed_ = true; - - return ret; + return Take(lock); } else { return std::nullopt; } @@ -140,16 +143,18 @@ class Future { Future() = delete; Future(Future &&old) { + MG_ASSERT(!old.consumed_or_moved_, "Future moved from after already being moved from or consumed."); shared_ = std::move(old.shared_); consumed_or_moved_ = old.consumed_or_moved_; - MG_ASSERT(!old.consumed_or_moved_, "Future moved from after already being moved from or consumed."); old.consumed_or_moved_ = true; } + Future &operator=(Future &&old) { - shared_ = std::move(old.shared_); MG_ASSERT(!old.consumed_or_moved_, "Future moved from after already being moved from or consumed."); + shared_ = std::move(old.shared_); old.consumed_or_moved_ = true; } + Future(const Future &) = delete; Future &operator=(const Future &) = delete; ~Future() = default; @@ -177,7 +182,7 @@ class Future { /// Block on the corresponding promise to be filled, /// returning the inner item when ready. - T Wait() { + T Wait() && { MG_ASSERT(!consumed_or_moved_, "Future should only be consumed with Wait once!"); T ret = shared_->Wait(); consumed_or_moved_ = true; @@ -201,13 +206,14 @@ class Promise { Promise() = delete; Promise(Promise &&old) { - shared_ = std::move(old.shared_); MG_ASSERT(!old.filled_or_moved_, "Promise moved from after already being moved from or filled."); + shared_ = std::move(old.shared_); old.filled_or_moved_ = true; } + Promise &operator=(Promise &&old) { - shared_ = std::move(old.shared_); MG_ASSERT(!old.filled_or_moved_, "Promise moved from after already being moved from or filled."); + shared_ = std::move(old.shared_); old.filled_or_moved_ = true; } Promise(const Promise &) = delete; diff --git a/src/io/simulator/simulator.hpp b/src/io/simulator/simulator.hpp index 4f4bee1f9..8e3ad85c0 100644 --- a/src/io/simulator/simulator.hpp +++ b/src/io/simulator/simulator.hpp @@ -12,6 +12,7 @@ #pragma once #include +#include #include "io/address.hpp" #include "io/simulator/simulator_config.hpp" @@ -20,7 +21,7 @@ namespace memgraph::io::simulator { class Simulator { - std::mt19937 rng_{}; + std::mt19937 rng_; std::shared_ptr simulator_handle_; public: @@ -30,7 +31,7 @@ class Simulator { void ShutDown() { simulator_handle_->ShutDown(); } Io Register(Address address) { - std::uniform_int_distribution seed_distrib{}; + std::uniform_int_distribution seed_distrib; uint64_t seed = seed_distrib(rng_); return Io(SimulatorTransport(simulator_handle_, address, seed), address); } diff --git a/src/io/simulator/simulator_config.hpp b/src/io/simulator/simulator_config.hpp index 2d5cf7342..4719488d2 100644 --- a/src/io/simulator/simulator_config.hpp +++ b/src/io/simulator/simulator_config.hpp @@ -11,13 +11,20 @@ #pragma once +#include + +#include "io/time.hpp" + namespace memgraph::io::simulator { + +using memgraph::io::Time; + struct SimulatorConfig { - int drop_percent = 0; + uint8_t drop_percent = 0; bool perform_timeouts = false; bool scramble_messages = true; uint64_t rng_seed = 0; - uint64_t start_time = 0; - uint64_t abort_time = ULLONG_MAX; + Time start_time = Time::min(); + Time abort_time = Time::max(); }; }; // namespace memgraph::io::simulator diff --git a/src/io/simulator/simulator_handle.hpp b/src/io/simulator/simulator_handle.hpp index b6f1899e2..33757ee9b 100644 --- a/src/io/simulator/simulator_handle.hpp +++ b/src/io/simulator/simulator_handle.hpp @@ -27,9 +27,14 @@ #include "io/errors.hpp" #include "io/simulator/simulator_config.hpp" #include "io/simulator/simulator_stats.hpp" +#include "io/time.hpp" #include "io/transport.hpp" namespace memgraph::io::simulator { + +using memgraph::io::Duration; +using memgraph::io::Time; + struct OpaqueMessage { Address from_address; uint64_t request_id; @@ -195,7 +200,7 @@ class OpaquePromise { }; struct DeadlineAndOpaquePromise { - uint64_t deadline; + Time deadline; OpaquePromise promise; }; @@ -206,13 +211,13 @@ class SimulatorHandle { // messages that have not yet been scheduled or dropped std::vector> in_flight_; - // the responsese to requests that are being waited on + // the responses to requests that are being waited on std::map promises_; // messages that are sent to servers that may later receive them std::map> can_receive_; - uint64_t cluster_wide_time_microseconds_; + Time cluster_wide_time_microseconds_; bool should_shut_down_ = false; SimulatorStats stats_; size_t blocked_on_receive_ = 0; @@ -250,7 +255,7 @@ class SimulatorHandle { } void TimeoutPromisesPastDeadline() { - uint64_t now = cluster_wide_time_microseconds_; + const Time now = cluster_wide_time_microseconds_; for (auto &[promise_key, dop] : promises_) { // TODO(tyler) queue this up and drop it after its deadline @@ -298,7 +303,7 @@ class SimulatorHandle { // We tick the clock forward when all servers are blocked but // there are no in-flight messages to schedule delivery of. std::poisson_distribution<> time_distrib(50); - uint64_t clock_advance = time_distrib(rng_); + Duration clock_advance = std::chrono::microseconds{time_distrib(rng_)}; cluster_wide_time_microseconds_ += clock_advance; MG_ASSERT(cluster_wide_time_microseconds_ < config_.abort_time, @@ -334,7 +339,7 @@ class SimulatorHandle { DeadlineAndOpaquePromise dop = std::move(promises_.at(promise_key)); promises_.erase(promise_key); - bool normal_timeout = config_.perform_timeouts && (dop.deadline < cluster_wide_time_microseconds_); + const bool normal_timeout = config_.perform_timeouts && (dop.deadline < cluster_wide_time_microseconds_); if (should_drop || normal_timeout) { stats_.timed_out_requests++; @@ -366,11 +371,11 @@ class SimulatorHandle { } template - void SubmitRequest(Address to_address, Address from_address, uint64_t request_id, Request &&request, - uint64_t timeout_microseconds, ResponsePromise &&promise) { + void SubmitRequest(Address to_address, Address from_address, uint64_t request_id, Request &&request, Duration timeout, + ResponsePromise &&promise) { std::unique_lock lock(mu_); - uint64_t deadline = cluster_wide_time_microseconds_ + timeout_microseconds; + const Time deadline = cluster_wide_time_microseconds_ + timeout; std::any message(std::move(request)); OpaqueMessage om{.from_address = from_address, .request_id = request_id, .message = std::move(message)}; @@ -390,10 +395,12 @@ class SimulatorHandle { } template - requires(sizeof...(Ms) > 0) RequestResult Receive(const Address &receiver, uint64_t timeout_microseconds) { + requires(sizeof...(Ms) > 0) RequestResult Receive(const Address &receiver, Duration timeout) { std::unique_lock lock(mu_); - uint64_t deadline = cluster_wide_time_microseconds_ + timeout_microseconds; + blocked_on_receive_ += 1; + + const Time deadline = cluster_wide_time_microseconds_ + timeout; while (!should_shut_down_ && (cluster_wide_time_microseconds_ < deadline)) { if (can_receive_.contains(receiver)) { @@ -405,20 +412,23 @@ class SimulatorHandle { // TODO(tyler) search for item in can_receive_ that matches the desired types, rather // than asserting that the last item in can_rx matches. auto m_opt = message.Take(); + + blocked_on_receive_ -= 1; + return std::move(m_opt).value(); } } - blocked_on_receive_ += 1; lock.unlock(); bool made_progress = MaybeTickSimulator(); lock.lock(); if (!should_shut_down_ && !made_progress) { cv_.wait(lock); } - blocked_on_receive_ -= 1; } + blocked_on_receive_ -= 1; + return TimedOut{}; } @@ -434,7 +444,7 @@ class SimulatorHandle { cv_.notify_all(); } - uint64_t Now() { + Time Now() { std::unique_lock lock(mu_); return cluster_wide_time_microseconds_; } diff --git a/src/io/simulator/simulator_transport.hpp b/src/io/simulator/simulator_transport.hpp index 38af6547b..6cc82ebeb 100644 --- a/src/io/simulator/simulator_transport.hpp +++ b/src/io/simulator/simulator_transport.hpp @@ -16,8 +16,13 @@ #include "io/address.hpp" #include "io/simulator/simulator_handle.hpp" +#include "io/time.hpp" namespace memgraph::io::simulator { + +using memgraph::io::Duration; +using memgraph::io::Time; + class SimulatorTransport { std::shared_ptr simulator_handle_; Address address_; @@ -28,21 +33,19 @@ class SimulatorTransport { : simulator_handle_(simulator_handle), address_(address), rng_(std::mt19937{seed}) {} template - ResponseFuture Request(Address address, uint64_t request_id, Request request, - uint64_t timeout_microseconds) { - std::function maybe_tick_simulator = [=] { return simulator_handle_->MaybeTickSimulator(); }; + ResponseFuture Request(Address address, uint64_t request_id, Request request, Duration timeout) { + std::function maybe_tick_simulator = [this] { return simulator_handle_->MaybeTickSimulator(); }; auto [future, promise] = memgraph::io::FuturePromisePairWithNotifier>(maybe_tick_simulator); - simulator_handle_->SubmitRequest(address, address_, request_id, std::move(request), timeout_microseconds, - std::move(promise)); + simulator_handle_->SubmitRequest(address, address_, request_id, std::move(request), timeout, std::move(promise)); return std::move(future); } template - requires(sizeof...(Ms) > 0) RequestResult Receive(uint64_t timeout_microseconds) { - return simulator_handle_->template Receive(address_, timeout_microseconds); + requires(sizeof...(Ms) > 0) RequestResult Receive(Duration timeout) { + return simulator_handle_->template Receive(address_, timeout); } template @@ -50,7 +53,7 @@ class SimulatorTransport { return simulator_handle_->template Send(address, address_, request_id, message); } - uint64_t Now() { return simulator_handle_->Now(); } + Time Now() { return simulator_handle_->Now(); } bool ShouldShutDown() { return simulator_handle_->ShouldShutDown(); } diff --git a/src/io/time.hpp b/src/io/time.hpp new file mode 100644 index 000000000..6ab1f1184 --- /dev/null +++ b/src/io/time.hpp @@ -0,0 +1,21 @@ +// Copyright 2022 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 +// License, and you may not use this file except in compliance with the Business Source License. +// +// As of the Change Date specified in that file, in accordance with +// the Business Source License, use of this software will be governed +// by the Apache License, Version 2.0, included in the file +// licenses/APL.txt. + +#pragma once + +#include + +namespace memgraph::io { + +using Duration = std::chrono::duration>; +using Time = std::chrono::time_point; + +} // namespace memgraph::io diff --git a/src/io/transport.hpp b/src/io/transport.hpp index d3e045cb2..0a0531fd6 100644 --- a/src/io/transport.hpp +++ b/src/io/transport.hpp @@ -11,15 +11,16 @@ #pragma once +#include #include #include #include -#include "utils/result.hpp" - #include "io/address.hpp" #include "io/errors.hpp" #include "io/future.hpp" +#include "io/time.hpp" +#include "utils/result.hpp" using memgraph::utils::BasicResult; @@ -61,46 +62,43 @@ class Io { I implementation_; Address address_; uint64_t request_id_counter_ = 0; - uint64_t default_timeout_microseconds_ = 50 * 1000; + Duration default_timeout_ = std::chrono::microseconds{50000}; public: Io(I io, Address address) : implementation_(io), address_(address) {} /// Set the default timeout for all requests that are issued /// without an explicit timeout set. - void SetDefaultTimeoutMicroseconds(uint64_t timeout_microseconds) { - default_timeout_microseconds_ = timeout_microseconds; - } + void SetDefaultTimeout(Duration timeout) { default_timeout_ = timeout; } /// Issue a request with an explicit timeout in microseconds provided. template - ResponseFuture RequestWithTimeout(Address address, Request request, uint64_t timeout_microseconds) { + ResponseFuture RequestWithTimeout(Address address, Request request, Duration timeout) { uint64_t request_id = ++request_id_counter_; - return implementation_.template Request(address, request_id, request, timeout_microseconds); + return implementation_.template Request(address, request_id, request, timeout); } /// Issue a request that times out after the default timeout. template ResponseFuture Request(Address address, Request request) { uint64_t request_id = ++request_id_counter_; - uint64_t timeout_microseconds = default_timeout_microseconds_; - return implementation_.template Request(address, request_id, std::move(request), - timeout_microseconds); + Duration timeout = default_timeout_; + return implementation_.template Request(address, request_id, std::move(request), timeout); } /// Wait for an explicit number of microseconds for a request of one of the /// provided types to arrive. template - RequestResult ReceiveWithTimeout(uint64_t timeout_microseconds) { - return implementation_.template Receive(timeout_microseconds); + RequestResult ReceiveWithTimeout(Duration timeout) { + return implementation_.template Receive(timeout); } /// Wait the default number of microseconds for a request of one of the /// provided types to arrive. template requires(sizeof...(Ms) > 0) RequestResult Receive() { - uint64_t timeout_microseconds = default_timeout_microseconds_; - return implementation_.template Receive(timeout_microseconds); + Duration timeout = default_timeout_; + return implementation_.template Receive(timeout); } /// Send a message in a best-effort fashion. If you need reliable delivery, @@ -114,7 +112,7 @@ class Io { /// This time source should be preferred over any other, because it /// lets us deterministically control clocks from tests for making /// things like timeouts deterministic. - uint64_t Now() { return implementation_.Now(); } + Time Now() { return implementation_.Now(); } /// Returns true of the system should shut-down. bool ShouldShutDown() { return implementation_.ShouldShutDown(); } diff --git a/src/query/v2/CMakeLists.txt b/src/query/v2/CMakeLists.txt index 3efb0c91e..187520b5c 100644 --- a/src/query/v2/CMakeLists.txt +++ b/src/query/v2/CMakeLists.txt @@ -84,7 +84,7 @@ add_custom_command( OUTPUT ${antlr_opencypher_generated_src} ${antlr_opencypher_generated_include} COMMAND ${CMAKE_COMMAND} -E make_directory ${opencypher_generated} COMMAND - java -jar ${CMAKE_SOURCE_DIR}/libs/antlr-4.9.2-complete.jar + java -jar ${CMAKE_SOURCE_DIR}/libs/antlr-4.10.1-complete.jar -Dlanguage=Cpp -visitor -package antlropencypher -o ${opencypher_generated} ${opencypher_lexer_grammar} ${opencypher_parser_grammar} diff --git a/src/query/v2/cypher_query_interpreter.cpp b/src/query/v2/cypher_query_interpreter.cpp index 42e2b3cf3..f242e96c2 100644 --- a/src/query/v2/cypher_query_interpreter.cpp +++ b/src/query/v2/cypher_query_interpreter.cpp @@ -21,8 +21,7 @@ namespace memgraph::query::v2 { CachedPlan::CachedPlan(std::unique_ptr plan) : plan_(std::move(plan)) {} ParsedQuery ParseQuery(const std::string &query_string, const std::map ¶ms, - utils::SkipList *cache, utils::SpinLock *antlr_lock, - const InterpreterConfig::Query &query_config) { + utils::SkipList *cache, const InterpreterConfig::Query &query_config) { // Strip the query for caching purposes. The process of stripping a query // "normalizes" it by replacing any literals with new parameters. This // results in just the *structure* of the query being taken into account for @@ -63,20 +62,16 @@ ParsedQuery ParseQuery(const std::string &query_string, const std::map guard(*antlr_lock); + try { + parser = std::make_unique(stripped_query.query()); + } catch (const SyntaxException &e) { + // There is a syntax exception in the stripped query. Re-run the parser + // on the original query to get an appropriate error messsage. + parser = std::make_unique(query_string); - try { - parser = std::make_unique(stripped_query.query()); - } catch (const SyntaxException &e) { - // There is a syntax exception in the stripped query. Re-run the parser - // on the original query to get an appropriate error messsage. - parser = std::make_unique(query_string); - - // If an exception was not thrown here, the stripper messed something - // up. - LOG_FATAL("The stripped query can't be parsed, but the original can."); - } + // If an exception was not thrown here, the stripper messed something + // up. + LOG_FATAL("The stripped query can't be parsed, but the original can."); } // Convert the ANTLR4 parse tree into an AST. diff --git a/src/query/v2/cypher_query_interpreter.hpp b/src/query/v2/cypher_query_interpreter.hpp index 423eafdde..95a48a458 100644 --- a/src/query/v2/cypher_query_interpreter.hpp +++ b/src/query/v2/cypher_query_interpreter.hpp @@ -111,8 +111,7 @@ struct ParsedQuery { }; ParsedQuery ParseQuery(const std::string &query_string, const std::map ¶ms, - utils::SkipList *cache, utils::SpinLock *antlr_lock, - const InterpreterConfig::Query &query_config); + utils::SkipList *cache, const InterpreterConfig::Query &query_config); class SingleNodeLogicalPlan final : public LogicalPlan { public: diff --git a/src/query/v2/frontend/ast/cypher_main_visitor.cpp b/src/query/v2/frontend/ast/cypher_main_visitor.cpp index 8a74fbbeb..976e3abfc 100644 --- a/src/query/v2/frontend/ast/cypher_main_visitor.cpp +++ b/src/query/v2/frontend/ast/cypher_main_visitor.cpp @@ -52,7 +52,7 @@ std::optional> VisitMemoryL return std::nullopt; } - auto memory_limit = memory_limit_ctx->literal()->accept(visitor); + auto *memory_limit = std::any_cast(memory_limit_ctx->literal()->accept(visitor)); size_t memory_scale = 1024U; if (memory_limit_ctx->MB()) { memory_scale = 1024U * 1024U; @@ -77,7 +77,7 @@ std::string JoinSymbolicNames(antlr4::tree::ParseTreeVisitor *visitor, const std::vector symbolicNames, const std::string &separator = ".") { return JoinTokens( - symbolicNames, [&](auto *token) { return token->accept(visitor).template as(); }, separator); + symbolicNames, [&](auto *token) { return std::any_cast(token->accept(visitor)); }, separator); } std::string JoinSymbolicNamesWithDotsAndMinus(antlr4::tree::ParseTreeVisitor &visitor, @@ -90,7 +90,7 @@ std::string JoinSymbolicNamesWithDotsAndMinus(antlr4::tree::ParseTreeVisitor &vi antlrcpp::Any CypherMainVisitor::visitExplainQuery(MemgraphCypher::ExplainQueryContext *ctx) { MG_ASSERT(ctx->children.size() == 2, "ExplainQuery should have exactly two children!"); - auto *cypher_query = ctx->children[1]->accept(this).as(); + auto *cypher_query = std::any_cast(ctx->children[1]->accept(this)); auto *explain_query = storage_->Create(); explain_query->cypher_query_ = cypher_query; query_ = explain_query; @@ -99,7 +99,7 @@ antlrcpp::Any CypherMainVisitor::visitExplainQuery(MemgraphCypher::ExplainQueryC antlrcpp::Any CypherMainVisitor::visitProfileQuery(MemgraphCypher::ProfileQueryContext *ctx) { MG_ASSERT(ctx->children.size() == 2, "ProfileQuery should have exactly two children!"); - auto *cypher_query = ctx->children[1]->accept(this).as(); + auto *cypher_query = std::any_cast(ctx->children[1]->accept(this)); auto *profile_query = storage_->Create(); profile_query->cypher_query_ = cypher_query; query_ = profile_query; @@ -132,7 +132,7 @@ antlrcpp::Any CypherMainVisitor::visitConstraintQuery(MemgraphCypher::Constraint } else if (ctx->DROP()) { constraint_query->action_type_ = ConstraintQuery::ActionType::DROP; } - constraint_query->constraint_ = ctx->constraint()->accept(this).as(); + constraint_query->constraint_ = std::any_cast(ctx->constraint()->accept(this)); query_ = constraint_query; return query_; } @@ -147,16 +147,16 @@ antlrcpp::Any CypherMainVisitor::visitConstraint(MemgraphCypher::ConstraintConte } else if (ctx->NODE() && ctx->KEY()) { constraint.type = Constraint::Type::NODE_KEY; } - constraint.label = AddLabel(ctx->labelName()->accept(this)); - std::string node_name = ctx->nodeName->symbolicName()->accept(this); + constraint.label = AddLabel(std::any_cast(ctx->labelName()->accept(this))); + auto node_name = std::any_cast(ctx->nodeName->symbolicName()->accept(this)); for (const auto &var_ctx : ctx->constraintPropertyList()->variable()) { - std::string var_name = var_ctx->symbolicName()->accept(this); + auto var_name = std::any_cast(var_ctx->symbolicName()->accept(this)); if (var_name != node_name) { throw SemanticException("All constraint variable should reference node '{}'", node_name); } } for (const auto &prop_lookup : ctx->constraintPropertyList()->propertyLookup()) { - constraint.properties.push_back(prop_lookup->propertyKeyName()->accept(this)); + constraint.properties.push_back(std::any_cast(prop_lookup->propertyKeyName()->accept(this))); } return constraint; @@ -165,7 +165,7 @@ antlrcpp::Any CypherMainVisitor::visitConstraint(MemgraphCypher::ConstraintConte antlrcpp::Any CypherMainVisitor::visitCypherQuery(MemgraphCypher::CypherQueryContext *ctx) { auto *cypher_query = storage_->Create(); MG_ASSERT(ctx->singleQuery(), "Expected single query."); - cypher_query->single_query_ = ctx->singleQuery()->accept(this).as(); + cypher_query->single_query_ = std::any_cast(ctx->singleQuery()->accept(this)); // Check that union and union all dont mix bool has_union = false; @@ -179,7 +179,7 @@ antlrcpp::Any CypherMainVisitor::visitCypherQuery(MemgraphCypher::CypherQueryCon if (has_union && has_union_all) { throw SemanticException("Invalid combination of UNION and UNION ALL."); } - cypher_query->cypher_unions_.push_back(child->accept(this).as()); + cypher_query->cypher_unions_.push_back(std::any_cast(child->accept(this))); } if (auto *memory_limit_ctx = ctx->queryMemoryLimit()) { @@ -196,7 +196,7 @@ antlrcpp::Any CypherMainVisitor::visitCypherQuery(MemgraphCypher::CypherQueryCon antlrcpp::Any CypherMainVisitor::visitIndexQuery(MemgraphCypher::IndexQueryContext *ctx) { MG_ASSERT(ctx->children.size() == 1, "IndexQuery should have exactly one child!"); - auto *index_query = ctx->children[0]->accept(this).as(); + auto *index_query = std::any_cast(ctx->children[0]->accept(this)); query_ = index_query; return index_query; } @@ -204,9 +204,9 @@ antlrcpp::Any CypherMainVisitor::visitIndexQuery(MemgraphCypher::IndexQueryConte antlrcpp::Any CypherMainVisitor::visitCreateIndex(MemgraphCypher::CreateIndexContext *ctx) { auto *index_query = storage_->Create(); index_query->action_ = IndexQuery::Action::CREATE; - index_query->label_ = AddLabel(ctx->labelName()->accept(this)); + index_query->label_ = AddLabel(std::any_cast(ctx->labelName()->accept(this))); if (ctx->propertyKeyName()) { - PropertyIx name_key = ctx->propertyKeyName()->accept(this); + auto name_key = std::any_cast(ctx->propertyKeyName()->accept(this)); index_query->properties_ = {name_key}; } return index_query; @@ -216,16 +216,16 @@ antlrcpp::Any CypherMainVisitor::visitDropIndex(MemgraphCypher::DropIndexContext auto *index_query = storage_->Create(); index_query->action_ = IndexQuery::Action::DROP; if (ctx->propertyKeyName()) { - PropertyIx key = ctx->propertyKeyName()->accept(this); + auto key = std::any_cast(ctx->propertyKeyName()->accept(this)); index_query->properties_ = {key}; } - index_query->label_ = AddLabel(ctx->labelName()->accept(this)); + index_query->label_ = AddLabel(std::any_cast(ctx->labelName()->accept(this))); return index_query; } antlrcpp::Any CypherMainVisitor::visitAuthQuery(MemgraphCypher::AuthQueryContext *ctx) { MG_ASSERT(ctx->children.size() == 1, "AuthQuery should have exactly one child!"); - auto *auth_query = ctx->children[0]->accept(this).as(); + auto *auth_query = std::any_cast(ctx->children[0]->accept(this)); query_ = auth_query; return auth_query; } @@ -238,7 +238,7 @@ antlrcpp::Any CypherMainVisitor::visitDumpQuery(MemgraphCypher::DumpQueryContext antlrcpp::Any CypherMainVisitor::visitReplicationQuery(MemgraphCypher::ReplicationQueryContext *ctx) { MG_ASSERT(ctx->children.size() == 1, "ReplicationQuery should have exactly one child!"); - auto *replication_query = ctx->children[0]->accept(this).as(); + auto *replication_query = std::any_cast(ctx->children[0]->accept(this)); query_ = replication_query; return replication_query; } @@ -255,7 +255,7 @@ antlrcpp::Any CypherMainVisitor::visitSetReplicationRole(MemgraphCypher::SetRepl replication_query->role_ = ReplicationQuery::ReplicationRole::REPLICA; if (ctx->WITH() && ctx->PORT()) { if (ctx->port->numberLiteral() && ctx->port->numberLiteral()->integerLiteral()) { - replication_query->port_ = ctx->port->accept(this); + replication_query->port_ = std::any_cast(ctx->port->accept(this)); } else { throw SyntaxException("Port must be an integer literal!"); } @@ -272,13 +272,13 @@ antlrcpp::Any CypherMainVisitor::visitShowReplicationRole(MemgraphCypher::ShowRe antlrcpp::Any CypherMainVisitor::visitRegisterReplica(MemgraphCypher::RegisterReplicaContext *ctx) { auto *replication_query = storage_->Create(); replication_query->action_ = ReplicationQuery::Action::REGISTER_REPLICA; - replication_query->replica_name_ = ctx->replicaName()->symbolicName()->accept(this).as(); + replication_query->replica_name_ = std::any_cast(ctx->replicaName()->symbolicName()->accept(this)); if (ctx->SYNC()) { replication_query->sync_mode_ = memgraph::query::v2::ReplicationQuery::SyncMode::SYNC; if (ctx->WITH() && ctx->TIMEOUT()) { if (ctx->timeout->numberLiteral()) { // we accept both double and integer literals - replication_query->timeout_ = ctx->timeout->accept(this); + replication_query->timeout_ = std::any_cast(ctx->timeout->accept(this)); } else { throw SemanticException("Timeout should be a integer or double literal!"); } @@ -293,7 +293,7 @@ antlrcpp::Any CypherMainVisitor::visitRegisterReplica(MemgraphCypher::RegisterRe if (!ctx->socketAddress()->literal()->StringLiteral()) { throw SemanticException("Socket address should be a string literal!"); } else { - replication_query->socket_address_ = ctx->socketAddress()->accept(this); + replication_query->socket_address_ = std::any_cast(ctx->socketAddress()->accept(this)); } return replication_query; @@ -302,7 +302,7 @@ antlrcpp::Any CypherMainVisitor::visitRegisterReplica(MemgraphCypher::RegisterRe antlrcpp::Any CypherMainVisitor::visitDropReplica(MemgraphCypher::DropReplicaContext *ctx) { auto *replication_query = storage_->Create(); replication_query->action_ = ReplicationQuery::Action::DROP_REPLICA; - replication_query->replica_name_ = ctx->replicaName()->symbolicName()->accept(this).as(); + replication_query->replica_name_ = std::any_cast(ctx->replicaName()->symbolicName()->accept(this)); return replication_query; } @@ -332,7 +332,7 @@ antlrcpp::Any CypherMainVisitor::visitLoadCsv(MemgraphCypher::LoadCsvContext *ct auto *load_csv = storage_->Create(); // handle file name if (ctx->csvFile()->literal()->StringLiteral()) { - load_csv->file_ = ctx->csvFile()->accept(this); + load_csv->file_ = std::any_cast(ctx->csvFile()->accept(this)); } else { throw SemanticException("CSV file path should be a string literal"); } @@ -349,7 +349,7 @@ antlrcpp::Any CypherMainVisitor::visitLoadCsv(MemgraphCypher::LoadCsvContext *ct // handle delimiter if (ctx->DELIMITER()) { if (ctx->delimiter()->literal()->StringLiteral()) { - load_csv->delimiter_ = ctx->delimiter()->accept(this); + load_csv->delimiter_ = std::any_cast(ctx->delimiter()->accept(this)); } else { throw SemanticException("Delimiter should be a string literal"); } @@ -358,14 +358,15 @@ antlrcpp::Any CypherMainVisitor::visitLoadCsv(MemgraphCypher::LoadCsvContext *ct // handle quote if (ctx->QUOTE()) { if (ctx->quote()->literal()->StringLiteral()) { - load_csv->quote_ = ctx->quote()->accept(this); + load_csv->quote_ = std::any_cast(ctx->quote()->accept(this)); } else { throw SemanticException("Quote should be a string literal"); } } // handle row variable - load_csv->row_var_ = storage_->Create(ctx->rowVar()->variable()->accept(this).as()); + load_csv->row_var_ = + storage_->Create(std::any_cast(ctx->rowVar()->variable()->accept(this))); return load_csv; } @@ -378,7 +379,7 @@ antlrcpp::Any CypherMainVisitor::visitFreeMemoryQuery(MemgraphCypher::FreeMemory antlrcpp::Any CypherMainVisitor::visitTriggerQuery(MemgraphCypher::TriggerQueryContext *ctx) { MG_ASSERT(ctx->children.size() == 1, "TriggerQuery should have exactly one child!"); - auto *trigger_query = ctx->children[0]->accept(this).as(); + auto *trigger_query = std::any_cast(ctx->children[0]->accept(this)); query_ = trigger_query; return trigger_query; } @@ -386,7 +387,7 @@ antlrcpp::Any CypherMainVisitor::visitTriggerQuery(MemgraphCypher::TriggerQueryC antlrcpp::Any CypherMainVisitor::visitCreateTrigger(MemgraphCypher::CreateTriggerContext *ctx) { auto *trigger_query = storage_->Create(); trigger_query->action_ = TriggerQuery::Action::CREATE_TRIGGER; - trigger_query->trigger_name_ = ctx->triggerName()->symbolicName()->accept(this).as(); + trigger_query->trigger_name_ = std::any_cast(ctx->triggerName()->symbolicName()->accept(this)); auto *statement = ctx->triggerStatement(); antlr4::misc::Interval interval{statement->start->getStartIndex(), statement->stop->getStopIndex()}; @@ -438,7 +439,7 @@ antlrcpp::Any CypherMainVisitor::visitCreateTrigger(MemgraphCypher::CreateTrigge antlrcpp::Any CypherMainVisitor::visitDropTrigger(MemgraphCypher::DropTriggerContext *ctx) { auto *trigger_query = storage_->Create(); trigger_query->action_ = TriggerQuery::Action::DROP_TRIGGER; - trigger_query->trigger_name_ = ctx->triggerName()->symbolicName()->accept(this).as(); + trigger_query->trigger_name_ = std::any_cast(ctx->triggerName()->symbolicName()->accept(this)); return trigger_query; } @@ -482,14 +483,14 @@ antlrcpp::Any CypherMainVisitor::visitCreateSnapshotQuery(MemgraphCypher::Create antlrcpp::Any CypherMainVisitor::visitStreamQuery(MemgraphCypher::StreamQueryContext *ctx) { MG_ASSERT(ctx->children.size() == 1, "StreamQuery should have exactly one child!"); - auto *stream_query = ctx->children[0]->accept(this).as(); + auto *stream_query = std::any_cast(ctx->children[0]->accept(this)); query_ = stream_query; return stream_query; } antlrcpp::Any CypherMainVisitor::visitCreateStream(MemgraphCypher::CreateStreamContext *ctx) { MG_ASSERT(ctx->children.size() == 1, "CreateStreamQuery should have exactly one child!"); - auto *stream_query = ctx->children[0]->accept(this).as(); + auto *stream_query = std::any_cast(ctx->children[0]->accept(this)); query_ = stream_query; return stream_query; } @@ -581,7 +582,8 @@ void MapCommonStreamConfigs(auto &memory, StreamQuery &stream_query) { antlrcpp::Any CypherMainVisitor::visitConfigKeyValuePair(MemgraphCypher::ConfigKeyValuePairContext *ctx) { MG_ASSERT(ctx->literal().size() == 2); - return std::pair{ctx->literal(0)->accept(this).as(), ctx->literal(1)->accept(this).as()}; + return std::pair{std::any_cast(ctx->literal(0)->accept(this)), + std::any_cast(ctx->literal(1)->accept(this))}; } antlrcpp::Any CypherMainVisitor::visitConfigMap(MemgraphCypher::ConfigMapContext *ctx) { @@ -589,7 +591,7 @@ antlrcpp::Any CypherMainVisitor::visitConfigMap(MemgraphCypher::ConfigMapContext for (auto *key_value_pair : ctx->configKeyValuePair()) { // If the queries are cached, then only the stripped query is parsed, so the actual keys cannot be determined // here. That means duplicates cannot be checked. - map.insert(key_value_pair->accept(this).as>()); + map.insert(std::any_cast>(key_value_pair->accept(this))); } return map; } @@ -598,7 +600,7 @@ antlrcpp::Any CypherMainVisitor::visitKafkaCreateStream(MemgraphCypher::KafkaCre auto *stream_query = storage_->Create(); stream_query->action_ = StreamQuery::Action::CREATE_STREAM; stream_query->type_ = StreamQuery::Type::KAFKA; - stream_query->stream_name_ = ctx->streamName()->symbolicName()->accept(this).as(); + stream_query->stream_name_ = std::any_cast(ctx->streamName()->symbolicName()->accept(this)); for (auto *create_config_ctx : ctx->kafkaCreateStreamConfig()) { create_config_ctx->accept(this); @@ -634,7 +636,7 @@ void GetTopicNames(auto &destination, MemgraphCypher::TopicNamesContext *topic_n if (!topic_names_ctx->literal()->StringLiteral()) { throw SemanticException("Topic names should be defined as a string literal or as symbolic names"); } - destination = topic_names_ctx->accept(&visitor).as(); + destination = std::any_cast(topic_names_ctx->accept(&visitor)); } } } // namespace @@ -661,7 +663,8 @@ antlrcpp::Any CypherMainVisitor::visitKafkaCreateStreamConfig(MemgraphCypher::Ka if (ctx->CONFIGS()) { ThrowIfExists(memory_, KafkaConfigKey::CONFIGS); static constexpr auto configs_key = static_cast(KafkaConfigKey::CONFIGS); - memory_.emplace(configs_key, ctx->configsMap->accept(this).as>()); + memory_.emplace(configs_key, + std::any_cast>(ctx->configsMap->accept(this))); return {}; } @@ -669,7 +672,7 @@ antlrcpp::Any CypherMainVisitor::visitKafkaCreateStreamConfig(MemgraphCypher::Ka ThrowIfExists(memory_, KafkaConfigKey::CREDENTIALS); static constexpr auto credentials_key = static_cast(KafkaConfigKey::CREDENTIALS); memory_.emplace(credentials_key, - ctx->credentialsMap->accept(this).as>()); + std::any_cast>(ctx->credentialsMap->accept(this))); return {}; } @@ -680,7 +683,7 @@ antlrcpp::Any CypherMainVisitor::visitKafkaCreateStreamConfig(MemgraphCypher::Ka } const auto bootstrap_servers_key = static_cast(KafkaConfigKey::BOOTSTRAP_SERVERS); - memory_[bootstrap_servers_key] = ctx->bootstrapServers->accept(this).as(); + memory_[bootstrap_servers_key] = std::any_cast(ctx->bootstrapServers->accept(this)); return {}; } @@ -701,7 +704,7 @@ antlrcpp::Any CypherMainVisitor::visitPulsarCreateStream(MemgraphCypher::PulsarC auto *stream_query = storage_->Create(); stream_query->action_ = StreamQuery::Action::CREATE_STREAM; stream_query->type_ = StreamQuery::Type::PULSAR; - stream_query->stream_name_ = ctx->streamName()->symbolicName()->accept(this).as(); + stream_query->stream_name_ = std::any_cast(ctx->streamName()->symbolicName()->accept(this)); for (auto *create_config_ctx : ctx->pulsarCreateStreamConfig()) { create_config_ctx->accept(this); @@ -733,7 +736,7 @@ antlrcpp::Any CypherMainVisitor::visitPulsarCreateStreamConfig(MemgraphCypher::P throw SemanticException("Service URL must be a string!"); } const auto service_url_key = static_cast(PulsarConfigKey::SERVICE_URL); - memory_[service_url_key] = ctx->serviceUrl->accept(this).as(); + memory_[service_url_key] = std::any_cast(ctx->serviceUrl->accept(this)); return {}; } @@ -751,7 +754,7 @@ antlrcpp::Any CypherMainVisitor::visitCommonCreateStreamConfig(MemgraphCypher::C throw SemanticException("Batch interval must be an integer literal!"); } const auto batch_interval_key = static_cast(CommonStreamConfigKey::BATCH_INTERVAL); - memory_[batch_interval_key] = ctx->batchInterval->accept(this).as(); + memory_[batch_interval_key] = std::any_cast(ctx->batchInterval->accept(this)); return {}; } @@ -761,14 +764,14 @@ antlrcpp::Any CypherMainVisitor::visitCommonCreateStreamConfig(MemgraphCypher::C throw SemanticException("Batch size must be an integer literal!"); } const auto batch_size_key = static_cast(CommonStreamConfigKey::BATCH_SIZE); - memory_[batch_size_key] = ctx->batchSize->accept(this).as(); + memory_[batch_size_key] = std::any_cast(ctx->batchSize->accept(this)); return {}; } antlrcpp::Any CypherMainVisitor::visitDropStream(MemgraphCypher::DropStreamContext *ctx) { auto *stream_query = storage_->Create(); stream_query->action_ = StreamQuery::Action::DROP_STREAM; - stream_query->stream_name_ = ctx->streamName()->symbolicName()->accept(this).as(); + stream_query->stream_name_ = std::any_cast(ctx->streamName()->symbolicName()->accept(this)); return stream_query; } @@ -780,7 +783,7 @@ antlrcpp::Any CypherMainVisitor::visitStartStream(MemgraphCypher::StartStreamCon if (!ctx->batchLimit->numberLiteral() || !ctx->batchLimit->numberLiteral()->integerLiteral()) { throw SemanticException("Batch limit should be an integer literal!"); } - stream_query->batch_limit_ = ctx->batchLimit->accept(this); + stream_query->batch_limit_ = std::any_cast(ctx->batchLimit->accept(this)); } if (ctx->TIMEOUT()) { if (!ctx->timeout->numberLiteral() || !ctx->timeout->numberLiteral()->integerLiteral()) { @@ -789,10 +792,10 @@ antlrcpp::Any CypherMainVisitor::visitStartStream(MemgraphCypher::StartStreamCon if (!ctx->BATCH_LIMIT()) { throw SemanticException("Parameter TIMEOUT can only be defined if BATCH_LIMIT is defined"); } - stream_query->timeout_ = ctx->timeout->accept(this); + stream_query->timeout_ = std::any_cast(ctx->timeout->accept(this)); } - stream_query->stream_name_ = ctx->streamName()->symbolicName()->accept(this).as(); + stream_query->stream_name_ = std::any_cast(ctx->streamName()->symbolicName()->accept(this)); return stream_query; } @@ -805,7 +808,7 @@ antlrcpp::Any CypherMainVisitor::visitStartAllStreams(MemgraphCypher::StartAllSt antlrcpp::Any CypherMainVisitor::visitStopStream(MemgraphCypher::StopStreamContext *ctx) { auto *stream_query = storage_->Create(); stream_query->action_ = StreamQuery::Action::STOP_STREAM; - stream_query->stream_name_ = ctx->streamName()->symbolicName()->accept(this).as(); + stream_query->stream_name_ = std::any_cast(ctx->streamName()->symbolicName()->accept(this)); return stream_query; } @@ -824,26 +827,26 @@ antlrcpp::Any CypherMainVisitor::visitShowStreams(MemgraphCypher::ShowStreamsCon antlrcpp::Any CypherMainVisitor::visitCheckStream(MemgraphCypher::CheckStreamContext *ctx) { auto *stream_query = storage_->Create(); stream_query->action_ = StreamQuery::Action::CHECK_STREAM; - stream_query->stream_name_ = ctx->streamName()->symbolicName()->accept(this).as(); + stream_query->stream_name_ = std::any_cast(ctx->streamName()->symbolicName()->accept(this)); if (ctx->BATCH_LIMIT()) { if (!ctx->batchLimit->numberLiteral() || !ctx->batchLimit->numberLiteral()->integerLiteral()) { throw SemanticException("Batch limit should be an integer literal!"); } - stream_query->batch_limit_ = ctx->batchLimit->accept(this); + stream_query->batch_limit_ = std::any_cast(ctx->batchLimit->accept(this)); } if (ctx->TIMEOUT()) { if (!ctx->timeout->numberLiteral() || !ctx->timeout->numberLiteral()->integerLiteral()) { throw SemanticException("Timeout should be an integer literal!"); } - stream_query->timeout_ = ctx->timeout->accept(this); + stream_query->timeout_ = std::any_cast(ctx->timeout->accept(this)); } return stream_query; } antlrcpp::Any CypherMainVisitor::visitSettingQuery(MemgraphCypher::SettingQueryContext *ctx) { MG_ASSERT(ctx->children.size() == 1, "SettingQuery should have exactly one child!"); - auto *setting_query = ctx->children[0]->accept(this).as(); + auto *setting_query = std::any_cast(ctx->children[0]->accept(this)); query_ = setting_query; return setting_query; } @@ -860,10 +863,10 @@ antlrcpp::Any CypherMainVisitor::visitSetSetting(MemgraphCypher::SetSettingConte throw SemanticException("Setting value should be a string literal"); } - setting_query->setting_name_ = ctx->settingName()->accept(this); + setting_query->setting_name_ = std::any_cast(ctx->settingName()->accept(this)); MG_ASSERT(setting_query->setting_name_); - setting_query->setting_value_ = ctx->settingValue()->accept(this); + setting_query->setting_value_ = std::any_cast(ctx->settingValue()->accept(this)); MG_ASSERT(setting_query->setting_value_); return setting_query; } @@ -876,7 +879,7 @@ antlrcpp::Any CypherMainVisitor::visitShowSetting(MemgraphCypher::ShowSettingCon throw SemanticException("Setting name should be a string literal"); } - setting_query->setting_name_ = ctx->settingName()->accept(this); + setting_query->setting_name_ = std::any_cast(ctx->settingName()->accept(this)); MG_ASSERT(setting_query->setting_name_); return setting_query; @@ -898,7 +901,7 @@ antlrcpp::Any CypherMainVisitor::visitCypherUnion(MemgraphCypher::CypherUnionCon bool distinct = !ctx->ALL(); auto *cypher_union = storage_->Create(distinct); DMG_ASSERT(ctx->singleQuery(), "Expected single query."); - cypher_union->single_query_ = ctx->singleQuery()->accept(this).as(); + cypher_union->single_query_ = std::any_cast(ctx->singleQuery()->accept(this)); return cypher_union; } @@ -906,10 +909,10 @@ antlrcpp::Any CypherMainVisitor::visitSingleQuery(MemgraphCypher::SingleQueryCon auto *single_query = storage_->Create(); for (auto *child : ctx->clause()) { antlrcpp::Any got = child->accept(this); - if (got.is()) { - single_query->clauses_.push_back(got.as()); + if (got.type() == typeid(Clause *)) { + single_query->clauses_.push_back(std::any_cast(got)); } else { - auto child_clauses = got.as>(); + auto child_clauses = std::any_cast>(got); single_query->clauses_.insert(single_query->clauses_.end(), child_clauses.begin(), child_clauses.end()); } } @@ -1021,42 +1024,42 @@ antlrcpp::Any CypherMainVisitor::visitSingleQuery(MemgraphCypher::SingleQueryCon antlrcpp::Any CypherMainVisitor::visitClause(MemgraphCypher::ClauseContext *ctx) { if (ctx->cypherReturn()) { - return static_cast(ctx->cypherReturn()->accept(this).as()); + return static_cast(std::any_cast(ctx->cypherReturn()->accept(this))); } if (ctx->cypherMatch()) { - return static_cast(ctx->cypherMatch()->accept(this).as()); + return static_cast(std::any_cast(ctx->cypherMatch()->accept(this))); } if (ctx->create()) { - return static_cast(ctx->create()->accept(this).as()); + return static_cast(std::any_cast(ctx->create()->accept(this))); } if (ctx->cypherDelete()) { - return static_cast(ctx->cypherDelete()->accept(this).as()); + return static_cast(std::any_cast(ctx->cypherDelete()->accept(this))); } if (ctx->set()) { // Different return type!!! - return ctx->set()->accept(this).as>(); + return std::any_cast>(ctx->set()->accept(this)); } if (ctx->remove()) { // Different return type!!! - return ctx->remove()->accept(this).as>(); + return std::any_cast>(ctx->remove()->accept(this)); } if (ctx->with()) { - return static_cast(ctx->with()->accept(this).as()); + return static_cast(std::any_cast(ctx->with()->accept(this))); } if (ctx->merge()) { - return static_cast(ctx->merge()->accept(this).as()); + return static_cast(std::any_cast(ctx->merge()->accept(this))); } if (ctx->unwind()) { - return static_cast(ctx->unwind()->accept(this).as()); + return static_cast(std::any_cast(ctx->unwind()->accept(this))); } if (ctx->callProcedure()) { - return static_cast(ctx->callProcedure()->accept(this).as()); + return static_cast(std::any_cast(ctx->callProcedure()->accept(this))); } if (ctx->loadCsv()) { - return static_cast(ctx->loadCsv()->accept(this).as()); + return static_cast(std::any_cast(ctx->loadCsv()->accept(this))); } if (ctx->foreach ()) { - return static_cast(ctx->foreach ()->accept(this).as()); + return static_cast(std::any_cast(ctx->foreach ()->accept(this))); } // TODO: implement other clauses. throw utils::NotYetImplemented("clause '{}'", ctx->getText()); @@ -1067,15 +1070,15 @@ antlrcpp::Any CypherMainVisitor::visitCypherMatch(MemgraphCypher::CypherMatchCon auto *match = storage_->Create(); match->optional_ = !!ctx->OPTIONAL(); if (ctx->where()) { - match->where_ = ctx->where()->accept(this); + match->where_ = std::any_cast(ctx->where()->accept(this)); } - match->patterns_ = ctx->pattern()->accept(this).as>(); + match->patterns_ = std::any_cast>(ctx->pattern()->accept(this)); return match; } antlrcpp::Any CypherMainVisitor::visitCreate(MemgraphCypher::CreateContext *ctx) { auto *create = storage_->Create(); - create->patterns_ = ctx->pattern()->accept(this).as>(); + create->patterns_ = std::any_cast>(ctx->pattern()->accept(this)); return create; } @@ -1093,7 +1096,7 @@ antlrcpp::Any CypherMainVisitor::visitCallProcedure(MemgraphCypher::CallProcedur call_proc->procedure_name_ = JoinSymbolicNames(this, ctx->procedureName()->symbolicName()); call_proc->arguments_.reserve(ctx->expression().size()); for (auto *expr : ctx->expression()) { - call_proc->arguments_.push_back(expr->accept(this)); + call_proc->arguments_.push_back(std::any_cast(expr->accept(this))); } if (auto *memory_limit_ctx = ctx->procedureMemoryLimit()) { @@ -1133,12 +1136,12 @@ antlrcpp::Any CypherMainVisitor::visitCallProcedure(MemgraphCypher::CallProcedur call_proc->result_identifiers_.reserve(yield_ctx->procedureResult().size()); for (auto *result : yield_ctx->procedureResult()) { MG_ASSERT(result->variable().size() == 1 || result->variable().size() == 2); - call_proc->result_fields_.push_back(result->variable()[0]->accept(this).as()); + call_proc->result_fields_.push_back(std::any_cast(result->variable()[0]->accept(this))); std::string result_alias; if (result->variable().size() == 2) { - result_alias = result->variable()[1]->accept(this).as(); + result_alias = std::any_cast(result->variable()[1]->accept(this)); } else { - result_alias = result->variable()[0]->accept(this).as(); + result_alias = std::any_cast(result->variable()[0]->accept(this)); } call_proc->result_identifiers_.push_back(storage_->Create(result_alias)); } @@ -1174,7 +1177,7 @@ antlrcpp::Any CypherMainVisitor::visitCallProcedure(MemgraphCypher::CallProcedur * @return std::string */ antlrcpp::Any CypherMainVisitor::visitUserOrRoleName(MemgraphCypher::UserOrRoleNameContext *ctx) { - return ctx->symbolicName()->accept(this).as(); + return std::any_cast(ctx->symbolicName()->accept(this)); } /** @@ -1183,7 +1186,7 @@ antlrcpp::Any CypherMainVisitor::visitUserOrRoleName(MemgraphCypher::UserOrRoleN antlrcpp::Any CypherMainVisitor::visitCreateRole(MemgraphCypher::CreateRoleContext *ctx) { AuthQuery *auth = storage_->Create(); auth->action_ = AuthQuery::Action::CREATE_ROLE; - auth->role_ = ctx->role->accept(this).as(); + auth->role_ = std::any_cast(ctx->role->accept(this)); return auth; } @@ -1193,7 +1196,7 @@ antlrcpp::Any CypherMainVisitor::visitCreateRole(MemgraphCypher::CreateRoleConte antlrcpp::Any CypherMainVisitor::visitDropRole(MemgraphCypher::DropRoleContext *ctx) { AuthQuery *auth = storage_->Create(); auth->action_ = AuthQuery::Action::DROP_ROLE; - auth->role_ = ctx->role->accept(this).as(); + auth->role_ = std::any_cast(ctx->role->accept(this)); return auth; } @@ -1212,12 +1215,12 @@ antlrcpp::Any CypherMainVisitor::visitShowRoles(MemgraphCypher::ShowRolesContext antlrcpp::Any CypherMainVisitor::visitCreateUser(MemgraphCypher::CreateUserContext *ctx) { AuthQuery *auth = storage_->Create(); auth->action_ = AuthQuery::Action::CREATE_USER; - auth->user_ = ctx->user->accept(this).as(); + auth->user_ = std::any_cast(ctx->user->accept(this)); if (ctx->password) { if (!ctx->password->StringLiteral() && !ctx->literal()->CYPHERNULL()) { throw SyntaxException("Password should be a string literal or null."); } - auth->password_ = ctx->password->accept(this); + auth->password_ = std::any_cast(ctx->password->accept(this)); } return auth; } @@ -1228,11 +1231,11 @@ antlrcpp::Any CypherMainVisitor::visitCreateUser(MemgraphCypher::CreateUserConte antlrcpp::Any CypherMainVisitor::visitSetPassword(MemgraphCypher::SetPasswordContext *ctx) { AuthQuery *auth = storage_->Create(); auth->action_ = AuthQuery::Action::SET_PASSWORD; - auth->user_ = ctx->user->accept(this).as(); + auth->user_ = std::any_cast(ctx->user->accept(this)); if (!ctx->password->StringLiteral() && !ctx->literal()->CYPHERNULL()) { throw SyntaxException("Password should be a string literal or null."); } - auth->password_ = ctx->password->accept(this); + auth->password_ = std::any_cast(ctx->password->accept(this)); return auth; } @@ -1242,7 +1245,7 @@ antlrcpp::Any CypherMainVisitor::visitSetPassword(MemgraphCypher::SetPasswordCon antlrcpp::Any CypherMainVisitor::visitDropUser(MemgraphCypher::DropUserContext *ctx) { AuthQuery *auth = storage_->Create(); auth->action_ = AuthQuery::Action::DROP_USER; - auth->user_ = ctx->user->accept(this).as(); + auth->user_ = std::any_cast(ctx->user->accept(this)); return auth; } @@ -1261,8 +1264,8 @@ antlrcpp::Any CypherMainVisitor::visitShowUsers(MemgraphCypher::ShowUsersContext antlrcpp::Any CypherMainVisitor::visitSetRole(MemgraphCypher::SetRoleContext *ctx) { AuthQuery *auth = storage_->Create(); auth->action_ = AuthQuery::Action::SET_ROLE; - auth->user_ = ctx->user->accept(this).as(); - auth->role_ = ctx->role->accept(this).as(); + auth->user_ = std::any_cast(ctx->user->accept(this)); + auth->role_ = std::any_cast(ctx->role->accept(this)); return auth; } @@ -1272,7 +1275,7 @@ antlrcpp::Any CypherMainVisitor::visitSetRole(MemgraphCypher::SetRoleContext *ct antlrcpp::Any CypherMainVisitor::visitClearRole(MemgraphCypher::ClearRoleContext *ctx) { AuthQuery *auth = storage_->Create(); auth->action_ = AuthQuery::Action::CLEAR_ROLE; - auth->user_ = ctx->user->accept(this).as(); + auth->user_ = std::any_cast(ctx->user->accept(this)); return auth; } @@ -1282,10 +1285,10 @@ antlrcpp::Any CypherMainVisitor::visitClearRole(MemgraphCypher::ClearRoleContext antlrcpp::Any CypherMainVisitor::visitGrantPrivilege(MemgraphCypher::GrantPrivilegeContext *ctx) { AuthQuery *auth = storage_->Create(); auth->action_ = AuthQuery::Action::GRANT_PRIVILEGE; - auth->user_or_role_ = ctx->userOrRole->accept(this).as(); + auth->user_or_role_ = std::any_cast(ctx->userOrRole->accept(this)); if (ctx->privilegeList()) { for (auto *privilege : ctx->privilegeList()->privilege()) { - auth->privileges_.push_back(privilege->accept(this)); + auth->privileges_.push_back(std::any_cast(privilege->accept(this))); } } else { /* grant all privileges */ @@ -1300,10 +1303,10 @@ antlrcpp::Any CypherMainVisitor::visitGrantPrivilege(MemgraphCypher::GrantPrivil antlrcpp::Any CypherMainVisitor::visitDenyPrivilege(MemgraphCypher::DenyPrivilegeContext *ctx) { AuthQuery *auth = storage_->Create(); auth->action_ = AuthQuery::Action::DENY_PRIVILEGE; - auth->user_or_role_ = ctx->userOrRole->accept(this).as(); + auth->user_or_role_ = std::any_cast(ctx->userOrRole->accept(this)); if (ctx->privilegeList()) { for (auto *privilege : ctx->privilegeList()->privilege()) { - auth->privileges_.push_back(privilege->accept(this)); + auth->privileges_.push_back(std::any_cast(privilege->accept(this))); } } else { /* deny all privileges */ @@ -1318,10 +1321,10 @@ antlrcpp::Any CypherMainVisitor::visitDenyPrivilege(MemgraphCypher::DenyPrivileg antlrcpp::Any CypherMainVisitor::visitRevokePrivilege(MemgraphCypher::RevokePrivilegeContext *ctx) { AuthQuery *auth = storage_->Create(); auth->action_ = AuthQuery::Action::REVOKE_PRIVILEGE; - auth->user_or_role_ = ctx->userOrRole->accept(this).as(); + auth->user_or_role_ = std::any_cast(ctx->userOrRole->accept(this)); if (ctx->privilegeList()) { for (auto *privilege : ctx->privilegeList()->privilege()) { - auth->privileges_.push_back(privilege->accept(this)); + auth->privileges_.push_back(std::any_cast(privilege->accept(this))); } } else { /* revoke all privileges */ @@ -1364,7 +1367,7 @@ antlrcpp::Any CypherMainVisitor::visitPrivilege(MemgraphCypher::PrivilegeContext antlrcpp::Any CypherMainVisitor::visitShowPrivileges(MemgraphCypher::ShowPrivilegesContext *ctx) { AuthQuery *auth = storage_->Create(); auth->action_ = AuthQuery::Action::SHOW_PRIVILEGES; - auth->user_or_role_ = ctx->userOrRole->accept(this).as(); + auth->user_or_role_ = std::any_cast(ctx->userOrRole->accept(this)); return auth; } @@ -1374,7 +1377,7 @@ antlrcpp::Any CypherMainVisitor::visitShowPrivileges(MemgraphCypher::ShowPrivile antlrcpp::Any CypherMainVisitor::visitShowRoleForUser(MemgraphCypher::ShowRoleForUserContext *ctx) { AuthQuery *auth = storage_->Create(); auth->action_ = AuthQuery::Action::SHOW_ROLE_FOR_USER; - auth->user_ = ctx->user->accept(this).as(); + auth->user_ = std::any_cast(ctx->user->accept(this)); return auth; } @@ -1384,13 +1387,13 @@ antlrcpp::Any CypherMainVisitor::visitShowRoleForUser(MemgraphCypher::ShowRoleFo antlrcpp::Any CypherMainVisitor::visitShowUsersForRole(MemgraphCypher::ShowUsersForRoleContext *ctx) { AuthQuery *auth = storage_->Create(); auth->action_ = AuthQuery::Action::SHOW_USERS_FOR_ROLE; - auth->role_ = ctx->role->accept(this).as(); + auth->role_ = std::any_cast(ctx->role->accept(this)); return auth; } antlrcpp::Any CypherMainVisitor::visitCypherReturn(MemgraphCypher::CypherReturnContext *ctx) { auto *return_clause = storage_->Create(); - return_clause->body_ = ctx->returnBody()->accept(this); + return_clause->body_ = std::any_cast(ctx->returnBody()->accept(this)); if (ctx->DISTINCT()) { return_clause->body_.distinct = true; } @@ -1400,23 +1403,23 @@ antlrcpp::Any CypherMainVisitor::visitCypherReturn(MemgraphCypher::CypherReturnC antlrcpp::Any CypherMainVisitor::visitReturnBody(MemgraphCypher::ReturnBodyContext *ctx) { ReturnBody body; if (ctx->order()) { - body.order_by = ctx->order()->accept(this).as>(); + body.order_by = std::any_cast>(ctx->order()->accept(this)); } if (ctx->skip()) { - body.skip = static_cast(ctx->skip()->accept(this)); + body.skip = static_cast(std::any_cast(ctx->skip()->accept(this))); } if (ctx->limit()) { - body.limit = static_cast(ctx->limit()->accept(this)); + body.limit = static_cast(std::any_cast(ctx->limit()->accept(this))); } std::tie(body.all_identifiers, body.named_expressions) = - ctx->returnItems()->accept(this).as>>(); + std::any_cast>>(ctx->returnItems()->accept(this)); return body; } antlrcpp::Any CypherMainVisitor::visitReturnItems(MemgraphCypher::ReturnItemsContext *ctx) { std::vector named_expressions; for (auto *item : ctx->returnItem()) { - named_expressions.push_back(item->accept(this)); + named_expressions.push_back(std::any_cast(item->accept(this))); } return std::pair>(ctx->getTokens(MemgraphCypher::ASTERISK).size(), named_expressions); @@ -1424,10 +1427,10 @@ antlrcpp::Any CypherMainVisitor::visitReturnItems(MemgraphCypher::ReturnItemsCon antlrcpp::Any CypherMainVisitor::visitReturnItem(MemgraphCypher::ReturnItemContext *ctx) { auto *named_expr = storage_->Create(); - named_expr->expression_ = ctx->expression()->accept(this); + named_expr->expression_ = std::any_cast(ctx->expression()->accept(this)); MG_ASSERT(named_expr->expression_); if (ctx->variable()) { - named_expr->name_ = std::string(ctx->variable()->accept(this).as()); + named_expr->name_ = std::string(std::any_cast(ctx->variable()->accept(this))); users_identifiers.insert(named_expr->name_); } else { if (in_with_ && !utils::IsSubtype(*named_expr->expression_, Identifier::kType)) { @@ -1442,33 +1445,34 @@ antlrcpp::Any CypherMainVisitor::visitReturnItem(MemgraphCypher::ReturnItemConte antlrcpp::Any CypherMainVisitor::visitOrder(MemgraphCypher::OrderContext *ctx) { std::vector order_by; for (auto *sort_item : ctx->sortItem()) { - order_by.push_back(sort_item->accept(this)); + order_by.push_back(std::any_cast(sort_item->accept(this))); } return order_by; } antlrcpp::Any CypherMainVisitor::visitSortItem(MemgraphCypher::SortItemContext *ctx) { - return SortItem{ctx->DESC() || ctx->DESCENDING() ? Ordering::DESC : Ordering::ASC, ctx->expression()->accept(this)}; + return SortItem{ctx->DESC() || ctx->DESCENDING() ? Ordering::DESC : Ordering::ASC, + std::any_cast(ctx->expression()->accept(this))}; } antlrcpp::Any CypherMainVisitor::visitNodePattern(MemgraphCypher::NodePatternContext *ctx) { auto *node = storage_->Create(); if (ctx->variable()) { - std::string variable = ctx->variable()->accept(this); + auto variable = std::any_cast(ctx->variable()->accept(this)); node->identifier_ = storage_->Create(variable); users_identifiers.insert(variable); } else { anonymous_identifiers.push_back(&node->identifier_); } if (ctx->nodeLabels()) { - node->labels_ = ctx->nodeLabels()->accept(this).as>(); + node->labels_ = std::any_cast>(ctx->nodeLabels()->accept(this)); } if (ctx->properties()) { // This can return either properties or parameters if (ctx->properties()->mapLiteral()) { - node->properties_ = ctx->properties()->accept(this).as>(); + node->properties_ = std::any_cast>(ctx->properties()->accept(this)); } else { - node->properties_ = ctx->properties()->accept(this).as(); + node->properties_ = std::any_cast(ctx->properties()->accept(this)); } } return node; @@ -1477,7 +1481,7 @@ antlrcpp::Any CypherMainVisitor::visitNodePattern(MemgraphCypher::NodePatternCon antlrcpp::Any CypherMainVisitor::visitNodeLabels(MemgraphCypher::NodeLabelsContext *ctx) { std::vector labels; for (auto *node_label : ctx->nodeLabel()) { - labels.push_back(AddLabel(node_label->accept(this))); + labels.push_back(AddLabel(std::any_cast(node_label->accept(this)))); } return labels; } @@ -1494,8 +1498,8 @@ antlrcpp::Any CypherMainVisitor::visitProperties(MemgraphCypher::PropertiesConte antlrcpp::Any CypherMainVisitor::visitMapLiteral(MemgraphCypher::MapLiteralContext *ctx) { std::unordered_map map; for (int i = 0; i < static_cast(ctx->propertyKeyName().size()); ++i) { - PropertyIx key = ctx->propertyKeyName()[i]->accept(this); - Expression *value = ctx->expression()[i]->accept(this); + auto key = std::any_cast(ctx->propertyKeyName()[i]->accept(this)); + auto *value = std::any_cast(ctx->expression()[i]->accept(this)); if (!map.insert({key, value}).second) { throw SemanticException("Same key can't appear twice in a map literal."); } @@ -1505,12 +1509,14 @@ antlrcpp::Any CypherMainVisitor::visitMapLiteral(MemgraphCypher::MapLiteralConte antlrcpp::Any CypherMainVisitor::visitListLiteral(MemgraphCypher::ListLiteralContext *ctx) { std::vector expressions; - for (auto expr_ctx_ptr : ctx->expression()) expressions.push_back(expr_ctx_ptr->accept(this)); + for (auto *expr_ctx : ctx->expression()) { + expressions.push_back(std::any_cast(expr_ctx->accept(this))); + } return expressions; } antlrcpp::Any CypherMainVisitor::visitPropertyKeyName(MemgraphCypher::PropertyKeyNameContext *ctx) { - return AddProperty(visitChildren(ctx)); + return AddProperty(std::any_cast(visitChildren(ctx))); } antlrcpp::Any CypherMainVisitor::visitSymbolicName(MemgraphCypher::SymbolicNameContext *ctx) { @@ -1548,15 +1554,15 @@ antlrcpp::Any CypherMainVisitor::visitSymbolicName(MemgraphCypher::SymbolicNameC antlrcpp::Any CypherMainVisitor::visitPattern(MemgraphCypher::PatternContext *ctx) { std::vector patterns; for (auto *pattern_part : ctx->patternPart()) { - patterns.push_back(pattern_part->accept(this)); + patterns.push_back(std::any_cast(pattern_part->accept(this))); } return patterns; } antlrcpp::Any CypherMainVisitor::visitPatternPart(MemgraphCypher::PatternPartContext *ctx) { - Pattern *pattern = ctx->anonymousPatternPart()->accept(this); + auto *pattern = std::any_cast(ctx->anonymousPatternPart()->accept(this)); if (ctx->variable()) { - std::string variable = ctx->variable()->accept(this); + auto variable = std::any_cast(ctx->variable()->accept(this)); pattern->identifier_ = storage_->Create(variable); users_identifiers.insert(variable); } else { @@ -1569,10 +1575,10 @@ antlrcpp::Any CypherMainVisitor::visitPatternElement(MemgraphCypher::PatternElem if (ctx->patternElement()) { return ctx->patternElement()->accept(this); } - auto pattern = storage_->Create(); - pattern->atoms_.push_back(ctx->nodePattern()->accept(this).as()); + auto *pattern = storage_->Create(); + pattern->atoms_.push_back(std::any_cast(ctx->nodePattern()->accept(this))); for (auto *pattern_element_chain : ctx->patternElementChain()) { - std::pair element = pattern_element_chain->accept(this); + auto element = std::any_cast>(pattern_element_chain->accept(this)); pattern->atoms_.push_back(element.first); pattern->atoms_.push_back(element.second); } @@ -1580,8 +1586,8 @@ antlrcpp::Any CypherMainVisitor::visitPatternElement(MemgraphCypher::PatternElem } antlrcpp::Any CypherMainVisitor::visitPatternElementChain(MemgraphCypher::PatternElementChainContext *ctx) { - return std::pair(ctx->relationshipPattern()->accept(this).as(), - ctx->nodePattern()->accept(this).as()); + return std::pair(std::any_cast(ctx->relationshipPattern()->accept(this)), + std::any_cast(ctx->nodePattern()->accept(this))); } antlrcpp::Any CypherMainVisitor::visitRelationshipPattern(MemgraphCypher::RelationshipPatternContext *ctx) { @@ -1592,7 +1598,7 @@ antlrcpp::Any CypherMainVisitor::visitRelationshipPattern(MemgraphCypher::Relati edge->type_ = EdgeAtom::Type::SINGLE; if (variableExpansion) std::tie(edge->type_, edge->lower_bound_, edge->upper_bound_) = - variableExpansion->accept(this).as>(); + std::any_cast>(variableExpansion->accept(this)); if (ctx->leftArrowHead() && !ctx->rightArrowHead()) { edge->direction_ = EdgeAtom::Direction::IN; @@ -1610,7 +1616,7 @@ antlrcpp::Any CypherMainVisitor::visitRelationshipPattern(MemgraphCypher::Relati } if (relationshipDetail->name) { - std::string variable = relationshipDetail->name->accept(this); + auto variable = std::any_cast(relationshipDetail->name->accept(this)); edge->identifier_ = storage_->Create(variable); users_identifiers.insert(variable); } else { @@ -1618,7 +1624,8 @@ antlrcpp::Any CypherMainVisitor::visitRelationshipPattern(MemgraphCypher::Relati } if (relationshipDetail->relationshipTypes()) { - edge->edge_types_ = ctx->relationshipDetail()->relationshipTypes()->accept(this).as>(); + edge->edge_types_ = + std::any_cast>(ctx->relationshipDetail()->relationshipTypes()->accept(this)); } auto relationshipLambdas = relationshipDetail->relationshipLambda(); @@ -1629,16 +1636,16 @@ antlrcpp::Any CypherMainVisitor::visitRelationshipPattern(MemgraphCypher::Relati "path expansion."); auto visit_lambda = [this](auto *lambda) { EdgeAtom::Lambda edge_lambda; - std::string traversed_edge_variable = lambda->traversed_edge->accept(this); + auto traversed_edge_variable = std::any_cast(lambda->traversed_edge->accept(this)); edge_lambda.inner_edge = storage_->Create(traversed_edge_variable); - std::string traversed_node_variable = lambda->traversed_node->accept(this); + auto traversed_node_variable = std::any_cast(lambda->traversed_node->accept(this)); edge_lambda.inner_node = storage_->Create(traversed_node_variable); - edge_lambda.expression = lambda->expression()->accept(this); + edge_lambda.expression = std::any_cast(lambda->expression()->accept(this)); return edge_lambda; }; auto visit_total_weight = [&]() { if (relationshipDetail->total_weight) { - std::string total_weight_name = relationshipDetail->total_weight->accept(this); + auto total_weight_name = std::any_cast(relationshipDetail->total_weight->accept(this)); edge->total_weight_ = storage_->Create(total_weight_name); } else { anonymous_identifiers.push_back(&edge->total_weight_); @@ -1688,11 +1695,11 @@ antlrcpp::Any CypherMainVisitor::visitRelationshipPattern(MemgraphCypher::Relati break; case 1: { if (properties[0]->mapLiteral()) { - edge->properties_ = properties[0]->accept(this).as>(); + edge->properties_ = std::any_cast>(properties[0]->accept(this)); break; } MG_ASSERT(properties[0]->parameter()); - edge->properties_ = properties[0]->accept(this).as(); + edge->properties_ = std::any_cast(properties[0]->accept(this)); break; } default: @@ -1715,7 +1722,7 @@ antlrcpp::Any CypherMainVisitor::visitRelationshipLambda(MemgraphCypher::Relatio antlrcpp::Any CypherMainVisitor::visitRelationshipTypes(MemgraphCypher::RelationshipTypesContext *ctx) { std::vector types; for (auto *edge_type : ctx->relTypeName()) { - types.push_back(AddEdgeType(edge_type->accept(this))); + types.push_back(AddEdgeType(std::any_cast(edge_type->accept(this)))); } return types; } @@ -1735,7 +1742,7 @@ antlrcpp::Any CypherMainVisitor::visitVariableExpansion(MemgraphCypher::Variable // Case -[*]- } else if (ctx->expression().size() == 1U) { auto dots_tokens = ctx->getTokens(MemgraphCypher::DOTS); - Expression *bound = ctx->expression()[0]->accept(this); + auto *bound = std::any_cast(ctx->expression()[0]->accept(this)); if (!dots_tokens.size()) { // Case -[*bound]- if (edge_type != EdgeAtom::Type::WEIGHTED_SHORTEST_PATH) lower = bound; @@ -1749,8 +1756,8 @@ antlrcpp::Any CypherMainVisitor::visitVariableExpansion(MemgraphCypher::Variable } } else { // Case -[*lbound..rbound]- - lower = ctx->expression()[0]->accept(this); - upper = ctx->expression()[1]->accept(this); + lower = std::any_cast(ctx->expression()[0]->accept(this)); + upper = std::any_cast(ctx->expression()[1]->accept(this)); } if (lower && edge_type == EdgeAtom::Type::WEIGHTED_SHORTEST_PATH) throw SemanticException("Lower bound is not allowed in weighted shortest path expansion."); @@ -1759,7 +1766,7 @@ antlrcpp::Any CypherMainVisitor::visitVariableExpansion(MemgraphCypher::Variable } antlrcpp::Any CypherMainVisitor::visitExpression(MemgraphCypher::ExpressionContext *ctx) { - return static_cast(ctx->expression12()->accept(this)); + return std::any_cast(ctx->expression12()->accept(this)); } // OR. @@ -1805,11 +1812,11 @@ antlrcpp::Any CypherMainVisitor::visitExpression8(MemgraphCypher::Expression8Con // 4 <= 5 < 7 > 6 -> false // All of those comparisons evaluate to true in memgraph. std::vector children; - children.push_back(ctx->expression7()->accept(this)); + children.push_back(std::any_cast(ctx->expression7()->accept(this))); std::vector operators; auto partial_comparison_expressions = ctx->partialComparisonExpression(); for (auto *child : partial_comparison_expressions) { - children.push_back(child->expression7()->accept(this)); + children.push_back(std::any_cast(child->expression7()->accept(this))); } // First production is comparison operator. for (auto *child : partial_comparison_expressions) { @@ -1871,7 +1878,7 @@ antlrcpp::Any CypherMainVisitor::visitExpression4(MemgraphCypher::Expression4Con // IS NULL, IS NOT NULL, STARTS WITH, .. antlrcpp::Any CypherMainVisitor::visitExpression3a(MemgraphCypher::Expression3aContext *ctx) { - Expression *expression = ctx->expression3b()->accept(this); + auto *expression = std::any_cast(ctx->expression3b()->accept(this)); for (auto *op : ctx->stringAndNullOperators()) { if (op->IS() && op->NOT() && op->CYPHERNULL()) { @@ -1880,12 +1887,12 @@ antlrcpp::Any CypherMainVisitor::visitExpression3a(MemgraphCypher::Expression3aC } else if (op->IS() && op->CYPHERNULL()) { expression = static_cast(storage_->Create(expression)); } else if (op->IN()) { - expression = - static_cast(storage_->Create(expression, op->expression3b()->accept(this))); + expression = static_cast( + storage_->Create(expression, std::any_cast(op->expression3b()->accept(this)))); } else if (utils::StartsWith(op->getText(), "=~")) { auto *regex_match = storage_->Create(); regex_match->string_expr_ = expression; - regex_match->regex_ = op->expression3b()->accept(this); + regex_match->regex_ = std::any_cast(op->expression3b()->accept(this)); expression = regex_match; } else { std::string function_name; @@ -1898,7 +1905,7 @@ antlrcpp::Any CypherMainVisitor::visitExpression3a(MemgraphCypher::Expression3aC } else { throw utils::NotYetImplemented("function '{}'", op->getText()); } - auto expression2 = op->expression3b()->accept(this); + auto *expression2 = std::any_cast(op->expression3b()->accept(this)); std::vector args = {expression, expression2}; expression = static_cast(storage_->Create(function_name, args)); } @@ -1911,18 +1918,19 @@ antlrcpp::Any CypherMainVisitor::visitStringAndNullOperators(MemgraphCypher::Str } antlrcpp::Any CypherMainVisitor::visitExpression3b(MemgraphCypher::Expression3bContext *ctx) { - Expression *expression = ctx->expression2a()->accept(this); + auto *expression = std::any_cast(ctx->expression2a()->accept(this)); for (auto *list_op : ctx->listIndexingOrSlicing()) { if (list_op->getTokens(MemgraphCypher::DOTS).size() == 0U) { // If there is no '..' then we need to create list indexing operator. - expression = storage_->Create(expression, list_op->expression()[0]->accept(this)); + expression = storage_->Create( + expression, std::any_cast(list_op->expression()[0]->accept(this))); } else if (!list_op->lower_bound && !list_op->upper_bound) { throw SemanticException("List slicing operator requires at least one bound."); } else { Expression *lower_bound_ast = - list_op->lower_bound ? static_cast(list_op->lower_bound->accept(this)) : nullptr; + list_op->lower_bound ? std::any_cast(list_op->lower_bound->accept(this)) : nullptr; Expression *upper_bound_ast = - list_op->upper_bound ? static_cast(list_op->upper_bound->accept(this)) : nullptr; + list_op->upper_bound ? std::any_cast(list_op->upper_bound->accept(this)) : nullptr; expression = storage_->Create(expression, lower_bound_ast, upper_bound_ast); } } @@ -1935,18 +1943,18 @@ antlrcpp::Any CypherMainVisitor::visitListIndexingOrSlicing(MemgraphCypher::List } antlrcpp::Any CypherMainVisitor::visitExpression2a(MemgraphCypher::Expression2aContext *ctx) { - Expression *expression = ctx->expression2b()->accept(this); + auto *expression = std::any_cast(ctx->expression2b()->accept(this)); if (ctx->nodeLabels()) { - auto labels = ctx->nodeLabels()->accept(this).as>(); + auto labels = std::any_cast>(ctx->nodeLabels()->accept(this)); expression = storage_->Create(expression, labels); } return expression; } antlrcpp::Any CypherMainVisitor::visitExpression2b(MemgraphCypher::Expression2bContext *ctx) { - Expression *expression = ctx->atom()->accept(this); + auto *expression = std::any_cast(ctx->atom()->accept(this)); for (auto *lookup : ctx->propertyLookup()) { - PropertyIx key = lookup->accept(this); + auto key = std::any_cast(lookup->accept(this)); auto property_lookup = storage_->Create(expression, key); expression = property_lookup; } @@ -1957,19 +1965,19 @@ antlrcpp::Any CypherMainVisitor::visitAtom(MemgraphCypher::AtomContext *ctx) { if (ctx->literal()) { return ctx->literal()->accept(this); } else if (ctx->parameter()) { - return static_cast(ctx->parameter()->accept(this).as()); + return static_cast(std::any_cast(ctx->parameter()->accept(this))); } else if (ctx->parenthesizedExpression()) { - return static_cast(ctx->parenthesizedExpression()->accept(this)); + return static_cast(std::any_cast(ctx->parenthesizedExpression()->accept(this))); } else if (ctx->variable()) { - std::string variable = ctx->variable()->accept(this); + auto variable = std::any_cast(ctx->variable()->accept(this)); users_identifiers.insert(variable); return static_cast(storage_->Create(variable)); } else if (ctx->functionInvocation()) { - return static_cast(ctx->functionInvocation()->accept(this)); + return std::any_cast(ctx->functionInvocation()->accept(this)); } else if (ctx->COALESCE()) { std::vector exprs; for (auto *expr_context : ctx->expression()) { - exprs.emplace_back(expr_context->accept(this).as()); + exprs.emplace_back(std::any_cast(expr_context->accept(this))); } return static_cast(storage_->Create(std::move(exprs))); } else if (ctx->COUNT()) { @@ -1978,57 +1986,57 @@ antlrcpp::Any CypherMainVisitor::visitAtom(MemgraphCypher::AtomContext *ctx) { // functionInvocation and atom producions in opencypher grammar. return static_cast(storage_->Create(nullptr, nullptr, Aggregation::Op::COUNT)); } else if (ctx->ALL()) { - auto *ident = - storage_->Create(ctx->filterExpression()->idInColl()->variable()->accept(this).as()); - Expression *list_expr = ctx->filterExpression()->idInColl()->expression()->accept(this); + auto *ident = storage_->Create( + std::any_cast(ctx->filterExpression()->idInColl()->variable()->accept(this))); + auto *list_expr = std::any_cast(ctx->filterExpression()->idInColl()->expression()->accept(this)); if (!ctx->filterExpression()->where()) { throw SyntaxException("ALL(...) requires a WHERE predicate."); } - Where *where = ctx->filterExpression()->where()->accept(this); + auto *where = std::any_cast(ctx->filterExpression()->where()->accept(this)); return static_cast(storage_->Create(ident, list_expr, where)); } else if (ctx->SINGLE()) { - auto *ident = - storage_->Create(ctx->filterExpression()->idInColl()->variable()->accept(this).as()); - Expression *list_expr = ctx->filterExpression()->idInColl()->expression()->accept(this); + auto *ident = storage_->Create( + std::any_cast(ctx->filterExpression()->idInColl()->variable()->accept(this))); + auto *list_expr = std::any_cast(ctx->filterExpression()->idInColl()->expression()->accept(this)); if (!ctx->filterExpression()->where()) { throw SyntaxException("SINGLE(...) requires a WHERE predicate."); } - Where *where = ctx->filterExpression()->where()->accept(this); + auto *where = std::any_cast(ctx->filterExpression()->where()->accept(this)); return static_cast(storage_->Create(ident, list_expr, where)); } else if (ctx->ANY()) { - auto *ident = - storage_->Create(ctx->filterExpression()->idInColl()->variable()->accept(this).as()); - Expression *list_expr = ctx->filterExpression()->idInColl()->expression()->accept(this); + auto *ident = storage_->Create( + std::any_cast(ctx->filterExpression()->idInColl()->variable()->accept(this))); + auto *list_expr = std::any_cast(ctx->filterExpression()->idInColl()->expression()->accept(this)); if (!ctx->filterExpression()->where()) { throw SyntaxException("ANY(...) requires a WHERE predicate."); } - Where *where = ctx->filterExpression()->where()->accept(this); + auto *where = std::any_cast(ctx->filterExpression()->where()->accept(this)); return static_cast(storage_->Create(ident, list_expr, where)); } else if (ctx->NONE()) { - auto *ident = - storage_->Create(ctx->filterExpression()->idInColl()->variable()->accept(this).as()); - Expression *list_expr = ctx->filterExpression()->idInColl()->expression()->accept(this); + auto *ident = storage_->Create( + std::any_cast(ctx->filterExpression()->idInColl()->variable()->accept(this))); + auto *list_expr = std::any_cast(ctx->filterExpression()->idInColl()->expression()->accept(this)); if (!ctx->filterExpression()->where()) { throw SyntaxException("NONE(...) requires a WHERE predicate."); } - Where *where = ctx->filterExpression()->where()->accept(this); + auto *where = std::any_cast(ctx->filterExpression()->where()->accept(this)); return static_cast(storage_->Create(ident, list_expr, where)); } else if (ctx->REDUCE()) { auto *accumulator = - storage_->Create(ctx->reduceExpression()->accumulator->accept(this).as()); - Expression *initializer = ctx->reduceExpression()->initial->accept(this); - auto *ident = - storage_->Create(ctx->reduceExpression()->idInColl()->variable()->accept(this).as()); - Expression *list = ctx->reduceExpression()->idInColl()->expression()->accept(this); - Expression *expr = ctx->reduceExpression()->expression().back()->accept(this); + storage_->Create(std::any_cast(ctx->reduceExpression()->accumulator->accept(this))); + auto *initializer = std::any_cast(ctx->reduceExpression()->initial->accept(this)); + auto *ident = storage_->Create( + std::any_cast(ctx->reduceExpression()->idInColl()->variable()->accept(this))); + auto *list = std::any_cast(ctx->reduceExpression()->idInColl()->expression()->accept(this)); + auto *expr = std::any_cast(ctx->reduceExpression()->expression().back()->accept(this)); return static_cast(storage_->Create(accumulator, initializer, ident, list, expr)); } else if (ctx->caseExpression()) { - return static_cast(ctx->caseExpression()->accept(this)); + return std::any_cast(ctx->caseExpression()->accept(this)); } else if (ctx->extractExpression()) { - auto *ident = - storage_->Create(ctx->extractExpression()->idInColl()->variable()->accept(this).as()); - Expression *list = ctx->extractExpression()->idInColl()->expression()->accept(this); - Expression *expr = ctx->extractExpression()->expression()->accept(this); + auto *ident = storage_->Create( + std::any_cast(ctx->extractExpression()->idInColl()->variable()->accept(this))); + auto *list = std::any_cast(ctx->extractExpression()->idInColl()->expression()->accept(this)); + auto *expr = std::any_cast(ctx->extractExpression()->expression()->accept(this)); return static_cast(storage_->Create(ident, list, expr)); } // TODO: Implement this. We don't support comprehensions, filtering... at @@ -2054,34 +2062,35 @@ antlrcpp::Any CypherMainVisitor::visitLiteral(MemgraphCypher::LiteralContext *ct return static_cast(storage_->Create(token_position)); } else if (ctx->StringLiteral()) { return static_cast(storage_->Create( - visitStringLiteral(ctx->StringLiteral()->getText()).as(), token_position)); + std::any_cast(visitStringLiteral(std::any_cast(ctx->StringLiteral()->getText()))), + token_position)); } else if (ctx->booleanLiteral()) { return static_cast( - storage_->Create(ctx->booleanLiteral()->accept(this).as(), token_position)); + storage_->Create(std::any_cast(ctx->booleanLiteral()->accept(this)), token_position)); } else if (ctx->numberLiteral()) { - return static_cast( - storage_->Create(ctx->numberLiteral()->accept(this).as(), token_position)); + return static_cast(storage_->Create( + std::any_cast(ctx->numberLiteral()->accept(this)), token_position)); } LOG_FATAL("Expected to handle all cases above"); } else if (ctx->listLiteral()) { return static_cast( - storage_->Create(ctx->listLiteral()->accept(this).as>())); + storage_->Create(std::any_cast>(ctx->listLiteral()->accept(this)))); } else { return static_cast(storage_->Create( - ctx->mapLiteral()->accept(this).as>())); + std::any_cast>(ctx->mapLiteral()->accept(this)))); } return visitChildren(ctx); } antlrcpp::Any CypherMainVisitor::visitParenthesizedExpression(MemgraphCypher::ParenthesizedExpressionContext *ctx) { - return static_cast(ctx->expression()->accept(this)); + return std::any_cast(ctx->expression()->accept(this)); } antlrcpp::Any CypherMainVisitor::visitNumberLiteral(MemgraphCypher::NumberLiteralContext *ctx) { if (ctx->integerLiteral()) { - return TypedValue(ctx->integerLiteral()->accept(this).as()); + return TypedValue(std::any_cast(ctx->integerLiteral()->accept(this))); } else if (ctx->doubleLiteral()) { - return TypedValue(ctx->doubleLiteral()->accept(this).as()); + return TypedValue(std::any_cast(ctx->doubleLiteral()->accept(this))); } else { // This should never happen, except grammar changes and we don't notice // change in this production. @@ -2094,10 +2103,10 @@ antlrcpp::Any CypherMainVisitor::visitFunctionInvocation(MemgraphCypher::Functio if (ctx->DISTINCT()) { throw utils::NotYetImplemented("DISTINCT function call"); } - std::string function_name = ctx->functionName()->accept(this); + auto function_name = std::any_cast(ctx->functionName()->accept(this)); std::vector expressions; for (auto *expression : ctx->expression()) { - expressions.push_back(expression->accept(this)); + expressions.push_back(std::any_cast(expression->accept(this))); } if (expressions.size() == 1U) { if (function_name == Aggregation::kCount) { @@ -2179,21 +2188,21 @@ antlrcpp::Any CypherMainVisitor::visitCypherDelete(MemgraphCypher::CypherDeleteC del->detach_ = true; } for (auto *expression : ctx->expression()) { - del->expressions_.push_back(expression->accept(this)); + del->expressions_.push_back(std::any_cast(expression->accept(this))); } return del; } antlrcpp::Any CypherMainVisitor::visitWhere(MemgraphCypher::WhereContext *ctx) { auto *where = storage_->Create(); - where->expression_ = ctx->expression()->accept(this); + where->expression_ = std::any_cast(ctx->expression()->accept(this)); return where; } antlrcpp::Any CypherMainVisitor::visitSet(MemgraphCypher::SetContext *ctx) { std::vector set_items; for (auto *set_item : ctx->setItem()) { - set_items.push_back(set_item->accept(this)); + set_items.push_back(std::any_cast(set_item->accept(this))); } return set_items; } @@ -2202,16 +2211,17 @@ antlrcpp::Any CypherMainVisitor::visitSetItem(MemgraphCypher::SetItemContext *ct // SetProperty if (ctx->propertyExpression()) { auto *set_property = storage_->Create(); - set_property->property_lookup_ = ctx->propertyExpression()->accept(this); - set_property->expression_ = ctx->expression()->accept(this); + set_property->property_lookup_ = std::any_cast(ctx->propertyExpression()->accept(this)); + set_property->expression_ = std::any_cast(ctx->expression()->accept(this)); return static_cast(set_property); } // SetProperties either assignment or update if (ctx->getTokens(MemgraphCypher::EQ).size() || ctx->getTokens(MemgraphCypher::PLUS_EQ).size()) { auto *set_properties = storage_->Create(); - set_properties->identifier_ = storage_->Create(ctx->variable()->accept(this).as()); - set_properties->expression_ = ctx->expression()->accept(this); + set_properties->identifier_ = + storage_->Create(std::any_cast(ctx->variable()->accept(this))); + set_properties->expression_ = std::any_cast(ctx->expression()->accept(this)); if (ctx->getTokens(MemgraphCypher::PLUS_EQ).size()) { set_properties->update_ = true; } @@ -2220,15 +2230,15 @@ antlrcpp::Any CypherMainVisitor::visitSetItem(MemgraphCypher::SetItemContext *ct // SetLabels auto *set_labels = storage_->Create(); - set_labels->identifier_ = storage_->Create(ctx->variable()->accept(this).as()); - set_labels->labels_ = ctx->nodeLabels()->accept(this).as>(); + set_labels->identifier_ = storage_->Create(std::any_cast(ctx->variable()->accept(this))); + set_labels->labels_ = std::any_cast>(ctx->nodeLabels()->accept(this)); return static_cast(set_labels); } antlrcpp::Any CypherMainVisitor::visitRemove(MemgraphCypher::RemoveContext *ctx) { std::vector remove_items; for (auto *remove_item : ctx->removeItem()) { - remove_items.push_back(remove_item->accept(this)); + remove_items.push_back(std::any_cast(remove_item->accept(this))); } return remove_items; } @@ -2237,21 +2247,21 @@ antlrcpp::Any CypherMainVisitor::visitRemoveItem(MemgraphCypher::RemoveItemConte // RemoveProperty if (ctx->propertyExpression()) { auto *remove_property = storage_->Create(); - remove_property->property_lookup_ = ctx->propertyExpression()->accept(this); + remove_property->property_lookup_ = std::any_cast(ctx->propertyExpression()->accept(this)); return static_cast(remove_property); } // RemoveLabels auto *remove_labels = storage_->Create(); - remove_labels->identifier_ = storage_->Create(ctx->variable()->accept(this).as()); - remove_labels->labels_ = ctx->nodeLabels()->accept(this).as>(); + remove_labels->identifier_ = storage_->Create(std::any_cast(ctx->variable()->accept(this))); + remove_labels->labels_ = std::any_cast>(ctx->nodeLabels()->accept(this)); return static_cast(remove_labels); } antlrcpp::Any CypherMainVisitor::visitPropertyExpression(MemgraphCypher::PropertyExpressionContext *ctx) { - Expression *expression = ctx->atom()->accept(this); + auto *expression = std::any_cast(ctx->atom()->accept(this)); for (auto *lookup : ctx->propertyLookup()) { - PropertyIx key = lookup->accept(this); + auto key = std::any_cast(lookup->accept(this)); auto property_lookup = storage_->Create(expression, key); expression = property_lookup; } @@ -2260,17 +2270,18 @@ antlrcpp::Any CypherMainVisitor::visitPropertyExpression(MemgraphCypher::Propert } antlrcpp::Any CypherMainVisitor::visitCaseExpression(MemgraphCypher::CaseExpressionContext *ctx) { - Expression *test_expression = ctx->test ? ctx->test->accept(this).as() : nullptr; + Expression *test_expression = ctx->test ? std::any_cast(ctx->test->accept(this)) : nullptr; auto alternatives = ctx->caseAlternatives(); // Reverse alternatives so that tree of IfOperators can be built bottom-up. std::reverse(alternatives.begin(), alternatives.end()); - Expression *else_expression = ctx->else_expression ? ctx->else_expression->accept(this).as() + Expression *else_expression = ctx->else_expression ? std::any_cast(ctx->else_expression->accept(this)) : storage_->Create(TypedValue()); for (auto *alternative : alternatives) { Expression *condition = - test_expression ? storage_->Create(test_expression, alternative->when_expression->accept(this)) - : alternative->when_expression->accept(this).as(); - Expression *then_expression = alternative->then_expression->accept(this); + test_expression ? storage_->Create( + test_expression, std::any_cast(alternative->when_expression->accept(this))) + : std::any_cast(alternative->when_expression->accept(this)); + auto *then_expression = std::any_cast(alternative->then_expression->accept(this)); else_expression = storage_->Create(condition, then_expression, else_expression); } return else_expression; @@ -2284,22 +2295,22 @@ antlrcpp::Any CypherMainVisitor::visitCaseAlternatives(MemgraphCypher::CaseAlter antlrcpp::Any CypherMainVisitor::visitWith(MemgraphCypher::WithContext *ctx) { auto *with = storage_->Create(); in_with_ = true; - with->body_ = ctx->returnBody()->accept(this); + with->body_ = std::any_cast(ctx->returnBody()->accept(this)); in_with_ = false; if (ctx->DISTINCT()) { with->body_.distinct = true; } if (ctx->where()) { - with->where_ = ctx->where()->accept(this); + with->where_ = std::any_cast(ctx->where()->accept(this)); } return with; } antlrcpp::Any CypherMainVisitor::visitMerge(MemgraphCypher::MergeContext *ctx) { auto *merge = storage_->Create(); - merge->pattern_ = ctx->patternPart()->accept(this); + merge->pattern_ = std::any_cast(ctx->patternPart()->accept(this)); for (auto &merge_action : ctx->mergeAction()) { - auto set = merge_action->set()->accept(this).as>(); + auto set = std::any_cast>(merge_action->set()->accept(this)); if (merge_action->MATCH()) { merge->on_match_.insert(merge->on_match_.end(), set.begin(), set.end()); } else { @@ -2312,8 +2323,8 @@ antlrcpp::Any CypherMainVisitor::visitMerge(MemgraphCypher::MergeContext *ctx) { antlrcpp::Any CypherMainVisitor::visitUnwind(MemgraphCypher::UnwindContext *ctx) { auto *named_expr = storage_->Create(); - named_expr->expression_ = ctx->expression()->accept(this); - named_expr->name_ = std::string(ctx->variable()->accept(this).as()); + named_expr->expression_ = std::any_cast(ctx->expression()->accept(this)); + named_expr->name_ = std::any_cast(ctx->variable()->accept(this)); return storage_->Create(named_expr); } @@ -2326,27 +2337,27 @@ antlrcpp::Any CypherMainVisitor::visitForeach(MemgraphCypher::ForeachContext *ct auto *for_each = storage_->Create(); auto *named_expr = storage_->Create(); - named_expr->expression_ = ctx->expression()->accept(this); - named_expr->name_ = std::string(ctx->variable()->accept(this).as()); + named_expr->expression_ = std::any_cast(ctx->expression()->accept(this)); + named_expr->name_ = std::any_cast(ctx->variable()->accept(this)); for_each->named_expression_ = named_expr; for (auto *update_clause_ctx : ctx->updateClause()) { if (auto *set = update_clause_ctx->set(); set) { - auto set_items = visitSet(set).as>(); + auto set_items = std::any_cast>(visitSet(set)); std::copy(set_items.begin(), set_items.end(), std::back_inserter(for_each->clauses_)); } else if (auto *remove = update_clause_ctx->remove(); remove) { - auto remove_items = visitRemove(remove).as>(); + auto remove_items = std::any_cast>(visitRemove(remove)); std::copy(remove_items.begin(), remove_items.end(), std::back_inserter(for_each->clauses_)); } else if (auto *merge = update_clause_ctx->merge(); merge) { - for_each->clauses_.push_back(visitMerge(merge).as()); + for_each->clauses_.push_back(std::any_cast(visitMerge(merge))); } else if (auto *create = update_clause_ctx->create(); create) { - for_each->clauses_.push_back(visitCreate(create).as()); + for_each->clauses_.push_back(std::any_cast(visitCreate(create))); } else if (auto *cypher_delete = update_clause_ctx->cypherDelete(); cypher_delete) { - for_each->clauses_.push_back(visitCypherDelete(cypher_delete).as()); + for_each->clauses_.push_back(std::any_cast(visitCypherDelete(cypher_delete))); } else { auto *nested_for_each = update_clause_ctx->foreach (); MG_ASSERT(nested_for_each != nullptr, "Unexpected clause in FOREACH"); - for_each->clauses_.push_back(visitForeach(nested_for_each).as()); + for_each->clauses_.push_back(std::any_cast(visitForeach(nested_for_each))); } } diff --git a/src/query/v2/frontend/ast/cypher_main_visitor.hpp b/src/query/v2/frontend/ast/cypher_main_visitor.hpp index f0d5ba78b..767c8ce65 100644 --- a/src/query/v2/frontend/ast/cypher_main_visitor.hpp +++ b/src/query/v2/frontend/ast/cypher_main_visitor.hpp @@ -115,7 +115,7 @@ class CypherMainVisitor : public antlropencypher::MemgraphCypherBaseVisitor { auto operators = ExtractOperators(all_children, allowed_operators); for (auto *expression : _expressions) { - expressions.push_back(expression->accept(this)); + expressions.push_back(std::any_cast(expression->accept(this))); } Expression *first_operand = expressions[0]; @@ -131,7 +131,7 @@ class CypherMainVisitor : public antlropencypher::MemgraphCypherBaseVisitor { DMG_ASSERT(_expression, "can't happen"); auto operators = ExtractOperators(all_children, allowed_operators); - Expression *expression = _expression->accept(this); + Expression *expression = std::any_cast(_expression->accept(this)); for (int i = (int)operators.size() - 1; i >= 0; --i) { expression = CreateUnaryOperatorByToken(operators[i], expression); } diff --git a/src/query/v2/interpreter.cpp b/src/query/v2/interpreter.cpp index a60d77dec..73f3e00be 100644 --- a/src/query/v2/interpreter.cpp +++ b/src/query/v2/interpreter.cpp @@ -1186,7 +1186,7 @@ PreparedQuery PrepareExplainQuery(ParsedQuery parsed_query, std::mapast_cache, &interpreter_context->antlr_lock, interpreter_context->config.query); + &interpreter_context->ast_cache, interpreter_context->config.query); auto *cypher_query = utils::Downcast(parsed_inner_query.query); MG_ASSERT(cypher_query, "Cypher grammar should not allow other queries in EXPLAIN"); @@ -1253,7 +1253,7 @@ PreparedQuery PrepareProfileQuery(ParsedQuery parsed_query, bool in_explicit_tra // full query string) when given just the inner query to execute. ParsedQuery parsed_inner_query = ParseQuery(parsed_query.query_string.substr(kProfileQueryStart.size()), parsed_query.user_parameters, - &interpreter_context->ast_cache, &interpreter_context->antlr_lock, interpreter_context->config.query); + &interpreter_context->ast_cache, interpreter_context->config.query); auto *cypher_query = utils::Downcast(parsed_inner_query.query); MG_ASSERT(cypher_query, "Cypher grammar should not allow other queries in PROFILE"); @@ -1571,8 +1571,7 @@ Callback CreateTrigger(TriggerQuery *trigger_query, interpreter_context->trigger_store.AddTrigger( std::move(trigger_name), trigger_statement, user_parameters, ToTriggerEventType(event_type), before_commit ? TriggerPhase::BEFORE_COMMIT : TriggerPhase::AFTER_COMMIT, &interpreter_context->ast_cache, - dba, &interpreter_context->antlr_lock, interpreter_context->config.query, std::move(owner), - interpreter_context->auth_checker); + dba, interpreter_context->config.query, std::move(owner), interpreter_context->auth_checker); return {}; }}; } @@ -2129,8 +2128,8 @@ Interpreter::PrepareResult Interpreter::Prepare(const std::string &query_string, query_execution->summary["cost_estimate"] = 0.0; utils::Timer parsing_timer; - ParsedQuery parsed_query = ParseQuery(query_string, params, &interpreter_context_->ast_cache, - &interpreter_context_->antlr_lock, interpreter_context_->config.query); + ParsedQuery parsed_query = + ParseQuery(query_string, params, &interpreter_context_->ast_cache, interpreter_context_->config.query); query_execution->summary["parsing_time"] = parsing_timer.Elapsed().count(); // Some queries require an active transaction in order to be prepared. diff --git a/src/query/v2/interpreter.hpp b/src/query/v2/interpreter.hpp index b1f89f22b..d3da9c724 100644 --- a/src/query/v2/interpreter.hpp +++ b/src/query/v2/interpreter.hpp @@ -171,13 +171,6 @@ struct InterpreterContext { storage::v3::Storage *db; - // ANTLR has singleton instance that is shared between threads. It is - // protected by locks inside of ANTLR. Unfortunately, they are not protected - // in a very good way. Once we have ANTLR version without race conditions we - // can remove this lock. This will probably never happen since ANTLR - // developers introduce more bugs in each version. Fortunately, we have - // cache so this lock probably won't impact performance much... - utils::SpinLock antlr_lock; std::optional tsc_frequency{utils::GetTSCFrequency()}; std::atomic is_shutting_down{false}; diff --git a/src/query/v2/trigger.cpp b/src/query/v2/trigger.cpp index 08f9ace9f..a8fe327de 100644 --- a/src/query/v2/trigger.cpp +++ b/src/query/v2/trigger.cpp @@ -153,10 +153,10 @@ std::vector> GetPredefinedIdentifier Trigger::Trigger(std::string name, const std::string &query, const std::map &user_parameters, const TriggerEventType event_type, utils::SkipList *query_cache, - DbAccessor *db_accessor, utils::SpinLock *antlr_lock, const InterpreterConfig::Query &query_config, + DbAccessor *db_accessor, const InterpreterConfig::Query &query_config, std::optional owner, const query::v2::AuthChecker *auth_checker) : name_{std::move(name)}, - parsed_statements_{ParseQuery(query, user_parameters, query_cache, antlr_lock, query_config)}, + parsed_statements_{ParseQuery(query, user_parameters, query_cache, query_config)}, event_type_{event_type}, owner_{std::move(owner)} { // We check immediately if the query is valid by trying to create a plan. @@ -257,7 +257,7 @@ inline constexpr uint64_t kVersion{2}; TriggerStore::TriggerStore(std::filesystem::path directory) : storage_{std::move(directory)} {} void TriggerStore::RestoreTriggers(utils::SkipList *query_cache, DbAccessor *db_accessor, - utils::SpinLock *antlr_lock, const InterpreterConfig::Query &query_config, + const InterpreterConfig::Query &query_config, const query::v2::AuthChecker *auth_checker) { MG_ASSERT(before_commit_triggers_.size() == 0 && after_commit_triggers_.size() == 0, "Cannot restore trigger when some triggers already exist!"); @@ -317,8 +317,8 @@ void TriggerStore::RestoreTriggers(utils::SkipList *query_cache std::optional trigger; try { - trigger.emplace(trigger_name, statement, user_parameters, event_type, query_cache, db_accessor, antlr_lock, - query_config, std::move(owner), auth_checker); + trigger.emplace(trigger_name, statement, user_parameters, event_type, query_cache, db_accessor, query_config, + std::move(owner), auth_checker); } catch (const utils::BasicException &e) { spdlog::warn("Failed to create trigger '{}' because: {}", trigger_name, e.what()); continue; @@ -336,8 +336,8 @@ void TriggerStore::AddTrigger(std::string name, const std::string &query, const std::map &user_parameters, TriggerEventType event_type, TriggerPhase phase, utils::SkipList *query_cache, DbAccessor *db_accessor, - utils::SpinLock *antlr_lock, const InterpreterConfig::Query &query_config, - std::optional owner, const query::v2::AuthChecker *auth_checker) { + const InterpreterConfig::Query &query_config, std::optional owner, + const query::v2::AuthChecker *auth_checker) { std::unique_lock store_guard{store_lock_}; if (storage_.Get(name)) { throw utils::BasicException("Trigger with the same name already exists."); @@ -345,8 +345,8 @@ void TriggerStore::AddTrigger(std::string name, const std::string &query, std::optional trigger; try { - trigger.emplace(std::move(name), query, user_parameters, event_type, query_cache, db_accessor, antlr_lock, - query_config, std::move(owner), auth_checker); + trigger.emplace(std::move(name), query, user_parameters, event_type, query_cache, db_accessor, query_config, + std::move(owner), auth_checker); } catch (const utils::BasicException &e) { const auto identifiers = GetPredefinedIdentifiers(event_type); std::stringstream identifier_names_stream; diff --git a/src/query/v2/trigger.hpp b/src/query/v2/trigger.hpp index 5ceaaa63e..35fdf88a5 100644 --- a/src/query/v2/trigger.hpp +++ b/src/query/v2/trigger.hpp @@ -35,8 +35,8 @@ struct Trigger { explicit Trigger(std::string name, const std::string &query, const std::map &user_parameters, TriggerEventType event_type, utils::SkipList *query_cache, DbAccessor *db_accessor, - utils::SpinLock *antlr_lock, const InterpreterConfig::Query &query_config, - std::optional owner, const AuthChecker *auth_checker); + const InterpreterConfig::Query &query_config, std::optional owner, + const query::v2::AuthChecker *auth_checker); void Execute(DbAccessor *dba, utils::MonotonicBufferResource *execution_memory, double max_execution_time_sec, std::atomic *is_shutting_down, const TriggerContext &context, @@ -81,14 +81,13 @@ struct TriggerStore { explicit TriggerStore(std::filesystem::path directory); void RestoreTriggers(utils::SkipList *query_cache, DbAccessor *db_accessor, - utils::SpinLock *antlr_lock, const InterpreterConfig::Query &query_config, - const query::v2::AuthChecker *auth_checker); + const InterpreterConfig::Query &query_config, const query::v2::AuthChecker *auth_checker); void AddTrigger(std::string name, const std::string &query, const std::map &user_parameters, TriggerEventType event_type, TriggerPhase phase, utils::SkipList *query_cache, DbAccessor *db_accessor, - utils::SpinLock *antlr_lock, const InterpreterConfig::Query &query_config, - std::optional owner, const query::v2::AuthChecker *auth_checker); + const InterpreterConfig::Query &query_config, std::optional owner, + const query::v2::AuthChecker *auth_checker); void DropTrigger(const std::string &name); diff --git a/tests/simulation/CMakeLists.txt b/tests/simulation/CMakeLists.txt index de62518ec..67f073418 100644 --- a/tests/simulation/CMakeLists.txt +++ b/tests/simulation/CMakeLists.txt @@ -29,6 +29,4 @@ add_simulation_test(future.cpp thread) add_simulation_test(basic_request.cpp address) -add_simulation_test(raft.cpp address) - add_simulation_test(trial_query_storage/query_storage_test.cpp address) diff --git a/tests/simulation/basic_request.cpp b/tests/simulation/basic_request.cpp index ecf8fbe1d..6e87b8e41 100644 --- a/tests/simulation/basic_request.cpp +++ b/tests/simulation/basic_request.cpp @@ -34,7 +34,7 @@ void run_server(Io io) { while (!io.ShouldShutDown()) { std::cout << "[SERVER] Is receiving..." << std::endl; - auto request_result = io.ReceiveWithTimeout(100000); + auto request_result = io.Receive(); if (request_result.HasError()) { std::cout << "[SERVER] Error, continue" << std::endl; continue; @@ -71,8 +71,8 @@ int main() { // send request CounterRequest cli_req; cli_req.proposal = i; - auto res_f = cli_io.RequestWithTimeout(srv_addr, cli_req, 1000); - auto res_rez = res_f.Wait(); + auto res_f = cli_io.Request(srv_addr, cli_req); + auto res_rez = std::move(res_f).Wait(); if (!res_rez.HasError()) { std::cout << "[CLIENT] Got a valid response" << std::endl; auto env = res_rez.GetValue(); diff --git a/tests/simulation/future.cpp b/tests/simulation/future.cpp index 94d3154c0..861769ea5 100644 --- a/tests/simulation/future.cpp +++ b/tests/simulation/future.cpp @@ -20,7 +20,7 @@ using namespace memgraph::io; void Fill(Promise promise_1) { promise_1.Fill("success"); } void Wait(Future future_1, Promise promise_2) { - std::string result_1 = future_1.Wait(); + std::string result_1 = std::move(future_1).Wait(); MG_ASSERT(result_1 == "success"); promise_2.Fill("it worked"); } @@ -49,7 +49,7 @@ int main() { t1.join(); t2.join(); - std::string result_2 = future_2.Wait(); + std::string result_2 = std::move(future_2).Wait(); MG_ASSERT(result_2 == "it worked"); return 0; diff --git a/tests/simulation/trial_query_storage/query_storage_test.cpp b/tests/simulation/trial_query_storage/query_storage_test.cpp index bf650b693..79c11da60 100644 --- a/tests/simulation/trial_query_storage/query_storage_test.cpp +++ b/tests/simulation/trial_query_storage/query_storage_test.cpp @@ -26,7 +26,7 @@ using memgraph::io::simulator::SimulatorTransport; void run_server(Io io) { while (!io.ShouldShutDown()) { std::cout << "[STORAGE] Is receiving..." << std::endl; - auto request_result = io.ReceiveWithTimeout(100000); + auto request_result = io.Receive(); if (request_result.HasError()) { std::cout << "[STORAGE] Error, continue" << std::endl; continue; @@ -78,8 +78,8 @@ int main() { auto req = ScanVerticesRequest{2, std::nullopt}; - auto res_f = cli_io.RequestWithTimeout(srv_addr, req, 1000); - auto res_rez = res_f.Wait(); + auto res_f = cli_io.Request(srv_addr, req); + auto res_rez = std::move(res_f).Wait(); // MG_ASSERT(res_rez.HasError()); simulator.ShutDown(); return 0;