From 8be2b4af638d584bb17c2c6fade88303d9427d45 Mon Sep 17 00:00:00 2001
From: Matej Ferencevic <matej.ferencevic@memgraph.io>
Date: Wed, 20 Nov 2019 19:36:56 +0100
Subject: [PATCH] Remove output formatters from vertex/edge accessors

Reviewers: teon.banek

Reviewed By: teon.banek

Subscribers: pullbot

Differential Revision: https://phabricator.memgraph.io/D2555
---
 src/query/db_accessor.hpp                   |  16 --
 src/query/path.hpp                          |  15 --
 src/query/typed_value.cpp                   |  34 -----
 src/query/typed_value.hpp                   |   7 -
 tests/manual/interactive_planning.cpp       |  32 ++--
 tests/unit/bfs_common.hpp                   |   5 +-
 tests/unit/formatters.hpp                   | 119 +++++++++++++++
 tests/unit/query_variable_start_planner.cpp | 156 ++++++++++++--------
 8 files changed, 233 insertions(+), 151 deletions(-)
 create mode 100644 tests/unit/formatters.hpp

diff --git a/src/query/db_accessor.hpp b/src/query/db_accessor.hpp
index 473d7a023..296bcfd91 100644
--- a/src/query/db_accessor.hpp
+++ b/src/query/db_accessor.hpp
@@ -70,10 +70,6 @@ class EdgeAccessor final {
   bool operator==(const EdgeAccessor &e) const { return impl_ == e.impl_; }
 
   bool operator!=(const EdgeAccessor &e) const { return !(*this == e); }
-
-  friend std::ostream &operator<<(std::ostream &s, const EdgeAccessor &e) {
-    throw utils::NotYetImplemented("operator<<");
-  }
 };
 
 class VertexAccessor final {
@@ -178,10 +174,6 @@ class VertexAccessor final {
   bool operator==(const VertexAccessor &v) const { return impl_ == v.impl_; }
 
   bool operator!=(const VertexAccessor &v) const { return !(*this == v); }
-
-  friend std::ostream &operator<<(std::ostream &s, const VertexAccessor &v) {
-    throw utils::NotYetImplemented("operator<<");
-  }
 };
 
 inline VertexAccessor EdgeAccessor::To() const {
@@ -285,10 +277,6 @@ class EdgeAccessor final {
   bool operator==(const EdgeAccessor &e) const { return impl_ == e.impl_; }
 
   bool operator!=(const EdgeAccessor &e) const { return !(*this == e); }
-
-  friend std::ostream &operator<<(std::ostream &s, const EdgeAccessor &e) {
-    return s << e.impl_;
-  }
 };
 
 class VertexAccessor final {
@@ -471,10 +459,6 @@ class VertexAccessor final {
   bool operator==(const VertexAccessor &v) const { return impl_ == v.impl_; }
 
   bool operator!=(const VertexAccessor &v) const { return !(*this == v); }
-
-  friend std::ostream &operator<<(std::ostream &s, const VertexAccessor &v) {
-    return s << v.impl_;
-  }
 };
 
 inline VertexAccessor EdgeAccessor::To() const {
diff --git a/src/query/path.hpp b/src/query/path.hpp
index fcabc6a74..249d60263 100644
--- a/src/query/path.hpp
+++ b/src/query/path.hpp
@@ -138,21 +138,6 @@ class Path {
     return vertices_ == other.vertices_ && edges_ == other.edges_;
   }
 
-  friend std::ostream &operator<<(std::ostream &os, const Path &path) {
-    DCHECK(path.vertices_.size() > 0U)
-        << "Attempting to stream out an invalid path";
-    os << path.vertices_[0];
-    for (int i = 0; i < static_cast<int>(path.edges_.size()); i++) {
-      bool arrow_to_left = path.vertices_[i] == path.edges_[i].To();
-      if (arrow_to_left) os << "<";
-      os << "-" << path.edges_[i] << "-";
-      if (!arrow_to_left) os << ">";
-      os << path.vertices_[i + 1];
-    }
-
-    return os;
-  }
-
  private:
   // Contains all the vertices in the path.
   utils::pmr::vector<VertexAccessor> vertices_;
diff --git a/src/query/typed_value.cpp b/src/query/typed_value.cpp
index dec08b625..2113574fe 100644
--- a/src/query/typed_value.cpp
+++ b/src/query/typed_value.cpp
@@ -9,7 +9,6 @@
 
 #include "glog/logging.h"
 
-#include "utils/algorithm.hpp"
 #include "utils/exceptions.hpp"
 #include "utils/hashing/fnv.hpp"
 
@@ -288,39 +287,6 @@ std::ostream &operator<<(std::ostream &os, const TypedValue::Type &type) {
   LOG(FATAL) << "Unsupported TypedValue::Type";
 }
 
-std::ostream &operator<<(std::ostream &os, const TypedValue &value) {
-  switch (value.type()) {
-    case TypedValue::Type::Null:
-      return os << "Null";
-    case TypedValue::Type::Bool:
-      return os << (value.ValueBool() ? "true" : "false");
-    case TypedValue::Type::Int:
-      return os << value.ValueInt();
-    case TypedValue::Type::Double:
-      return os << value.ValueDouble();
-    case TypedValue::Type::String:
-      return os << value.ValueString();
-    case TypedValue::Type::List:
-      os << "[";
-      utils::PrintIterable(os, value.ValueList());
-      return os << "]";
-    case TypedValue::Type::Map:
-      os << "{";
-      utils::PrintIterable(os, value.ValueMap(), ", ",
-                           [](auto &stream, const auto &pair) {
-                             stream << pair.first << ": " << pair.second;
-                           });
-      return os << "}";
-    case TypedValue::Type::Vertex:
-      return os << value.ValueVertex();
-    case TypedValue::Type::Edge:
-      return os << value.ValueEdge();
-    case TypedValue::Type::Path:
-      return os << value.ValuePath();
-  }
-  LOG(FATAL) << "Unsupported PropertyValue::Type";
-}
-
 #define DEFINE_TYPED_VALUE_COPY_ASSIGNMENT(type_param, typed_value_type, \
                                            member)                       \
   TypedValue &TypedValue::operator=(type_param other) {                  \
diff --git a/src/query/typed_value.hpp b/src/query/typed_value.hpp
index 9f52e0387..e778c9381 100644
--- a/src/query/typed_value.hpp
+++ b/src/query/typed_value.hpp
@@ -733,11 +733,4 @@ TypedValue operator%(const TypedValue &a, const TypedValue &b);
 /** Output the TypedValue::Type value as a string */
 std::ostream &operator<<(std::ostream &os, const TypedValue::Type &type);
 
-/**
- * Output the TypedValue value as a readable string.
- * Note that the primary use of this is for debugging and may not yield the
- * pretty results you want to display to the user.
- */
-std::ostream &operator<<(std::ostream &os, const TypedValue &value);
-
 }  // namespace query
diff --git a/tests/manual/interactive_planning.cpp b/tests/manual/interactive_planning.cpp
index dc5da18a3..06cad3802 100644
--- a/tests/manual/interactive_planning.cpp
+++ b/tests/manual/interactive_planning.cpp
@@ -17,6 +17,7 @@
 #include "query/plan/planner.hpp"
 #include "query/plan/pretty_print.hpp"
 #include "query/typed_value.hpp"
+#include "storage/v2/property_value.hpp"
 #include "utils/string.hpp"
 
 DEFINE_string(save_mock_db_file, "",
@@ -168,15 +169,14 @@ class InteractiveDbAccessor {
       return 0;
     }
     auto &value_vertex_count = property_value_vertex_count_[label_prop];
-    query::TypedValue tv_value(value);
-    if (value_vertex_count.find(tv_value) == value_vertex_count.end()) {
+    if (value_vertex_count.find(value) == value_vertex_count.end()) {
       std::stringstream ss;
-      ss << tv_value;
+      ss << value;
       int64_t count = ReadVertexCount("label '" + label + "' and property '" +
                                       property + "' value '" + ss.str() + "'");
-      value_vertex_count[tv_value] = count;
+      value_vertex_count[value] = count;
     }
-    return value_vertex_count.at(tv_value);
+    return value_vertex_count.at(value);
   }
 
   int64_t VerticesCount(
@@ -301,7 +301,7 @@ class InteractiveDbAccessor {
       }
       DLOG(INFO) << "Load " << label << " " << property << " " << value_count;
       for (int v = 0; v < value_count; ++v) {
-        auto value = LoadTypedValue(in);
+        auto value = LoadPropertyValue(in);
         int64_t count;
         in >> count;
         if (in.fail()) {
@@ -324,10 +324,8 @@ class InteractiveDbAccessor {
   std::map<std::pair<std::string, std::string>, int64_t>
       label_property_vertex_count_;
   std::map<std::pair<std::string, std::string>, bool> label_property_index_;
-  std::map<
-      std::pair<std::string, std::string>,
-      std::unordered_map<query::TypedValue, int64_t, query::TypedValue::Hash,
-                         query::TypedValue::BoolEqual>>
+  std::map<std::pair<std::string, std::string>,
+           std::map<storage::PropertyValue, int64_t>>
       property_value_vertex_count_;
   // TODO: Cache faked index counts by range.
 
@@ -336,27 +334,27 @@ class InteractiveDbAccessor {
         [&message]() { return ReadInt("Vertices with " + message + ": "); });
   }
 
-  query::TypedValue LoadTypedValue(std::istream &in) {
+  storage::PropertyValue LoadPropertyValue(std::istream &in) {
     std::string type;
     in >> type;
     if (type == "bool") {
-      return LoadTypedValue<bool>(in);
+      return LoadPropertyValue<bool>(in);
     } else if (type == "int") {
-      return LoadTypedValue<int64_t>(in);
+      return LoadPropertyValue<int64_t>(in);
     } else if (type == "double") {
-      return LoadTypedValue<double>(in);
+      return LoadPropertyValue<double>(in);
     } else if (type == "string") {
-      return LoadTypedValue<std::string>(in);
+      return LoadPropertyValue<std::string>(in);
     } else {
       throw utils::BasicException("Unable to read type '{}'", type);
     }
   }
 
   template <typename T>
-  query::TypedValue LoadTypedValue(std::istream &in) {
+  storage::PropertyValue LoadPropertyValue(std::istream &in) {
     T val;
     in >> val;
-    return query::TypedValue(val);
+    return storage::PropertyValue(val);
   }
 };
 
diff --git a/tests/unit/bfs_common.hpp b/tests/unit/bfs_common.hpp
index 38e4fabb4..f50336a2f 100644
--- a/tests/unit/bfs_common.hpp
+++ b/tests/unit/bfs_common.hpp
@@ -8,6 +8,8 @@
 #include "query/plan/operator.hpp"
 #include "query_common.hpp"
 
+#include "formatters.hpp"
+
 namespace query {
 void PrintTo(const query::EdgeAtom::Direction &dir, std::ostream *os) {
   switch (dir) {
@@ -436,7 +438,8 @@ void BfsTest(Database *db, int lower_bound, int upper_bound,
            query::TypedValue::BoolEqual{}(results[j][3], blocked))
       ++j;
 
-    SCOPED_TRACE(fmt::format("blocked entity = {}", blocked));
+    SCOPED_TRACE(
+        fmt::format("blocked entity = {}", ToString(blocked, execution_dba)));
 
     // When an edge is blocked, it is blocked in both directions so we remove
     // it before modifying edge list to account for direction and edge types;
diff --git a/tests/unit/formatters.hpp b/tests/unit/formatters.hpp
new file mode 100644
index 000000000..66f64a9fd
--- /dev/null
+++ b/tests/unit/formatters.hpp
@@ -0,0 +1,119 @@
+#pragma once
+
+#include <sstream>
+#include <string>
+
+#include <glog/logging.h>
+
+#include "query/typed_value.hpp"
+#include "utils/algorithm.hpp"
+
+/// Functions that convert types to a `std::string` representation of it. The
+/// `TAccessor` supplied must have the functions `NameToLabel`, `LabelToName`,
+/// `NameToProperty`, `PropertyToName`, `NameToEdgeType` and `EdgeTypeToName`.
+/// For example, both `storage::Storage` and `storage::Storage::Accessor` will
+/// be apropriate.
+
+template <class TAccessor>
+inline std::string ToString(const query::VertexAccessor &vertex,
+                            const TAccessor &acc) {
+  std::ostringstream os;
+  os << "V(";
+  auto maybe_labels = vertex.Labels(storage::View::NEW);
+  CHECK(maybe_labels.HasValue());
+  utils::PrintIterable(os, *maybe_labels, ":", [&](auto &stream, auto label) {
+    stream << acc.LabelToName(label);
+  });
+  if (maybe_labels->size() > 0) os << " ";
+  os << "{";
+  auto maybe_properties = vertex.Properties(storage::View::NEW);
+  CHECK(maybe_properties.HasValue());
+  utils::PrintIterable(
+      os, *maybe_properties, ", ", [&](auto &stream, const auto &pair) {
+        stream << acc.PropertyToName(pair.first) << ": " << pair.second;
+      });
+  os << "})";
+  return os.str();
+}
+
+template <class TAccessor>
+inline std::string ToString(const query::EdgeAccessor &edge,
+                            const TAccessor &acc) {
+  std::ostringstream os;
+  os << "E[" << acc.EdgeTypeToName(edge.EdgeType());
+  os << " {";
+  auto maybe_properties = edge.Properties(storage::View::NEW);
+  CHECK(maybe_properties.HasValue());
+  utils::PrintIterable(
+      os, *maybe_properties, ", ", [&](auto &stream, const auto &pair) {
+        stream << acc.PropertyToName(pair.first) << ": " << pair.second;
+      });
+  os << "}]";
+  return os.str();
+}
+
+template <class TAccessor>
+inline std::string ToString(const query::Path &path, const TAccessor &acc) {
+  std::ostringstream os;
+  const auto &vertices = path.vertices();
+  const auto &edges = path.edges();
+  CHECK(vertices.size() > 0U) << "Attempting to stream out an invalid path";
+  os << ToString(vertices[0], acc);
+  for (size_t i = 0; i < edges.size(); ++i) {
+    bool arrow_to_left = vertices[i] == edges[i].To();
+    if (arrow_to_left) os << "<";
+    os << "-" << ToString(edges[i], acc) << "-";
+    if (!arrow_to_left) os << ">";
+    os << ToString(vertices[i + 1], acc);
+  }
+  return os.str();
+}
+
+template <class TAccessor>
+inline std::string ToString(const query::TypedValue &value,
+                            const TAccessor &acc) {
+  std::ostringstream os;
+  switch (value.type()) {
+    case query::TypedValue::Type::Null:
+      os << "null";
+      break;
+    case query::TypedValue::Type::Bool:
+      os << (value.ValueBool() ? "true" : "false");
+      break;
+    case query::TypedValue::Type::Int:
+      os << value.ValueInt();
+      break;
+    case query::TypedValue::Type::Double:
+      os << value.ValueDouble();
+      break;
+    case query::TypedValue::Type::String:
+      os << value.ValueString();
+      break;
+    case query::TypedValue::Type::List:
+      os << "[";
+      utils::PrintIterable(os, value.ValueList(), ", ",
+                           [&](auto &stream, const auto &item) {
+                             stream << ToString(item, acc);
+                           });
+      os << "]";
+      break;
+    case query::TypedValue::Type::Map:
+      os << "{";
+      utils::PrintIterable(
+          os, value.ValueMap(), ", ", [&](auto &stream, const auto &pair) {
+            stream << pair.first << ": " << ToString(pair.second, acc);
+          });
+      os << "}";
+      break;
+    case query::TypedValue::Type::Vertex:
+      os << ToString(value.ValueVertex(), acc);
+      break;
+    case query::TypedValue::Type::Edge:
+      os << ToString(value.ValueEdge(), acc);
+      break;
+    case query::TypedValue::Type::Path:
+      os << ToString(value.ValuePath(), acc);
+      break;
+  }
+  return os.str();
+}
diff --git a/tests/unit/query_variable_start_planner.cpp b/tests/unit/query_variable_start_planner.cpp
index af2d74e18..8f5acf41b 100644
--- a/tests/unit/query_variable_start_planner.cpp
+++ b/tests/unit/query_variable_start_planner.cpp
@@ -9,31 +9,38 @@
 
 #include "query_plan_common.hpp"
 
+#include "formatters.hpp"
+
 using namespace query::plan;
 using query::AstStorage;
 using Type = query::EdgeAtom::Type;
 using Direction = query::EdgeAtom::Direction;
 
-namespace std {
-
-// Overloads for printing resulting rows from a query.
-std::ostream &operator<<(std::ostream &stream,
-                         const std::vector<TypedValue> &row) {
-  utils::PrintIterable(stream, row);
-  return stream;
+// Functions for printing resulting rows from a query.
+template <class TAccessor>
+std::string ToString(const std::vector<TypedValue> &row, const TAccessor &acc) {
+  std::ostringstream os;
+  utils::PrintIterable(os, row, ", ", [&](auto &stream, const auto &item) {
+    stream << ToString(item, acc);
+  });
+  return os.str();
 }
-std::ostream &operator<<(std::ostream &stream,
-                         const std::vector<std::vector<TypedValue>> &rows) {
-  utils::PrintIterable(stream, rows, "\n");
-  return stream;
+template <class TAccessor>
+std::string ToString(const std::vector<std::vector<TypedValue>> &rows,
+                     const TAccessor &acc) {
+  std::ostringstream os;
+  utils::PrintIterable(os, rows, "\n", [&](auto &stream, const auto &item) {
+    stream << ToString(item, acc);
+  });
+  return os.str();
 }
 
-}  // namespace std
-
 namespace {
 
+template <class TAccessor>
 void AssertRows(const std::vector<std::vector<TypedValue>> &datum,
-                std::vector<std::vector<TypedValue>> expected) {
+                std::vector<std::vector<TypedValue>> expected,
+                const TAccessor &acc) {
   auto row_equal = [](const auto &row1, const auto &row2) {
     if (row1.size() != row2.size()) {
       return false;
@@ -51,19 +58,18 @@ void AssertRows(const std::vector<std::vector<TypedValue>> &datum,
   ASSERT_TRUE(std::is_permutation(datum.begin(), datum.end(), expected.begin(),
                                   expected.end(), row_equal))
       << "Actual rows:" << std::endl
-      << datum << std::endl
+      << ToString(datum, acc) << std::endl
       << "Expected rows:" << std::endl
-      << expected;
+      << ToString(expected, acc);
 };
 
 void CheckPlansProduce(
     size_t expected_plan_count, query::CypherQuery *query, AstStorage &storage,
-    database::GraphDbAccessor *dba,
+    query::DbAccessor *dba,
     std::function<void(const std::vector<std::vector<TypedValue>> &)> check) {
   auto symbol_table = query::MakeSymbolTable(query);
-  query::DbAccessor execution_dba(dba);
   auto planning_context =
-      MakePlanningContext(&storage, &symbol_table, query, &execution_dba);
+      MakePlanningContext(&storage, &symbol_table, query, dba);
   auto query_parts = CollectQueryParts(symbol_table, storage, query);
   EXPECT_TRUE(query_parts.query_parts.size() > 0);
   auto single_query_parts = query_parts.query_parts.at(0).single_query_parts;
@@ -73,7 +79,7 @@ void CheckPlansProduce(
   for (const auto &plan : plans) {
     auto *produce = dynamic_cast<Produce *>(plan.get());
     ASSERT_TRUE(produce);
-    auto context = MakeContext(storage, symbol_table, &execution_dba);
+    auto context = MakeContext(storage, symbol_table, dba);
     auto results = CollectProduce(*produce, &context);
     check(results);
   }
@@ -93,10 +99,13 @@ TEST(TestVariableStartPlanner, MatchReturn) {
       MATCH(PATTERN(NODE("n"), EDGE("r", Direction::OUT), NODE("m"))),
       RETURN("n")));
   // We have 2 nodes `n` and `m` from which we could start, so expect 2 plans.
-  CheckPlansProduce(2, query, storage, &dba, [&](const auto &results) {
-    // We expect to produce only a single (v1) node.
-    AssertRows(results, {{TypedValue(query::VertexAccessor(v1))}});
-  });
+  query::DbAccessor execution_dba(&dba);
+  CheckPlansProduce(
+      2, query, storage, &execution_dba, [&](const auto &results) {
+        // We expect to produce only a single (v1) node.
+        AssertRows(results, {{TypedValue(query::VertexAccessor(v1))}},
+                   execution_dba);
+      });
 }
 
 TEST(TestVariableStartPlanner, MatchTripletPatternReturn) {
@@ -117,10 +126,13 @@ TEST(TestVariableStartPlanner, MatchTripletPatternReturn) {
                       EDGE("e", Direction::OUT), NODE("l"))),
         RETURN("n")));
     // We have 3 nodes: `n`, `m` and `l` from which we could start.
-    CheckPlansProduce(3, query, storage, &dba, [&](const auto &results) {
-      // We expect to produce only a single (v1) node.
-      AssertRows(results, {{TypedValue(query::VertexAccessor(v1))}});
-    });
+    query::DbAccessor execution_dba(&dba);
+    CheckPlansProduce(
+        3, query, storage, &execution_dba, [&](const auto &results) {
+          // We expect to produce only a single (v1) node.
+          AssertRows(results, {{TypedValue(query::VertexAccessor(v1))}},
+                     execution_dba);
+        });
   }
   {
     // Equivalent to `MATCH (n) -[r]-> (m), (m) -[e]-> (l) RETURN n`.
@@ -129,9 +141,12 @@ TEST(TestVariableStartPlanner, MatchTripletPatternReturn) {
         MATCH(PATTERN(NODE("n"), EDGE("r", Direction::OUT), NODE("m")),
               PATTERN(NODE("m"), EDGE("e", Direction::OUT), NODE("l"))),
         RETURN("n")));
-    CheckPlansProduce(3, query, storage, &dba, [&](const auto &results) {
-      AssertRows(results, {{TypedValue(query::VertexAccessor(v1))}});
-    });
+    query::DbAccessor execution_dba(&dba);
+    CheckPlansProduce(
+        3, query, storage, &execution_dba, [&](const auto &results) {
+          AssertRows(results, {{TypedValue(query::VertexAccessor(v1))}},
+                     execution_dba);
+        });
   }
 }
 
@@ -153,15 +168,18 @@ TEST(TestVariableStartPlanner, MatchOptionalMatchReturn) {
       RETURN("n", "l")));
   // We have 2 nodes `n` and `m` from which we could start the MATCH, and 2
   // nodes for OPTIONAL MATCH. This should produce 2 * 2 plans.
-  CheckPlansProduce(4, query, storage, &dba, [&](const auto &results) {
-    // We expect to produce 2 rows:
-    //   * (v1), (v3)
-    //   * (v2), null
-    AssertRows(results,
-               {{TypedValue(query::VertexAccessor(v1)),
-                 TypedValue(query::VertexAccessor(v3))},
-                {TypedValue(query::VertexAccessor(v2)), TypedValue()}});
-  });
+  query::DbAccessor execution_dba(&dba);
+  CheckPlansProduce(
+      4, query, storage, &execution_dba, [&](const auto &results) {
+        // We expect to produce 2 rows:
+        //   * (v1), (v3)
+        //   * (v2), null
+        AssertRows(results,
+                   {{TypedValue(query::VertexAccessor(v1)),
+                     TypedValue(query::VertexAccessor(v3))},
+                    {TypedValue(query::VertexAccessor(v2)), TypedValue()}},
+                   execution_dba);
+      });
 }
 
 TEST(TestVariableStartPlanner, MatchOptionalMatchMergeReturn) {
@@ -185,11 +203,15 @@ TEST(TestVariableStartPlanner, MatchOptionalMatchMergeReturn) {
       RETURN("n", "m", "l", "u", "v")));
   // Since MATCH, OPTIONAL MATCH and MERGE each have 2 nodes from which we can
   // start, we generate 2 * 2 * 2 plans.
-  CheckPlansProduce(8, query, storage, &dba, [&](const auto &results) {
-    // We expect to produce a single row: (v1), (v2), null, (v1), (v2)
-    AssertRows(results, {{TypedValue(v1), TypedValue(v2), TypedValue(),
-                          TypedValue(v1), TypedValue(v2)}});
-  });
+  query::DbAccessor execution_dba(&dba);
+  CheckPlansProduce(8, query, storage, &execution_dba,
+                    [&](const auto &results) {
+                      // We expect to produce a single row: (v1), (v2), null, (v1), (v2)
+                      AssertRows(results,
+                                 {{TypedValue(v1), TypedValue(v2), TypedValue(),
+                                   TypedValue(v1), TypedValue(v2)}},
+                                 execution_dba);
+                    });
 }
 
 TEST(TestVariableStartPlanner, MatchWithMatchReturn) {
@@ -209,10 +231,13 @@ TEST(TestVariableStartPlanner, MatchWithMatchReturn) {
       RETURN("n", "m", "l")));
   // We can start from 2 nodes in each match. Since WITH separates query parts,
   // we expect to get 2 plans for each, which totals 2 * 2.
-  CheckPlansProduce(4, query, storage, &dba, [&](const auto &results) {
-    // We expect to produce a single row: (v1), (v1), (v2)
-    AssertRows(results, {{TypedValue(v1), TypedValue(v1), TypedValue(v2)}});
-  });
+  query::DbAccessor execution_dba(&dba);
+  CheckPlansProduce(
+      4, query, storage, &execution_dba, [&](const auto &results) {
+        // We expect to produce a single row: (v1), (v1), (v2)
+        AssertRows(results, {{TypedValue(v1), TypedValue(v1), TypedValue(v2)}},
+                   execution_dba);
+      });
 }
 
 TEST(TestVariableStartPlanner, MatchVariableExpand) {
@@ -236,9 +261,12 @@ TEST(TestVariableStartPlanner, MatchVariableExpand) {
   // [r1, r2]
   TypedValue r1_r2_list(
       std::vector<TypedValue>{TypedValue(r1), TypedValue(r2)});
-  CheckPlansProduce(2, query, storage, &dba, [&](const auto &results) {
-    AssertRows(results, {{r1_list}, {r2_list}, {r1_r2_list}});
-  });
+  query::DbAccessor execution_dba(&dba);
+  CheckPlansProduce(2, query, storage, &execution_dba,
+                    [&](const auto &results) {
+                      AssertRows(results, {{r1_list}, {r2_list}, {r1_r2_list}},
+                                 execution_dba);
+                    });
 }
 
 TEST(TestVariableStartPlanner, MatchVariableExpandReferenceNode) {
@@ -266,9 +294,11 @@ TEST(TestVariableStartPlanner, MatchVariableExpandReferenceNode) {
   TypedValue r1_list(std::vector<TypedValue>{TypedValue(r1)});
   // [r2] (v2 -[*..2]-> v3)
   TypedValue r2_list(std::vector<TypedValue>{TypedValue(r2)});
-  CheckPlansProduce(2, query, storage, &dba, [&](const auto &results) {
-    AssertRows(results, {{r1_list}, {r2_list}});
-  });
+  query::DbAccessor execution_dba(&dba);
+  CheckPlansProduce(
+      2, query, storage, &execution_dba, [&](const auto &results) {
+        AssertRows(results, {{r1_list}, {r2_list}}, execution_dba);
+      });
 }
 
 TEST(TestVariableStartPlanner, MatchVariableExpandBoth) {
@@ -295,9 +325,11 @@ TEST(TestVariableStartPlanner, MatchVariableExpandBoth) {
   // [r1, r2]
   TypedValue r1_r2_list(
       std::vector<TypedValue>{TypedValue(r1), TypedValue(r2)});
-  CheckPlansProduce(2, query, storage, &dba, [&](const auto &results) {
-    AssertRows(results, {{r1_list}, {r1_r2_list}});
-  });
+  query::DbAccessor execution_dba(&dba);
+  CheckPlansProduce(
+      2, query, storage, &execution_dba, [&](const auto &results) {
+        AssertRows(results, {{r1_list}, {r1_r2_list}}, execution_dba);
+      });
 }
 
 TEST(TestVariableStartPlanner, MatchBfs) {
@@ -327,9 +359,11 @@ TEST(TestVariableStartPlanner, MatchBfs) {
       SINGLE_QUERY(MATCH(PATTERN(NODE("n"), bfs, NODE("m"))), RETURN("r")));
   // We expect to get a single column with the following rows:
   TypedValue r1_list(std::vector<TypedValue>{TypedValue(r1)});  // [r1]
-  CheckPlansProduce(2, query, storage, &dba, [&](const auto &results) {
-    AssertRows(results, {{r1_list}});
-  });
+  query::DbAccessor execution_dba(&dba);
+  CheckPlansProduce(2, query, storage, &execution_dba,
+                    [&](const auto &results) {
+                      AssertRows(results, {{r1_list}}, execution_dba);
+                    });
 }
 
 }  // namespace