From 74d36638219c7a85c4a14e3c40704a069bd829cd Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Marko=20Budiseli=C4=87?= <marko.budiselic@memgraph.com>
Date: Tue, 26 Jul 2022 08:31:38 +0200
Subject: [PATCH] Upgrade Antrl to 4.10.1 and remove antlr_lock (#441)

---
 libs/.gitignore                               |   1 +
 libs/CMakeLists.txt                           |   1 +
 libs/antlr4.10.1.patch                        |  13 +
 libs/antlr4.patch                             |  43 --
 libs/setup.sh                                 |   8 +-
 src/memgraph.cpp                              |   5 +-
 src/query/CMakeLists.txt                      |   2 +-
 src/query/cypher_query_interpreter.cpp        |  25 +-
 src/query/cypher_query_interpreter.hpp        |   3 +-
 .../frontend/ast/cypher_main_visitor.cpp      | 471 +++++++++---------
 .../frontend/ast/cypher_main_visitor.hpp      |   4 +-
 src/query/interpreter.cpp                     |  11 +-
 src/query/interpreter.hpp                     |   7 -
 src/query/trigger.cpp                         |  18 +-
 src/query/trigger.hpp                         |   9 +-
 tests/manual/antlr_sigsegv.cpp                |   9 +
 tests/unit/query_trigger.cpp                  |  45 +-
 17 files changed, 325 insertions(+), 350 deletions(-)
 create mode 100644 libs/antlr4.10.1.patch
 delete mode 100644 libs/antlr4.patch

diff --git a/libs/.gitignore b/libs/.gitignore
index 0bec9e7d4..f4ebfc3a0 100644
--- a/libs/.gitignore
+++ b/libs/.gitignore
@@ -5,3 +5,4 @@
 !CMakeLists.txt
 !__main.cpp
 !pulsar.patch
+!antlr4.10.1.patch
diff --git a/libs/CMakeLists.txt b/libs/CMakeLists.txt
index 10f30dfe6..618c0ce5c 100644
--- a/libs/CMakeLists.txt
+++ b/libs/CMakeLists.txt
@@ -106,6 +106,7 @@ import_external_library(antlr4 STATIC
              -DWITH_LIBCXX=OFF # because of debian bug
              -DCMAKE_SKIP_INSTALL_ALL_DEPENDENCY=true
              -DCMAKE_CXX_STANDARD=20
+             -DANTLR_BUILD_CPP_TESTS=OFF
   BUILD_COMMAND $(MAKE) antlr4_static
   INSTALL_COMMAND $(MAKE) install)
 
diff --git a/libs/antlr4.10.1.patch b/libs/antlr4.10.1.patch
new file mode 100644
index 000000000..b5206f491
--- /dev/null
+++ b/libs/antlr4.10.1.patch
@@ -0,0 +1,13 @@
+diff --git a/runtime/Cpp/runtime/CMakeLists.txt b/runtime/Cpp/runtime/CMakeLists.txt
+index baf46cac9..2e7756de8 100644
+--- a/runtime/Cpp/runtime/CMakeLists.txt
++++ b/runtime/Cpp/runtime/CMakeLists.txt
+@@ -134,7 +134,7 @@ set_target_properties(antlr4_static
+                                  ARCHIVE_OUTPUT_DIRECTORY ${LIB_OUTPUT_DIR}
+                                  COMPILE_FLAGS "${disabled_compile_warnings} ${extra_static_compile_flags}")
+
+-install(TARGETS antlr4_shared
++install(TARGETS antlr4_shared OPTIONAL
+         EXPORT antlr4-targets
+         ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
+         LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
diff --git a/libs/antlr4.patch b/libs/antlr4.patch
deleted file mode 100644
index 694dd2e39..000000000
--- a/libs/antlr4.patch
+++ /dev/null
@@ -1,43 +0,0 @@
-diff --git a/runtime/Cpp/runtime/CMakeLists.txt b/runtime/Cpp/runtime/CMakeLists.txt
-index a8503bb..11362cf 100644
---- a/runtime/Cpp/runtime/CMakeLists.txt
-+++ b/runtime/Cpp/runtime/CMakeLists.txt
-@@ -5,8 +5,8 @@ set(THIRDPARTY_DIR ${CMAKE_BINARY_DIR}/runtime/thirdparty)
- set(UTFCPP_DIR ${THIRDPARTY_DIR}/utfcpp)
- ExternalProject_Add(
-   utfcpp
--  GIT_REPOSITORY        "git://github.com/nemtrif/utfcpp"
--  GIT_TAG               "v3.1.1"
-+  GIT_REPOSITORY        "https://github.com/nemtrif/utfcpp"
-+  GIT_TAG               "v3.2.1"
-   SOURCE_DIR            ${UTFCPP_DIR}
-   UPDATE_DISCONNECTED   1
-   CMAKE_ARGS            -DCMAKE_INSTALL_PREFIX=${UTFCPP_DIR}/install -Dgtest_force_shared_crt=ON
-@@ -118,7 +118,7 @@ set_target_properties(antlr4_static
-                                  ARCHIVE_OUTPUT_DIRECTORY ${LIB_OUTPUT_DIR}
-                                  COMPILE_FLAGS "${disabled_compile_warnings} ${extra_static_compile_flags}")
- 
--install(TARGETS antlr4_shared
-+install(TARGETS antlr4_shared OPTIONAL
-         DESTINATION lib
-         EXPORT antlr4-targets)
- install(TARGETS antlr4_static
-diff --git a/runtime/Cpp/runtime/src/support/Any.h b/runtime/Cpp/runtime/src/support/Any.h
-index 468db98..65a473b 100644
---- a/runtime/Cpp/runtime/src/support/Any.h
-+++ b/runtime/Cpp/runtime/src/support/Any.h
-@@ -122,12 +122,12 @@ private:
-     }
- 
-   private:
--    template<int N = 0, typename std::enable_if<N == N && std::is_nothrow_copy_constructible<T>::value, int>::type = 0>
-+    template<int N = 0, typename std::enable_if<N == N && std::is_copy_constructible<T>::value, int>::type = 0>
-     Base* clone() const {
-       return new Derived<T>(value);
-     }
- 
--    template<int N = 0, typename std::enable_if<N == N && !std::is_nothrow_copy_constructible<T>::value, int>::type = 0>
-+    template<int N = 0, typename std::enable_if<N == N && !std::is_copy_constructible<T>::value, int>::type = 0>
-     Base* clone() const {
-       return nullptr;
-     }
diff --git a/libs/setup.sh b/libs/setup.sh
index 6a73f65d1..dd59d5d3a 100755
--- a/libs/setup.sh
+++ b/libs/setup.sh
@@ -105,7 +105,7 @@ repo_clone_try_double () {
 # Download from primary_urls might fail because the cache is not installed.
 declare -A primary_urls=(
   ["antlr4-code"]="http://$local_cache_host/git/antlr4.git"
-  ["antlr4-generator"]="http://$local_cache_host/file/antlr-4.9.2-complete.jar"
+  ["antlr4-generator"]="http://$local_cache_host/file/antlr-4.10.1-complete.jar"
   ["cppitertools"]="http://$local_cache_host/git/cppitertools.git"
   ["rapidcheck"]="http://$local_cache_host/git/rapidcheck.git"
   ["gbenchmark"]="http://$local_cache_host/git/benchmark.git"
@@ -130,7 +130,7 @@ declare -A primary_urls=(
 # should fail.
 declare -A secondary_urls=(
   ["antlr4-code"]="https://github.com/antlr/antlr4.git"
-  ["antlr4-generator"]="http://www.antlr.org/download/antlr-4.9.2-complete.jar"
+  ["antlr4-generator"]="https://www.antlr.org/download/antlr-4.10.1-complete.jar"
   ["cppitertools"]="https://github.com/ryanhaining/cppitertools.git"
   ["rapidcheck"]="https://github.com/emil-e/rapidcheck.git"
   ["gbenchmark"]="https://github.com/google/benchmark.git"
@@ -152,10 +152,10 @@ declare -A secondary_urls=(
 # antlr
 file_get_try_double "${primary_urls[antlr4-generator]}" "${secondary_urls[antlr4-generator]}"
 
-antlr4_tag="4.9.2" # v4.9.2
+antlr4_tag="4.10.1" # v4.10.1
 repo_clone_try_double "${primary_urls[antlr4-code]}" "${secondary_urls[antlr4-code]}" "antlr4" "$antlr4_tag" true
 pushd antlr4
-git apply ../antlr4.patch
+git apply ../antlr4.10.1.patch
 popd
 
 # cppitertools v2.0 2019-12-23
diff --git a/src/memgraph.cpp b/src/memgraph.cpp
index 9bd3f3f92..d4fc3bad1 100644
--- a/src/memgraph.cpp
+++ b/src/memgraph.cpp
@@ -1252,9 +1252,8 @@ int main(int argc, char **argv) {
     // the triggers
     auto storage_accessor = interpreter_context.db->Access();
     auto dba = memgraph::query::DbAccessor{&storage_accessor};
-    interpreter_context.trigger_store.RestoreTriggers(&interpreter_context.ast_cache, &dba,
-                                                      &interpreter_context.antlr_lock, interpreter_context.config.query,
-                                                      interpreter_context.auth_checker);
+    interpreter_context.trigger_store.RestoreTriggers(
+        &interpreter_context.ast_cache, &dba, interpreter_context.config.query, interpreter_context.auth_checker);
   }
 
   // As the Stream transformations are using modules, they have to be restored after the query modules are loaded.
diff --git a/src/query/CMakeLists.txt b/src/query/CMakeLists.txt
index 0302df4da..0303f2fa5 100644
--- a/src/query/CMakeLists.txt
+++ b/src/query/CMakeLists.txt
@@ -82,7 +82,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/cypher_query_interpreter.cpp b/src/query/cypher_query_interpreter.cpp
index 96aa75d03..05d7e417e 100644
--- a/src/query/cypher_query_interpreter.cpp
+++ b/src/query/cypher_query_interpreter.cpp
@@ -21,8 +21,7 @@ namespace memgraph::query {
 CachedPlan::CachedPlan(std::unique_ptr<LogicalPlan> plan) : plan_(std::move(plan)) {}
 
 ParsedQuery ParseQuery(const std::string &query_string, const std::map<std::string, storage::PropertyValue> &params,
-                       utils::SkipList<QueryCacheEntry> *cache, utils::SpinLock *antlr_lock,
-                       const InterpreterConfig::Query &query_config) {
+                       utils::SkipList<QueryCacheEntry> *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<std::stri
   };
 
   if (it == accessor.end()) {
-    {
-      std::unique_lock<utils::SpinLock> guard(*antlr_lock);
+    try {
+      parser = std::make_unique<frontend::opencypher::Parser>(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<frontend::opencypher::Parser>(query_string);
 
-      try {
-        parser = std::make_unique<frontend::opencypher::Parser>(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<frontend::opencypher::Parser>(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/cypher_query_interpreter.hpp b/src/query/cypher_query_interpreter.hpp
index 2318cae3f..14b4a3792 100644
--- a/src/query/cypher_query_interpreter.hpp
+++ b/src/query/cypher_query_interpreter.hpp
@@ -111,8 +111,7 @@ struct ParsedQuery {
 };
 
 ParsedQuery ParseQuery(const std::string &query_string, const std::map<std::string, storage::PropertyValue> &params,
-                       utils::SkipList<QueryCacheEntry> *cache, utils::SpinLock *antlr_lock,
-                       const InterpreterConfig::Query &query_config);
+                       utils::SkipList<QueryCacheEntry> *cache, const InterpreterConfig::Query &query_config);
 
 class SingleNodeLogicalPlan final : public LogicalPlan {
  public:
diff --git a/src/query/frontend/ast/cypher_main_visitor.cpp b/src/query/frontend/ast/cypher_main_visitor.cpp
index a12643298..e97bdc05e 100644
--- a/src/query/frontend/ast/cypher_main_visitor.cpp
+++ b/src/query/frontend/ast/cypher_main_visitor.cpp
@@ -52,7 +52,7 @@ std::optional<std::pair<memgraph::query::Expression *, size_t>> VisitMemoryLimit
     return std::nullopt;
   }
 
-  auto memory_limit = memory_limit_ctx->literal()->accept(visitor);
+  auto *memory_limit = std::any_cast<Expression *>(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<MemgraphCypher::SymbolicNameContext *> symbolicNames,
                               const std::string &separator = ".") {
   return JoinTokens(
-      symbolicNames, [&](auto *token) { return token->accept(visitor).template as<std::string>(); }, separator);
+      symbolicNames, [&](auto *token) { return std::any_cast<std::string>(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<CypherQuery *>();
+  auto *cypher_query = std::any_cast<CypherQuery *>(ctx->children[1]->accept(this));
   auto *explain_query = storage_->Create<ExplainQuery>();
   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<CypherQuery *>();
+  auto *cypher_query = std::any_cast<CypherQuery *>(ctx->children[1]->accept(this));
   auto *profile_query = storage_->Create<ProfileQuery>();
   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>();
+  constraint_query->constraint_ = std::any_cast<Constraint>(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<std::string>(ctx->labelName()->accept(this)));
+  auto node_name = std::any_cast<std::string>(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<std::string>(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<PropertyIx>(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<CypherQuery>();
   MG_ASSERT(ctx->singleQuery(), "Expected single query.");
-  cypher_query->single_query_ = ctx->singleQuery()->accept(this).as<SingleQuery *>();
+  cypher_query->single_query_ = std::any_cast<SingleQuery *>(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<CypherUnion *>());
+    cypher_query->cypher_unions_.push_back(std::any_cast<CypherUnion *>(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<IndexQuery *>();
+  auto *index_query = std::any_cast<IndexQuery *>(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<IndexQuery>();
   index_query->action_ = IndexQuery::Action::CREATE;
-  index_query->label_ = AddLabel(ctx->labelName()->accept(this));
+  index_query->label_ = AddLabel(std::any_cast<std::string>(ctx->labelName()->accept(this)));
   if (ctx->propertyKeyName()) {
-    PropertyIx name_key = ctx->propertyKeyName()->accept(this);
+    auto name_key = std::any_cast<PropertyIx>(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<IndexQuery>();
   index_query->action_ = IndexQuery::Action::DROP;
   if (ctx->propertyKeyName()) {
-    PropertyIx key = ctx->propertyKeyName()->accept(this);
+    auto key = std::any_cast<PropertyIx>(ctx->propertyKeyName()->accept(this));
     index_query->properties_ = {key};
   }
-  index_query->label_ = AddLabel(ctx->labelName()->accept(this));
+  index_query->label_ = AddLabel(std::any_cast<std::string>(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<AuthQuery *>();
+  auto *auth_query = std::any_cast<AuthQuery *>(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<ReplicationQuery *>();
+  auto *replication_query = std::any_cast<ReplicationQuery *>(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<Expression *>(ctx->port->accept(this));
       } else {
         throw SyntaxException("Port must be an integer literal!");
       }
@@ -272,7 +272,7 @@ antlrcpp::Any CypherMainVisitor::visitShowReplicationRole(MemgraphCypher::ShowRe
 antlrcpp::Any CypherMainVisitor::visitRegisterReplica(MemgraphCypher::RegisterReplicaContext *ctx) {
   auto *replication_query = storage_->Create<ReplicationQuery>();
   replication_query->action_ = ReplicationQuery::Action::REGISTER_REPLICA;
-  replication_query->replica_name_ = ctx->replicaName()->symbolicName()->accept(this).as<std::string>();
+  replication_query->replica_name_ = std::any_cast<std::string>(ctx->replicaName()->symbolicName()->accept(this));
   if (ctx->SYNC()) {
     replication_query->sync_mode_ = memgraph::query::ReplicationQuery::SyncMode::SYNC;
   } else if (ctx->ASYNC()) {
@@ -282,7 +282,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<Expression *>(ctx->socketAddress()->accept(this));
   }
 
   return replication_query;
@@ -291,7 +291,7 @@ antlrcpp::Any CypherMainVisitor::visitRegisterReplica(MemgraphCypher::RegisterRe
 antlrcpp::Any CypherMainVisitor::visitDropReplica(MemgraphCypher::DropReplicaContext *ctx) {
   auto *replication_query = storage_->Create<ReplicationQuery>();
   replication_query->action_ = ReplicationQuery::Action::DROP_REPLICA;
-  replication_query->replica_name_ = ctx->replicaName()->symbolicName()->accept(this).as<std::string>();
+  replication_query->replica_name_ = std::any_cast<std::string>(ctx->replicaName()->symbolicName()->accept(this));
   return replication_query;
 }
 
@@ -321,7 +321,7 @@ antlrcpp::Any CypherMainVisitor::visitLoadCsv(MemgraphCypher::LoadCsvContext *ct
   auto *load_csv = storage_->Create<LoadCsv>();
   // handle file name
   if (ctx->csvFile()->literal()->StringLiteral()) {
-    load_csv->file_ = ctx->csvFile()->accept(this);
+    load_csv->file_ = std::any_cast<Expression *>(ctx->csvFile()->accept(this));
   } else {
     throw SemanticException("CSV file path should be a string literal");
   }
@@ -338,7 +338,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<Expression *>(ctx->delimiter()->accept(this));
     } else {
       throw SemanticException("Delimiter should be a string literal");
     }
@@ -347,14 +347,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<Expression *>(ctx->quote()->accept(this));
     } else {
       throw SemanticException("Quote should be a string literal");
     }
   }
 
   // handle row variable
-  load_csv->row_var_ = storage_->Create<Identifier>(ctx->rowVar()->variable()->accept(this).as<std::string>());
+  load_csv->row_var_ =
+      storage_->Create<Identifier>(std::any_cast<std::string>(ctx->rowVar()->variable()->accept(this)));
 
   return load_csv;
 }
@@ -367,7 +368,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<TriggerQuery *>();
+  auto *trigger_query = std::any_cast<TriggerQuery *>(ctx->children[0]->accept(this));
   query_ = trigger_query;
   return trigger_query;
 }
@@ -375,7 +376,7 @@ antlrcpp::Any CypherMainVisitor::visitTriggerQuery(MemgraphCypher::TriggerQueryC
 antlrcpp::Any CypherMainVisitor::visitCreateTrigger(MemgraphCypher::CreateTriggerContext *ctx) {
   auto *trigger_query = storage_->Create<TriggerQuery>();
   trigger_query->action_ = TriggerQuery::Action::CREATE_TRIGGER;
-  trigger_query->trigger_name_ = ctx->triggerName()->symbolicName()->accept(this).as<std::string>();
+  trigger_query->trigger_name_ = std::any_cast<std::string>(ctx->triggerName()->symbolicName()->accept(this));
 
   auto *statement = ctx->triggerStatement();
   antlr4::misc::Interval interval{statement->start->getStartIndex(), statement->stop->getStopIndex()};
@@ -427,7 +428,7 @@ antlrcpp::Any CypherMainVisitor::visitCreateTrigger(MemgraphCypher::CreateTrigge
 antlrcpp::Any CypherMainVisitor::visitDropTrigger(MemgraphCypher::DropTriggerContext *ctx) {
   auto *trigger_query = storage_->Create<TriggerQuery>();
   trigger_query->action_ = TriggerQuery::Action::DROP_TRIGGER;
-  trigger_query->trigger_name_ = ctx->triggerName()->symbolicName()->accept(this).as<std::string>();
+  trigger_query->trigger_name_ = std::any_cast<std::string>(ctx->triggerName()->symbolicName()->accept(this));
   return trigger_query;
 }
 
@@ -471,14 +472,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<StreamQuery *>();
+  auto *stream_query = std::any_cast<StreamQuery *>(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<StreamQuery *>();
+  auto *stream_query = std::any_cast<StreamQuery *>(ctx->children[0]->accept(this));
   query_ = stream_query;
   return stream_query;
 }
@@ -570,7 +571,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<Expression *>(), ctx->literal(1)->accept(this).as<Expression *>()};
+  return std::pair{std::any_cast<Expression *>(ctx->literal(0)->accept(this)),
+                   std::any_cast<Expression *>(ctx->literal(1)->accept(this))};
 }
 
 antlrcpp::Any CypherMainVisitor::visitConfigMap(MemgraphCypher::ConfigMapContext *ctx) {
@@ -578,7 +580,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<std::pair<Expression *, Expression *>>());
+    map.insert(std::any_cast<std::pair<Expression *, Expression *>>(key_value_pair->accept(this)));
   }
   return map;
 }
@@ -587,7 +589,7 @@ antlrcpp::Any CypherMainVisitor::visitKafkaCreateStream(MemgraphCypher::KafkaCre
   auto *stream_query = storage_->Create<StreamQuery>();
   stream_query->action_ = StreamQuery::Action::CREATE_STREAM;
   stream_query->type_ = StreamQuery::Type::KAFKA;
-  stream_query->stream_name_ = ctx->streamName()->symbolicName()->accept(this).as<std::string>();
+  stream_query->stream_name_ = std::any_cast<std::string>(ctx->streamName()->symbolicName()->accept(this));
 
   for (auto *create_config_ctx : ctx->kafkaCreateStreamConfig()) {
     create_config_ctx->accept(this);
@@ -623,7 +625,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<Expression *>();
+    destination = std::any_cast<Expression *>(topic_names_ctx->accept(&visitor));
   }
 }
 }  // namespace
@@ -650,7 +652,8 @@ antlrcpp::Any CypherMainVisitor::visitKafkaCreateStreamConfig(MemgraphCypher::Ka
   if (ctx->CONFIGS()) {
     ThrowIfExists(memory_, KafkaConfigKey::CONFIGS);
     static constexpr auto configs_key = static_cast<uint8_t>(KafkaConfigKey::CONFIGS);
-    memory_.emplace(configs_key, ctx->configsMap->accept(this).as<std::unordered_map<Expression *, Expression *>>());
+    memory_.emplace(configs_key,
+                    std::any_cast<std::unordered_map<Expression *, Expression *>>(ctx->configsMap->accept(this)));
     return {};
   }
 
@@ -658,7 +661,7 @@ antlrcpp::Any CypherMainVisitor::visitKafkaCreateStreamConfig(MemgraphCypher::Ka
     ThrowIfExists(memory_, KafkaConfigKey::CREDENTIALS);
     static constexpr auto credentials_key = static_cast<uint8_t>(KafkaConfigKey::CREDENTIALS);
     memory_.emplace(credentials_key,
-                    ctx->credentialsMap->accept(this).as<std::unordered_map<Expression *, Expression *>>());
+                    std::any_cast<std::unordered_map<Expression *, Expression *>>(ctx->credentialsMap->accept(this)));
     return {};
   }
 
@@ -669,7 +672,7 @@ antlrcpp::Any CypherMainVisitor::visitKafkaCreateStreamConfig(MemgraphCypher::Ka
   }
 
   const auto bootstrap_servers_key = static_cast<uint8_t>(KafkaConfigKey::BOOTSTRAP_SERVERS);
-  memory_[bootstrap_servers_key] = ctx->bootstrapServers->accept(this).as<Expression *>();
+  memory_[bootstrap_servers_key] = std::any_cast<Expression *>(ctx->bootstrapServers->accept(this));
   return {};
 }
 
@@ -690,7 +693,7 @@ antlrcpp::Any CypherMainVisitor::visitPulsarCreateStream(MemgraphCypher::PulsarC
   auto *stream_query = storage_->Create<StreamQuery>();
   stream_query->action_ = StreamQuery::Action::CREATE_STREAM;
   stream_query->type_ = StreamQuery::Type::PULSAR;
-  stream_query->stream_name_ = ctx->streamName()->symbolicName()->accept(this).as<std::string>();
+  stream_query->stream_name_ = std::any_cast<std::string>(ctx->streamName()->symbolicName()->accept(this));
 
   for (auto *create_config_ctx : ctx->pulsarCreateStreamConfig()) {
     create_config_ctx->accept(this);
@@ -722,7 +725,7 @@ antlrcpp::Any CypherMainVisitor::visitPulsarCreateStreamConfig(MemgraphCypher::P
     throw SemanticException("Service URL must be a string!");
   }
   const auto service_url_key = static_cast<uint8_t>(PulsarConfigKey::SERVICE_URL);
-  memory_[service_url_key] = ctx->serviceUrl->accept(this).as<Expression *>();
+  memory_[service_url_key] = std::any_cast<Expression *>(ctx->serviceUrl->accept(this));
   return {};
 }
 
@@ -740,7 +743,7 @@ antlrcpp::Any CypherMainVisitor::visitCommonCreateStreamConfig(MemgraphCypher::C
       throw SemanticException("Batch interval must be an integer literal!");
     }
     const auto batch_interval_key = static_cast<uint8_t>(CommonStreamConfigKey::BATCH_INTERVAL);
-    memory_[batch_interval_key] = ctx->batchInterval->accept(this).as<Expression *>();
+    memory_[batch_interval_key] = std::any_cast<Expression *>(ctx->batchInterval->accept(this));
     return {};
   }
 
@@ -750,14 +753,14 @@ antlrcpp::Any CypherMainVisitor::visitCommonCreateStreamConfig(MemgraphCypher::C
     throw SemanticException("Batch size must be an integer literal!");
   }
   const auto batch_size_key = static_cast<uint8_t>(CommonStreamConfigKey::BATCH_SIZE);
-  memory_[batch_size_key] = ctx->batchSize->accept(this).as<Expression *>();
+  memory_[batch_size_key] = std::any_cast<Expression *>(ctx->batchSize->accept(this));
   return {};
 }
 
 antlrcpp::Any CypherMainVisitor::visitDropStream(MemgraphCypher::DropStreamContext *ctx) {
   auto *stream_query = storage_->Create<StreamQuery>();
   stream_query->action_ = StreamQuery::Action::DROP_STREAM;
-  stream_query->stream_name_ = ctx->streamName()->symbolicName()->accept(this).as<std::string>();
+  stream_query->stream_name_ = std::any_cast<std::string>(ctx->streamName()->symbolicName()->accept(this));
   return stream_query;
 }
 
@@ -769,7 +772,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<Expression *>(ctx->batchLimit->accept(this));
   }
   if (ctx->TIMEOUT()) {
     if (!ctx->timeout->numberLiteral() || !ctx->timeout->numberLiteral()->integerLiteral()) {
@@ -778,10 +781,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<Expression *>(ctx->timeout->accept(this));
   }
 
-  stream_query->stream_name_ = ctx->streamName()->symbolicName()->accept(this).as<std::string>();
+  stream_query->stream_name_ = std::any_cast<std::string>(ctx->streamName()->symbolicName()->accept(this));
   return stream_query;
 }
 
@@ -794,7 +797,7 @@ antlrcpp::Any CypherMainVisitor::visitStartAllStreams(MemgraphCypher::StartAllSt
 antlrcpp::Any CypherMainVisitor::visitStopStream(MemgraphCypher::StopStreamContext *ctx) {
   auto *stream_query = storage_->Create<StreamQuery>();
   stream_query->action_ = StreamQuery::Action::STOP_STREAM;
-  stream_query->stream_name_ = ctx->streamName()->symbolicName()->accept(this).as<std::string>();
+  stream_query->stream_name_ = std::any_cast<std::string>(ctx->streamName()->symbolicName()->accept(this));
   return stream_query;
 }
 
@@ -813,26 +816,26 @@ antlrcpp::Any CypherMainVisitor::visitShowStreams(MemgraphCypher::ShowStreamsCon
 antlrcpp::Any CypherMainVisitor::visitCheckStream(MemgraphCypher::CheckStreamContext *ctx) {
   auto *stream_query = storage_->Create<StreamQuery>();
   stream_query->action_ = StreamQuery::Action::CHECK_STREAM;
-  stream_query->stream_name_ = ctx->streamName()->symbolicName()->accept(this).as<std::string>();
+  stream_query->stream_name_ = std::any_cast<std::string>(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<Expression *>(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<Expression *>(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<SettingQuery *>();
+  auto *setting_query = std::any_cast<SettingQuery *>(ctx->children[0]->accept(this));
   query_ = setting_query;
   return setting_query;
 }
@@ -849,10 +852,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<Expression *>(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<Expression *>(ctx->settingValue()->accept(this));
   MG_ASSERT(setting_query->setting_value_);
   return setting_query;
 }
@@ -865,7 +868,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<Expression *>(ctx->settingName()->accept(this));
   MG_ASSERT(setting_query->setting_name_);
 
   return setting_query;
@@ -887,7 +890,7 @@ antlrcpp::Any CypherMainVisitor::visitCypherUnion(MemgraphCypher::CypherUnionCon
   bool distinct = !ctx->ALL();
   auto *cypher_union = storage_->Create<CypherUnion>(distinct);
   DMG_ASSERT(ctx->singleQuery(), "Expected single query.");
-  cypher_union->single_query_ = ctx->singleQuery()->accept(this).as<SingleQuery *>();
+  cypher_union->single_query_ = std::any_cast<SingleQuery *>(ctx->singleQuery()->accept(this));
   return cypher_union;
 }
 
@@ -895,10 +898,10 @@ antlrcpp::Any CypherMainVisitor::visitSingleQuery(MemgraphCypher::SingleQueryCon
   auto *single_query = storage_->Create<SingleQuery>();
   for (auto *child : ctx->clause()) {
     antlrcpp::Any got = child->accept(this);
-    if (got.is<Clause *>()) {
-      single_query->clauses_.push_back(got.as<Clause *>());
+    if (got.type() == typeid(Clause *)) {
+      single_query->clauses_.push_back(std::any_cast<Clause *>(got));
     } else {
-      auto child_clauses = got.as<std::vector<Clause *>>();
+      auto child_clauses = std::any_cast<std::vector<Clause *>>(got);
       single_query->clauses_.insert(single_query->clauses_.end(), child_clauses.begin(), child_clauses.end());
     }
   }
@@ -1010,42 +1013,42 @@ antlrcpp::Any CypherMainVisitor::visitSingleQuery(MemgraphCypher::SingleQueryCon
 
 antlrcpp::Any CypherMainVisitor::visitClause(MemgraphCypher::ClauseContext *ctx) {
   if (ctx->cypherReturn()) {
-    return static_cast<Clause *>(ctx->cypherReturn()->accept(this).as<Return *>());
+    return static_cast<Clause *>(std::any_cast<Return *>(ctx->cypherReturn()->accept(this)));
   }
   if (ctx->cypherMatch()) {
-    return static_cast<Clause *>(ctx->cypherMatch()->accept(this).as<Match *>());
+    return static_cast<Clause *>(std::any_cast<Match *>(ctx->cypherMatch()->accept(this)));
   }
   if (ctx->create()) {
-    return static_cast<Clause *>(ctx->create()->accept(this).as<Create *>());
+    return static_cast<Clause *>(std::any_cast<Create *>(ctx->create()->accept(this)));
   }
   if (ctx->cypherDelete()) {
-    return static_cast<Clause *>(ctx->cypherDelete()->accept(this).as<Delete *>());
+    return static_cast<Clause *>(std::any_cast<Delete *>(ctx->cypherDelete()->accept(this)));
   }
   if (ctx->set()) {
     // Different return type!!!
-    return ctx->set()->accept(this).as<std::vector<Clause *>>();
+    return std::any_cast<std::vector<Clause *>>(ctx->set()->accept(this));
   }
   if (ctx->remove()) {
     // Different return type!!!
-    return ctx->remove()->accept(this).as<std::vector<Clause *>>();
+    return std::any_cast<std::vector<Clause *>>(ctx->remove()->accept(this));
   }
   if (ctx->with()) {
-    return static_cast<Clause *>(ctx->with()->accept(this).as<With *>());
+    return static_cast<Clause *>(std::any_cast<With *>(ctx->with()->accept(this)));
   }
   if (ctx->merge()) {
-    return static_cast<Clause *>(ctx->merge()->accept(this).as<Merge *>());
+    return static_cast<Clause *>(std::any_cast<Merge *>(ctx->merge()->accept(this)));
   }
   if (ctx->unwind()) {
-    return static_cast<Clause *>(ctx->unwind()->accept(this).as<Unwind *>());
+    return static_cast<Clause *>(std::any_cast<Unwind *>(ctx->unwind()->accept(this)));
   }
   if (ctx->callProcedure()) {
-    return static_cast<Clause *>(ctx->callProcedure()->accept(this).as<CallProcedure *>());
+    return static_cast<Clause *>(std::any_cast<CallProcedure *>(ctx->callProcedure()->accept(this)));
   }
   if (ctx->loadCsv()) {
-    return static_cast<Clause *>(ctx->loadCsv()->accept(this).as<LoadCsv *>());
+    return static_cast<Clause *>(std::any_cast<LoadCsv *>(ctx->loadCsv()->accept(this)));
   }
   if (ctx->foreach ()) {
-    return static_cast<Clause *>(ctx->foreach ()->accept(this).as<Foreach *>());
+    return static_cast<Clause *>(std::any_cast<Foreach *>(ctx->foreach ()->accept(this)));
   }
   // TODO: implement other clauses.
   throw utils::NotYetImplemented("clause '{}'", ctx->getText());
@@ -1056,15 +1059,15 @@ antlrcpp::Any CypherMainVisitor::visitCypherMatch(MemgraphCypher::CypherMatchCon
   auto *match = storage_->Create<Match>();
   match->optional_ = !!ctx->OPTIONAL();
   if (ctx->where()) {
-    match->where_ = ctx->where()->accept(this);
+    match->where_ = std::any_cast<Where *>(ctx->where()->accept(this));
   }
-  match->patterns_ = ctx->pattern()->accept(this).as<std::vector<Pattern *>>();
+  match->patterns_ = std::any_cast<std::vector<Pattern *>>(ctx->pattern()->accept(this));
   return match;
 }
 
 antlrcpp::Any CypherMainVisitor::visitCreate(MemgraphCypher::CreateContext *ctx) {
   auto *create = storage_->Create<Create>();
-  create->patterns_ = ctx->pattern()->accept(this).as<std::vector<Pattern *>>();
+  create->patterns_ = std::any_cast<std::vector<Pattern *>>(ctx->pattern()->accept(this));
   return create;
 }
 
@@ -1082,7 +1085,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<Expression *>(expr->accept(this)));
   }
 
   if (auto *memory_limit_ctx = ctx->procedureMemoryLimit()) {
@@ -1122,12 +1125,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<std::string>());
+      call_proc->result_fields_.push_back(std::any_cast<std::string>(result->variable()[0]->accept(this)));
       std::string result_alias;
       if (result->variable().size() == 2) {
-        result_alias = result->variable()[1]->accept(this).as<std::string>();
+        result_alias = std::any_cast<std::string>(result->variable()[1]->accept(this));
       } else {
-        result_alias = result->variable()[0]->accept(this).as<std::string>();
+        result_alias = std::any_cast<std::string>(result->variable()[0]->accept(this));
       }
       call_proc->result_identifiers_.push_back(storage_->Create<Identifier>(result_alias));
     }
@@ -1163,7 +1166,7 @@ antlrcpp::Any CypherMainVisitor::visitCallProcedure(MemgraphCypher::CallProcedur
  * @return std::string
  */
 antlrcpp::Any CypherMainVisitor::visitUserOrRoleName(MemgraphCypher::UserOrRoleNameContext *ctx) {
-  return ctx->symbolicName()->accept(this).as<std::string>();
+  return std::any_cast<std::string>(ctx->symbolicName()->accept(this));
 }
 
 /**
@@ -1172,7 +1175,7 @@ antlrcpp::Any CypherMainVisitor::visitUserOrRoleName(MemgraphCypher::UserOrRoleN
 antlrcpp::Any CypherMainVisitor::visitCreateRole(MemgraphCypher::CreateRoleContext *ctx) {
   AuthQuery *auth = storage_->Create<AuthQuery>();
   auth->action_ = AuthQuery::Action::CREATE_ROLE;
-  auth->role_ = ctx->role->accept(this).as<std::string>();
+  auth->role_ = std::any_cast<std::string>(ctx->role->accept(this));
   return auth;
 }
 
@@ -1182,7 +1185,7 @@ antlrcpp::Any CypherMainVisitor::visitCreateRole(MemgraphCypher::CreateRoleConte
 antlrcpp::Any CypherMainVisitor::visitDropRole(MemgraphCypher::DropRoleContext *ctx) {
   AuthQuery *auth = storage_->Create<AuthQuery>();
   auth->action_ = AuthQuery::Action::DROP_ROLE;
-  auth->role_ = ctx->role->accept(this).as<std::string>();
+  auth->role_ = std::any_cast<std::string>(ctx->role->accept(this));
   return auth;
 }
 
@@ -1201,12 +1204,12 @@ antlrcpp::Any CypherMainVisitor::visitShowRoles(MemgraphCypher::ShowRolesContext
 antlrcpp::Any CypherMainVisitor::visitCreateUser(MemgraphCypher::CreateUserContext *ctx) {
   AuthQuery *auth = storage_->Create<AuthQuery>();
   auth->action_ = AuthQuery::Action::CREATE_USER;
-  auth->user_ = ctx->user->accept(this).as<std::string>();
+  auth->user_ = std::any_cast<std::string>(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<Expression *>(ctx->password->accept(this));
   }
   return auth;
 }
@@ -1217,11 +1220,11 @@ antlrcpp::Any CypherMainVisitor::visitCreateUser(MemgraphCypher::CreateUserConte
 antlrcpp::Any CypherMainVisitor::visitSetPassword(MemgraphCypher::SetPasswordContext *ctx) {
   AuthQuery *auth = storage_->Create<AuthQuery>();
   auth->action_ = AuthQuery::Action::SET_PASSWORD;
-  auth->user_ = ctx->user->accept(this).as<std::string>();
+  auth->user_ = std::any_cast<std::string>(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<Expression *>(ctx->password->accept(this));
   return auth;
 }
 
@@ -1231,7 +1234,7 @@ antlrcpp::Any CypherMainVisitor::visitSetPassword(MemgraphCypher::SetPasswordCon
 antlrcpp::Any CypherMainVisitor::visitDropUser(MemgraphCypher::DropUserContext *ctx) {
   AuthQuery *auth = storage_->Create<AuthQuery>();
   auth->action_ = AuthQuery::Action::DROP_USER;
-  auth->user_ = ctx->user->accept(this).as<std::string>();
+  auth->user_ = std::any_cast<std::string>(ctx->user->accept(this));
   return auth;
 }
 
@@ -1250,8 +1253,8 @@ antlrcpp::Any CypherMainVisitor::visitShowUsers(MemgraphCypher::ShowUsersContext
 antlrcpp::Any CypherMainVisitor::visitSetRole(MemgraphCypher::SetRoleContext *ctx) {
   AuthQuery *auth = storage_->Create<AuthQuery>();
   auth->action_ = AuthQuery::Action::SET_ROLE;
-  auth->user_ = ctx->user->accept(this).as<std::string>();
-  auth->role_ = ctx->role->accept(this).as<std::string>();
+  auth->user_ = std::any_cast<std::string>(ctx->user->accept(this));
+  auth->role_ = std::any_cast<std::string>(ctx->role->accept(this));
   return auth;
 }
 
@@ -1261,7 +1264,7 @@ antlrcpp::Any CypherMainVisitor::visitSetRole(MemgraphCypher::SetRoleContext *ct
 antlrcpp::Any CypherMainVisitor::visitClearRole(MemgraphCypher::ClearRoleContext *ctx) {
   AuthQuery *auth = storage_->Create<AuthQuery>();
   auth->action_ = AuthQuery::Action::CLEAR_ROLE;
-  auth->user_ = ctx->user->accept(this).as<std::string>();
+  auth->user_ = std::any_cast<std::string>(ctx->user->accept(this));
   return auth;
 }
 
@@ -1271,10 +1274,10 @@ antlrcpp::Any CypherMainVisitor::visitClearRole(MemgraphCypher::ClearRoleContext
 antlrcpp::Any CypherMainVisitor::visitGrantPrivilege(MemgraphCypher::GrantPrivilegeContext *ctx) {
   AuthQuery *auth = storage_->Create<AuthQuery>();
   auth->action_ = AuthQuery::Action::GRANT_PRIVILEGE;
-  auth->user_or_role_ = ctx->userOrRole->accept(this).as<std::string>();
+  auth->user_or_role_ = std::any_cast<std::string>(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<AuthQuery::Privilege>(privilege->accept(this)));
     }
   } else {
     /* grant all privileges */
@@ -1289,10 +1292,10 @@ antlrcpp::Any CypherMainVisitor::visitGrantPrivilege(MemgraphCypher::GrantPrivil
 antlrcpp::Any CypherMainVisitor::visitDenyPrivilege(MemgraphCypher::DenyPrivilegeContext *ctx) {
   AuthQuery *auth = storage_->Create<AuthQuery>();
   auth->action_ = AuthQuery::Action::DENY_PRIVILEGE;
-  auth->user_or_role_ = ctx->userOrRole->accept(this).as<std::string>();
+  auth->user_or_role_ = std::any_cast<std::string>(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<AuthQuery::Privilege>(privilege->accept(this)));
     }
   } else {
     /* deny all privileges */
@@ -1307,10 +1310,10 @@ antlrcpp::Any CypherMainVisitor::visitDenyPrivilege(MemgraphCypher::DenyPrivileg
 antlrcpp::Any CypherMainVisitor::visitRevokePrivilege(MemgraphCypher::RevokePrivilegeContext *ctx) {
   AuthQuery *auth = storage_->Create<AuthQuery>();
   auth->action_ = AuthQuery::Action::REVOKE_PRIVILEGE;
-  auth->user_or_role_ = ctx->userOrRole->accept(this).as<std::string>();
+  auth->user_or_role_ = std::any_cast<std::string>(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<AuthQuery::Privilege>(privilege->accept(this)));
     }
   } else {
     /* revoke all privileges */
@@ -1353,7 +1356,7 @@ antlrcpp::Any CypherMainVisitor::visitPrivilege(MemgraphCypher::PrivilegeContext
 antlrcpp::Any CypherMainVisitor::visitShowPrivileges(MemgraphCypher::ShowPrivilegesContext *ctx) {
   AuthQuery *auth = storage_->Create<AuthQuery>();
   auth->action_ = AuthQuery::Action::SHOW_PRIVILEGES;
-  auth->user_or_role_ = ctx->userOrRole->accept(this).as<std::string>();
+  auth->user_or_role_ = std::any_cast<std::string>(ctx->userOrRole->accept(this));
   return auth;
 }
 
@@ -1363,7 +1366,7 @@ antlrcpp::Any CypherMainVisitor::visitShowPrivileges(MemgraphCypher::ShowPrivile
 antlrcpp::Any CypherMainVisitor::visitShowRoleForUser(MemgraphCypher::ShowRoleForUserContext *ctx) {
   AuthQuery *auth = storage_->Create<AuthQuery>();
   auth->action_ = AuthQuery::Action::SHOW_ROLE_FOR_USER;
-  auth->user_ = ctx->user->accept(this).as<std::string>();
+  auth->user_ = std::any_cast<std::string>(ctx->user->accept(this));
   return auth;
 }
 
@@ -1373,13 +1376,13 @@ antlrcpp::Any CypherMainVisitor::visitShowRoleForUser(MemgraphCypher::ShowRoleFo
 antlrcpp::Any CypherMainVisitor::visitShowUsersForRole(MemgraphCypher::ShowUsersForRoleContext *ctx) {
   AuthQuery *auth = storage_->Create<AuthQuery>();
   auth->action_ = AuthQuery::Action::SHOW_USERS_FOR_ROLE;
-  auth->role_ = ctx->role->accept(this).as<std::string>();
+  auth->role_ = std::any_cast<std::string>(ctx->role->accept(this));
   return auth;
 }
 
 antlrcpp::Any CypherMainVisitor::visitCypherReturn(MemgraphCypher::CypherReturnContext *ctx) {
   auto *return_clause = storage_->Create<Return>();
-  return_clause->body_ = ctx->returnBody()->accept(this);
+  return_clause->body_ = std::any_cast<ReturnBody>(ctx->returnBody()->accept(this));
   if (ctx->DISTINCT()) {
     return_clause->body_.distinct = true;
   }
@@ -1389,23 +1392,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<std::vector<SortItem>>();
+    body.order_by = std::any_cast<std::vector<SortItem>>(ctx->order()->accept(this));
   }
   if (ctx->skip()) {
-    body.skip = static_cast<Expression *>(ctx->skip()->accept(this));
+    body.skip = static_cast<Expression *>(std::any_cast<Expression *>(ctx->skip()->accept(this)));
   }
   if (ctx->limit()) {
-    body.limit = static_cast<Expression *>(ctx->limit()->accept(this));
+    body.limit = static_cast<Expression *>(std::any_cast<Expression *>(ctx->limit()->accept(this)));
   }
   std::tie(body.all_identifiers, body.named_expressions) =
-      ctx->returnItems()->accept(this).as<std::pair<bool, std::vector<NamedExpression *>>>();
+      std::any_cast<std::pair<bool, std::vector<NamedExpression *>>>(ctx->returnItems()->accept(this));
   return body;
 }
 
 antlrcpp::Any CypherMainVisitor::visitReturnItems(MemgraphCypher::ReturnItemsContext *ctx) {
   std::vector<NamedExpression *> named_expressions;
   for (auto *item : ctx->returnItem()) {
-    named_expressions.push_back(item->accept(this));
+    named_expressions.push_back(std::any_cast<NamedExpression *>(item->accept(this)));
   }
   return std::pair<bool, std::vector<NamedExpression *>>(ctx->getTokens(MemgraphCypher::ASTERISK).size(),
                                                          named_expressions);
@@ -1413,10 +1416,10 @@ antlrcpp::Any CypherMainVisitor::visitReturnItems(MemgraphCypher::ReturnItemsCon
 
 antlrcpp::Any CypherMainVisitor::visitReturnItem(MemgraphCypher::ReturnItemContext *ctx) {
   auto *named_expr = storage_->Create<NamedExpression>();
-  named_expr->expression_ = ctx->expression()->accept(this);
+  named_expr->expression_ = std::any_cast<Expression *>(ctx->expression()->accept(this));
   MG_ASSERT(named_expr->expression_);
   if (ctx->variable()) {
-    named_expr->name_ = std::string(ctx->variable()->accept(this).as<std::string>());
+    named_expr->name_ = std::string(std::any_cast<std::string>(ctx->variable()->accept(this)));
     users_identifiers.insert(named_expr->name_);
   } else {
     if (in_with_ && !utils::IsSubtype(*named_expr->expression_, Identifier::kType)) {
@@ -1431,33 +1434,34 @@ antlrcpp::Any CypherMainVisitor::visitReturnItem(MemgraphCypher::ReturnItemConte
 antlrcpp::Any CypherMainVisitor::visitOrder(MemgraphCypher::OrderContext *ctx) {
   std::vector<SortItem> order_by;
   for (auto *sort_item : ctx->sortItem()) {
-    order_by.push_back(sort_item->accept(this));
+    order_by.push_back(std::any_cast<SortItem>(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<Expression *>(ctx->expression()->accept(this))};
 }
 
 antlrcpp::Any CypherMainVisitor::visitNodePattern(MemgraphCypher::NodePatternContext *ctx) {
   auto *node = storage_->Create<NodeAtom>();
   if (ctx->variable()) {
-    std::string variable = ctx->variable()->accept(this);
+    auto variable = std::any_cast<std::string>(ctx->variable()->accept(this));
     node->identifier_ = storage_->Create<Identifier>(variable);
     users_identifiers.insert(variable);
   } else {
     anonymous_identifiers.push_back(&node->identifier_);
   }
   if (ctx->nodeLabels()) {
-    node->labels_ = ctx->nodeLabels()->accept(this).as<std::vector<LabelIx>>();
+    node->labels_ = std::any_cast<std::vector<LabelIx>>(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<std::unordered_map<PropertyIx, Expression *>>();
+      node->properties_ = std::any_cast<std::unordered_map<PropertyIx, Expression *>>(ctx->properties()->accept(this));
     } else {
-      node->properties_ = ctx->properties()->accept(this).as<ParameterLookup *>();
+      node->properties_ = std::any_cast<ParameterLookup *>(ctx->properties()->accept(this));
     }
   }
   return node;
@@ -1466,7 +1470,7 @@ antlrcpp::Any CypherMainVisitor::visitNodePattern(MemgraphCypher::NodePatternCon
 antlrcpp::Any CypherMainVisitor::visitNodeLabels(MemgraphCypher::NodeLabelsContext *ctx) {
   std::vector<LabelIx> labels;
   for (auto *node_label : ctx->nodeLabel()) {
-    labels.push_back(AddLabel(node_label->accept(this)));
+    labels.push_back(AddLabel(std::any_cast<std::string>(node_label->accept(this))));
   }
   return labels;
 }
@@ -1483,8 +1487,8 @@ antlrcpp::Any CypherMainVisitor::visitProperties(MemgraphCypher::PropertiesConte
 antlrcpp::Any CypherMainVisitor::visitMapLiteral(MemgraphCypher::MapLiteralContext *ctx) {
   std::unordered_map<PropertyIx, Expression *> map;
   for (int i = 0; i < static_cast<int>(ctx->propertyKeyName().size()); ++i) {
-    PropertyIx key = ctx->propertyKeyName()[i]->accept(this);
-    Expression *value = ctx->expression()[i]->accept(this);
+    auto key = std::any_cast<PropertyIx>(ctx->propertyKeyName()[i]->accept(this));
+    auto *value = std::any_cast<Expression *>(ctx->expression()[i]->accept(this));
     if (!map.insert({key, value}).second) {
       throw SemanticException("Same key can't appear twice in a map literal.");
     }
@@ -1494,12 +1498,14 @@ antlrcpp::Any CypherMainVisitor::visitMapLiteral(MemgraphCypher::MapLiteralConte
 
 antlrcpp::Any CypherMainVisitor::visitListLiteral(MemgraphCypher::ListLiteralContext *ctx) {
   std::vector<Expression *> 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<Expression *>(expr_ctx->accept(this)));
+  }
   return expressions;
 }
 
 antlrcpp::Any CypherMainVisitor::visitPropertyKeyName(MemgraphCypher::PropertyKeyNameContext *ctx) {
-  return AddProperty(visitChildren(ctx));
+  return AddProperty(std::any_cast<std::string>(visitChildren(ctx)));
 }
 
 antlrcpp::Any CypherMainVisitor::visitSymbolicName(MemgraphCypher::SymbolicNameContext *ctx) {
@@ -1537,15 +1543,15 @@ antlrcpp::Any CypherMainVisitor::visitSymbolicName(MemgraphCypher::SymbolicNameC
 antlrcpp::Any CypherMainVisitor::visitPattern(MemgraphCypher::PatternContext *ctx) {
   std::vector<Pattern *> patterns;
   for (auto *pattern_part : ctx->patternPart()) {
-    patterns.push_back(pattern_part->accept(this));
+    patterns.push_back(std::any_cast<Pattern *>(pattern_part->accept(this)));
   }
   return patterns;
 }
 
 antlrcpp::Any CypherMainVisitor::visitPatternPart(MemgraphCypher::PatternPartContext *ctx) {
-  Pattern *pattern = ctx->anonymousPatternPart()->accept(this);
+  auto *pattern = std::any_cast<Pattern *>(ctx->anonymousPatternPart()->accept(this));
   if (ctx->variable()) {
-    std::string variable = ctx->variable()->accept(this);
+    auto variable = std::any_cast<std::string>(ctx->variable()->accept(this));
     pattern->identifier_ = storage_->Create<Identifier>(variable);
     users_identifiers.insert(variable);
   } else {
@@ -1558,10 +1564,10 @@ antlrcpp::Any CypherMainVisitor::visitPatternElement(MemgraphCypher::PatternElem
   if (ctx->patternElement()) {
     return ctx->patternElement()->accept(this);
   }
-  auto pattern = storage_->Create<Pattern>();
-  pattern->atoms_.push_back(ctx->nodePattern()->accept(this).as<NodeAtom *>());
+  auto *pattern = storage_->Create<Pattern>();
+  pattern->atoms_.push_back(std::any_cast<NodeAtom *>(ctx->nodePattern()->accept(this)));
   for (auto *pattern_element_chain : ctx->patternElementChain()) {
-    std::pair<PatternAtom *, PatternAtom *> element = pattern_element_chain->accept(this);
+    auto element = std::any_cast<std::pair<PatternAtom *, PatternAtom *>>(pattern_element_chain->accept(this));
     pattern->atoms_.push_back(element.first);
     pattern->atoms_.push_back(element.second);
   }
@@ -1569,8 +1575,8 @@ antlrcpp::Any CypherMainVisitor::visitPatternElement(MemgraphCypher::PatternElem
 }
 
 antlrcpp::Any CypherMainVisitor::visitPatternElementChain(MemgraphCypher::PatternElementChainContext *ctx) {
-  return std::pair<PatternAtom *, PatternAtom *>(ctx->relationshipPattern()->accept(this).as<EdgeAtom *>(),
-                                                 ctx->nodePattern()->accept(this).as<NodeAtom *>());
+  return std::pair<PatternAtom *, PatternAtom *>(std::any_cast<EdgeAtom *>(ctx->relationshipPattern()->accept(this)),
+                                                 std::any_cast<NodeAtom *>(ctx->nodePattern()->accept(this)));
 }
 
 antlrcpp::Any CypherMainVisitor::visitRelationshipPattern(MemgraphCypher::RelationshipPatternContext *ctx) {
@@ -1581,7 +1587,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::tuple<EdgeAtom::Type, Expression *, Expression *>>();
+        std::any_cast<std::tuple<EdgeAtom::Type, Expression *, Expression *>>(variableExpansion->accept(this));
 
   if (ctx->leftArrowHead() && !ctx->rightArrowHead()) {
     edge->direction_ = EdgeAtom::Direction::IN;
@@ -1599,7 +1605,7 @@ antlrcpp::Any CypherMainVisitor::visitRelationshipPattern(MemgraphCypher::Relati
   }
 
   if (relationshipDetail->name) {
-    std::string variable = relationshipDetail->name->accept(this);
+    auto variable = std::any_cast<std::string>(relationshipDetail->name->accept(this));
     edge->identifier_ = storage_->Create<Identifier>(variable);
     users_identifiers.insert(variable);
   } else {
@@ -1607,7 +1613,8 @@ antlrcpp::Any CypherMainVisitor::visitRelationshipPattern(MemgraphCypher::Relati
   }
 
   if (relationshipDetail->relationshipTypes()) {
-    edge->edge_types_ = ctx->relationshipDetail()->relationshipTypes()->accept(this).as<std::vector<EdgeTypeIx>>();
+    edge->edge_types_ =
+        std::any_cast<std::vector<EdgeTypeIx>>(ctx->relationshipDetail()->relationshipTypes()->accept(this));
   }
 
   auto relationshipLambdas = relationshipDetail->relationshipLambda();
@@ -1618,16 +1625,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<std::string>(lambda->traversed_edge->accept(this));
       edge_lambda.inner_edge = storage_->Create<Identifier>(traversed_edge_variable);
-      std::string traversed_node_variable = lambda->traversed_node->accept(this);
+      auto traversed_node_variable = std::any_cast<std::string>(lambda->traversed_node->accept(this));
       edge_lambda.inner_node = storage_->Create<Identifier>(traversed_node_variable);
-      edge_lambda.expression = lambda->expression()->accept(this);
+      edge_lambda.expression = std::any_cast<Expression *>(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<std::string>(relationshipDetail->total_weight->accept(this));
         edge->total_weight_ = storage_->Create<Identifier>(total_weight_name);
       } else {
         anonymous_identifiers.push_back(&edge->total_weight_);
@@ -1677,11 +1684,11 @@ antlrcpp::Any CypherMainVisitor::visitRelationshipPattern(MemgraphCypher::Relati
       break;
     case 1: {
       if (properties[0]->mapLiteral()) {
-        edge->properties_ = properties[0]->accept(this).as<std::unordered_map<PropertyIx, Expression *>>();
+        edge->properties_ = std::any_cast<std::unordered_map<PropertyIx, Expression *>>(properties[0]->accept(this));
         break;
       }
       MG_ASSERT(properties[0]->parameter());
-      edge->properties_ = properties[0]->accept(this).as<ParameterLookup *>();
+      edge->properties_ = std::any_cast<ParameterLookup *>(properties[0]->accept(this));
       break;
     }
     default:
@@ -1704,7 +1711,7 @@ antlrcpp::Any CypherMainVisitor::visitRelationshipLambda(MemgraphCypher::Relatio
 antlrcpp::Any CypherMainVisitor::visitRelationshipTypes(MemgraphCypher::RelationshipTypesContext *ctx) {
   std::vector<EdgeTypeIx> types;
   for (auto *edge_type : ctx->relTypeName()) {
-    types.push_back(AddEdgeType(edge_type->accept(this)));
+    types.push_back(AddEdgeType(std::any_cast<std::string>(edge_type->accept(this))));
   }
   return types;
 }
@@ -1724,7 +1731,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<Expression *>(ctx->expression()[0]->accept(this));
     if (!dots_tokens.size()) {
       // Case -[*bound]-
       if (edge_type != EdgeAtom::Type::WEIGHTED_SHORTEST_PATH) lower = bound;
@@ -1738,8 +1745,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<Expression *>(ctx->expression()[0]->accept(this));
+    upper = std::any_cast<Expression *>(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.");
@@ -1748,7 +1755,7 @@ antlrcpp::Any CypherMainVisitor::visitVariableExpansion(MemgraphCypher::Variable
 }
 
 antlrcpp::Any CypherMainVisitor::visitExpression(MemgraphCypher::ExpressionContext *ctx) {
-  return static_cast<Expression *>(ctx->expression12()->accept(this));
+  return std::any_cast<Expression *>(ctx->expression12()->accept(this));
 }
 
 // OR.
@@ -1794,11 +1801,11 @@ antlrcpp::Any CypherMainVisitor::visitExpression8(MemgraphCypher::Expression8Con
   //  4 <= 5 < 7 > 6 -> false
   //  All of those comparisons evaluate to true in memgraph.
   std::vector<Expression *> children;
-  children.push_back(ctx->expression7()->accept(this));
+  children.push_back(std::any_cast<Expression *>(ctx->expression7()->accept(this)));
   std::vector<size_t> 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<Expression *>(child->expression7()->accept(this)));
   }
   // First production is comparison operator.
   for (auto *child : partial_comparison_expressions) {
@@ -1860,7 +1867,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<Expression *>(ctx->expression3b()->accept(this));
 
   for (auto *op : ctx->stringAndNullOperators()) {
     if (op->IS() && op->NOT() && op->CYPHERNULL()) {
@@ -1869,12 +1876,12 @@ antlrcpp::Any CypherMainVisitor::visitExpression3a(MemgraphCypher::Expression3aC
     } else if (op->IS() && op->CYPHERNULL()) {
       expression = static_cast<Expression *>(storage_->Create<IsNullOperator>(expression));
     } else if (op->IN()) {
-      expression =
-          static_cast<Expression *>(storage_->Create<InListOperator>(expression, op->expression3b()->accept(this)));
+      expression = static_cast<Expression *>(
+          storage_->Create<InListOperator>(expression, std::any_cast<Expression *>(op->expression3b()->accept(this))));
     } else if (utils::StartsWith(op->getText(), "=~")) {
       auto *regex_match = storage_->Create<RegexMatch>();
       regex_match->string_expr_ = expression;
-      regex_match->regex_ = op->expression3b()->accept(this);
+      regex_match->regex_ = std::any_cast<Expression *>(op->expression3b()->accept(this));
       expression = regex_match;
     } else {
       std::string function_name;
@@ -1887,7 +1894,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<Expression *>(op->expression3b()->accept(this));
       std::vector<Expression *> args = {expression, expression2};
       expression = static_cast<Expression *>(storage_->Create<Function>(function_name, args));
     }
@@ -1900,18 +1907,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<Expression *>(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<SubscriptOperator>(expression, list_op->expression()[0]->accept(this));
+      expression = storage_->Create<SubscriptOperator>(
+          expression, std::any_cast<Expression *>(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<Expression *>(list_op->lower_bound->accept(this)) : nullptr;
+          list_op->lower_bound ? std::any_cast<Expression *>(list_op->lower_bound->accept(this)) : nullptr;
       Expression *upper_bound_ast =
-          list_op->upper_bound ? static_cast<Expression *>(list_op->upper_bound->accept(this)) : nullptr;
+          list_op->upper_bound ? std::any_cast<Expression *>(list_op->upper_bound->accept(this)) : nullptr;
       expression = storage_->Create<ListSlicingOperator>(expression, lower_bound_ast, upper_bound_ast);
     }
   }
@@ -1924,18 +1932,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<Expression *>(ctx->expression2b()->accept(this));
   if (ctx->nodeLabels()) {
-    auto labels = ctx->nodeLabels()->accept(this).as<std::vector<LabelIx>>();
+    auto labels = std::any_cast<std::vector<LabelIx>>(ctx->nodeLabels()->accept(this));
     expression = storage_->Create<LabelsTest>(expression, labels);
   }
   return expression;
 }
 
 antlrcpp::Any CypherMainVisitor::visitExpression2b(MemgraphCypher::Expression2bContext *ctx) {
-  Expression *expression = ctx->atom()->accept(this);
+  auto *expression = std::any_cast<Expression *>(ctx->atom()->accept(this));
   for (auto *lookup : ctx->propertyLookup()) {
-    PropertyIx key = lookup->accept(this);
+    auto key = std::any_cast<PropertyIx>(lookup->accept(this));
     auto property_lookup = storage_->Create<PropertyLookup>(expression, key);
     expression = property_lookup;
   }
@@ -1946,19 +1954,19 @@ antlrcpp::Any CypherMainVisitor::visitAtom(MemgraphCypher::AtomContext *ctx) {
   if (ctx->literal()) {
     return ctx->literal()->accept(this);
   } else if (ctx->parameter()) {
-    return static_cast<Expression *>(ctx->parameter()->accept(this).as<ParameterLookup *>());
+    return static_cast<Expression *>(std::any_cast<ParameterLookup *>(ctx->parameter()->accept(this)));
   } else if (ctx->parenthesizedExpression()) {
-    return static_cast<Expression *>(ctx->parenthesizedExpression()->accept(this));
+    return static_cast<Expression *>(std::any_cast<Expression *>(ctx->parenthesizedExpression()->accept(this)));
   } else if (ctx->variable()) {
-    std::string variable = ctx->variable()->accept(this);
+    auto variable = std::any_cast<std::string>(ctx->variable()->accept(this));
     users_identifiers.insert(variable);
     return static_cast<Expression *>(storage_->Create<Identifier>(variable));
   } else if (ctx->functionInvocation()) {
-    return static_cast<Expression *>(ctx->functionInvocation()->accept(this));
+    return std::any_cast<Expression *>(ctx->functionInvocation()->accept(this));
   } else if (ctx->COALESCE()) {
     std::vector<Expression *> exprs;
     for (auto *expr_context : ctx->expression()) {
-      exprs.emplace_back(expr_context->accept(this).as<Expression *>());
+      exprs.emplace_back(std::any_cast<Expression *>(expr_context->accept(this)));
     }
     return static_cast<Expression *>(storage_->Create<Coalesce>(std::move(exprs)));
   } else if (ctx->COUNT()) {
@@ -1967,57 +1975,57 @@ antlrcpp::Any CypherMainVisitor::visitAtom(MemgraphCypher::AtomContext *ctx) {
     // functionInvocation and atom producions in opencypher grammar.
     return static_cast<Expression *>(storage_->Create<Aggregation>(nullptr, nullptr, Aggregation::Op::COUNT));
   } else if (ctx->ALL()) {
-    auto *ident =
-        storage_->Create<Identifier>(ctx->filterExpression()->idInColl()->variable()->accept(this).as<std::string>());
-    Expression *list_expr = ctx->filterExpression()->idInColl()->expression()->accept(this);
+    auto *ident = storage_->Create<Identifier>(
+        std::any_cast<std::string>(ctx->filterExpression()->idInColl()->variable()->accept(this)));
+    auto *list_expr = std::any_cast<Expression *>(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<Where *>(ctx->filterExpression()->where()->accept(this));
     return static_cast<Expression *>(storage_->Create<All>(ident, list_expr, where));
   } else if (ctx->SINGLE()) {
-    auto *ident =
-        storage_->Create<Identifier>(ctx->filterExpression()->idInColl()->variable()->accept(this).as<std::string>());
-    Expression *list_expr = ctx->filterExpression()->idInColl()->expression()->accept(this);
+    auto *ident = storage_->Create<Identifier>(
+        std::any_cast<std::string>(ctx->filterExpression()->idInColl()->variable()->accept(this)));
+    auto *list_expr = std::any_cast<Expression *>(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<Where *>(ctx->filterExpression()->where()->accept(this));
     return static_cast<Expression *>(storage_->Create<Single>(ident, list_expr, where));
   } else if (ctx->ANY()) {
-    auto *ident =
-        storage_->Create<Identifier>(ctx->filterExpression()->idInColl()->variable()->accept(this).as<std::string>());
-    Expression *list_expr = ctx->filterExpression()->idInColl()->expression()->accept(this);
+    auto *ident = storage_->Create<Identifier>(
+        std::any_cast<std::string>(ctx->filterExpression()->idInColl()->variable()->accept(this)));
+    auto *list_expr = std::any_cast<Expression *>(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<Where *>(ctx->filterExpression()->where()->accept(this));
     return static_cast<Expression *>(storage_->Create<Any>(ident, list_expr, where));
   } else if (ctx->NONE()) {
-    auto *ident =
-        storage_->Create<Identifier>(ctx->filterExpression()->idInColl()->variable()->accept(this).as<std::string>());
-    Expression *list_expr = ctx->filterExpression()->idInColl()->expression()->accept(this);
+    auto *ident = storage_->Create<Identifier>(
+        std::any_cast<std::string>(ctx->filterExpression()->idInColl()->variable()->accept(this)));
+    auto *list_expr = std::any_cast<Expression *>(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<Where *>(ctx->filterExpression()->where()->accept(this));
     return static_cast<Expression *>(storage_->Create<None>(ident, list_expr, where));
   } else if (ctx->REDUCE()) {
     auto *accumulator =
-        storage_->Create<Identifier>(ctx->reduceExpression()->accumulator->accept(this).as<std::string>());
-    Expression *initializer = ctx->reduceExpression()->initial->accept(this);
-    auto *ident =
-        storage_->Create<Identifier>(ctx->reduceExpression()->idInColl()->variable()->accept(this).as<std::string>());
-    Expression *list = ctx->reduceExpression()->idInColl()->expression()->accept(this);
-    Expression *expr = ctx->reduceExpression()->expression().back()->accept(this);
+        storage_->Create<Identifier>(std::any_cast<std::string>(ctx->reduceExpression()->accumulator->accept(this)));
+    auto *initializer = std::any_cast<Expression *>(ctx->reduceExpression()->initial->accept(this));
+    auto *ident = storage_->Create<Identifier>(
+        std::any_cast<std::string>(ctx->reduceExpression()->idInColl()->variable()->accept(this)));
+    auto *list = std::any_cast<Expression *>(ctx->reduceExpression()->idInColl()->expression()->accept(this));
+    auto *expr = std::any_cast<Expression *>(ctx->reduceExpression()->expression().back()->accept(this));
     return static_cast<Expression *>(storage_->Create<Reduce>(accumulator, initializer, ident, list, expr));
   } else if (ctx->caseExpression()) {
-    return static_cast<Expression *>(ctx->caseExpression()->accept(this));
+    return std::any_cast<Expression *>(ctx->caseExpression()->accept(this));
   } else if (ctx->extractExpression()) {
-    auto *ident =
-        storage_->Create<Identifier>(ctx->extractExpression()->idInColl()->variable()->accept(this).as<std::string>());
-    Expression *list = ctx->extractExpression()->idInColl()->expression()->accept(this);
-    Expression *expr = ctx->extractExpression()->expression()->accept(this);
+    auto *ident = storage_->Create<Identifier>(
+        std::any_cast<std::string>(ctx->extractExpression()->idInColl()->variable()->accept(this)));
+    auto *list = std::any_cast<Expression *>(ctx->extractExpression()->idInColl()->expression()->accept(this));
+    auto *expr = std::any_cast<Expression *>(ctx->extractExpression()->expression()->accept(this));
     return static_cast<Expression *>(storage_->Create<Extract>(ident, list, expr));
   }
   // TODO: Implement this. We don't support comprehensions, filtering... at
@@ -2043,34 +2051,35 @@ antlrcpp::Any CypherMainVisitor::visitLiteral(MemgraphCypher::LiteralContext *ct
       return static_cast<Expression *>(storage_->Create<ParameterLookup>(token_position));
     } else if (ctx->StringLiteral()) {
       return static_cast<Expression *>(storage_->Create<PrimitiveLiteral>(
-          visitStringLiteral(ctx->StringLiteral()->getText()).as<std::string>(), token_position));
+          std::any_cast<std::string>(visitStringLiteral(std::any_cast<std::string>(ctx->StringLiteral()->getText()))),
+          token_position));
     } else if (ctx->booleanLiteral()) {
       return static_cast<Expression *>(
-          storage_->Create<PrimitiveLiteral>(ctx->booleanLiteral()->accept(this).as<bool>(), token_position));
+          storage_->Create<PrimitiveLiteral>(std::any_cast<bool>(ctx->booleanLiteral()->accept(this)), token_position));
     } else if (ctx->numberLiteral()) {
-      return static_cast<Expression *>(
-          storage_->Create<PrimitiveLiteral>(ctx->numberLiteral()->accept(this).as<TypedValue>(), token_position));
+      return static_cast<Expression *>(storage_->Create<PrimitiveLiteral>(
+          std::any_cast<TypedValue>(ctx->numberLiteral()->accept(this)), token_position));
     }
     LOG_FATAL("Expected to handle all cases above");
   } else if (ctx->listLiteral()) {
     return static_cast<Expression *>(
-        storage_->Create<ListLiteral>(ctx->listLiteral()->accept(this).as<std::vector<Expression *>>()));
+        storage_->Create<ListLiteral>(std::any_cast<std::vector<Expression *>>(ctx->listLiteral()->accept(this))));
   } else {
     return static_cast<Expression *>(storage_->Create<MapLiteral>(
-        ctx->mapLiteral()->accept(this).as<std::unordered_map<PropertyIx, Expression *>>()));
+        std::any_cast<std::unordered_map<PropertyIx, Expression *>>(ctx->mapLiteral()->accept(this))));
   }
   return visitChildren(ctx);
 }
 
 antlrcpp::Any CypherMainVisitor::visitParenthesizedExpression(MemgraphCypher::ParenthesizedExpressionContext *ctx) {
-  return static_cast<Expression *>(ctx->expression()->accept(this));
+  return std::any_cast<Expression *>(ctx->expression()->accept(this));
 }
 
 antlrcpp::Any CypherMainVisitor::visitNumberLiteral(MemgraphCypher::NumberLiteralContext *ctx) {
   if (ctx->integerLiteral()) {
-    return TypedValue(ctx->integerLiteral()->accept(this).as<int64_t>());
+    return TypedValue(std::any_cast<int64_t>(ctx->integerLiteral()->accept(this)));
   } else if (ctx->doubleLiteral()) {
-    return TypedValue(ctx->doubleLiteral()->accept(this).as<double>());
+    return TypedValue(std::any_cast<double>(ctx->doubleLiteral()->accept(this)));
   } else {
     // This should never happen, except grammar changes and we don't notice
     // change in this production.
@@ -2083,10 +2092,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<std::string>(ctx->functionName()->accept(this));
   std::vector<Expression *> expressions;
   for (auto *expression : ctx->expression()) {
-    expressions.push_back(expression->accept(this));
+    expressions.push_back(std::any_cast<Expression *>(expression->accept(this)));
   }
   if (expressions.size() == 1U) {
     if (function_name == Aggregation::kCount) {
@@ -2168,21 +2177,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 *>(expression->accept(this)));
   }
   return del;
 }
 
 antlrcpp::Any CypherMainVisitor::visitWhere(MemgraphCypher::WhereContext *ctx) {
   auto *where = storage_->Create<Where>();
-  where->expression_ = ctx->expression()->accept(this);
+  where->expression_ = std::any_cast<Expression *>(ctx->expression()->accept(this));
   return where;
 }
 
 antlrcpp::Any CypherMainVisitor::visitSet(MemgraphCypher::SetContext *ctx) {
   std::vector<Clause *> set_items;
   for (auto *set_item : ctx->setItem()) {
-    set_items.push_back(set_item->accept(this));
+    set_items.push_back(std::any_cast<Clause *>(set_item->accept(this)));
   }
   return set_items;
 }
@@ -2191,16 +2200,17 @@ antlrcpp::Any CypherMainVisitor::visitSetItem(MemgraphCypher::SetItemContext *ct
   // SetProperty
   if (ctx->propertyExpression()) {
     auto *set_property = storage_->Create<SetProperty>();
-    set_property->property_lookup_ = ctx->propertyExpression()->accept(this);
-    set_property->expression_ = ctx->expression()->accept(this);
+    set_property->property_lookup_ = std::any_cast<PropertyLookup *>(ctx->propertyExpression()->accept(this));
+    set_property->expression_ = std::any_cast<Expression *>(ctx->expression()->accept(this));
     return static_cast<Clause *>(set_property);
   }
 
   // SetProperties either assignment or update
   if (ctx->getTokens(MemgraphCypher::EQ).size() || ctx->getTokens(MemgraphCypher::PLUS_EQ).size()) {
     auto *set_properties = storage_->Create<SetProperties>();
-    set_properties->identifier_ = storage_->Create<Identifier>(ctx->variable()->accept(this).as<std::string>());
-    set_properties->expression_ = ctx->expression()->accept(this);
+    set_properties->identifier_ =
+        storage_->Create<Identifier>(std::any_cast<std::string>(ctx->variable()->accept(this)));
+    set_properties->expression_ = std::any_cast<Expression *>(ctx->expression()->accept(this));
     if (ctx->getTokens(MemgraphCypher::PLUS_EQ).size()) {
       set_properties->update_ = true;
     }
@@ -2209,15 +2219,15 @@ antlrcpp::Any CypherMainVisitor::visitSetItem(MemgraphCypher::SetItemContext *ct
 
   // SetLabels
   auto *set_labels = storage_->Create<SetLabels>();
-  set_labels->identifier_ = storage_->Create<Identifier>(ctx->variable()->accept(this).as<std::string>());
-  set_labels->labels_ = ctx->nodeLabels()->accept(this).as<std::vector<LabelIx>>();
+  set_labels->identifier_ = storage_->Create<Identifier>(std::any_cast<std::string>(ctx->variable()->accept(this)));
+  set_labels->labels_ = std::any_cast<std::vector<LabelIx>>(ctx->nodeLabels()->accept(this));
   return static_cast<Clause *>(set_labels);
 }
 
 antlrcpp::Any CypherMainVisitor::visitRemove(MemgraphCypher::RemoveContext *ctx) {
   std::vector<Clause *> remove_items;
   for (auto *remove_item : ctx->removeItem()) {
-    remove_items.push_back(remove_item->accept(this));
+    remove_items.push_back(std::any_cast<Clause *>(remove_item->accept(this)));
   }
   return remove_items;
 }
@@ -2226,21 +2236,21 @@ antlrcpp::Any CypherMainVisitor::visitRemoveItem(MemgraphCypher::RemoveItemConte
   // RemoveProperty
   if (ctx->propertyExpression()) {
     auto *remove_property = storage_->Create<RemoveProperty>();
-    remove_property->property_lookup_ = ctx->propertyExpression()->accept(this);
+    remove_property->property_lookup_ = std::any_cast<PropertyLookup *>(ctx->propertyExpression()->accept(this));
     return static_cast<Clause *>(remove_property);
   }
 
   // RemoveLabels
   auto *remove_labels = storage_->Create<RemoveLabels>();
-  remove_labels->identifier_ = storage_->Create<Identifier>(ctx->variable()->accept(this).as<std::string>());
-  remove_labels->labels_ = ctx->nodeLabels()->accept(this).as<std::vector<LabelIx>>();
+  remove_labels->identifier_ = storage_->Create<Identifier>(std::any_cast<std::string>(ctx->variable()->accept(this)));
+  remove_labels->labels_ = std::any_cast<std::vector<LabelIx>>(ctx->nodeLabels()->accept(this));
   return static_cast<Clause *>(remove_labels);
 }
 
 antlrcpp::Any CypherMainVisitor::visitPropertyExpression(MemgraphCypher::PropertyExpressionContext *ctx) {
-  Expression *expression = ctx->atom()->accept(this);
+  auto *expression = std::any_cast<Expression *>(ctx->atom()->accept(this));
   for (auto *lookup : ctx->propertyLookup()) {
-    PropertyIx key = lookup->accept(this);
+    auto key = std::any_cast<PropertyIx>(lookup->accept(this));
     auto property_lookup = storage_->Create<PropertyLookup>(expression, key);
     expression = property_lookup;
   }
@@ -2249,17 +2259,18 @@ antlrcpp::Any CypherMainVisitor::visitPropertyExpression(MemgraphCypher::Propert
 }
 
 antlrcpp::Any CypherMainVisitor::visitCaseExpression(MemgraphCypher::CaseExpressionContext *ctx) {
-  Expression *test_expression = ctx->test ? ctx->test->accept(this).as<Expression *>() : nullptr;
+  Expression *test_expression = ctx->test ? std::any_cast<Expression *>(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 *>()
+  Expression *else_expression = ctx->else_expression ? std::any_cast<Expression *>(ctx->else_expression->accept(this))
                                                      : storage_->Create<PrimitiveLiteral>(TypedValue());
   for (auto *alternative : alternatives) {
     Expression *condition =
-        test_expression ? storage_->Create<EqualOperator>(test_expression, alternative->when_expression->accept(this))
-                        : alternative->when_expression->accept(this).as<Expression *>();
-    Expression *then_expression = alternative->then_expression->accept(this);
+        test_expression ? storage_->Create<EqualOperator>(
+                              test_expression, std::any_cast<Expression *>(alternative->when_expression->accept(this)))
+                        : std::any_cast<Expression *>(alternative->when_expression->accept(this));
+    auto *then_expression = std::any_cast<Expression *>(alternative->then_expression->accept(this));
     else_expression = storage_->Create<IfOperator>(condition, then_expression, else_expression);
   }
   return else_expression;
@@ -2273,22 +2284,22 @@ antlrcpp::Any CypherMainVisitor::visitCaseAlternatives(MemgraphCypher::CaseAlter
 antlrcpp::Any CypherMainVisitor::visitWith(MemgraphCypher::WithContext *ctx) {
   auto *with = storage_->Create<With>();
   in_with_ = true;
-  with->body_ = ctx->returnBody()->accept(this);
+  with->body_ = std::any_cast<ReturnBody>(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<Where *>(ctx->where()->accept(this));
   }
   return with;
 }
 
 antlrcpp::Any CypherMainVisitor::visitMerge(MemgraphCypher::MergeContext *ctx) {
   auto *merge = storage_->Create<Merge>();
-  merge->pattern_ = ctx->patternPart()->accept(this);
+  merge->pattern_ = std::any_cast<Pattern *>(ctx->patternPart()->accept(this));
   for (auto &merge_action : ctx->mergeAction()) {
-    auto set = merge_action->set()->accept(this).as<std::vector<Clause *>>();
+    auto set = std::any_cast<std::vector<Clause *>>(merge_action->set()->accept(this));
     if (merge_action->MATCH()) {
       merge->on_match_.insert(merge->on_match_.end(), set.begin(), set.end());
     } else {
@@ -2301,8 +2312,8 @@ antlrcpp::Any CypherMainVisitor::visitMerge(MemgraphCypher::MergeContext *ctx) {
 
 antlrcpp::Any CypherMainVisitor::visitUnwind(MemgraphCypher::UnwindContext *ctx) {
   auto *named_expr = storage_->Create<NamedExpression>();
-  named_expr->expression_ = ctx->expression()->accept(this);
-  named_expr->name_ = std::string(ctx->variable()->accept(this).as<std::string>());
+  named_expr->expression_ = std::any_cast<Expression *>(ctx->expression()->accept(this));
+  named_expr->name_ = std::any_cast<std::string>(ctx->variable()->accept(this));
   return storage_->Create<Unwind>(named_expr);
 }
 
@@ -2315,27 +2326,27 @@ antlrcpp::Any CypherMainVisitor::visitForeach(MemgraphCypher::ForeachContext *ct
   auto *for_each = storage_->Create<Foreach>();
 
   auto *named_expr = storage_->Create<NamedExpression>();
-  named_expr->expression_ = ctx->expression()->accept(this);
-  named_expr->name_ = std::string(ctx->variable()->accept(this).as<std::string>());
+  named_expr->expression_ = std::any_cast<Expression *>(ctx->expression()->accept(this));
+  named_expr->name_ = std::any_cast<std::string>(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<std::vector<Clause *>>();
+      auto set_items = std::any_cast<std::vector<Clause *>>(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<std::vector<Clause *>>();
+      auto remove_items = std::any_cast<std::vector<Clause *>>(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<Merge *>());
+      for_each->clauses_.push_back(std::any_cast<Merge *>(visitMerge(merge)));
     } else if (auto *create = update_clause_ctx->create(); create) {
-      for_each->clauses_.push_back(visitCreate(create).as<Create *>());
+      for_each->clauses_.push_back(std::any_cast<Create *>(visitCreate(create)));
     } else if (auto *cypher_delete = update_clause_ctx->cypherDelete(); cypher_delete) {
-      for_each->clauses_.push_back(visitCypherDelete(cypher_delete).as<Delete *>());
+      for_each->clauses_.push_back(std::any_cast<Delete *>(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<Foreach *>());
+      for_each->clauses_.push_back(std::any_cast<Foreach *>(visitForeach(nested_for_each)));
     }
   }
 
diff --git a/src/query/frontend/ast/cypher_main_visitor.hpp b/src/query/frontend/ast/cypher_main_visitor.hpp
index 2a6b8ff5e..d3a12072e 100644
--- a/src/query/frontend/ast/cypher_main_visitor.hpp
+++ b/src/query/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 *>(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 *>(_expression->accept(this));
     for (int i = (int)operators.size() - 1; i >= 0; --i) {
       expression = CreateUnaryOperatorByToken(operators[i], expression);
     }
diff --git a/src/query/interpreter.cpp b/src/query/interpreter.cpp
index bc1a6a725..2925b1c14 100644
--- a/src/query/interpreter.cpp
+++ b/src/query/interpreter.cpp
@@ -1181,7 +1181,7 @@ PreparedQuery PrepareExplainQuery(ParsedQuery parsed_query, std::map<std::string
   // full query string) when given just the inner query to execute.
   ParsedQuery parsed_inner_query =
       ParseQuery(parsed_query.query_string.substr(kExplainQueryStart.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<CypherQuery>(parsed_inner_query.query);
   MG_ASSERT(cypher_query, "Cypher grammar should not allow other queries in EXPLAIN");
@@ -1248,7 +1248,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<CypherQuery>(parsed_inner_query.query);
   MG_ASSERT(cypher_query, "Cypher grammar should not allow other queries in PROFILE");
@@ -1566,8 +1566,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 {};
       }};
 }
@@ -2123,8 +2122,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/interpreter.hpp b/src/query/interpreter.hpp
index 5373588d9..0f9e8b901 100644
--- a/src/query/interpreter.hpp
+++ b/src/query/interpreter.hpp
@@ -173,13 +173,6 @@ struct InterpreterContext {
 
   storage::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<double> tsc_frequency{utils::GetTSCFrequency()};
   std::atomic<bool> is_shutting_down{false};
 
diff --git a/src/query/trigger.cpp b/src/query/trigger.cpp
index 9ff3262a7..ee8e84e3f 100644
--- a/src/query/trigger.cpp
+++ b/src/query/trigger.cpp
@@ -153,10 +153,10 @@ std::vector<std::pair<Identifier, TriggerIdentifierTag>> GetPredefinedIdentifier
 Trigger::Trigger(std::string name, const std::string &query,
                  const std::map<std::string, storage::PropertyValue> &user_parameters,
                  const TriggerEventType event_type, utils::SkipList<QueryCacheEntry> *query_cache,
-                 DbAccessor *db_accessor, utils::SpinLock *antlr_lock, const InterpreterConfig::Query &query_config,
+                 DbAccessor *db_accessor, const InterpreterConfig::Query &query_config,
                  std::optional<std::string> owner, const query::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<QueryCacheEntry> *query_cache, DbAccessor *db_accessor,
-                                   utils::SpinLock *antlr_lock, const InterpreterConfig::Query &query_config,
+                                   const InterpreterConfig::Query &query_config,
                                    const query::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<QueryCacheEntry> *query_cache
 
     std::optional<Trigger> 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<std::string, storage::PropertyValue> &user_parameters,
                               TriggerEventType event_type, TriggerPhase phase,
                               utils::SkipList<QueryCacheEntry> *query_cache, DbAccessor *db_accessor,
-                              utils::SpinLock *antlr_lock, const InterpreterConfig::Query &query_config,
-                              std::optional<std::string> owner, const query::AuthChecker *auth_checker) {
+                              const InterpreterConfig::Query &query_config, std::optional<std::string> owner,
+                              const query::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> 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/trigger.hpp b/src/query/trigger.hpp
index 6ed986ec7..a1b6b7012 100644
--- a/src/query/trigger.hpp
+++ b/src/query/trigger.hpp
@@ -34,7 +34,7 @@ namespace memgraph::query {
 struct Trigger {
   explicit Trigger(std::string name, const std::string &query,
                    const std::map<std::string, storage::PropertyValue> &user_parameters, TriggerEventType event_type,
-                   utils::SkipList<QueryCacheEntry> *query_cache, DbAccessor *db_accessor, utils::SpinLock *antlr_lock,
+                   utils::SkipList<QueryCacheEntry> *query_cache, DbAccessor *db_accessor,
                    const InterpreterConfig::Query &query_config, std::optional<std::string> owner,
                    const query::AuthChecker *auth_checker);
 
@@ -81,14 +81,13 @@ struct TriggerStore {
   explicit TriggerStore(std::filesystem::path directory);
 
   void RestoreTriggers(utils::SkipList<QueryCacheEntry> *query_cache, DbAccessor *db_accessor,
-                       utils::SpinLock *antlr_lock, const InterpreterConfig::Query &query_config,
-                       const query::AuthChecker *auth_checker);
+                       const InterpreterConfig::Query &query_config, const query::AuthChecker *auth_checker);
 
   void AddTrigger(std::string name, const std::string &query,
                   const std::map<std::string, storage::PropertyValue> &user_parameters, TriggerEventType event_type,
                   TriggerPhase phase, utils::SkipList<QueryCacheEntry> *query_cache, DbAccessor *db_accessor,
-                  utils::SpinLock *antlr_lock, const InterpreterConfig::Query &query_config,
-                  std::optional<std::string> owner, const query::AuthChecker *auth_checker);
+                  const InterpreterConfig::Query &query_config, std::optional<std::string> owner,
+                  const query::AuthChecker *auth_checker);
 
   void DropTrigger(const std::string &name);
 
diff --git a/tests/manual/antlr_sigsegv.cpp b/tests/manual/antlr_sigsegv.cpp
index cd6bba3f5..234530668 100644
--- a/tests/manual/antlr_sigsegv.cpp
+++ b/tests/manual/antlr_sigsegv.cpp
@@ -20,6 +20,15 @@
 #include "utils/signals.hpp"
 #include "utils/stacktrace.hpp"
 
+// This test was introduced because Antlr Cpp runtime doesn't work well in a
+// highly concurrent environment. Interpreter `interpret.hpp` contains
+// `antlr_lock` used to avoid crashes.
+//   v4.6 and before -> Crashes.
+//   v4.8            -> Does NOT crash but sometimes this tests does NOT finish.
+//                      Looks like a deadlock. -> The lock is still REQUIRED.
+//   v4.9            -> Seems to be working.
+//   v4.10           -> Seems to be working as well. -> antlr_lock removed
+
 using namespace std::chrono_literals;
 
 TEST(Antlr, Sigsegv) {
diff --git a/tests/unit/query_trigger.cpp b/tests/unit/query_trigger.cpp
index 57bc4f3bc..3375515a3 100644
--- a/tests/unit/query_trigger.cpp
+++ b/tests/unit/query_trigger.cpp
@@ -891,7 +891,6 @@ class TriggerStoreTest : public ::testing::Test {
   std::optional<memgraph::query::DbAccessor> dba;
 
   memgraph::utils::SkipList<memgraph::query::QueryCacheEntry> ast_cache;
-  memgraph::utils::SpinLock antlr_lock;
   memgraph::query::AllowEverythingAuthChecker auth_checker;
 
  private:
@@ -909,7 +908,7 @@ TEST_F(TriggerStoreTest, Restore) {
 
   const auto reset_store = [&] {
     store.emplace(testing_directory);
-    store->RestoreTriggers(&ast_cache, &*dba, &antlr_lock, memgraph::query::InterpreterConfig::Query{}, &auth_checker);
+    store->RestoreTriggers(&ast_cache, &*dba, memgraph::query::InterpreterConfig::Query{}, &auth_checker);
   };
 
   reset_store();
@@ -930,12 +929,12 @@ TEST_F(TriggerStoreTest, Restore) {
   store->AddTrigger(
       trigger_name_before, trigger_statement,
       std::map<std::string, memgraph::storage::PropertyValue>{{"parameter", memgraph::storage::PropertyValue{1}}},
-      event_type, memgraph::query::TriggerPhase::BEFORE_COMMIT, &ast_cache, &*dba, &antlr_lock,
+      event_type, memgraph::query::TriggerPhase::BEFORE_COMMIT, &ast_cache, &*dba,
       memgraph::query::InterpreterConfig::Query{}, std::nullopt, &auth_checker);
   store->AddTrigger(
       trigger_name_after, trigger_statement,
       std::map<std::string, memgraph::storage::PropertyValue>{{"parameter", memgraph::storage::PropertyValue{"value"}}},
-      event_type, memgraph::query::TriggerPhase::AFTER_COMMIT, &ast_cache, &*dba, &antlr_lock,
+      event_type, memgraph::query::TriggerPhase::AFTER_COMMIT, &ast_cache, &*dba,
       memgraph::query::InterpreterConfig::Query{}, {owner}, &auth_checker);
 
   const auto check_triggers = [&] {
@@ -986,16 +985,16 @@ TEST_F(TriggerStoreTest, AddTrigger) {
 
   // Invalid query in statements
   ASSERT_THROW(store.AddTrigger("trigger", "RETUR 1", {}, memgraph::query::TriggerEventType::VERTEX_CREATE,
-                                memgraph::query::TriggerPhase::BEFORE_COMMIT, &ast_cache, &*dba, &antlr_lock,
+                                memgraph::query::TriggerPhase::BEFORE_COMMIT, &ast_cache, &*dba,
                                 memgraph::query::InterpreterConfig::Query{}, std::nullopt, &auth_checker),
                memgraph::utils::BasicException);
   ASSERT_THROW(store.AddTrigger("trigger", "RETURN createdEdges", {}, memgraph::query::TriggerEventType::VERTEX_CREATE,
-                                memgraph::query::TriggerPhase::BEFORE_COMMIT, &ast_cache, &*dba, &antlr_lock,
+                                memgraph::query::TriggerPhase::BEFORE_COMMIT, &ast_cache, &*dba,
                                 memgraph::query::InterpreterConfig::Query{}, std::nullopt, &auth_checker),
                memgraph::utils::BasicException);
 
   ASSERT_THROW(store.AddTrigger("trigger", "RETURN $parameter", {}, memgraph::query::TriggerEventType::VERTEX_CREATE,
-                                memgraph::query::TriggerPhase::BEFORE_COMMIT, &ast_cache, &*dba, &antlr_lock,
+                                memgraph::query::TriggerPhase::BEFORE_COMMIT, &ast_cache, &*dba,
                                 memgraph::query::InterpreterConfig::Query{}, std::nullopt, &auth_checker),
                memgraph::utils::BasicException);
 
@@ -1003,15 +1002,15 @@ TEST_F(TriggerStoreTest, AddTrigger) {
       "trigger", "RETURN $parameter",
       std::map<std::string, memgraph::storage::PropertyValue>{{"parameter", memgraph::storage::PropertyValue{1}}},
       memgraph::query::TriggerEventType::VERTEX_CREATE, memgraph::query::TriggerPhase::BEFORE_COMMIT, &ast_cache, &*dba,
-      &antlr_lock, memgraph::query::InterpreterConfig::Query{}, std::nullopt, &auth_checker));
+      memgraph::query::InterpreterConfig::Query{}, std::nullopt, &auth_checker));
 
   // Inserting with the same name
   ASSERT_THROW(store.AddTrigger("trigger", "RETURN 1", {}, memgraph::query::TriggerEventType::VERTEX_CREATE,
-                                memgraph::query::TriggerPhase::BEFORE_COMMIT, &ast_cache, &*dba, &antlr_lock,
+                                memgraph::query::TriggerPhase::BEFORE_COMMIT, &ast_cache, &*dba,
                                 memgraph::query::InterpreterConfig::Query{}, std::nullopt, &auth_checker),
                memgraph::utils::BasicException);
   ASSERT_THROW(store.AddTrigger("trigger", "RETURN 1", {}, memgraph::query::TriggerEventType::VERTEX_CREATE,
-                                memgraph::query::TriggerPhase::AFTER_COMMIT, &ast_cache, &*dba, &antlr_lock,
+                                memgraph::query::TriggerPhase::AFTER_COMMIT, &ast_cache, &*dba,
                                 memgraph::query::InterpreterConfig::Query{}, std::nullopt, &auth_checker),
                memgraph::utils::BasicException);
 
@@ -1027,7 +1026,7 @@ TEST_F(TriggerStoreTest, DropTrigger) {
 
   const auto *trigger_name = "trigger";
   store.AddTrigger(trigger_name, "RETURN 1", {}, memgraph::query::TriggerEventType::VERTEX_CREATE,
-                   memgraph::query::TriggerPhase::BEFORE_COMMIT, &ast_cache, &*dba, &antlr_lock,
+                   memgraph::query::TriggerPhase::BEFORE_COMMIT, &ast_cache, &*dba,
                    memgraph::query::InterpreterConfig::Query{}, std::nullopt, &auth_checker);
 
   ASSERT_THROW(store.DropTrigger("Unknown"), memgraph::utils::BasicException);
@@ -1040,7 +1039,7 @@ TEST_F(TriggerStoreTest, TriggerInfo) {
 
   std::vector<memgraph::query::TriggerStore::TriggerInfo> expected_info;
   store.AddTrigger("trigger", "RETURN 1", {}, memgraph::query::TriggerEventType::VERTEX_CREATE,
-                   memgraph::query::TriggerPhase::BEFORE_COMMIT, &ast_cache, &*dba, &antlr_lock,
+                   memgraph::query::TriggerPhase::BEFORE_COMMIT, &ast_cache, &*dba,
                    memgraph::query::InterpreterConfig::Query{}, std::nullopt, &auth_checker);
   expected_info.push_back({"trigger", "RETURN 1", memgraph::query::TriggerEventType::VERTEX_CREATE,
                            memgraph::query::TriggerPhase::BEFORE_COMMIT});
@@ -1060,7 +1059,7 @@ TEST_F(TriggerStoreTest, TriggerInfo) {
   check_trigger_info();
 
   store.AddTrigger("edge_update_trigger", "RETURN 1", {}, memgraph::query::TriggerEventType::EDGE_UPDATE,
-                   memgraph::query::TriggerPhase::AFTER_COMMIT, &ast_cache, &*dba, &antlr_lock,
+                   memgraph::query::TriggerPhase::AFTER_COMMIT, &ast_cache, &*dba,
                    memgraph::query::InterpreterConfig::Query{}, std::nullopt, &auth_checker);
   expected_info.push_back({"edge_update_trigger", "RETURN 1", memgraph::query::TriggerEventType::EDGE_UPDATE,
                            memgraph::query::TriggerPhase::AFTER_COMMIT});
@@ -1174,7 +1173,7 @@ TEST_F(TriggerStoreTest, AnyTriggerAllKeywords) {
     for (const auto keyword : keywords) {
       SCOPED_TRACE(keyword);
       EXPECT_NO_THROW(store.AddTrigger(trigger_name, fmt::format("RETURN {}", keyword), {}, event_type,
-                                       memgraph::query::TriggerPhase::BEFORE_COMMIT, &ast_cache, &*dba, &antlr_lock,
+                                       memgraph::query::TriggerPhase::BEFORE_COMMIT, &ast_cache, &*dba,
                                        memgraph::query::InterpreterConfig::Query{}, std::nullopt, &auth_checker));
       store.DropTrigger(trigger_name);
     }
@@ -1199,23 +1198,23 @@ TEST_F(TriggerStoreTest, AuthCheckerUsage) {
 
   ASSERT_NO_THROW(store->AddTrigger("successfull_trigger_1", "CREATE (n:VERTEX) RETURN n", {},
                                     memgraph::query::TriggerEventType::EDGE_UPDATE,
-                                    memgraph::query::TriggerPhase::AFTER_COMMIT, &ast_cache, &*dba, &antlr_lock,
+                                    memgraph::query::TriggerPhase::AFTER_COMMIT, &ast_cache, &*dba,
                                     memgraph::query::InterpreterConfig::Query{}, std::nullopt, &mock_checker));
 
   ASSERT_NO_THROW(store->AddTrigger("successfull_trigger_2", "CREATE (n:VERTEX) RETURN n", {},
                                     memgraph::query::TriggerEventType::EDGE_UPDATE,
-                                    memgraph::query::TriggerPhase::AFTER_COMMIT, &ast_cache, &*dba, &antlr_lock,
+                                    memgraph::query::TriggerPhase::AFTER_COMMIT, &ast_cache, &*dba,
                                     memgraph::query::InterpreterConfig::Query{}, owner, &mock_checker));
 
   EXPECT_CALL(mock_checker, IsUserAuthorized(std::optional<std::string>{}, ElementsAre(Privilege::MATCH)))
       .Times(1)
       .WillOnce(Return(false));
 
-  ASSERT_THROW(store->AddTrigger("unprivileged_trigger", "MATCH (n:VERTEX) RETURN n", {},
-                                 memgraph::query::TriggerEventType::EDGE_UPDATE,
-                                 memgraph::query::TriggerPhase::AFTER_COMMIT, &ast_cache, &*dba, &antlr_lock,
-                                 memgraph::query::InterpreterConfig::Query{}, std::nullopt, &mock_checker);
-               , memgraph::utils::BasicException);
+  ASSERT_THROW(
+      store->AddTrigger("unprivileged_trigger", "MATCH (n:VERTEX) RETURN n", {},
+                        memgraph::query::TriggerEventType::EDGE_UPDATE, memgraph::query::TriggerPhase::AFTER_COMMIT,
+                        &ast_cache, &*dba, memgraph::query::InterpreterConfig::Query{}, std::nullopt, &mock_checker);
+      , memgraph::utils::BasicException);
 
   store.emplace(testing_directory);
   EXPECT_CALL(mock_checker, IsUserAuthorized(std::optional<std::string>{}, ElementsAre(Privilege::CREATE)))
@@ -1223,8 +1222,8 @@ TEST_F(TriggerStoreTest, AuthCheckerUsage) {
       .WillOnce(Return(false));
   EXPECT_CALL(mock_checker, IsUserAuthorized(owner, ElementsAre(Privilege::CREATE))).Times(1).WillOnce(Return(true));
 
-  ASSERT_NO_THROW(store->RestoreTriggers(&ast_cache, &*dba, &antlr_lock, memgraph::query::InterpreterConfig::Query{},
-                                         &mock_checker));
+  ASSERT_NO_THROW(
+      store->RestoreTriggers(&ast_cache, &*dba, memgraph::query::InterpreterConfig::Query{}, &mock_checker));
 
   const auto triggers = store->GetTriggerInfo();
   ASSERT_EQ(triggers.size(), 1);