Cleanup query/context.hpp

Summary:
Rename Context to ExecutionContext and make it struct
Move ParsingContext to cypher_main_visitor.hpp

Reviewers: mtomic, llugovic

Reviewed By: llugovic

Subscribers: pullbot

Differential Revision: https://phabricator.memgraph.io/D1810
This commit is contained in:
Teon Banek 2019-01-16 11:30:17 +01:00
parent aba360968c
commit d7422a16d2
22 changed files with 407 additions and 408 deletions

View File

@ -15,16 +15,16 @@ ProduceRpcServer::OngoingProduce::OngoingProduce(
const query::Parameters &parameters, const query::Parameters &parameters,
std::vector<query::Symbol> pull_symbols) std::vector<query::Symbol> pull_symbols)
: dba_(db->Access(tx_id)), : dba_(db->Access(tx_id)),
context_(*dba_), context_{dba_.get()},
pull_symbols_(std::move(pull_symbols)), pull_symbols_(std::move(pull_symbols)),
frame_(plan_pack.symbol_table.max_position()), frame_(plan_pack.symbol_table.max_position()),
cursor_(plan_pack.plan->MakeCursor(*dba_)) { cursor_(plan_pack.plan->MakeCursor(*dba_)) {
context_.symbol_table_ = plan_pack.symbol_table; context_.symbol_table = plan_pack.symbol_table;
context_.evaluation_context_.timestamp = timestamp; context_.evaluation_context.timestamp = timestamp;
context_.evaluation_context_.parameters = parameters; context_.evaluation_context.parameters = parameters;
context_.evaluation_context_.properties = context_.evaluation_context.properties =
query::NamesToProperties(plan_pack.storage.properties_, dba_.get()); query::NamesToProperties(plan_pack.storage.properties_, dba_.get());
context_.evaluation_context_.labels = context_.evaluation_context.labels =
query::NamesToLabels(plan_pack.storage.labels_, dba_.get()); query::NamesToLabels(plan_pack.storage.labels_, dba_.get());
} }

View File

@ -60,7 +60,7 @@ class ProduceRpcServer {
private: private:
std::unique_ptr<database::GraphDbAccessor> dba_; std::unique_ptr<database::GraphDbAccessor> dba_;
query::Context context_; query::ExecutionContext context_;
std::vector<query::Symbol> pull_symbols_; std::vector<query::Symbol> pull_symbols_;
query::Frame frame_; query::Frame frame_;
PullState cursor_state_{PullState::CURSOR_IN_PROGRESS}; PullState cursor_state_{PullState::CURSOR_IN_PROGRESS};

View File

@ -38,29 +38,13 @@ inline std::vector<storage::Label> NamesToLabels(
return labels; return labels;
} }
class Context { struct ExecutionContext {
public: database::GraphDbAccessor *db_accessor{nullptr};
Context(const Context &) = delete; SymbolTable symbol_table;
Context &operator=(const Context &) = delete; EvaluationContext evaluation_context;
Context(Context &&) = default; bool is_profile_query{false};
Context &operator=(Context &&) = default; plan::ProfilingStats stats;
plan::ProfilingStats *stats_root{nullptr};
explicit Context(database::GraphDbAccessor &db_accessor)
: db_accessor_(db_accessor) {}
database::GraphDbAccessor &db_accessor_;
SymbolTable symbol_table_;
EvaluationContext evaluation_context_;
bool is_profile_query_{false};
plan::ProfilingStats stats_;
plan::ProfilingStats *stats_root_{nullptr};
};
// TODO: Move this to somewhere in query/frontend. Currently, frontend includes
// this and therefore implicitly includes the whole database because of the
// includes at the top of this file.
struct ParsingContext {
bool is_query_cached = false;
}; };
} // namespace query } // namespace query

View File

@ -264,7 +264,6 @@ cpp<#
expression_->Clone(storage)); \ expression_->Clone(storage)); \
} }
class Context;
class Tree; class Tree;
// It would be better to call this AstTree, but we already have a class Tree, // It would be better to call this AstTree, but we already have a class Tree,

View File

@ -4,10 +4,9 @@
#include <unordered_set> #include <unordered_set>
#include <utility> #include <utility>
#include "antlr4-runtime.h" #include <antlr4-runtime.h>
#include "glog/logging.h" #include <glog/logging.h>
#include "query/context.hpp"
#include "query/frontend/ast/ast.hpp" #include "query/frontend/ast/ast.hpp"
#include "query/frontend/opencypher/generated/MemgraphCypherBaseVisitor.h" #include "query/frontend/opencypher/generated/MemgraphCypherBaseVisitor.h"
#include "utils/exceptions.hpp" #include "utils/exceptions.hpp"
@ -17,6 +16,10 @@ namespace frontend {
using antlropencypher::MemgraphCypher; using antlropencypher::MemgraphCypher;
struct ParsingContext {
bool is_query_cached = false;
};
class CypherMainVisitor : public antlropencypher::MemgraphCypherBaseVisitor { class CypherMainVisitor : public antlropencypher::MemgraphCypherBaseVisitor {
public: public:
explicit CypherMainVisitor(ParsingContext context, AstStorage *storage) explicit CypherMainVisitor(ParsingContext context, AstStorage *storage)

View File

@ -749,15 +749,16 @@ Interpreter::Results Interpreter::operator()(
relative_time_symbol.name(), absolute_time_symbol.name()}; relative_time_symbol.name(), absolute_time_symbol.name()};
auto output_plan = std::make_unique<plan::OutputTable>( auto output_plan = std::make_unique<plan::OutputTable>(
output_symbols, [cypher_query_plan](Frame *frame, Context *context) { output_symbols,
[cypher_query_plan](Frame *frame, ExecutionContext *context) {
auto cursor = auto cursor =
cypher_query_plan->plan().MakeCursor(context->db_accessor_); cypher_query_plan->plan().MakeCursor(*context->db_accessor);
// Pull everything to profile the execution // Pull everything to profile the execution
utils::Timer timer; utils::Timer timer;
while (cursor->Pull(*frame, *context)) continue; while (cursor->Pull(*frame, *context)) continue;
return FormatProfilingStats(context->stats_, timer.Elapsed()); return FormatProfilingStats(context->stats, timer.Elapsed());
}); });
plan = std::make_shared<CachedPlan>(std::make_unique<SingleNodeLogicalPlan>( plan = std::make_shared<CachedPlan>(std::make_unique<SingleNodeLogicalPlan>(
@ -810,7 +811,7 @@ Interpreter::Results Interpreter::operator()(
plan = std::make_shared<CachedPlan>(std::make_unique<SingleNodeLogicalPlan>( plan = std::make_shared<CachedPlan>(std::make_unique<SingleNodeLogicalPlan>(
std::make_unique<plan::OutputTable>( std::make_unique<plan::OutputTable>(
output_symbols, output_symbols,
[fn = callback.fn](Frame *, Context *) { return fn(); }), [fn = callback.fn](Frame *, ExecutionContext *) { return fn(); }),
0.0, AstStorage{}, symbol_table)); 0.0, AstStorage{}, symbol_table));
auto planning_time = planning_timer.Elapsed(); auto planning_time = planning_timer.Elapsed();
@ -842,7 +843,7 @@ std::shared_ptr<Interpreter::CachedPlan> Interpreter::CypherQueryToPlan(
Interpreter::ParsedQuery Interpreter::ParseQuery( Interpreter::ParsedQuery Interpreter::ParseQuery(
const std::string &stripped_query, const std::string &original_query, const std::string &stripped_query, const std::string &original_query,
const ParsingContext &context, AstStorage *ast_storage, const frontend::ParsingContext &context, AstStorage *ast_storage,
database::GraphDbAccessor *db_accessor) { database::GraphDbAccessor *db_accessor) {
if (!context.is_query_cached) { if (!context.is_query_cached) {
// Parse original query into antlr4 AST. // Parse original query into antlr4 AST.
@ -915,7 +916,7 @@ Interpreter::StripAndParseQuery(
parameters->Add(param_pair.first, param_it->second); parameters->Add(param_pair.first, param_it->second);
} }
ParsingContext parsing_context; frontend::ParsingContext parsing_context;
parsing_context.is_query_cached = true; parsing_context.is_query_cached = true;
auto parsed_query = ParseQuery(stripped_query.query(), query_string, auto parsed_query = ParseQuery(stripped_query.query(), query_string,

View File

@ -7,6 +7,7 @@
#include "database/graph_db_accessor.hpp" #include "database/graph_db_accessor.hpp"
#include "query/context.hpp" #include "query/context.hpp"
#include "query/frontend/ast/ast.hpp" #include "query/frontend/ast/ast.hpp"
#include "query/frontend/ast/cypher_main_visitor.hpp"
#include "query/frontend/stripped.hpp" #include "query/frontend/stripped.hpp"
#include "query/interpret/frame.hpp" #include "query/interpret/frame.hpp"
#include "query/plan/operator.hpp" #include "query/plan/operator.hpp"
@ -90,7 +91,7 @@ class Interpreter {
std::map<std::string, TypedValue> summary, std::map<std::string, TypedValue> summary,
std::vector<AuthQuery::Privilege> privileges, std::vector<AuthQuery::Privilege> privileges,
bool is_profile_query = false) bool is_profile_query = false)
: ctx_(*db_accessor), : ctx_{db_accessor},
plan_(plan), plan_(plan),
cursor_(plan_->plan().MakeCursor(*db_accessor)), cursor_(plan_->plan().MakeCursor(*db_accessor)),
frame_(plan_->symbol_table().max_position()), frame_(plan_->symbol_table().max_position()),
@ -98,16 +99,16 @@ class Interpreter {
header_(header), header_(header),
summary_(summary), summary_(summary),
privileges_(std::move(privileges)) { privileges_(std::move(privileges)) {
ctx_.is_profile_query_ = is_profile_query; ctx_.is_profile_query = is_profile_query;
ctx_.symbol_table_ = plan_->symbol_table(); ctx_.symbol_table = plan_->symbol_table();
ctx_.evaluation_context_.timestamp = ctx_.evaluation_context.timestamp =
std::chrono::duration_cast<std::chrono::milliseconds>( std::chrono::duration_cast<std::chrono::milliseconds>(
std::chrono::system_clock::now().time_since_epoch()) std::chrono::system_clock::now().time_since_epoch())
.count(); .count();
ctx_.evaluation_context_.parameters = parameters; ctx_.evaluation_context.parameters = parameters;
ctx_.evaluation_context_.properties = ctx_.evaluation_context.properties =
NamesToProperties(plan_->ast_storage().properties_, db_accessor); NamesToProperties(plan_->ast_storage().properties_, db_accessor);
ctx_.evaluation_context_.labels = ctx_.evaluation_context.labels =
NamesToLabels(plan_->ast_storage().labels_, db_accessor); NamesToLabels(plan_->ast_storage().labels_, db_accessor);
} }
@ -162,10 +163,10 @@ class Interpreter {
return privileges_; return privileges_;
} }
bool IsProfileQuery() const { return ctx_.is_profile_query_; } bool IsProfileQuery() const { return ctx_.is_profile_query; }
private: private:
Context ctx_; ExecutionContext ctx_;
std::shared_ptr<CachedPlan> plan_; std::shared_ptr<CachedPlan> plan_;
std::unique_ptr<query::plan::Cursor> cursor_; std::unique_ptr<query::plan::Cursor> cursor_;
Frame frame_; Frame frame_;
@ -235,7 +236,8 @@ class Interpreter {
// stripped query -> high level tree // stripped query -> high level tree
ParsedQuery ParseQuery(const std::string &stripped_query, ParsedQuery ParseQuery(const std::string &stripped_query,
const std::string &original_query, const std::string &original_query,
const ParsingContext &context, AstStorage *ast_storage, const frontend::ParsingContext &context,
AstStorage *ast_storage,
database::GraphDbAccessor *db_accessor); database::GraphDbAccessor *db_accessor);
}; };

View File

@ -31,7 +31,8 @@ namespace query::plan {
// Create a vertex on this GraphDb and return it. Defined in operator.cpp // Create a vertex on this GraphDb and return it. Defined in operator.cpp
VertexAccessor &CreateLocalVertex(const NodeCreationInfo &node_info, VertexAccessor &CreateLocalVertex(const NodeCreationInfo &node_info,
Frame *frame, const Context &context); Frame *frame,
const ExecutionContext &context);
bool PullRemote::Accept(HierarchicalLogicalOperatorVisitor &visitor) { bool PullRemote::Accept(HierarchicalLogicalOperatorVisitor &visitor) {
auto *distributed_visitor = auto *distributed_visitor =
@ -231,9 +232,9 @@ class RemotePuller {
worker_ids_.erase(std::find(worker_ids_.begin(), worker_ids_.end(), 0)); worker_ids_.erase(std::find(worker_ids_.begin(), worker_ids_.end(), 0));
} }
void Initialize(Context &context) { void Initialize(ExecutionContext &context) {
if (!remote_pulls_initialized_) { if (!remote_pulls_initialized_) {
VLOG(10) << "[RemotePuller] [" << context.db_accessor_.transaction_id() VLOG(10) << "[RemotePuller] [" << context.db_accessor->transaction_id()
<< "] [" << plan_id_ << "] [" << command_id_ << "] initialized"; << "] [" << plan_id_ << "] [" << command_id_ << "] initialized";
for (auto &worker_id : worker_ids_) { for (auto &worker_id : worker_ids_) {
UpdatePullForWorker(worker_id, context); UpdatePullForWorker(worker_id, context);
@ -242,12 +243,12 @@ class RemotePuller {
} }
} }
void Update(Context &context) { void Update(ExecutionContext &context) {
// If we don't have results for a worker, check if his remote pull // If we don't have results for a worker, check if his remote pull
// finished and save results locally. // finished and save results locally.
auto move_frames = [this, &context](int worker_id, auto remote_results) { auto move_frames = [this, &context](int worker_id, auto remote_results) {
VLOG(10) << "[RemotePuller] [" << context.db_accessor_.transaction_id() VLOG(10) << "[RemotePuller] [" << context.db_accessor->transaction_id()
<< "] [" << plan_id_ << "] [" << command_id_ << "] [" << plan_id_ << "] [" << command_id_
<< "] received results from " << worker_id; << "] received results from " << worker_id;
remote_results_[worker_id] = std::move(remote_results.frames); remote_results_[worker_id] = std::move(remote_results.frames);
@ -271,7 +272,7 @@ class RemotePuller {
switch (remote_results.pull_state) { switch (remote_results.pull_state) {
case distributed::PullState::CURSOR_EXHAUSTED: case distributed::PullState::CURSOR_EXHAUSTED:
VLOG(10) << "[RemotePuller] [" VLOG(10) << "[RemotePuller] ["
<< context.db_accessor_.transaction_id() << "] [" << plan_id_ << context.db_accessor->transaction_id() << "] [" << plan_id_
<< "] [" << command_id_ << "] cursor exhausted from " << "] [" << command_id_ << "] cursor exhausted from "
<< worker_id; << worker_id;
move_frames(worker_id, remote_results); move_frames(worker_id, remote_results);
@ -279,7 +280,7 @@ class RemotePuller {
break; break;
case distributed::PullState::CURSOR_IN_PROGRESS: case distributed::PullState::CURSOR_IN_PROGRESS:
VLOG(10) << "[RemotePuller] [" VLOG(10) << "[RemotePuller] ["
<< context.db_accessor_.transaction_id() << "] [" << plan_id_ << context.db_accessor->transaction_id() << "] [" << plan_id_
<< "] [" << command_id_ << "] cursor in progress from " << "] [" << command_id_ << "] cursor in progress from "
<< worker_id; << worker_id;
move_frames(worker_id, remote_results); move_frames(worker_id, remote_results);
@ -380,10 +381,10 @@ class RemotePuller {
std::vector<int> worker_ids_; std::vector<int> worker_ids_;
bool remote_pulls_initialized_ = false; bool remote_pulls_initialized_ = false;
void UpdatePullForWorker(int worker_id, Context &context) { void UpdatePullForWorker(int worker_id, const ExecutionContext &context) {
remote_pulls_[worker_id] = remote_pulls_[worker_id] =
pull_clients_->Pull(&db_, worker_id, plan_id_, command_id_, pull_clients_->Pull(&db_, worker_id, plan_id_, command_id_,
context.evaluation_context_, symbols_, false); context.evaluation_context, symbols_, false);
} }
}; };
@ -398,13 +399,13 @@ class PullRemoteCursor : public Cursor {
&dynamic_cast<database::Master *>(&db.db())->pull_clients(), db, &dynamic_cast<database::Master *>(&db.db())->pull_clients(), db,
self.symbols_, self.plan_id_, command_id_) {} self.symbols_, self.plan_id_, command_id_) {}
bool Pull(Frame &frame, Context &context) override { bool Pull(Frame &frame, ExecutionContext &context) override {
if (context.db_accessor_.should_abort()) throw HintedAbortError(); if (context.db_accessor->should_abort()) throw HintedAbortError();
remote_puller_.Initialize(context); remote_puller_.Initialize(context);
bool have_remote_results = false; bool have_remote_results = false;
while (!have_remote_results && remote_puller_.WorkerCount() > 0) { while (!have_remote_results && remote_puller_.WorkerCount() > 0) {
if (context.db_accessor_.should_abort()) throw HintedAbortError(); if (context.db_accessor->should_abort()) throw HintedAbortError();
remote_puller_.Update(context); remote_puller_.Update(context);
// Get locally stored results from workers in a round-robin fasion. // Get locally stored results from workers in a round-robin fasion.
@ -431,14 +432,14 @@ class PullRemoteCursor : public Cursor {
// local results. // local results.
if (input_cursor_ && input_cursor_->Pull(frame, context)) { if (input_cursor_ && input_cursor_->Pull(frame, context)) {
VLOG(10) << "[PullRemoteCursor] [" VLOG(10) << "[PullRemoteCursor] ["
<< context.db_accessor_.transaction_id() << "] [" << context.db_accessor->transaction_id() << "] ["
<< self_.plan_id_ << "] [" << command_id_ << self_.plan_id_ << "] [" << command_id_
<< "] producing local results "; << "] producing local results ";
return true; return true;
} }
VLOG(10) << "[PullRemoteCursor] [" VLOG(10) << "[PullRemoteCursor] ["
<< context.db_accessor_.transaction_id() << "] [" << context.db_accessor->transaction_id() << "] ["
<< self_.plan_id_ << "] [" << command_id_ << self_.plan_id_ << "] [" << command_id_
<< "] no results available, sleeping "; << "] no results available, sleeping ";
// If there aren't any local/remote results available, sleep. // If there aren't any local/remote results available, sleep.
@ -451,7 +452,7 @@ class PullRemoteCursor : public Cursor {
if (!have_remote_results) { if (!have_remote_results) {
if (input_cursor_ && input_cursor_->Pull(frame, context)) { if (input_cursor_ && input_cursor_->Pull(frame, context)) {
VLOG(10) << "[PullRemoteCursor] [" VLOG(10) << "[PullRemoteCursor] ["
<< context.db_accessor_.transaction_id() << "] [" << context.db_accessor->transaction_id() << "] ["
<< self_.plan_id_ << "] [" << command_id_ << self_.plan_id_ << "] [" << command_id_
<< "] producing local results "; << "] producing local results ";
return true; return true;
@ -462,7 +463,7 @@ class PullRemoteCursor : public Cursor {
{ {
int worker_id = remote_puller_.GetWorkerId(last_pulled_worker_id_index_); int worker_id = remote_puller_.GetWorkerId(last_pulled_worker_id_index_);
VLOG(10) << "[PullRemoteCursor] [" VLOG(10) << "[PullRemoteCursor] ["
<< context.db_accessor_.transaction_id() << "] [" << context.db_accessor->transaction_id() << "] ["
<< self_.plan_id_ << "] [" << command_id_ << self_.plan_id_ << "] [" << command_id_
<< "] producing results from worker " << worker_id; << "] producing results from worker " << worker_id;
auto result = remote_puller_.PopResultFromWorker(worker_id); auto result = remote_puller_.PopResultFromWorker(worker_id);
@ -513,7 +514,7 @@ class SynchronizeCursor : public Cursor {
// TODO: Pass in a Master GraphDb. // TODO: Pass in a Master GraphDb.
dynamic_cast<database::Master *>(&db.db())->WorkerId()) {} dynamic_cast<database::Master *>(&db.db())->WorkerId()) {}
bool Pull(Frame &frame, Context &context) override { bool Pull(Frame &frame, ExecutionContext &context) override {
if (!initial_pull_done_) { if (!initial_pull_done_) {
InitialPull(frame, context); InitialPull(frame, context);
initial_pull_done_ = true; initial_pull_done_ = true;
@ -521,7 +522,7 @@ class SynchronizeCursor : public Cursor {
// Yield local stuff while available. // Yield local stuff while available.
if (!local_frames_.empty()) { if (!local_frames_.empty()) {
VLOG(10) << "[SynchronizeCursor] [" VLOG(10) << "[SynchronizeCursor] ["
<< context.db_accessor_.transaction_id() << context.db_accessor->transaction_id()
<< "] producing local results"; << "] producing local results";
auto &result = local_frames_.back(); auto &result = local_frames_.back();
for (size_t i = 0; i < frame.elems().size(); ++i) { for (size_t i = 0; i < frame.elems().size(); ++i) {
@ -537,7 +538,7 @@ class SynchronizeCursor : public Cursor {
// We're out of local stuff, yield from pull_remote if available. // We're out of local stuff, yield from pull_remote if available.
if (pull_remote_cursor_ && pull_remote_cursor_->Pull(frame, context)) { if (pull_remote_cursor_ && pull_remote_cursor_->Pull(frame, context)) {
VLOG(10) << "[SynchronizeCursor] [" VLOG(10) << "[SynchronizeCursor] ["
<< context.db_accessor_.transaction_id() << context.db_accessor->transaction_id()
<< "] producing remote results"; << "] producing remote results";
return true; return true;
} }
@ -569,8 +570,8 @@ class SynchronizeCursor : public Cursor {
tx::CommandId command_id_; tx::CommandId command_id_;
int master_id_; int master_id_;
void InitialPull(Frame &frame, Context &context) { void InitialPull(Frame &frame, ExecutionContext &context) {
VLOG(10) << "[SynchronizeCursor] [" << context.db_accessor_.transaction_id() VLOG(10) << "[SynchronizeCursor] [" << context.db_accessor->transaction_id()
<< "] initial pull"; << "] initial pull";
// Tell all workers to accumulate, only if there is a remote pull. // Tell all workers to accumulate, only if there is a remote pull.
@ -579,8 +580,8 @@ class SynchronizeCursor : public Cursor {
for (auto worker_id : pull_clients_->GetWorkerIds()) { for (auto worker_id : pull_clients_->GetWorkerIds()) {
if (worker_id == master_id_) continue; if (worker_id == master_id_) continue;
worker_accumulations.emplace_back(pull_clients_->Pull( worker_accumulations.emplace_back(pull_clients_->Pull(
&context.db_accessor_, worker_id, self_.pull_remote_->plan_id_, context.db_accessor, worker_id, self_.pull_remote_->plan_id_,
command_id_, context.evaluation_context_, command_id_, context.evaluation_context,
self_.pull_remote_->symbols_, true, 0)); self_.pull_remote_->symbols_, true, 0));
} }
} }
@ -627,11 +628,11 @@ class SynchronizeCursor : public Cursor {
} }
if (self_.advance_command_) { if (self_.advance_command_) {
context.db_accessor_.AdvanceCommand(); context.db_accessor->AdvanceCommand();
} }
// Make all the workers apply their deltas. // Make all the workers apply their deltas.
auto tx_id = context.db_accessor_.transaction_id(); auto tx_id = context.db_accessor->transaction_id();
auto apply_futures = updates_clients_->UpdateApplyAll(master_id_, tx_id); auto apply_futures = updates_clients_->UpdateApplyAll(master_id_, tx_id);
updates_server_->Apply(tx_id); updates_server_->Apply(tx_id);
for (auto &future : apply_futures) { for (auto &future : apply_futures) {
@ -672,11 +673,11 @@ class PullRemoteOrderByCursor : public Cursor {
&dynamic_cast<database::Master *>(&db.db())->pull_clients(), db, &dynamic_cast<database::Master *>(&db.db())->pull_clients(), db,
self.symbols_, self.plan_id_, command_id_) {} self.symbols_, self.plan_id_, command_id_) {}
bool Pull(Frame &frame, Context &context) override { bool Pull(Frame &frame, ExecutionContext &context) override {
if (context.db_accessor_.should_abort()) throw HintedAbortError(); if (context.db_accessor->should_abort()) throw HintedAbortError();
ExpressionEvaluator evaluator(&frame, context.symbol_table_, ExpressionEvaluator evaluator(&frame, context.symbol_table,
context.evaluation_context_, context.evaluation_context,
&context.db_accessor_, GraphView::OLD); context.db_accessor, GraphView::OLD);
auto evaluate_result = [this, &evaluator]() { auto evaluate_result = [this, &evaluator]() {
std::vector<TypedValue> order_by; std::vector<TypedValue> order_by;
@ -696,7 +697,7 @@ class PullRemoteOrderByCursor : public Cursor {
if (!merge_initialized_) { if (!merge_initialized_) {
VLOG(10) << "[PullRemoteOrderBy] [" VLOG(10) << "[PullRemoteOrderBy] ["
<< context.db_accessor_.transaction_id() << "] [" << context.db_accessor->transaction_id() << "] ["
<< self_.plan_id_ << "] [" << command_id_ << "] initialize"; << self_.plan_id_ << "] [" << command_id_ << "] initialize";
remote_puller_.Initialize(context); remote_puller_.Initialize(context);
missing_results_from_ = remote_puller_.Workers(); missing_results_from_ = remote_puller_.Workers();
@ -719,7 +720,7 @@ class PullRemoteOrderByCursor : public Cursor {
} }
while (!missing_results_from_.empty()) { while (!missing_results_from_.empty()) {
if (context.db_accessor_.should_abort()) throw HintedAbortError(); if (context.db_accessor->should_abort()) throw HintedAbortError();
remote_puller_.Update(context); remote_puller_.Update(context);
bool has_all_result = true; bool has_all_result = true;
@ -733,7 +734,7 @@ class PullRemoteOrderByCursor : public Cursor {
if (!has_all_result) { if (!has_all_result) {
VLOG(10) << "[PullRemoteOrderByCursor] [" VLOG(10) << "[PullRemoteOrderByCursor] ["
<< context.db_accessor_.transaction_id() << "] [" << context.db_accessor->transaction_id() << "] ["
<< self_.plan_id_ << "] [" << command_id_ << self_.plan_id_ << "] [" << command_id_
<< "] missing results, sleep"; << "] missing results, sleep";
// If we don't have results from all workers, sleep before continuing. // If we don't have results from all workers, sleep before continuing.
@ -766,14 +767,14 @@ class PullRemoteOrderByCursor : public Cursor {
if (result_it->worker_id) { if (result_it->worker_id) {
VLOG(10) << "[PullRemoteOrderByCursor] [" VLOG(10) << "[PullRemoteOrderByCursor] ["
<< context.db_accessor_.transaction_id() << "] [" << context.db_accessor->transaction_id() << "] ["
<< self_.plan_id_ << "] [" << command_id_ << self_.plan_id_ << "] [" << command_id_
<< "] producing results from worker " << "] producing results from worker "
<< result_it->worker_id.value(); << result_it->worker_id.value();
missing_results_from_.push_back(result_it->worker_id.value()); missing_results_from_.push_back(result_it->worker_id.value());
} else { } else {
VLOG(10) << "[PullRemoteOrderByCursor] [" VLOG(10) << "[PullRemoteOrderByCursor] ["
<< context.db_accessor_.transaction_id() << "] [" << context.db_accessor->transaction_id() << "] ["
<< self_.plan_id_ << "] [" << command_id_ << self_.plan_id_ << "] [" << command_id_
<< "] producing local results"; << "] producing local results";
missing_master_result_ = true; missing_master_result_ = true;
@ -820,7 +821,7 @@ class DistributedExpandCursor : public query::plan::Cursor {
database::GraphDbAccessor *db) database::GraphDbAccessor *db)
: input_cursor_(self->input()->MakeCursor(*db)), self_(self) {} : input_cursor_(self->input()->MakeCursor(*db)), self_(self) {}
bool Pull(Frame &frame, Context &context) override { bool Pull(Frame &frame, ExecutionContext &context) override {
// A helper function for expanding a node from an edge. // A helper function for expanding a node from an edge.
auto pull_node = [this, &frame](const EdgeAccessor &new_edge, auto pull_node = [this, &frame](const EdgeAccessor &new_edge,
EdgeAtom::Direction direction) { EdgeAtom::Direction direction) {
@ -863,7 +864,7 @@ class DistributedExpandCursor : public query::plan::Cursor {
}; };
while (true) { while (true) {
if (context.db_accessor_.should_abort()) throw HintedAbortError(); if (context.db_accessor->should_abort()) throw HintedAbortError();
// Try to get any remote edges we may have available first. If we yielded // Try to get any remote edges we may have available first. If we yielded
// all of the local edges first, we may accumulate large amounts of future // all of the local edges first, we may accumulate large amounts of future
// edges. // edges.
@ -966,7 +967,7 @@ class DistributedExpandCursor : public query::plan::Cursor {
last_frame_.clear(); last_frame_.clear();
} }
bool InitEdges(Frame &frame, Context &context) { bool InitEdges(Frame &frame, ExecutionContext &context) {
// Input Vertex could be null if it is created by a failed optional match. // Input Vertex could be null if it is created by a failed optional match.
// In those cases we skip that input pull and continue with the next. // In those cases we skip that input pull and continue with the next.
while (true) { while (true) {
@ -1079,20 +1080,20 @@ class DistributedExpandBfsCursor : public query::plan::Cursor {
pull_pos_ = subcursor_ids_.end(); pull_pos_ = subcursor_ids_.end();
} }
bool Pull(Frame &frame, Context &context) override { bool Pull(Frame &frame, ExecutionContext &context) override {
if (!subcursors_initialized_) { if (!subcursors_initialized_) {
InitSubcursors(&context.db_accessor_, context.symbol_table_, InitSubcursors(context.db_accessor, context.symbol_table,
context.evaluation_context_); context.evaluation_context);
subcursors_initialized_ = true; subcursors_initialized_ = true;
} }
// Evaluator for the filtering condition and expansion depth. // Evaluator for the filtering condition and expansion depth.
ExpressionEvaluator evaluator( ExpressionEvaluator evaluator(
&frame, context.symbol_table_, context.evaluation_context_, &frame, context.symbol_table, context.evaluation_context,
&context.db_accessor_, self_.common_.graph_view); context.db_accessor, self_.common_.graph_view);
while (true) { while (true) {
if (context.db_accessor_.should_abort()) throw HintedAbortError(); if (context.db_accessor->should_abort()) throw HintedAbortError();
TypedValue last_vertex; TypedValue last_vertex;
if (!skip_rest_) { if (!skip_rest_) {
@ -1254,8 +1255,8 @@ int RandomWorkerId(const database::DistributedGraphDb &db) {
// Creates a vertex on the GraphDb with the given worker_id. Can be this worker. // Creates a vertex on the GraphDb with the given worker_id. Can be this worker.
VertexAccessor &CreateVertexOnWorker(int worker_id, VertexAccessor &CreateVertexOnWorker(int worker_id,
const NodeCreationInfo &node_info, const NodeCreationInfo &node_info,
Frame &frame, Context &context) { Frame &frame, ExecutionContext &context) {
auto &dba = context.db_accessor_; auto &dba = *context.db_accessor;
auto *distributed_db = auto *distributed_db =
dynamic_cast<database::DistributedGraphDb *>(&dba.db()); dynamic_cast<database::DistributedGraphDb *>(&dba.db());
@ -1268,9 +1269,9 @@ VertexAccessor &CreateVertexOnWorker(int worker_id,
// Evaluator should use the latest accessors, as modified in this query, when // Evaluator should use the latest accessors, as modified in this query, when
// setting properties on new nodes. // setting properties on new nodes.
ExpressionEvaluator evaluator(&frame, context.symbol_table_, ExpressionEvaluator evaluator(&frame, context.symbol_table,
context.evaluation_context_, context.evaluation_context, context.db_accessor,
&context.db_accessor_, GraphView::NEW); GraphView::NEW);
for (auto &kv : node_info.properties) { for (auto &kv : node_info.properties) {
auto value = kv.second->Accept(evaluator); auto value = kv.second->Accept(evaluator);
if (!value.IsPropertyValue()) { if (!value.IsPropertyValue()) {
@ -1299,7 +1300,7 @@ class DistributedCreateNodeCursor : public query::plan::Cursor {
CHECK(db_); CHECK(db_);
} }
bool Pull(Frame &frame, Context &context) override { bool Pull(Frame &frame, ExecutionContext &context) override {
if (input_cursor_->Pull(frame, context)) { if (input_cursor_->Pull(frame, context)) {
if (on_random_worker_) { if (on_random_worker_) {
CreateVertexOnWorker(RandomWorkerId(*db_), node_info_, frame, context); CreateVertexOnWorker(RandomWorkerId(*db_), node_info_, frame, context);
@ -1333,7 +1334,7 @@ class DistributedCreateExpandCursor : public query::plan::Cursor {
CHECK(db_); CHECK(db_);
} }
bool Pull(Frame &frame, Context &context) override { bool Pull(Frame &frame, ExecutionContext &context) override {
if (!input_cursor_->Pull(frame, context)) return false; if (!input_cursor_->Pull(frame, context)) return false;
// get the origin vertex // get the origin vertex
@ -1343,9 +1344,9 @@ class DistributedCreateExpandCursor : public query::plan::Cursor {
// Similarly to CreateNode, newly created edges and nodes should use the // Similarly to CreateNode, newly created edges and nodes should use the
// latest accesors. // latest accesors.
ExpressionEvaluator evaluator(&frame, context.symbol_table_, ExpressionEvaluator evaluator(&frame, context.symbol_table,
context.evaluation_context_, context.evaluation_context,
&context.db_accessor_, GraphView::NEW); context.db_accessor, GraphView::NEW);
// E.g. we pickup new properties: `CREATE (n {p: 42}) -[:r {ep: n.p}]-> ()` // E.g. we pickup new properties: `CREATE (n {p: 42}) -[:r {ep: n.p}]-> ()`
v1.SwitchNew(); v1.SwitchNew();
@ -1353,21 +1354,21 @@ class DistributedCreateExpandCursor : public query::plan::Cursor {
auto &v2 = OtherVertex(v1.GlobalAddress().worker_id(), frame, context); auto &v2 = OtherVertex(v1.GlobalAddress().worker_id(), frame, context);
v2.SwitchNew(); v2.SwitchNew();
auto *dba = &context.db_accessor_; auto *dba = context.db_accessor;
// create an edge between the two nodes // create an edge between the two nodes
switch (self_->edge_info_.direction) { switch (self_->edge_info_.direction) {
case EdgeAtom::Direction::IN: case EdgeAtom::Direction::IN:
CreateEdge(&v2, &v1, &frame, context.symbol_table_, &evaluator, dba); CreateEdge(&v2, &v1, &frame, context.symbol_table, &evaluator, dba);
break; break;
case EdgeAtom::Direction::OUT: case EdgeAtom::Direction::OUT:
CreateEdge(&v1, &v2, &frame, context.symbol_table_, &evaluator, dba); CreateEdge(&v1, &v2, &frame, context.symbol_table, &evaluator, dba);
break; break;
case EdgeAtom::Direction::BOTH: case EdgeAtom::Direction::BOTH:
// in the case of an undirected CreateExpand we choose an arbitrary // in the case of an undirected CreateExpand we choose an arbitrary
// direction. this is used in the MERGE clause // direction. this is used in the MERGE clause
// it is not allowed in the CREATE clause, and the semantic // it is not allowed in the CREATE clause, and the semantic
// checker needs to ensure it doesn't reach this point // checker needs to ensure it doesn't reach this point
CreateEdge(&v1, &v2, &frame, context.symbol_table_, &evaluator, dba); CreateEdge(&v1, &v2, &frame, context.symbol_table, &evaluator, dba);
} }
return true; return true;
@ -1377,7 +1378,8 @@ class DistributedCreateExpandCursor : public query::plan::Cursor {
void Reset() override { input_cursor_->Reset(); } void Reset() override { input_cursor_->Reset(); }
VertexAccessor &OtherVertex(int worker_id, Frame &frame, Context &context) { VertexAccessor &OtherVertex(int worker_id, Frame &frame,
ExecutionContext &context) {
if (self_->existing_node_) { if (self_->existing_node_) {
const auto &dest_node_symbol = self_->node_info_.symbol; const auto &dest_node_symbol = self_->node_info_.symbol;
TypedValue &dest_node_value = frame[dest_node_symbol]; TypedValue &dest_node_value = frame[dest_node_symbol];

View File

@ -79,7 +79,7 @@ uint64_t ComputeProfilingKey(const T *obj) {
#define SCOPED_PROFILE_OP(name) \ #define SCOPED_PROFILE_OP(name) \
ScopedProfile profile{ComputeProfilingKey(this), name, &context}; ScopedProfile profile{ComputeProfilingKey(this), name, &context};
bool Once::OnceCursor::Pull(Frame &, Context &context) { bool Once::OnceCursor::Pull(Frame &, ExecutionContext &context) {
SCOPED_PROFILE_OP("Once"); SCOPED_PROFILE_OP("Once");
if (!did_pull_) { if (!did_pull_) {
@ -106,15 +106,16 @@ CreateNode::CreateNode(const std::shared_ptr<LogicalOperator> &input,
// Creates a vertex on this GraphDb. Returns a reference to vertex placed on the // Creates a vertex on this GraphDb. Returns a reference to vertex placed on the
// frame. // frame.
VertexAccessor &CreateLocalVertex(const NodeCreationInfo &node_info, VertexAccessor &CreateLocalVertex(const NodeCreationInfo &node_info,
Frame *frame, const Context &context) { Frame *frame,
auto &dba = context.db_accessor_; const ExecutionContext &context) {
auto &dba = *context.db_accessor;
auto new_node = dba.InsertVertex(); auto new_node = dba.InsertVertex();
for (auto label : node_info.labels) new_node.add_label(label); for (auto label : node_info.labels) new_node.add_label(label);
// Evaluator should use the latest accessors, as modified in this query, when // Evaluator should use the latest accessors, as modified in this query, when
// setting properties on new nodes. // setting properties on new nodes.
ExpressionEvaluator evaluator(frame, context.symbol_table_, ExpressionEvaluator evaluator(frame, context.symbol_table,
context.evaluation_context_, context.evaluation_context, context.db_accessor,
&context.db_accessor_, GraphView::NEW); GraphView::NEW);
for (auto &kv : node_info.properties) for (auto &kv : node_info.properties)
PropsSetChecked(&new_node, kv.first, kv.second->Accept(evaluator)); PropsSetChecked(&new_node, kv.first, kv.second->Accept(evaluator));
(*frame)[node_info.symbol] = new_node; (*frame)[node_info.symbol] = new_node;
@ -139,7 +140,8 @@ CreateNode::CreateNodeCursor::CreateNodeCursor(const CreateNode &self,
database::GraphDbAccessor &db) database::GraphDbAccessor &db)
: self_(self), input_cursor_(self.input_->MakeCursor(db)) {} : self_(self), input_cursor_(self.input_->MakeCursor(db)) {}
bool CreateNode::CreateNodeCursor::Pull(Frame &frame, Context &context) { bool CreateNode::CreateNodeCursor::Pull(Frame &frame,
ExecutionContext &context) {
SCOPED_PROFILE_OP("CreateNode"); SCOPED_PROFILE_OP("CreateNode");
if (input_cursor_->Pull(frame, context)) { if (input_cursor_->Pull(frame, context)) {
@ -183,7 +185,8 @@ CreateExpand::CreateExpandCursor::CreateExpandCursor(
const CreateExpand &self, database::GraphDbAccessor &db) const CreateExpand &self, database::GraphDbAccessor &db)
: self_(self), db_(db), input_cursor_(self.input_->MakeCursor(db)) {} : self_(self), db_(db), input_cursor_(self.input_->MakeCursor(db)) {}
bool CreateExpand::CreateExpandCursor::Pull(Frame &frame, Context &context) { bool CreateExpand::CreateExpandCursor::Pull(Frame &frame,
ExecutionContext &context) {
SCOPED_PROFILE_OP("CreateExpand"); SCOPED_PROFILE_OP("CreateExpand");
if (!input_cursor_->Pull(frame, context)) return false; if (!input_cursor_->Pull(frame, context)) return false;
@ -195,9 +198,9 @@ bool CreateExpand::CreateExpandCursor::Pull(Frame &frame, Context &context) {
// Similarly to CreateNode, newly created edges and nodes should use the // Similarly to CreateNode, newly created edges and nodes should use the
// latest accesors. // latest accesors.
ExpressionEvaluator evaluator(&frame, context.symbol_table_, ExpressionEvaluator evaluator(&frame, context.symbol_table,
context.evaluation_context_, context.evaluation_context, context.db_accessor,
&context.db_accessor_, GraphView::NEW); GraphView::NEW);
// E.g. we pickup new properties: `CREATE (n {p: 42}) -[:r {ep: n.p}]-> ()` // E.g. we pickup new properties: `CREATE (n {p: 42}) -[:r {ep: n.p}]-> ()`
v1.SwitchNew(); v1.SwitchNew();
@ -208,17 +211,17 @@ bool CreateExpand::CreateExpandCursor::Pull(Frame &frame, Context &context) {
// create an edge between the two nodes // create an edge between the two nodes
switch (self_.edge_info_.direction) { switch (self_.edge_info_.direction) {
case EdgeAtom::Direction::IN: case EdgeAtom::Direction::IN:
CreateEdge(v2, v1, frame, context.symbol_table_, evaluator); CreateEdge(v2, v1, frame, context.symbol_table, evaluator);
break; break;
case EdgeAtom::Direction::OUT: case EdgeAtom::Direction::OUT:
CreateEdge(v1, v2, frame, context.symbol_table_, evaluator); CreateEdge(v1, v2, frame, context.symbol_table, evaluator);
break; break;
case EdgeAtom::Direction::BOTH: case EdgeAtom::Direction::BOTH:
// in the case of an undirected CreateExpand we choose an arbitrary // in the case of an undirected CreateExpand we choose an arbitrary
// direction. this is used in the MERGE clause // direction. this is used in the MERGE clause
// it is not allowed in the CREATE clause, and the semantic // it is not allowed in the CREATE clause, and the semantic
// checker needs to ensure it doesn't reach this point // checker needs to ensure it doesn't reach this point
CreateEdge(v1, v2, frame, context.symbol_table_, evaluator); CreateEdge(v1, v2, frame, context.symbol_table, evaluator);
} }
return true; return true;
@ -229,7 +232,7 @@ void CreateExpand::CreateExpandCursor::Shutdown() { input_cursor_->Shutdown(); }
void CreateExpand::CreateExpandCursor::Reset() { input_cursor_->Reset(); } void CreateExpand::CreateExpandCursor::Reset() { input_cursor_->Reset(); }
VertexAccessor &CreateExpand::CreateExpandCursor::OtherVertex( VertexAccessor &CreateExpand::CreateExpandCursor::OtherVertex(
Frame &frame, Context &context) { Frame &frame, ExecutionContext &context) {
if (self_.existing_node_) { if (self_.existing_node_) {
TypedValue &dest_node_value = frame[self_.node_info_.symbol]; TypedValue &dest_node_value = frame[self_.node_info_.symbol];
ExpectType(self_.node_info_.symbol, dest_node_value, ExpectType(self_.node_info_.symbol, dest_node_value,
@ -261,7 +264,7 @@ class ScanAllCursor : public Cursor {
get_vertices_(std::move(get_vertices)), get_vertices_(std::move(get_vertices)),
db_(db) {} db_(db) {}
bool Pull(Frame &frame, Context &context) override { bool Pull(Frame &frame, ExecutionContext &context) override {
SCOPED_PROFILE_OP("ScanAll"); SCOPED_PROFILE_OP("ScanAll");
if (db_.should_abort()) throw HintedAbortError(); if (db_.should_abort()) throw HintedAbortError();
@ -296,7 +299,7 @@ class ScanAllCursor : public Cursor {
const std::unique_ptr<Cursor> input_cursor_; const std::unique_ptr<Cursor> input_cursor_;
TVerticesFun get_vertices_; TVerticesFun get_vertices_;
std::experimental::optional<typename std::result_of<TVerticesFun( std::experimental::optional<typename std::result_of<TVerticesFun(
Frame &, Context &)>::type::value_type> Frame &, ExecutionContext &)>::type::value_type>
vertices_; vertices_;
std::experimental::optional<decltype(vertices_.value().begin())> vertices_it_; std::experimental::optional<decltype(vertices_.value().begin())> vertices_it_;
database::GraphDbAccessor &db_; database::GraphDbAccessor &db_;
@ -312,7 +315,7 @@ ACCEPT_WITH_INPUT(ScanAll)
std::unique_ptr<Cursor> ScanAll::MakeCursor( std::unique_ptr<Cursor> ScanAll::MakeCursor(
database::GraphDbAccessor &db) const { database::GraphDbAccessor &db) const {
auto vertices = [this, &db](Frame &, Context &) { auto vertices = [this, &db](Frame &, ExecutionContext &) {
return std::experimental::make_optional( return std::experimental::make_optional(
db.Vertices(graph_view_ == GraphView::NEW)); db.Vertices(graph_view_ == GraphView::NEW));
}; };
@ -335,7 +338,7 @@ ACCEPT_WITH_INPUT(ScanAllByLabel)
std::unique_ptr<Cursor> ScanAllByLabel::MakeCursor( std::unique_ptr<Cursor> ScanAllByLabel::MakeCursor(
database::GraphDbAccessor &db) const { database::GraphDbAccessor &db) const {
auto vertices = [this, &db](Frame &, Context &) { auto vertices = [this, &db](Frame &, ExecutionContext &) {
return std::experimental::make_optional( return std::experimental::make_optional(
db.Vertices(label_, graph_view_ == GraphView::NEW)); db.Vertices(label_, graph_view_ == GraphView::NEW));
}; };
@ -362,13 +365,13 @@ ACCEPT_WITH_INPUT(ScanAllByLabelPropertyRange)
std::unique_ptr<Cursor> ScanAllByLabelPropertyRange::MakeCursor( std::unique_ptr<Cursor> ScanAllByLabelPropertyRange::MakeCursor(
database::GraphDbAccessor &db) const { database::GraphDbAccessor &db) const {
auto vertices = [this, &db](Frame &frame, Context &context) auto vertices = [this, &db](Frame &frame, ExecutionContext &context)
-> std::experimental::optional<decltype( -> std::experimental::optional<decltype(
db.Vertices(label_, property_, std::experimental::nullopt, db.Vertices(label_, property_, std::experimental::nullopt,
std::experimental::nullopt, false))> { std::experimental::nullopt, false))> {
ExpressionEvaluator evaluator(&frame, context.symbol_table_, ExpressionEvaluator evaluator(&frame, context.symbol_table,
context.evaluation_context_, context.evaluation_context,
&context.db_accessor_, graph_view_); context.db_accessor, graph_view_);
auto convert = [&evaluator](const auto &bound) auto convert = [&evaluator](const auto &bound)
-> std::experimental::optional<utils::Bound<PropertyValue>> { -> std::experimental::optional<utils::Bound<PropertyValue>> {
if (!bound) return std::experimental::nullopt; if (!bound) return std::experimental::nullopt;
@ -414,12 +417,12 @@ ACCEPT_WITH_INPUT(ScanAllByLabelPropertyValue)
std::unique_ptr<Cursor> ScanAllByLabelPropertyValue::MakeCursor( std::unique_ptr<Cursor> ScanAllByLabelPropertyValue::MakeCursor(
database::GraphDbAccessor &db) const { database::GraphDbAccessor &db) const {
auto vertices = [this, &db](Frame &frame, Context &context) auto vertices = [this, &db](Frame &frame, ExecutionContext &context)
-> std::experimental::optional<decltype( -> std::experimental::optional<decltype(
db.Vertices(label_, property_, PropertyValue::Null, false))> { db.Vertices(label_, property_, PropertyValue::Null, false))> {
ExpressionEvaluator evaluator(&frame, context.symbol_table_, ExpressionEvaluator evaluator(&frame, context.symbol_table,
context.evaluation_context_, context.evaluation_context,
&context.db_accessor_, graph_view_); context.db_accessor, graph_view_);
auto value = expression_->Accept(evaluator); auto value = expression_->Accept(evaluator);
if (value.IsNull()) return std::experimental::nullopt; if (value.IsNull()) return std::experimental::nullopt;
if (!value.IsPropertyValue()) { if (!value.IsPropertyValue()) {
@ -472,7 +475,7 @@ Expand::ExpandCursor::ExpandCursor(const Expand &self,
database::GraphDbAccessor &db) database::GraphDbAccessor &db)
: self_(self), input_cursor_(self.input_->MakeCursor(db)), db_(db) {} : self_(self), input_cursor_(self.input_->MakeCursor(db)), db_(db) {}
bool Expand::ExpandCursor::Pull(Frame &frame, Context &context) { bool Expand::ExpandCursor::Pull(Frame &frame, ExecutionContext &context) {
SCOPED_PROFILE_OP("Expand"); SCOPED_PROFILE_OP("Expand");
// A helper function for expanding a node from an edge. // A helper function for expanding a node from an edge.
@ -533,7 +536,7 @@ void Expand::ExpandCursor::Reset() {
out_edges_it_ = std::experimental::nullopt; out_edges_it_ = std::experimental::nullopt;
} }
bool Expand::ExpandCursor::InitEdges(Frame &frame, Context &context) { bool Expand::ExpandCursor::InitEdges(Frame &frame, ExecutionContext &context) {
// Input Vertex could be null if it is created by a failed optional match. In // Input Vertex could be null if it is created by a failed optional match. In
// those cases we skip that input pull and continue with the next. // those cases we skip that input pull and continue with the next.
while (true) { while (true) {
@ -681,12 +684,12 @@ class ExpandVariableCursor : public Cursor {
database::GraphDbAccessor &db) database::GraphDbAccessor &db)
: self_(self), input_cursor_(self.input_->MakeCursor(db)) {} : self_(self), input_cursor_(self.input_->MakeCursor(db)) {}
bool Pull(Frame &frame, Context &context) override { bool Pull(Frame &frame, ExecutionContext &context) override {
SCOPED_PROFILE_OP("ExpandVariable"); SCOPED_PROFILE_OP("ExpandVariable");
ExpressionEvaluator evaluator( ExpressionEvaluator evaluator(
&frame, context.symbol_table_, context.evaluation_context_, &frame, context.symbol_table, context.evaluation_context,
&context.db_accessor_, self_.common_.graph_view); context.db_accessor, self_.common_.graph_view);
while (true) { while (true) {
if (Expand(frame, context)) return true; if (Expand(frame, context)) return true;
@ -747,12 +750,12 @@ class ExpandVariableCursor : public Cursor {
* @return If the Pull succeeded. If not, this VariableExpandCursor * @return If the Pull succeeded. If not, this VariableExpandCursor
* is exhausted. * is exhausted.
*/ */
bool PullInput(Frame &frame, Context &context) { bool PullInput(Frame &frame, ExecutionContext &context) {
// Input Vertex could be null if it is created by a failed optional // Input Vertex could be null if it is created by a failed optional
// match. // match.
// In those cases we skip that input pull and continue with the next. // In those cases we skip that input pull and continue with the next.
while (true) { while (true) {
if (context.db_accessor_.should_abort()) throw HintedAbortError(); if (context.db_accessor->should_abort()) throw HintedAbortError();
if (!input_cursor_->Pull(frame, context)) return false; if (!input_cursor_->Pull(frame, context)) return false;
TypedValue &vertex_value = frame[self_.input_symbol_]; TypedValue &vertex_value = frame[self_.input_symbol_];
@ -764,10 +767,10 @@ class ExpandVariableCursor : public Cursor {
SwitchAccessor(vertex, self_.common_.graph_view); SwitchAccessor(vertex, self_.common_.graph_view);
// Evaluate the upper and lower bounds. // Evaluate the upper and lower bounds.
ExpressionEvaluator evaluator(&frame, context.symbol_table_, ExpressionEvaluator evaluator(&frame, context.symbol_table,
context.evaluation_context_, context.evaluation_context,
&context.db_accessor_, context.db_accessor,
self_.common_.graph_view); self_.common_.graph_view);
auto calc_bound = [&evaluator](auto &bound) { auto calc_bound = [&evaluator](auto &bound) {
auto value = EvaluateInt(&evaluator, bound, "Variable expansion bound"); auto value = EvaluateInt(&evaluator, bound, "Variable expansion bound");
@ -826,15 +829,15 @@ class ExpandVariableCursor : public Cursor {
* case no more expansions are available from the current input * case no more expansions are available from the current input
* vertex and another Pull from the input cursor should be performed. * vertex and another Pull from the input cursor should be performed.
*/ */
bool Expand(Frame &frame, Context &context) { bool Expand(Frame &frame, ExecutionContext &context) {
ExpressionEvaluator evaluator( ExpressionEvaluator evaluator(
&frame, context.symbol_table_, context.evaluation_context_, &frame, context.symbol_table, context.evaluation_context,
&context.db_accessor_, self_.common_.graph_view); context.db_accessor, self_.common_.graph_view);
// Some expansions might not be valid due to edge uniqueness and // Some expansions might not be valid due to edge uniqueness and
// existing_node criterions, so expand in a loop until either the input // existing_node criterions, so expand in a loop until either the input
// vertex is exhausted or a valid variable-length expansion is available. // vertex is exhausted or a valid variable-length expansion is available.
while (true) { while (true) {
if (context.db_accessor_.should_abort()) throw HintedAbortError(); if (context.db_accessor->should_abort()) throw HintedAbortError();
// pop from the stack while there is stuff to pop and the current // pop from the stack while there is stuff to pop and the current
// level is exhausted // level is exhausted
while (!edges_.empty() && edges_it_.back() == edges_.back().end()) { while (!edges_.empty() && edges_it_.back() == edges_.back().end()) {
@ -927,12 +930,12 @@ class STShortestPathCursor : public query::plan::Cursor {
"set!"; "set!";
} }
bool Pull(Frame &frame, Context &context) override { bool Pull(Frame &frame, ExecutionContext &context) override {
SCOPED_PROFILE_OP("STShortestPath"); SCOPED_PROFILE_OP("STShortestPath");
ExpressionEvaluator evaluator(&frame, context.symbol_table_, ExpressionEvaluator evaluator(&frame, context.symbol_table,
context.evaluation_context_, context.evaluation_context,
&context.db_accessor_, GraphView::OLD); context.db_accessor, GraphView::OLD);
while (input_cursor_->Pull(frame, context)) { while (input_cursor_->Pull(frame, context)) {
auto source_tv = frame[self_.input_symbol_]; auto source_tv = frame[self_.input_symbol_];
auto sink_tv = frame[self_.common_.node_symbol]; auto sink_tv = frame[self_.common_.node_symbol];
@ -957,7 +960,7 @@ class STShortestPathCursor : public query::plan::Cursor {
if (upper_bound < 1 || lower_bound > upper_bound) continue; if (upper_bound < 1 || lower_bound > upper_bound) continue;
if (FindPath(context.db_accessor_, source, sink, lower_bound, upper_bound, if (FindPath(*context.db_accessor, source, sink, lower_bound, upper_bound,
&frame, &evaluator)) { &frame, &evaluator)) {
return true; return true;
} }
@ -1163,12 +1166,12 @@ class SingleSourceShortestPathCursor : public query::plan::Cursor {
"should be used instead!"; "should be used instead!";
} }
bool Pull(Frame &frame, Context &context) override { bool Pull(Frame &frame, ExecutionContext &context) override {
SCOPED_PROFILE_OP("SingleSourceShortestPath"); SCOPED_PROFILE_OP("SingleSourceShortestPath");
ExpressionEvaluator evaluator(&frame, context.symbol_table_, ExpressionEvaluator evaluator(&frame, context.symbol_table,
context.evaluation_context_, context.evaluation_context,
&context.db_accessor_, GraphView::OLD); context.db_accessor, GraphView::OLD);
// for the given (edge, vertex) pair checks if they satisfy the // for the given (edge, vertex) pair checks if they satisfy the
// "where" condition. if so, places them in the to_visit_ structure. // "where" condition. if so, places them in the to_visit_ structure.
@ -1213,7 +1216,7 @@ class SingleSourceShortestPathCursor : public query::plan::Cursor {
// do it all in a loop because we skip some elements // do it all in a loop because we skip some elements
while (true) { while (true) {
if (context.db_accessor_.should_abort()) throw HintedAbortError(); if (context.db_accessor->should_abort()) throw HintedAbortError();
// if we have nothing to visit on the current depth, switch to next // if we have nothing to visit on the current depth, switch to next
if (to_visit_current_.empty()) to_visit_current_.swap(to_visit_next_); if (to_visit_current_.empty()) to_visit_current_.swap(to_visit_next_);
@ -1317,12 +1320,12 @@ class ExpandWeightedShortestPathCursor : public query::plan::Cursor {
database::GraphDbAccessor &db) database::GraphDbAccessor &db)
: self_(self), input_cursor_(self_.input_->MakeCursor(db)) {} : self_(self), input_cursor_(self_.input_->MakeCursor(db)) {}
bool Pull(Frame &frame, Context &context) override { bool Pull(Frame &frame, ExecutionContext &context) override {
SCOPED_PROFILE_OP("ExpandWeightedShortestPath"); SCOPED_PROFILE_OP("ExpandWeightedShortestPath");
ExpressionEvaluator evaluator( ExpressionEvaluator evaluator(
&frame, context.symbol_table_, context.evaluation_context_, &frame, context.symbol_table, context.evaluation_context,
&context.db_accessor_, self_.common_.graph_view); context.db_accessor, self_.common_.graph_view);
auto create_state = [this](VertexAccessor vertex, int depth) { auto create_state = [this](VertexAccessor vertex, int depth) {
return std::make_pair(vertex, upper_bound_set_ ? depth : 0); return std::make_pair(vertex, upper_bound_set_ ? depth : 0);
}; };
@ -1385,7 +1388,7 @@ class ExpandWeightedShortestPathCursor : public query::plan::Cursor {
}; };
while (true) { while (true) {
if (context.db_accessor_.should_abort()) throw HintedAbortError(); if (context.db_accessor->should_abort()) throw HintedAbortError();
if (pq_.empty()) { if (pq_.empty()) {
if (!input_cursor_->Pull(frame, context)) return false; if (!input_cursor_->Pull(frame, context)) return false;
auto vertex_value = frame[self_.input_symbol_]; auto vertex_value = frame[self_.input_symbol_];
@ -1425,7 +1428,7 @@ class ExpandWeightedShortestPathCursor : public query::plan::Cursor {
} }
while (!pq_.empty()) { while (!pq_.empty()) {
if (context.db_accessor_.should_abort()) throw HintedAbortError(); if (context.db_accessor->should_abort()) throw HintedAbortError();
auto current = pq_.top(); auto current = pq_.top();
double current_weight = std::get<0>(current); double current_weight = std::get<0>(current);
int current_depth = std::get<1>(current); int current_depth = std::get<1>(current);
@ -1579,7 +1582,7 @@ class ConstructNamedPathCursor : public Cursor {
database::GraphDbAccessor &db) database::GraphDbAccessor &db)
: self_(self), input_cursor_(self_.input()->MakeCursor(db)) {} : self_(self), input_cursor_(self_.input()->MakeCursor(db)) {}
bool Pull(Frame &frame, Context &context) override { bool Pull(Frame &frame, ExecutionContext &context) override {
SCOPED_PROFILE_OP("ConstructNamedPath"); SCOPED_PROFILE_OP("ConstructNamedPath");
if (!input_cursor_->Pull(frame, context)) return false; if (!input_cursor_->Pull(frame, context)) return false;
@ -1690,14 +1693,14 @@ Filter::FilterCursor::FilterCursor(const Filter &self,
database::GraphDbAccessor &db) database::GraphDbAccessor &db)
: self_(self), input_cursor_(self_.input_->MakeCursor(db)) {} : self_(self), input_cursor_(self_.input_->MakeCursor(db)) {}
bool Filter::FilterCursor::Pull(Frame &frame, Context &context) { bool Filter::FilterCursor::Pull(Frame &frame, ExecutionContext &context) {
SCOPED_PROFILE_OP("Filter"); SCOPED_PROFILE_OP("Filter");
// Like all filters, newly set values should not affect filtering of old // Like all filters, newly set values should not affect filtering of old
// nodes and edges. // nodes and edges.
ExpressionEvaluator evaluator(&frame, context.symbol_table_, ExpressionEvaluator evaluator(&frame, context.symbol_table,
context.evaluation_context_, context.evaluation_context, context.db_accessor,
&context.db_accessor_, GraphView::OLD); GraphView::OLD);
while (input_cursor_->Pull(frame, context)) { while (input_cursor_->Pull(frame, context)) {
if (EvaluateFilter(evaluator, self_.expression_)) return true; if (EvaluateFilter(evaluator, self_.expression_)) return true;
} }
@ -1737,14 +1740,14 @@ Produce::ProduceCursor::ProduceCursor(const Produce &self,
database::GraphDbAccessor &db) database::GraphDbAccessor &db)
: self_(self), input_cursor_(self_.input_->MakeCursor(db)) {} : self_(self), input_cursor_(self_.input_->MakeCursor(db)) {}
bool Produce::ProduceCursor::Pull(Frame &frame, Context &context) { bool Produce::ProduceCursor::Pull(Frame &frame, ExecutionContext &context) {
SCOPED_PROFILE_OP("Produce"); SCOPED_PROFILE_OP("Produce");
if (input_cursor_->Pull(frame, context)) { if (input_cursor_->Pull(frame, context)) {
// Produce should always yield the latest results. // Produce should always yield the latest results.
ExpressionEvaluator evaluator(&frame, context.symbol_table_, ExpressionEvaluator evaluator(&frame, context.symbol_table,
context.evaluation_context_, context.evaluation_context,
&context.db_accessor_, GraphView::NEW); context.db_accessor, GraphView::NEW);
for (auto named_expr : self_.named_expressions_) for (auto named_expr : self_.named_expressions_)
named_expr->Accept(evaluator); named_expr->Accept(evaluator);
@ -1776,7 +1779,7 @@ Delete::DeleteCursor::DeleteCursor(const Delete &self,
database::GraphDbAccessor &db) database::GraphDbAccessor &db)
: self_(self), db_(db), input_cursor_(self_.input_->MakeCursor(db)) {} : self_(self), db_(db), input_cursor_(self_.input_->MakeCursor(db)) {}
bool Delete::DeleteCursor::Pull(Frame &frame, Context &context) { bool Delete::DeleteCursor::Pull(Frame &frame, ExecutionContext &context) {
SCOPED_PROFILE_OP("Delete"); SCOPED_PROFILE_OP("Delete");
if (!input_cursor_->Pull(frame, context)) return false; if (!input_cursor_->Pull(frame, context)) return false;
@ -1784,9 +1787,9 @@ bool Delete::DeleteCursor::Pull(Frame &frame, Context &context) {
// Delete should get the latest information, this way it is also possible // Delete should get the latest information, this way it is also possible
// to // to
// delete newly added nodes and edges. // delete newly added nodes and edges.
ExpressionEvaluator evaluator(&frame, context.symbol_table_, ExpressionEvaluator evaluator(&frame, context.symbol_table,
context.evaluation_context_, context.evaluation_context, context.db_accessor,
&context.db_accessor_, GraphView::NEW); GraphView::NEW);
// collect expressions results so edges can get deleted before vertices // collect expressions results so edges can get deleted before vertices
// this is necessary because an edge that gets deleted could block vertex // this is necessary because an edge that gets deleted could block vertex
// deletion // deletion
@ -1857,15 +1860,16 @@ SetProperty::SetPropertyCursor::SetPropertyCursor(const SetProperty &self,
database::GraphDbAccessor &db) database::GraphDbAccessor &db)
: self_(self), input_cursor_(self.input_->MakeCursor(db)) {} : self_(self), input_cursor_(self.input_->MakeCursor(db)) {}
bool SetProperty::SetPropertyCursor::Pull(Frame &frame, Context &context) { bool SetProperty::SetPropertyCursor::Pull(Frame &frame,
ExecutionContext &context) {
SCOPED_PROFILE_OP("SetProperty"); SCOPED_PROFILE_OP("SetProperty");
if (!input_cursor_->Pull(frame, context)) return false; if (!input_cursor_->Pull(frame, context)) return false;
// Set, just like Create needs to see the latest changes. // Set, just like Create needs to see the latest changes.
ExpressionEvaluator evaluator(&frame, context.symbol_table_, ExpressionEvaluator evaluator(&frame, context.symbol_table,
context.evaluation_context_, context.evaluation_context, context.db_accessor,
&context.db_accessor_, GraphView::NEW); GraphView::NEW);
TypedValue lhs = self_.lhs_->expression_->Accept(evaluator); TypedValue lhs = self_.lhs_->expression_->Accept(evaluator);
TypedValue rhs = self_.rhs_->Accept(evaluator); TypedValue rhs = self_.rhs_->Accept(evaluator);
@ -1916,7 +1920,8 @@ SetProperties::SetPropertiesCursor::SetPropertiesCursor(
const SetProperties &self, database::GraphDbAccessor &db) const SetProperties &self, database::GraphDbAccessor &db)
: self_(self), db_(db), input_cursor_(self.input_->MakeCursor(db)) {} : self_(self), db_(db), input_cursor_(self.input_->MakeCursor(db)) {}
bool SetProperties::SetPropertiesCursor::Pull(Frame &frame, Context &context) { bool SetProperties::SetPropertiesCursor::Pull(Frame &frame,
ExecutionContext &context) {
SCOPED_PROFILE_OP("SetProperties"); SCOPED_PROFILE_OP("SetProperties");
if (!input_cursor_->Pull(frame, context)) return false; if (!input_cursor_->Pull(frame, context)) return false;
@ -1924,9 +1929,9 @@ bool SetProperties::SetPropertiesCursor::Pull(Frame &frame, Context &context) {
TypedValue &lhs = frame[self_.input_symbol_]; TypedValue &lhs = frame[self_.input_symbol_];
// Set, just like Create needs to see the latest changes. // Set, just like Create needs to see the latest changes.
ExpressionEvaluator evaluator(&frame, context.symbol_table_, ExpressionEvaluator evaluator(&frame, context.symbol_table,
context.evaluation_context_, context.evaluation_context, context.db_accessor,
&context.db_accessor_, GraphView::NEW); GraphView::NEW);
TypedValue rhs = self_.rhs_->Accept(evaluator); TypedValue rhs = self_.rhs_->Accept(evaluator);
switch (lhs.type()) { switch (lhs.type()) {
@ -2020,7 +2025,7 @@ SetLabels::SetLabelsCursor::SetLabelsCursor(const SetLabels &self,
database::GraphDbAccessor &db) database::GraphDbAccessor &db)
: self_(self), input_cursor_(self.input_->MakeCursor(db)) {} : self_(self), input_cursor_(self.input_->MakeCursor(db)) {}
bool SetLabels::SetLabelsCursor::Pull(Frame &frame, Context &context) { bool SetLabels::SetLabelsCursor::Pull(Frame &frame, ExecutionContext &context) {
SCOPED_PROFILE_OP("SetLabels"); SCOPED_PROFILE_OP("SetLabels");
if (!input_cursor_->Pull(frame, context)) return false; if (!input_cursor_->Pull(frame, context)) return false;
@ -2065,15 +2070,15 @@ RemoveProperty::RemovePropertyCursor::RemovePropertyCursor(
: self_(self), input_cursor_(self.input_->MakeCursor(db)) {} : self_(self), input_cursor_(self.input_->MakeCursor(db)) {}
bool RemoveProperty::RemovePropertyCursor::Pull(Frame &frame, bool RemoveProperty::RemovePropertyCursor::Pull(Frame &frame,
Context &context) { ExecutionContext &context) {
SCOPED_PROFILE_OP("RemoveProperty"); SCOPED_PROFILE_OP("RemoveProperty");
if (!input_cursor_->Pull(frame, context)) return false; if (!input_cursor_->Pull(frame, context)) return false;
// Remove, just like Delete needs to see the latest changes. // Remove, just like Delete needs to see the latest changes.
ExpressionEvaluator evaluator(&frame, context.symbol_table_, ExpressionEvaluator evaluator(&frame, context.symbol_table,
context.evaluation_context_, context.evaluation_context, context.db_accessor,
&context.db_accessor_, GraphView::NEW); GraphView::NEW);
TypedValue lhs = self_.lhs_->expression_->Accept(evaluator); TypedValue lhs = self_.lhs_->expression_->Accept(evaluator);
switch (lhs.type()) { switch (lhs.type()) {
@ -2130,7 +2135,8 @@ RemoveLabels::RemoveLabelsCursor::RemoveLabelsCursor(
const RemoveLabels &self, database::GraphDbAccessor &db) const RemoveLabels &self, database::GraphDbAccessor &db)
: self_(self), input_cursor_(self.input_->MakeCursor(db)) {} : self_(self), input_cursor_(self.input_->MakeCursor(db)) {}
bool RemoveLabels::RemoveLabelsCursor::Pull(Frame &frame, Context &context) { bool RemoveLabels::RemoveLabelsCursor::Pull(Frame &frame,
ExecutionContext &context) {
SCOPED_PROFILE_OP("RemoveLabels"); SCOPED_PROFILE_OP("RemoveLabels");
if (!input_cursor_->Pull(frame, context)) return false; if (!input_cursor_->Pull(frame, context)) return false;
@ -2199,7 +2205,7 @@ bool ContainsSameEdge(const TypedValue &a, const TypedValue &b) {
} // namespace } // namespace
bool EdgeUniquenessFilter::EdgeUniquenessFilterCursor::Pull( bool EdgeUniquenessFilter::EdgeUniquenessFilterCursor::Pull(
Frame &frame, Context &context) { Frame &frame, ExecutionContext &context) {
SCOPED_PROFILE_OP("EdgeUniquenessFilter"); SCOPED_PROFILE_OP("EdgeUniquenessFilter");
auto expansion_ok = [&]() { auto expansion_ok = [&]() {
@ -2246,7 +2252,8 @@ Accumulate::AccumulateCursor::AccumulateCursor(const Accumulate &self,
database::GraphDbAccessor &db) database::GraphDbAccessor &db)
: self_(self), db_(db), input_cursor_(self.input_->MakeCursor(db)) {} : self_(self), db_(db), input_cursor_(self.input_->MakeCursor(db)) {}
bool Accumulate::AccumulateCursor::Pull(Frame &frame, Context &context) { bool Accumulate::AccumulateCursor::Pull(Frame &frame,
ExecutionContext &context) {
SCOPED_PROFILE_OP("Accumulate"); SCOPED_PROFILE_OP("Accumulate");
// cache all the input // cache all the input
@ -2332,7 +2339,7 @@ TypedValue DefaultAggregationOpValue(const Aggregate::Element &element) {
} }
} // namespace } // namespace
bool Aggregate::AggregateCursor::Pull(Frame &frame, Context &context) { bool Aggregate::AggregateCursor::Pull(Frame &frame, ExecutionContext &context) {
SCOPED_PROFILE_OP("Aggregate"); SCOPED_PROFILE_OP("Aggregate");
if (!pulled_all_input_) { if (!pulled_all_input_) {
@ -2369,12 +2376,13 @@ bool Aggregate::AggregateCursor::Pull(Frame &frame, Context &context) {
return true; return true;
} }
void Aggregate::AggregateCursor::ProcessAll(Frame &frame, Context &context) { void Aggregate::AggregateCursor::ProcessAll(Frame &frame,
ExpressionEvaluator evaluator(&frame, context.symbol_table_, ExecutionContext &context) {
context.evaluation_context_, ExpressionEvaluator evaluator(&frame, context.symbol_table,
&context.db_accessor_, GraphView::NEW); context.evaluation_context, context.db_accessor,
GraphView::NEW);
while (input_cursor_->Pull(frame, context)) { while (input_cursor_->Pull(frame, context)) {
ProcessOne(frame, context.symbol_table_, evaluator); ProcessOne(frame, context.symbol_table, evaluator);
} }
// calculate AVG aggregations (so far they have only been summed) // calculate AVG aggregations (so far they have only been summed)
@ -2596,7 +2604,7 @@ std::vector<Symbol> Skip::ModifiedSymbols(const SymbolTable &table) const {
Skip::SkipCursor::SkipCursor(const Skip &self, database::GraphDbAccessor &db) Skip::SkipCursor::SkipCursor(const Skip &self, database::GraphDbAccessor &db)
: self_(self), input_cursor_(self_.input_->MakeCursor(db)) {} : self_(self), input_cursor_(self_.input_->MakeCursor(db)) {}
bool Skip::SkipCursor::Pull(Frame &frame, Context &context) { bool Skip::SkipCursor::Pull(Frame &frame, ExecutionContext &context) {
SCOPED_PROFILE_OP("Skip"); SCOPED_PROFILE_OP("Skip");
while (input_cursor_->Pull(frame, context)) { while (input_cursor_->Pull(frame, context)) {
@ -2604,9 +2612,9 @@ bool Skip::SkipCursor::Pull(Frame &frame, Context &context) {
// First successful pull from the input, evaluate the skip expression. // First successful pull from the input, evaluate the skip expression.
// The skip expression doesn't contain identifiers so graph view // The skip expression doesn't contain identifiers so graph view
// parameter is not important. // parameter is not important.
ExpressionEvaluator evaluator(&frame, context.symbol_table_, ExpressionEvaluator evaluator(&frame, context.symbol_table,
context.evaluation_context_, context.evaluation_context,
&context.db_accessor_, GraphView::OLD); context.db_accessor, GraphView::OLD);
TypedValue to_skip = self_.expression_->Accept(evaluator); TypedValue to_skip = self_.expression_->Accept(evaluator);
if (to_skip.type() != TypedValue::Type::Int) if (to_skip.type() != TypedValue::Type::Int)
throw QueryRuntimeException( throw QueryRuntimeException(
@ -2656,7 +2664,7 @@ Limit::LimitCursor::LimitCursor(const Limit &self,
database::GraphDbAccessor &db) database::GraphDbAccessor &db)
: self_(self), input_cursor_(self_.input_->MakeCursor(db)) {} : self_(self), input_cursor_(self_.input_->MakeCursor(db)) {}
bool Limit::LimitCursor::Pull(Frame &frame, Context &context) { bool Limit::LimitCursor::Pull(Frame &frame, ExecutionContext &context) {
SCOPED_PROFILE_OP("Limit"); SCOPED_PROFILE_OP("Limit");
// We need to evaluate the limit expression before the first input Pull // We need to evaluate the limit expression before the first input Pull
@ -2666,9 +2674,9 @@ bool Limit::LimitCursor::Pull(Frame &frame, Context &context) {
if (limit_ == -1) { if (limit_ == -1) {
// Limit expression doesn't contain identifiers so graph view is not // Limit expression doesn't contain identifiers so graph view is not
// important. // important.
ExpressionEvaluator evaluator(&frame, context.symbol_table_, ExpressionEvaluator evaluator(&frame, context.symbol_table,
context.evaluation_context_, context.evaluation_context,
&context.db_accessor_, GraphView::OLD); context.db_accessor, GraphView::OLD);
TypedValue limit = self_.expression_->Accept(evaluator); TypedValue limit = self_.expression_->Accept(evaluator);
if (limit.type() != TypedValue::Type::Int) if (limit.type() != TypedValue::Type::Int)
throw QueryRuntimeException( throw QueryRuntimeException(
@ -2730,13 +2738,13 @@ OrderBy::OrderByCursor::OrderByCursor(const OrderBy &self,
database::GraphDbAccessor &db) database::GraphDbAccessor &db)
: self_(self), input_cursor_(self_.input_->MakeCursor(db)) {} : self_(self), input_cursor_(self_.input_->MakeCursor(db)) {}
bool OrderBy::OrderByCursor::Pull(Frame &frame, Context &context) { bool OrderBy::OrderByCursor::Pull(Frame &frame, ExecutionContext &context) {
SCOPED_PROFILE_OP("OrderBy"); SCOPED_PROFILE_OP("OrderBy");
if (!did_pull_all_) { if (!did_pull_all_) {
ExpressionEvaluator evaluator(&frame, context.symbol_table_, ExpressionEvaluator evaluator(&frame, context.symbol_table,
context.evaluation_context_, context.evaluation_context,
&context.db_accessor_, GraphView::OLD); context.db_accessor, GraphView::OLD);
while (input_cursor_->Pull(frame, context)) { while (input_cursor_->Pull(frame, context)) {
// collect the order_by elements // collect the order_by elements
std::vector<TypedValue> order_by; std::vector<TypedValue> order_by;
@ -2765,7 +2773,7 @@ bool OrderBy::OrderByCursor::Pull(Frame &frame, Context &context) {
if (cache_it_ == cache_.end()) return false; if (cache_it_ == cache_.end()) return false;
if (context.db_accessor_.should_abort()) throw HintedAbortError(); if (context.db_accessor->should_abort()) throw HintedAbortError();
// place the output values on the frame // place the output values on the frame
DCHECK(self_.output_symbols_.size() == cache_it_->second.size()) DCHECK(self_.output_symbols_.size() == cache_it_->second.size())
@ -2822,7 +2830,7 @@ Merge::MergeCursor::MergeCursor(const Merge &self,
merge_match_cursor_(self.merge_match_->MakeCursor(db)), merge_match_cursor_(self.merge_match_->MakeCursor(db)),
merge_create_cursor_(self.merge_create_->MakeCursor(db)) {} merge_create_cursor_(self.merge_create_->MakeCursor(db)) {}
bool Merge::MergeCursor::Pull(Frame &frame, Context &context) { bool Merge::MergeCursor::Pull(Frame &frame, ExecutionContext &context) {
SCOPED_PROFILE_OP("Merge"); SCOPED_PROFILE_OP("Merge");
while (true) { while (true) {
@ -2906,7 +2914,7 @@ Optional::OptionalCursor::OptionalCursor(const Optional &self,
input_cursor_(self.input_->MakeCursor(db)), input_cursor_(self.input_->MakeCursor(db)),
optional_cursor_(self.optional_->MakeCursor(db)) {} optional_cursor_(self.optional_->MakeCursor(db)) {}
bool Optional::OptionalCursor::Pull(Frame &frame, Context &context) { bool Optional::OptionalCursor::Pull(Frame &frame, ExecutionContext &context) {
SCOPED_PROFILE_OP("Optional"); SCOPED_PROFILE_OP("Optional");
while (true) { while (true) {
@ -2979,7 +2987,7 @@ Unwind::UnwindCursor::UnwindCursor(const Unwind &self,
database::GraphDbAccessor &db) database::GraphDbAccessor &db)
: self_(self), db_(db), input_cursor_(self.input_->MakeCursor(db)) {} : self_(self), db_(db), input_cursor_(self.input_->MakeCursor(db)) {}
bool Unwind::UnwindCursor::Pull(Frame &frame, Context &context) { bool Unwind::UnwindCursor::Pull(Frame &frame, ExecutionContext &context) {
SCOPED_PROFILE_OP("Unwind"); SCOPED_PROFILE_OP("Unwind");
while (true) { while (true) {
@ -2990,9 +2998,9 @@ bool Unwind::UnwindCursor::Pull(Frame &frame, Context &context) {
if (!input_cursor_->Pull(frame, context)) return false; if (!input_cursor_->Pull(frame, context)) return false;
// successful pull from input, initialize value and iterator // successful pull from input, initialize value and iterator
ExpressionEvaluator evaluator(&frame, context.symbol_table_, ExpressionEvaluator evaluator(&frame, context.symbol_table,
context.evaluation_context_, context.evaluation_context,
&context.db_accessor_, GraphView::OLD); context.db_accessor, GraphView::OLD);
TypedValue input_value = self_.input_expression_->Accept(evaluator); TypedValue input_value = self_.input_expression_->Accept(evaluator);
if (input_value.type() != TypedValue::Type::List) if (input_value.type() != TypedValue::Type::List)
throw QueryRuntimeException( throw QueryRuntimeException(
@ -3044,7 +3052,7 @@ Distinct::DistinctCursor::DistinctCursor(const Distinct &self,
database::GraphDbAccessor &db) database::GraphDbAccessor &db)
: self_(self), input_cursor_(self.input_->MakeCursor(db)) {} : self_(self), input_cursor_(self.input_->MakeCursor(db)) {}
bool Distinct::DistinctCursor::Pull(Frame &frame, Context &context) { bool Distinct::DistinctCursor::Pull(Frame &frame, ExecutionContext &context) {
SCOPED_PROFILE_OP("Distinct"); SCOPED_PROFILE_OP("Distinct");
while (true) { while (true) {
@ -3105,7 +3113,7 @@ Union::UnionCursor::UnionCursor(const Union &self,
left_cursor_(self.left_op_->MakeCursor(db)), left_cursor_(self.left_op_->MakeCursor(db)),
right_cursor_(self.right_op_->MakeCursor(db)) {} right_cursor_(self.right_op_->MakeCursor(db)) {}
bool Union::UnionCursor::Pull(Frame &frame, Context &context) { bool Union::UnionCursor::Pull(Frame &frame, ExecutionContext &context) {
SCOPED_PROFILE_OP("Union"); SCOPED_PROFILE_OP("Union");
std::unordered_map<std::string, TypedValue> results; std::unordered_map<std::string, TypedValue> results;
@ -3170,7 +3178,7 @@ class CartesianCursor : public Cursor {
<< "CartesianCursor: Missing right operator cursor."; << "CartesianCursor: Missing right operator cursor.";
} }
bool Pull(Frame &frame, Context &context) override { bool Pull(Frame &frame, ExecutionContext &context) override {
SCOPED_PROFILE_OP("Cartesian"); SCOPED_PROFILE_OP("Cartesian");
if (!cartesian_pull_initialized_) { if (!cartesian_pull_initialized_) {
@ -3208,7 +3216,7 @@ class CartesianCursor : public Cursor {
restore_frame(self_.right_symbols_, right_op_frame_); restore_frame(self_.right_symbols_, right_op_frame_);
} }
if (context.db_accessor_.should_abort()) throw HintedAbortError(); if (context.db_accessor->should_abort()) throw HintedAbortError();
restore_frame(self_.left_symbols_, *left_op_frames_it_); restore_frame(self_.left_symbols_, *left_op_frames_it_);
left_op_frames_it_++; left_op_frames_it_++;
@ -3249,12 +3257,12 @@ std::unique_ptr<Cursor> Cartesian::MakeCursor(
OutputTable::OutputTable(std::vector<Symbol> output_symbols, OutputTable::OutputTable(std::vector<Symbol> output_symbols,
std::vector<std::vector<TypedValue>> rows) std::vector<std::vector<TypedValue>> rows)
: output_symbols_(std::move(output_symbols)), : output_symbols_(std::move(output_symbols)),
callback_([rows](Frame *, Context *) { return rows; }) {} callback_([rows](Frame *, ExecutionContext *) { return rows; }) {}
OutputTable::OutputTable( OutputTable::OutputTable(std::vector<Symbol> output_symbols,
std::vector<Symbol> output_symbols, std::function<std::vector<std::vector<TypedValue>>(
std::function<std::vector<std::vector<TypedValue>>(Frame *, Context *)> Frame *, ExecutionContext *)>
callback) callback)
: output_symbols_(std::move(output_symbols)), : output_symbols_(std::move(output_symbols)),
callback_(std::move(callback)) {} callback_(std::move(callback)) {}
@ -3264,7 +3272,7 @@ class OutputTableCursor : public Cursor {
public: public:
OutputTableCursor(const OutputTable &self) : self_(self) {} OutputTableCursor(const OutputTable &self) : self_(self) {}
bool Pull(Frame &frame, Context &context) override { bool Pull(Frame &frame, ExecutionContext &context) override {
if (!pulled_) { if (!pulled_) {
rows_ = self_.callback_(&frame, &context); rows_ = self_.callback_(&frame, &context);
for (const auto &row : rows_) { for (const auto &row : rows_) {

View File

@ -28,7 +28,7 @@ cpp<#
(lcp:namespace query) (lcp:namespace query)
#>cpp #>cpp
class Context; struct ExecutionContext;
class ExpressionEvaluator; class ExpressionEvaluator;
class Frame; class Frame;
class SymbolTable; class SymbolTable;
@ -50,11 +50,11 @@ class Cursor {
/// ///
/// @param Frame May be read from or written to while performing the /// @param Frame May be read from or written to while performing the
/// iteration. /// iteration.
/// @param Context Used to get the position of symbols in frame and other /// @param ExecutionContext Used to get the position of symbols in frame and
/// information. /// other information.
/// ///
/// @throws QueryRuntimeException if something went wrong with execution /// @throws QueryRuntimeException if something went wrong with execution
virtual bool Pull(Frame &, Context &) = 0; virtual bool Pull(Frame &, ExecutionContext &) = 0;
/// Resets the Cursor to its initial state. /// Resets the Cursor to its initial state.
virtual void Reset() = 0; virtual void Reset() = 0;
@ -363,7 +363,7 @@ and false on every following Pull.")
class OnceCursor : public Cursor { class OnceCursor : public Cursor {
public: public:
OnceCursor() {} OnceCursor() {}
bool Pull(Frame &, Context &) override; bool Pull(Frame &, ExecutionContext &) override;
void Shutdown() override; void Shutdown() override;
void Reset() override; void Reset() override;
@ -485,7 +485,7 @@ a preceeding `MATCH`), or multiple nodes (`MATCH ... CREATE` or
class CreateNodeCursor : public Cursor { class CreateNodeCursor : public Cursor {
public: public:
CreateNodeCursor(const CreateNode &self, database::GraphDbAccessor &db); CreateNodeCursor(const CreateNode &self, database::GraphDbAccessor &db);
bool Pull(Frame &, Context &) override; bool Pull(Frame &, ExecutionContext &) override;
void Shutdown() override; void Shutdown() override;
void Reset() override; void Reset() override;
@ -596,7 +596,7 @@ chained in cases when longer paths need creating.
class CreateExpandCursor : public Cursor { class CreateExpandCursor : public Cursor {
public: public:
CreateExpandCursor(const CreateExpand &self, database::GraphDbAccessor &db); CreateExpandCursor(const CreateExpand &self, database::GraphDbAccessor &db);
bool Pull(Frame &, Context &) override; bool Pull(Frame &, ExecutionContext &) override;
void Shutdown() override; void Shutdown() override;
void Reset() override; void Reset() override;
@ -606,7 +606,7 @@ chained in cases when longer paths need creating.
const std::unique_ptr<Cursor> input_cursor_; const std::unique_ptr<Cursor> input_cursor_;
// Get the existing node (if existing_node_ == true), or create a new node // Get the existing node (if existing_node_ == true), or create a new node
VertexAccessor &OtherVertex(Frame &frame, Context &context); VertexAccessor &OtherVertex(Frame &frame, ExecutionContext &context);
/** /**
* Helper function for creating an edge and adding it * Helper function for creating an edge and adding it
@ -963,7 +963,7 @@ pulled.")
class ExpandCursor : public Cursor { class ExpandCursor : public Cursor {
public: public:
ExpandCursor(const Expand &self, database::GraphDbAccessor &db); ExpandCursor(const Expand &self, database::GraphDbAccessor &db);
bool Pull(Frame &, Context &) override; bool Pull(Frame &, ExecutionContext &) override;
void Shutdown() override; void Shutdown() override;
void Reset() override; void Reset() override;
@ -986,7 +986,7 @@ pulled.")
std::experimental::optional<OutEdgeT> out_edges_; std::experimental::optional<OutEdgeT> out_edges_;
std::experimental::optional<OutEdgeIteratorT> out_edges_it_; std::experimental::optional<OutEdgeIteratorT> out_edges_it_;
bool InitEdges(Frame &, Context &); bool InitEdges(Frame &, ExecutionContext &);
}; };
cpp<#) cpp<#)
(:serialize (:slk) (:capnp))) (:serialize (:slk) (:capnp)))
@ -1264,7 +1264,7 @@ a boolean value.")
class FilterCursor : public Cursor { class FilterCursor : public Cursor {
public: public:
FilterCursor(const Filter &self, database::GraphDbAccessor &db); FilterCursor(const Filter &self, database::GraphDbAccessor &db);
bool Pull(Frame &, Context &) override; bool Pull(Frame &, ExecutionContext &) override;
void Shutdown() override; void Shutdown() override;
void Reset() override; void Reset() override;
@ -1320,7 +1320,7 @@ RETURN clause) the Produce's pull succeeds exactly once.")
class ProduceCursor : public Cursor { class ProduceCursor : public Cursor {
public: public:
ProduceCursor(const Produce &self, database::GraphDbAccessor &db); ProduceCursor(const Produce &self, database::GraphDbAccessor &db);
bool Pull(Frame &, Context &) override; bool Pull(Frame &, ExecutionContext &) override;
void Shutdown() override; void Shutdown() override;
void Reset() override; void Reset() override;
@ -1372,7 +1372,7 @@ Has a flag for using DETACH DELETE when deleting vertices.")
class DeleteCursor : public Cursor { class DeleteCursor : public Cursor {
public: public:
DeleteCursor(const Delete &self, database::GraphDbAccessor &db); DeleteCursor(const Delete &self, database::GraphDbAccessor &db);
bool Pull(Frame &, Context &) override; bool Pull(Frame &, ExecutionContext &) override;
void Shutdown() override; void Shutdown() override;
void Reset() override; void Reset() override;
@ -1429,7 +1429,7 @@ can be stored (a TypedValue that can be converted to PropertyValue).")
class SetPropertyCursor : public Cursor { class SetPropertyCursor : public Cursor {
public: public:
SetPropertyCursor(const SetProperty &self, database::GraphDbAccessor &db); SetPropertyCursor(const SetProperty &self, database::GraphDbAccessor &db);
bool Pull(Frame &, Context &) override; bool Pull(Frame &, ExecutionContext &) override;
void Shutdown() override; void Shutdown() override;
void Reset() override; void Reset() override;
@ -1493,7 +1493,7 @@ that the old properties are discarded and replaced with new ones.")
public: public:
SetPropertiesCursor(const SetProperties &self, SetPropertiesCursor(const SetProperties &self,
database::GraphDbAccessor &db); database::GraphDbAccessor &db);
bool Pull(Frame &, Context &) override; bool Pull(Frame &, ExecutionContext &) override;
void Shutdown() override; void Shutdown() override;
void Reset() override; void Reset() override;
@ -1549,7 +1549,7 @@ It does NOT remove labels that are already set on that Vertex.")
class SetLabelsCursor : public Cursor { class SetLabelsCursor : public Cursor {
public: public:
SetLabelsCursor(const SetLabels &self, database::GraphDbAccessor &db); SetLabelsCursor(const SetLabels &self, database::GraphDbAccessor &db);
bool Pull(Frame &, Context &) override; bool Pull(Frame &, ExecutionContext &) override;
void Shutdown() override; void Shutdown() override;
void Reset() override; void Reset() override;
@ -1597,7 +1597,7 @@ It does NOT remove labels that are already set on that Vertex.")
public: public:
RemovePropertyCursor(const RemoveProperty &self, RemovePropertyCursor(const RemoveProperty &self,
database::GraphDbAccessor &db); database::GraphDbAccessor &db);
bool Pull(Frame &, Context &) override; bool Pull(Frame &, ExecutionContext &) override;
void Shutdown() override; void Shutdown() override;
void Reset() override; void Reset() override;
@ -1644,7 +1644,7 @@ If a label does not exist on a Vertex, nothing happens.")
class RemoveLabelsCursor : public Cursor { class RemoveLabelsCursor : public Cursor {
public: public:
RemoveLabelsCursor(const RemoveLabels &self, database::GraphDbAccessor &db); RemoveLabelsCursor(const RemoveLabels &self, database::GraphDbAccessor &db);
bool Pull(Frame &, Context &) override; bool Pull(Frame &, ExecutionContext &) override;
void Shutdown() override; void Shutdown() override;
void Reset() override; void Reset() override;
@ -1703,7 +1703,7 @@ edge lists).")
public: public:
EdgeUniquenessFilterCursor(const EdgeUniquenessFilter &self, EdgeUniquenessFilterCursor(const EdgeUniquenessFilter &self,
database::GraphDbAccessor &db); database::GraphDbAccessor &db);
bool Pull(Frame &, Context &) override; bool Pull(Frame &, ExecutionContext &) override;
void Shutdown() override; void Shutdown() override;
void Reset() override; void Reset() override;
@ -1773,7 +1773,7 @@ has been cached will be reconstructed before Pull returns.
class AccumulateCursor : public Cursor { class AccumulateCursor : public Cursor {
public: public:
AccumulateCursor(const Accumulate &self, database::GraphDbAccessor &db); AccumulateCursor(const Accumulate &self, database::GraphDbAccessor &db);
bool Pull(Frame &, Context &) override; bool Pull(Frame &, ExecutionContext &) override;
void Shutdown() override; void Shutdown() override;
void Reset() override; void Reset() override;
@ -1904,7 +1904,7 @@ elements are in an undefined state after aggregation.")
class AggregateCursor : public Cursor { class AggregateCursor : public Cursor {
public: public:
AggregateCursor(const Aggregate &self, database::GraphDbAccessor &db); AggregateCursor(const Aggregate &self, database::GraphDbAccessor &db);
bool Pull(Frame &, Context &) override; bool Pull(Frame &, ExecutionContext &) override;
void Shutdown() override; void Shutdown() override;
void Reset() override; void Reset() override;
@ -1953,7 +1953,7 @@ elements are in an undefined state after aggregation.")
* cache cardinality depends on number of * cache cardinality depends on number of
* aggregation results, and not on the number of inputs. * aggregation results, and not on the number of inputs.
*/ */
void ProcessAll(Frame &, Context &); void ProcessAll(Frame &, ExecutionContext &);
/** /**
* Performs a single accumulation. * Performs a single accumulation.
@ -2028,7 +2028,7 @@ operator's implementation does not expect this.")
class SkipCursor : public Cursor { class SkipCursor : public Cursor {
public: public:
SkipCursor(const Skip &self, database::GraphDbAccessor &db); SkipCursor(const Skip &self, database::GraphDbAccessor &db);
bool Pull(Frame &, Context &) override; bool Pull(Frame &, ExecutionContext &) override;
void Shutdown() override; void Shutdown() override;
void Reset() override; void Reset() override;
@ -2091,7 +2091,7 @@ input should be performed).")
class LimitCursor : public Cursor { class LimitCursor : public Cursor {
public: public:
LimitCursor(const Limit &self, database::GraphDbAccessor &db); LimitCursor(const Limit &self, database::GraphDbAccessor &db);
bool Pull(Frame &, Context &) override; bool Pull(Frame &, ExecutionContext &) override;
void Shutdown() override; void Shutdown() override;
void Reset() override; void Reset() override;
@ -2158,7 +2158,7 @@ are valid for usage after the OrderBy operator.")
class OrderByCursor : public Cursor { class OrderByCursor : public Cursor {
public: public:
OrderByCursor(const OrderBy &self, database::GraphDbAccessor &db); OrderByCursor(const OrderBy &self, database::GraphDbAccessor &db);
bool Pull(Frame &, Context &) override; bool Pull(Frame &, ExecutionContext &) override;
void Shutdown() override; void Shutdown() override;
void Reset() override; void Reset() override;
@ -2232,7 +2232,7 @@ documentation.")
class MergeCursor : public Cursor { class MergeCursor : public Cursor {
public: public:
MergeCursor(const Merge &self, database::GraphDbAccessor &db); MergeCursor(const Merge &self, database::GraphDbAccessor &db);
bool Pull(Frame &, Context &) override; bool Pull(Frame &, ExecutionContext &) override;
void Shutdown() override; void Shutdown() override;
void Reset() override; void Reset() override;
@ -2295,7 +2295,7 @@ and returns true, once.")
class OptionalCursor : public Cursor { class OptionalCursor : public Cursor {
public: public:
OptionalCursor(const Optional &self, database::GraphDbAccessor &db); OptionalCursor(const Optional &self, database::GraphDbAccessor &db);
bool Pull(Frame &, Context &) override; bool Pull(Frame &, ExecutionContext &) override;
void Shutdown() override; void Shutdown() override;
void Reset() override; void Reset() override;
@ -2354,7 +2354,7 @@ Input is optional (unwind can be the first clause in a query).")
class UnwindCursor : public Cursor { class UnwindCursor : public Cursor {
public: public:
UnwindCursor(const Unwind &self, database::GraphDbAccessor &db); UnwindCursor(const Unwind &self, database::GraphDbAccessor &db);
bool Pull(Frame &, Context &) override; bool Pull(Frame &, ExecutionContext &) override;
void Shutdown() override; void Shutdown() override;
void Reset() override; void Reset() override;
@ -2410,7 +2410,7 @@ This implementation maintains input ordering.")
public: public:
DistinctCursor(const Distinct &self, database::GraphDbAccessor &db); DistinctCursor(const Distinct &self, database::GraphDbAccessor &db);
bool Pull(Frame &, Context &) override; bool Pull(Frame &, ExecutionContext &) override;
void Shutdown() override; void Shutdown() override;
void Reset() override; void Reset() override;
@ -2479,7 +2479,7 @@ of symbols used by each of the inputs.")
class UnionCursor : public Cursor { class UnionCursor : public Cursor {
public: public:
UnionCursor(const Union &self, database::GraphDbAccessor &db); UnionCursor(const Union &self, database::GraphDbAccessor &db);
bool Pull(Frame &, Context &) override; bool Pull(Frame &, ExecutionContext &) override;
void Shutdown() override; void Shutdown() override;
void Reset() override; void Reset() override;
@ -2537,7 +2537,7 @@ of symbols used by each of the inputs.")
(lcp:define-class output-table (logical-operator) (lcp:define-class output-table (logical-operator)
((output-symbols "std::vector<Symbol>" :scope :public :dont-save t) ((output-symbols "std::vector<Symbol>" :scope :public :dont-save t)
(callback "std::function<std::vector<std::vector<TypedValue>>(Frame *, Context *)>" (callback "std::function<std::vector<std::vector<TypedValue>>(Frame *, ExecutionContext *)>"
:scope :public :dont-save t)) :scope :public :dont-save t))
(:documentation "An operator that outputs a table, producing a single row on each pull") (:documentation "An operator that outputs a table, producing a single row on each pull")
(:public (:public
@ -2545,7 +2545,7 @@ of symbols used by each of the inputs.")
OutputTable() {} OutputTable() {}
OutputTable( OutputTable(
std::vector<Symbol> output_symbols, std::vector<Symbol> output_symbols,
std::function<std::vector<std::vector<TypedValue>>(Frame *, Context *)> std::function<std::vector<std::vector<TypedValue>>(Frame *, ExecutionContext *)>
callback); callback);
OutputTable(std::vector<Symbol> output_symbols, OutputTable(std::vector<Symbol> output_symbols,
std::vector<std::vector<TypedValue>> rows); std::vector<std::vector<TypedValue>> rows);

View File

@ -11,21 +11,21 @@ namespace plan {
/** /**
* A RAII class used for profiling logical operators. Instances of this class * A RAII class used for profiling logical operators. Instances of this class
* update the profiling data stored within the `Context` object and build up a * update the profiling data stored within the `ExecutionContext` object and build
* tree of `ProfilingStats` instances. The structure of the `ProfilingStats` * up a tree of `ProfilingStats` instances. The structure of the `ProfilingStats`
* tree depends on the `LogicalOperator`s that were executed. * tree depends on the `LogicalOperator`s that were executed.
*/ */
class ScopedProfile { class ScopedProfile {
public: public:
ScopedProfile(uint64_t key, const char *name, ScopedProfile(uint64_t key, const char *name,
query::Context *context) noexcept query::ExecutionContext *context) noexcept
: context_(context) { : context_(context) {
if (UNLIKELY(context_->is_profile_query_)) { if (UNLIKELY(context_->is_profile_query)) {
root_ = context_->stats_root_; root_ = context_->stats_root;
// Are we the root logical operator? // Are we the root logical operator?
if (!root_) { if (!root_) {
stats_ = &context_->stats_; stats_ = &context_->stats;
stats_->key = key; stats_->key = key;
stats_->name = name; stats_->name = name;
} else { } else {
@ -45,23 +45,23 @@ class ScopedProfile {
} }
} }
context_->stats_root_ = stats_; context_->stats_root = stats_;
stats_->actual_hits++; stats_->actual_hits++;
start_time_ = utils::ReadTSC(); start_time_ = utils::ReadTSC();
} }
} }
~ScopedProfile() noexcept { ~ScopedProfile() noexcept {
if (UNLIKELY(context_->is_profile_query_)) { if (UNLIKELY(context_->is_profile_query)) {
stats_->num_cycles += utils::ReadTSC() - start_time_; stats_->num_cycles += utils::ReadTSC() - start_time_;
// Restore the old root ("pop") // Restore the old root ("pop")
context_->stats_root_ = root_; context_->stats_root = root_;
} }
} }
private: private:
query::Context *context_; query::ExecutionContext *context_;
ProfilingStats *root_; ProfilingStats *root_;
ProfilingStats *stats_; ProfilingStats *stats_;
unsigned long long start_time_; unsigned long long start_time_;

View File

@ -13,7 +13,7 @@ std::string AssembleQueryString(const std::string &expression_string) {
query::Query *ParseQuery(const std::string &query_string, query::Query *ParseQuery(const std::string &query_string,
query::AstStorage *ast_storage) { query::AstStorage *ast_storage) {
query::ParsingContext context; query::frontend::ParsingContext context;
query::frontend::opencypher::Parser parser(query_string); query::frontend::opencypher::Parser parser(query_string);
query::frontend::CypherMainVisitor visitor(context, ast_storage); query::frontend::CypherMainVisitor visitor(context, ast_storage);

View File

@ -436,7 +436,7 @@ void ExaminePlans(
} }
query::Query *MakeAst(const std::string &query, query::AstStorage *storage) { query::Query *MakeAst(const std::string &query, query::AstStorage *storage) {
query::ParsingContext parsing_context; query::frontend::ParsingContext parsing_context;
parsing_context.is_query_cached = false; parsing_context.is_query_cached = false;
// query -> AST // query -> AST
auto parser = std::make_unique<query::frontend::opencypher::Parser>(query); auto parser = std::make_unique<query::frontend::opencypher::Parser>(query);

View File

@ -138,7 +138,7 @@ class Yield : public query::plan::LogicalOperator {
: self_(self), : self_(self),
input_cursor_(std::move(input_cursor)), input_cursor_(std::move(input_cursor)),
pull_index_(self_->values_.size()) {} pull_index_(self_->values_.size()) {}
bool Pull(query::Frame &frame, query::Context &context) override { bool Pull(query::Frame &frame, query::ExecutionContext &context) override {
if (pull_index_ == self_->values_.size()) { if (pull_index_ == self_->values_.size()) {
if (!input_cursor_->Pull(frame, context)) return false; if (!input_cursor_->Pull(frame, context)) return false;
pull_index_ = 0; pull_index_ = 0;
@ -155,6 +155,7 @@ class Yield : public query::plan::LogicalOperator {
} }
void Shutdown() override {} void Shutdown() override {}
private: private:
const Yield *self_; const Yield *self_;
std::unique_ptr<query::plan::Cursor> input_cursor_; std::unique_ptr<query::plan::Cursor> input_cursor_;
@ -163,12 +164,12 @@ class Yield : public query::plan::LogicalOperator {
}; };
std::vector<std::vector<query::TypedValue>> PullResults( std::vector<std::vector<query::TypedValue>> PullResults(
query::plan::LogicalOperator *last_op, query::Context *context, query::plan::LogicalOperator *last_op, query::ExecutionContext *context,
std::vector<query::Symbol> output_symbols) { std::vector<query::Symbol> output_symbols) {
auto cursor = last_op->MakeCursor(context->db_accessor_); auto cursor = last_op->MakeCursor(*context->db_accessor);
std::vector<std::vector<query::TypedValue>> output; std::vector<std::vector<query::TypedValue>> output;
{ {
query::Frame frame(context->symbol_table_.max_position()); query::Frame frame(context->symbol_table.max_position());
while (cursor->Pull(frame, *context)) { while (cursor->Pull(frame, *context)) {
output.emplace_back(); output.emplace_back();
for (const auto &symbol : output_symbols) { for (const auto &symbol : output_symbols) {
@ -208,8 +209,7 @@ class Database {
bool existing_node, query::Expression *lower_bound, bool existing_node, query::Expression *lower_bound,
query::Expression *upper_bound, query::Expression *upper_bound,
const query::plan::ExpansionLambda &filter_lambda) = 0; const query::plan::ExpansionLambda &filter_lambda) = 0;
virtual std::pair<std::vector<VertexAddress>, virtual std::pair<std::vector<VertexAddress>, std::vector<EdgeAddress>>
std::vector<EdgeAddress>>
BuildGraph(database::GraphDbAccessor *dba, BuildGraph(database::GraphDbAccessor *dba,
const std::vector<int> &vertex_locations, const std::vector<int> &vertex_locations,
const std::vector<std::tuple<int, int, std::string>> &edges) = 0; const std::vector<std::tuple<int, int, std::string>> &edges) = 0;
@ -220,8 +220,8 @@ class Database {
// Returns an operator that yields vertices given by their address. We will also // Returns an operator that yields vertices given by their address. We will also
// include query::TypedValue::Null to account for the optional match case. // include query::TypedValue::Null to account for the optional match case.
std::unique_ptr<query::plan::LogicalOperator> YieldVertices( std::unique_ptr<query::plan::LogicalOperator> YieldVertices(
database::GraphDbAccessor *dba, database::GraphDbAccessor *dba, std::vector<VertexAddress> vertices,
std::vector<VertexAddress> vertices, query::Symbol symbol, query::Symbol symbol,
std::shared_ptr<query::plan::LogicalOperator> input_op) { std::shared_ptr<query::plan::LogicalOperator> input_op) {
std::vector<std::vector<query::TypedValue>> frames; std::vector<std::vector<query::TypedValue>> frames;
frames.push_back(std::vector<query::TypedValue>{query::TypedValue::Null}); frames.push_back(std::vector<query::TypedValue>{query::TypedValue::Null});
@ -235,8 +235,7 @@ std::unique_ptr<query::plan::LogicalOperator> YieldVertices(
// Returns an operator that yields edges and vertices given by their address. // Returns an operator that yields edges and vertices given by their address.
std::unique_ptr<query::plan::LogicalOperator> YieldEntities( std::unique_ptr<query::plan::LogicalOperator> YieldEntities(
database::GraphDbAccessor *dba, database::GraphDbAccessor *dba, std::vector<VertexAddress> vertices,
std::vector<VertexAddress> vertices,
std::vector<EdgeAddress> edges, query::Symbol symbol, std::vector<EdgeAddress> edges, query::Symbol symbol,
std::shared_ptr<query::plan::LogicalOperator> input_op) { std::shared_ptr<query::plan::LogicalOperator> input_op) {
std::vector<std::vector<query::TypedValue>> frames; std::vector<std::vector<query::TypedValue>> frames;
@ -308,22 +307,22 @@ void BfsTest(Database *db, int lower_bound, int upper_bound,
auto dba_ptr = db->Access(); auto dba_ptr = db->Access();
auto &dba = *dba_ptr; auto &dba = *dba_ptr;
query::AstStorage storage; query::AstStorage storage;
query::Context context(*dba_ptr); query::ExecutionContext context{dba_ptr.get()};
query::Symbol blocked_sym = query::Symbol blocked_sym =
context.symbol_table_.CreateSymbol("blocked", true); context.symbol_table.CreateSymbol("blocked", true);
query::Symbol source_sym = context.symbol_table_.CreateSymbol("source", true); query::Symbol source_sym = context.symbol_table.CreateSymbol("source", true);
query::Symbol sink_sym = context.symbol_table_.CreateSymbol("sink", true); query::Symbol sink_sym = context.symbol_table.CreateSymbol("sink", true);
query::Symbol edges_sym = context.symbol_table_.CreateSymbol("edges", true); query::Symbol edges_sym = context.symbol_table.CreateSymbol("edges", true);
query::Symbol inner_node_sym = query::Symbol inner_node_sym =
context.symbol_table_.CreateSymbol("inner_node", true); context.symbol_table.CreateSymbol("inner_node", true);
query::Symbol inner_edge_sym = query::Symbol inner_edge_sym =
context.symbol_table_.CreateSymbol("inner_edge", true); context.symbol_table.CreateSymbol("inner_edge", true);
query::Identifier *blocked = IDENT("blocked"); query::Identifier *blocked = IDENT("blocked");
query::Identifier *inner_node = IDENT("inner_node"); query::Identifier *inner_node = IDENT("inner_node");
query::Identifier *inner_edge = IDENT("inner_edge"); query::Identifier *inner_edge = IDENT("inner_edge");
context.symbol_table_[*blocked] = blocked_sym; context.symbol_table[*blocked] = blocked_sym;
context.symbol_table_[*inner_node] = inner_node_sym; context.symbol_table[*inner_node] = inner_node_sym;
context.symbol_table_[*inner_edge] = inner_edge_sym; context.symbol_table[*inner_edge] = inner_edge_sym;
std::vector<VertexAddress> vertices; std::vector<VertexAddress> vertices;
std::vector<EdgeAddress> edges; std::vector<EdgeAddress> edges;
@ -368,7 +367,7 @@ void BfsTest(Database *db, int lower_bound, int upper_bound,
{VertexAccessor(vertices[5], *dba_ptr)}}); {VertexAccessor(vertices[5], *dba_ptr)}});
filter_expr = NEQ(PROPERTY_LOOKUP(inner_node, PROPERTY_PAIR("id")), filter_expr = NEQ(PROPERTY_LOOKUP(inner_node, PROPERTY_PAIR("id")),
PARAMETER_LOOKUP(0)); PARAMETER_LOOKUP(0));
context.evaluation_context_.parameters.Add(0, 5); context.evaluation_context.parameters.Add(0, 5);
break; break;
case FilterLambdaType::ERROR: case FilterLambdaType::ERROR:
// Evaluate to 42 for vertex #5 which is on worker 1. // Evaluate to 42 for vertex #5 which is on worker 1.
@ -398,9 +397,9 @@ void BfsTest(Database *db, int lower_bound, int upper_bound,
query::plan::ExpansionLambda{inner_edge_sym, inner_node_sym, query::plan::ExpansionLambda{inner_edge_sym, inner_node_sym,
filter_expr}); filter_expr});
context.evaluation_context_.properties = context.evaluation_context.properties =
query::NamesToProperties(storage.properties_, &dba); query::NamesToProperties(storage.properties_, &dba);
context.evaluation_context_.labels = context.evaluation_context.labels =
query::NamesToLabels(storage.labels_, &dba); query::NamesToLabels(storage.labels_, &dba);
std::vector<std::vector<query::TypedValue>> results; std::vector<std::vector<query::TypedValue>> results;

View File

@ -82,16 +82,16 @@ TEST_F(DistributedQueryPlan, PullProduceRpc) {
auto produce = MakeProduce(unwind, x_ne); auto produce = MakeProduce(unwind, x_ne);
// Test that the plan works locally. // Test that the plan works locally.
Context ctx = MakeContext(storage, symbol_table, dba.get()); auto ctx = MakeContext(storage, symbol_table, dba.get());
auto results = CollectProduce(*produce, &ctx); auto results = CollectProduce(*produce, &ctx);
ASSERT_EQ(results.size(), 5); ASSERT_EQ(results.size(), 5);
const int plan_id = 42; const int plan_id = 42;
master().plan_dispatcher().DispatchPlan(plan_id, produce, ctx.symbol_table_); master().plan_dispatcher().DispatchPlan(plan_id, produce, ctx.symbol_table);
tx::CommandId command_id = dba->transaction().cid(); tx::CommandId command_id = dba->transaction().cid();
auto &evaluation_context = ctx.evaluation_context_; auto &evaluation_context = ctx.evaluation_context;
std::vector<query::Symbol> symbols{ctx.symbol_table_[*x_ne]}; std::vector<query::Symbol> symbols{ctx.symbol_table[*x_ne]};
auto remote_pull = [this, &command_id, &evaluation_context, &symbols]( auto remote_pull = [this, &command_id, &evaluation_context, &symbols](
GraphDbAccessor &dba, int worker_id) { GraphDbAccessor &dba, int worker_id) {
return master().pull_clients().Pull(&dba, worker_id, plan_id, command_id, return master().pull_clients().Pull(&dba, worker_id, plan_id, command_id,
@ -202,17 +202,17 @@ TEST_F(DistributedQueryPlan, PullProduceRpcWithGraphElements) {
}; };
// Test that the plan works locally. // Test that the plan works locally.
Context ctx = MakeContext(storage, symbol_table, dba.get()); auto ctx = MakeContext(storage, symbol_table, dba.get());
auto results = CollectProduce(*produce, &ctx); auto results = CollectProduce(*produce, &ctx);
check_result(0, results); check_result(0, results);
const int plan_id = 42; const int plan_id = 42;
master().plan_dispatcher().DispatchPlan(plan_id, produce, ctx.symbol_table_); master().plan_dispatcher().DispatchPlan(plan_id, produce, ctx.symbol_table);
tx::CommandId command_id = dba->transaction().cid(); tx::CommandId command_id = dba->transaction().cid();
auto &evaluation_context = ctx.evaluation_context_; auto &evaluation_context = ctx.evaluation_context;
std::vector<query::Symbol> symbols{ctx.symbol_table_[*return_n_r], std::vector<query::Symbol> symbols{ctx.symbol_table[*return_n_r],
ctx.symbol_table_[*return_m], p_sym}; ctx.symbol_table[*return_m], p_sym};
auto remote_pull = [this, &command_id, &evaluation_context, &symbols]( auto remote_pull = [this, &command_id, &evaluation_context, &symbols](
GraphDbAccessor &dba, int worker_id) { GraphDbAccessor &dba, int worker_id) {
return master().pull_clients().Pull(&dba, worker_id, plan_id, command_id, return master().pull_clients().Pull(&dba, worker_id, plan_id, command_id,
@ -267,7 +267,7 @@ TEST_F(DistributedQueryPlan, Synchronize) {
auto return_n_p_sym = symbol_table.CreateSymbol("n.p", true); auto return_n_p_sym = symbol_table.CreateSymbol("n.p", true);
symbol_table[*return_n_p] = return_n_p_sym; symbol_table[*return_n_p] = return_n_p_sym;
auto produce = MakeProduce(synchronize, return_n_p); auto produce = MakeProduce(synchronize, return_n_p);
Context ctx = MakeContext(storage, symbol_table, &dba); auto ctx = MakeContext(storage, symbol_table, &dba);
auto results = CollectProduce(*produce, &ctx); auto results = CollectProduce(*produce, &ctx);
ASSERT_EQ(results.size(), 2); ASSERT_EQ(results.size(), 2);
ASSERT_EQ(results[0].size(), 1); ASSERT_EQ(results[0].size(), 1);
@ -291,7 +291,7 @@ TEST_F(DistributedQueryPlan, Create) {
node.symbol = symbol_table.CreateSymbol("n", true); node.symbol = symbol_table.CreateSymbol("n", true);
auto create = auto create =
std::make_shared<query::plan::DistributedCreateNode>(unwind, node, true); std::make_shared<query::plan::DistributedCreateNode>(unwind, node, true);
Context context = MakeContext(storage, symbol_table, dba.get()); auto context = MakeContext(storage, symbol_table, dba.get());
PullAll(*create, &context); PullAll(*create, &context);
dba->Commit(); dba->Commit();
EXPECT_GT(VertexCount(master()), 200); EXPECT_GT(VertexCount(master()), 200);
@ -347,7 +347,7 @@ TEST_F(DistributedQueryPlan, PullRemoteOrderBy) {
auto n_p_ne = NEXPR("n.prop", n_p); auto n_p_ne = NEXPR("n.prop", n_p);
symbol_table[*n_p_ne] = symbol_table.CreateSymbol("n.prop", true); symbol_table[*n_p_ne] = symbol_table.CreateSymbol("n.prop", true);
auto produce = MakeProduce(pull_remote_order_by, n_p_ne); auto produce = MakeProduce(pull_remote_order_by, n_p_ne);
Context ctx = MakeContext(storage, symbol_table, &dba); auto ctx = MakeContext(storage, symbol_table, &dba);
auto results = CollectProduce(*produce, &ctx); auto results = CollectProduce(*produce, &ctx);
ASSERT_EQ(results.size(), 300); ASSERT_EQ(results.size(), 300);

View File

@ -19,7 +19,7 @@ TEST_F(DistributedReset, ResetTest) {
master().plan_dispatcher().DispatchPlan(42, once, symbol_table); master().plan_dispatcher().DispatchPlan(42, once, symbol_table);
auto dba = master().Access(); auto dba = master().Access();
query::Frame frame(0); query::Frame frame(0);
query::Context context(*dba); query::ExecutionContext context{dba.get()};
auto pull_remote_cursor = pull_remote->MakeCursor(*dba); auto pull_remote_cursor = pull_remote->MakeCursor(*dba);
for (int i = 0; i < 3; ++i) { for (int i = 0; i < 3; ++i) {

View File

@ -68,7 +68,7 @@ TEST(QueryPlan, Accumulate) {
auto m_p_ne = NEXPR("m.p", m_p); auto m_p_ne = NEXPR("m.p", m_p);
symbol_table[*m_p_ne] = symbol_table.CreateSymbol("m_p_ne", true); symbol_table[*m_p_ne] = symbol_table.CreateSymbol("m_p_ne", true);
auto produce = MakeProduce(last_op, n_p_ne, m_p_ne); auto produce = MakeProduce(last_op, n_p_ne, m_p_ne);
Context context = MakeContext(storage, symbol_table, &dba); auto context = MakeContext(storage, symbol_table, &dba);
auto results = CollectProduce(*produce, &context); auto results = CollectProduce(*produce, &context);
std::vector<int> results_data; std::vector<int> results_data;
for (const auto &row : results) for (const auto &row : results)
@ -98,7 +98,7 @@ TEST(QueryPlan, AccumulateAdvance) {
auto accumulate = std::make_shared<Accumulate>( auto accumulate = std::make_shared<Accumulate>(
create, std::vector<Symbol>{node.symbol}, advance); create, std::vector<Symbol>{node.symbol}, advance);
auto match = MakeScanAll(storage, symbol_table, "m", accumulate); auto match = MakeScanAll(storage, symbol_table, "m", accumulate);
Context context = MakeContext(storage, symbol_table, dba.get()); auto context = MakeContext(storage, symbol_table, dba.get());
EXPECT_EQ(advance ? 1 : 0, PullAll(*match.op_, &context)); EXPECT_EQ(advance ? 1 : 0, PullAll(*match.op_, &context));
}; };
check(false); check(false);
@ -189,7 +189,7 @@ class QueryPlanAggregateOps : public ::testing::Test {
auto produce = auto produce =
MakeAggregationProduce(n.op_, symbol_table, storage, MakeAggregationProduce(n.op_, symbol_table, storage,
aggregation_expressions, ops, group_bys, {}); aggregation_expressions, ops, group_bys, {});
Context context = MakeContext(storage, symbol_table, &dba); auto context = MakeContext(storage, symbol_table, &dba);
return CollectProduce(*produce, &context); return CollectProduce(*produce, &context);
} }
}; };
@ -333,7 +333,7 @@ TEST(QueryPlan, AggregateGroupByValues) {
MakeAggregationProduce(n.op_, symbol_table, storage, {n_p}, MakeAggregationProduce(n.op_, symbol_table, storage, {n_p},
{Aggregation::Op::COUNT}, {n_p}, {n.sym_}); {Aggregation::Op::COUNT}, {n_p}, {n.sym_});
Context context = MakeContext(storage, symbol_table, &dba); auto context = MakeContext(storage, symbol_table, &dba);
auto results = CollectProduce(*produce, &context); auto results = CollectProduce(*produce, &context);
ASSERT_EQ(results.size(), group_by_vals.size() - 2); ASSERT_EQ(results.size(), group_by_vals.size() - 2);
TypedValue::unordered_set result_group_bys; TypedValue::unordered_set result_group_bys;
@ -382,7 +382,7 @@ TEST(QueryPlan, AggregateMultipleGroupBy) {
{Aggregation::Op::COUNT}, {Aggregation::Op::COUNT},
{n_p1, n_p2, n_p3}, {n.sym_}); {n_p1, n_p2, n_p3}, {n.sym_});
Context context = MakeContext(storage, symbol_table, &dba); auto context = MakeContext(storage, symbol_table, &dba);
auto results = CollectProduce(*produce, &context); auto results = CollectProduce(*produce, &context);
EXPECT_EQ(results.size(), 2 * 3 * 5); EXPECT_EQ(results.size(), 2 * 3 * 5);
} }
@ -399,7 +399,7 @@ TEST(QueryPlan, AggregateNoInput) {
auto produce = MakeAggregationProduce(nullptr, symbol_table, storage, {two}, auto produce = MakeAggregationProduce(nullptr, symbol_table, storage, {two},
{Aggregation::Op::COUNT}, {}, {}); {Aggregation::Op::COUNT}, {}, {});
Context context = MakeContext(storage, symbol_table, dba.get()); auto context = MakeContext(storage, symbol_table, dba.get());
auto results = CollectProduce(*produce, &context); auto results = CollectProduce(*produce, &context);
EXPECT_EQ(1, results.size()); EXPECT_EQ(1, results.size());
EXPECT_EQ(1, results[0].size()); EXPECT_EQ(1, results[0].size());
@ -433,7 +433,7 @@ TEST(QueryPlan, AggregateCountEdgeCases) {
auto count = [&]() { auto count = [&]() {
auto produce = MakeAggregationProduce(n.op_, symbol_table, storage, {n_p}, auto produce = MakeAggregationProduce(n.op_, symbol_table, storage, {n_p},
{Aggregation::Op::COUNT}, {}, {}); {Aggregation::Op::COUNT}, {}, {});
Context context = MakeContext(storage, symbol_table, &dba); auto context = MakeContext(storage, symbol_table, &dba);
auto results = CollectProduce(*produce, &context); auto results = CollectProduce(*produce, &context);
if (results.size() == 0) return -1L; if (results.size() == 0) return -1L;
EXPECT_EQ(1, results.size()); EXPECT_EQ(1, results.size());
@ -494,7 +494,7 @@ TEST(QueryPlan, AggregateFirstValueTypes) {
auto aggregate = [&](Expression *expression, Aggregation::Op aggr_op) { auto aggregate = [&](Expression *expression, Aggregation::Op aggr_op) {
auto produce = MakeAggregationProduce(n.op_, symbol_table, storage, auto produce = MakeAggregationProduce(n.op_, symbol_table, storage,
{expression}, {aggr_op}, {}, {}); {expression}, {aggr_op}, {}, {});
Context context = MakeContext(storage, symbol_table, &dba); auto context = MakeContext(storage, symbol_table, &dba);
CollectProduce(*produce, &context); CollectProduce(*produce, &context);
}; };
@ -553,7 +553,7 @@ TEST(QueryPlan, AggregateTypes) {
auto aggregate = [&](Expression *expression, Aggregation::Op aggr_op) { auto aggregate = [&](Expression *expression, Aggregation::Op aggr_op) {
auto produce = MakeAggregationProduce(n.op_, symbol_table, storage, auto produce = MakeAggregationProduce(n.op_, symbol_table, storage,
{expression}, {aggr_op}, {}, {}); {expression}, {aggr_op}, {}, {});
Context context = MakeContext(storage, symbol_table, &dba); auto context = MakeContext(storage, symbol_table, &dba);
CollectProduce(*produce, &context); CollectProduce(*produce, &context);
}; };
@ -611,7 +611,7 @@ TEST(QueryPlan, Unwind) {
symbol_table[*y_ne] = symbol_table.CreateSymbol("y_ne", true); symbol_table[*y_ne] = symbol_table.CreateSymbol("y_ne", true);
auto produce = MakeProduce(unwind_1, x_ne, y_ne); auto produce = MakeProduce(unwind_1, x_ne, y_ne);
Context context = MakeContext(storage, symbol_table, dba.get()); auto context = MakeContext(storage, symbol_table, dba.get());
auto results = CollectProduce(*produce, &context); auto results = CollectProduce(*produce, &context);
ASSERT_EQ(4, results.size()); ASSERT_EQ(4, results.size());
const std::vector<int> expected_x_card{3, 3, 3, 1}; const std::vector<int> expected_x_card{3, 3, 3, 1};

View File

@ -31,7 +31,7 @@ TEST(QueryPlan, Skip) {
auto n = MakeScanAll(storage, symbol_table, "n1"); auto n = MakeScanAll(storage, symbol_table, "n1");
auto skip = std::make_shared<plan::Skip>(n.op_, LITERAL(2)); auto skip = std::make_shared<plan::Skip>(n.op_, LITERAL(2));
Context context = MakeContext(storage, symbol_table, dba.get()); auto context = MakeContext(storage, symbol_table, dba.get());
EXPECT_EQ(0, PullAll(*skip, &context)); EXPECT_EQ(0, PullAll(*skip, &context));
dba->InsertVertex(); dba->InsertVertex();
@ -61,7 +61,7 @@ TEST(QueryPlan, Limit) {
auto n = MakeScanAll(storage, symbol_table, "n1"); auto n = MakeScanAll(storage, symbol_table, "n1");
auto skip = std::make_shared<plan::Limit>(n.op_, LITERAL(2)); auto skip = std::make_shared<plan::Limit>(n.op_, LITERAL(2));
Context context = MakeContext(storage, symbol_table, dba.get()); auto context = MakeContext(storage, symbol_table, dba.get());
EXPECT_EQ(0, PullAll(*skip, &context)); EXPECT_EQ(0, PullAll(*skip, &context));
dba->InsertVertex(); dba->InsertVertex();
@ -100,7 +100,7 @@ TEST(QueryPlan, CreateLimit) {
auto c = std::make_shared<CreateNode>(n.op_, m); auto c = std::make_shared<CreateNode>(n.op_, m);
auto skip = std::make_shared<plan::Limit>(c, LITERAL(1)); auto skip = std::make_shared<plan::Limit>(c, LITERAL(1));
Context context = MakeContext(storage, symbol_table, dba.get()); auto context = MakeContext(storage, symbol_table, dba.get());
EXPECT_EQ(1, PullAll(*skip, &context)); EXPECT_EQ(1, PullAll(*skip, &context));
dba->AdvanceCommand(); dba->AdvanceCommand();
EXPECT_EQ(3, CountIterable(dba->Vertices(false))); EXPECT_EQ(3, CountIterable(dba->Vertices(false)));
@ -159,7 +159,7 @@ TEST(QueryPlan, OrderBy) {
auto n_p_ne = NEXPR("n.p", n_p); auto n_p_ne = NEXPR("n.p", n_p);
symbol_table[*n_p_ne] = symbol_table.CreateSymbol("n.p", true); symbol_table[*n_p_ne] = symbol_table.CreateSymbol("n.p", true);
auto produce = MakeProduce(order_by, n_p_ne); auto produce = MakeProduce(order_by, n_p_ne);
Context context = MakeContext(storage, symbol_table, &dba); auto context = MakeContext(storage, symbol_table, &dba);
auto results = CollectProduce(*produce, &context); auto results = CollectProduce(*produce, &context);
ASSERT_EQ(values.size(), results.size()); ASSERT_EQ(values.size(), results.size());
for (int j = 0; j < results.size(); ++j) for (int j = 0; j < results.size(); ++j)
@ -214,7 +214,7 @@ TEST(QueryPlan, OrderByMultiple) {
auto n_p2_ne = NEXPR("n.p2", n_p2); auto n_p2_ne = NEXPR("n.p2", n_p2);
symbol_table[*n_p2_ne] = symbol_table.CreateSymbol("n.p2", true); symbol_table[*n_p2_ne] = symbol_table.CreateSymbol("n.p2", true);
auto produce = MakeProduce(order_by, n_p1_ne, n_p2_ne); auto produce = MakeProduce(order_by, n_p1_ne, n_p2_ne);
Context context = MakeContext(storage, symbol_table, &dba); auto context = MakeContext(storage, symbol_table, &dba);
auto results = CollectProduce(*produce, &context); auto results = CollectProduce(*produce, &context);
ASSERT_EQ(N * N, results.size()); ASSERT_EQ(N * N, results.size());
for (int j = 0; j < N * N; ++j) { for (int j = 0; j < N * N; ++j) {
@ -266,7 +266,7 @@ TEST(QueryPlan, OrderByExceptions) {
auto order_by = std::make_shared<plan::OrderBy>( auto order_by = std::make_shared<plan::OrderBy>(
n.op_, std::vector<SortItem>{{Ordering::ASC, n_p}}, n.op_, std::vector<SortItem>{{Ordering::ASC, n_p}},
std::vector<Symbol>{}); std::vector<Symbol>{});
Context context = MakeContext(storage, symbol_table, &dba); auto context = MakeContext(storage, symbol_table, &dba);
EXPECT_THROW(PullAll(*order_by, &context), QueryRuntimeException); EXPECT_THROW(PullAll(*order_by, &context), QueryRuntimeException);
} }
} }

View File

@ -17,20 +17,21 @@ using namespace query::plan;
using Bound = ScanAllByLabelPropertyRange::Bound; using Bound = ScanAllByLabelPropertyRange::Bound;
Context MakeContext(const AstStorage &storage, const SymbolTable &symbol_table, ExecutionContext MakeContext(const AstStorage &storage,
database::GraphDbAccessor *dba) { const SymbolTable &symbol_table,
Context context(*dba); database::GraphDbAccessor *dba) {
context.symbol_table_ = symbol_table; ExecutionContext context{dba};
context.evaluation_context_.properties = context.symbol_table = symbol_table;
context.evaluation_context.properties =
NamesToProperties(storage.properties_, dba); NamesToProperties(storage.properties_, dba);
context.evaluation_context_.labels = NamesToLabels(storage.labels_, dba); context.evaluation_context.labels = NamesToLabels(storage.labels_, dba);
return context; return context;
} }
/** Helper function that collects all the results from the given Produce. */ /** Helper function that collects all the results from the given Produce. */
std::vector<std::vector<TypedValue>> CollectProduce(const Produce &produce, std::vector<std::vector<TypedValue>> CollectProduce(const Produce &produce,
Context *context) { ExecutionContext *context) {
Frame frame(context->symbol_table_.max_position()); Frame frame(context->symbol_table.max_position());
// top level node in the operator tree is a produce (return) // top level node in the operator tree is a produce (return)
// so stream out results // so stream out results
@ -38,10 +39,10 @@ std::vector<std::vector<TypedValue>> CollectProduce(const Produce &produce,
// collect the symbols from the return clause // collect the symbols from the return clause
std::vector<Symbol> symbols; std::vector<Symbol> symbols;
for (auto named_expression : produce.named_expressions_) for (auto named_expression : produce.named_expressions_)
symbols.emplace_back(context->symbol_table_[*named_expression]); symbols.emplace_back(context->symbol_table[*named_expression]);
// stream out results // stream out results
auto cursor = produce.MakeCursor(context->db_accessor_); auto cursor = produce.MakeCursor(*context->db_accessor);
std::vector<std::vector<TypedValue>> results; std::vector<std::vector<TypedValue>> results;
while (cursor->Pull(frame, *context)) { while (cursor->Pull(frame, *context)) {
std::vector<TypedValue> values; std::vector<TypedValue> values;
@ -52,9 +53,9 @@ std::vector<std::vector<TypedValue>> CollectProduce(const Produce &produce,
return results; return results;
} }
int PullAll(const LogicalOperator &logical_op, Context *context) { int PullAll(const LogicalOperator &logical_op, ExecutionContext *context) {
Frame frame(context->symbol_table_.max_position()); Frame frame(context->symbol_table.max_position());
auto cursor = logical_op.MakeCursor(context->db_accessor_); auto cursor = logical_op.MakeCursor(*context->db_accessor);
int count = 0; int count = 0;
while (cursor->Pull(frame, *context)) count++; while (cursor->Pull(frame, *context)) count++;
return count; return count;

View File

@ -33,7 +33,7 @@ TEST(QueryPlan, CreateNodeWithAttributes) {
node.properties.emplace_back(property.second, LITERAL(42)); node.properties.emplace_back(property.second, LITERAL(42));
auto create = std::make_shared<CreateNode>(nullptr, node); auto create = std::make_shared<CreateNode>(nullptr, node);
Context context = MakeContext(storage, symbol_table, &dba); auto context = MakeContext(storage, symbol_table, &dba);
PullAll(*create, &context); PullAll(*create, &context);
dba.AdvanceCommand(); dba.AdvanceCommand();
@ -80,7 +80,7 @@ TEST(QueryPlan, CreateReturn) {
symbol_table[*named_expr_n->expression_] = node.symbol; symbol_table[*named_expr_n->expression_] = node.symbol;
auto produce = MakeProduce(create, named_expr_n, named_expr_n_p); auto produce = MakeProduce(create, named_expr_n, named_expr_n_p);
Context context = MakeContext(storage, symbol_table, &dba); auto context = MakeContext(storage, symbol_table, &dba);
auto results = CollectProduce(*produce, &context); auto results = CollectProduce(*produce, &context);
EXPECT_EQ(1, results.size()); EXPECT_EQ(1, results.size());
EXPECT_EQ(2, results[0].size()); EXPECT_EQ(2, results[0].size());
@ -132,7 +132,7 @@ TEST(QueryPlan, CreateExpand) {
auto create_op = std::make_shared<CreateNode>(nullptr, n); auto create_op = std::make_shared<CreateNode>(nullptr, n);
auto create_expand = auto create_expand =
std::make_shared<CreateExpand>(m, r, create_op, n.symbol, cycle); std::make_shared<CreateExpand>(m, r, create_op, n.symbol, cycle);
Context context = MakeContext(storage, symbol_table, &dba); auto context = MakeContext(storage, symbol_table, &dba);
PullAll(*create_expand, &context); PullAll(*create_expand, &context);
dba.AdvanceCommand(); dba.AdvanceCommand();
@ -188,7 +188,7 @@ TEST(QueryPlan, MatchCreateNode) {
auto create_node = std::make_shared<CreateNode>(n_scan_all.op_, m); auto create_node = std::make_shared<CreateNode>(n_scan_all.op_, m);
EXPECT_EQ(CountIterable(dba->Vertices(false)), 3); EXPECT_EQ(CountIterable(dba->Vertices(false)), 3);
Context context = MakeContext(storage, symbol_table, dba.get()); auto context = MakeContext(storage, symbol_table, dba.get());
PullAll(*create_node, &context); PullAll(*create_node, &context);
dba->AdvanceCommand(); dba->AdvanceCommand();
EXPECT_EQ(CountIterable(dba->Vertices(false)), 6); EXPECT_EQ(CountIterable(dba->Vertices(false)), 6);
@ -231,7 +231,7 @@ TEST(QueryPlan, MatchCreateExpand) {
auto create_expand = std::make_shared<CreateExpand>(m, r, n_scan_all.op_, auto create_expand = std::make_shared<CreateExpand>(m, r, n_scan_all.op_,
n_scan_all.sym_, cycle); n_scan_all.sym_, cycle);
Context context = MakeContext(storage, symbol_table, dba.get()); auto context = MakeContext(storage, symbol_table, dba.get());
PullAll(*create_expand, &context); PullAll(*create_expand, &context);
dba->AdvanceCommand(); dba->AdvanceCommand();
@ -271,7 +271,7 @@ TEST(QueryPlan, Delete) {
symbol_table[*n_get] = n.sym_; symbol_table[*n_get] = n.sym_;
auto delete_op = std::make_shared<plan::Delete>( auto delete_op = std::make_shared<plan::Delete>(
n.op_, std::vector<Expression *>{n_get}, false); n.op_, std::vector<Expression *>{n_get}, false);
Context context = MakeContext(storage, symbol_table, dba.get()); auto context = MakeContext(storage, symbol_table, dba.get());
EXPECT_THROW(PullAll(*delete_op, &context), QueryRuntimeException); EXPECT_THROW(PullAll(*delete_op, &context), QueryRuntimeException);
dba->AdvanceCommand(); dba->AdvanceCommand();
EXPECT_EQ(4, CountIterable(dba->Vertices(false))); EXPECT_EQ(4, CountIterable(dba->Vertices(false)));
@ -286,7 +286,7 @@ TEST(QueryPlan, Delete) {
auto delete_op = std::make_shared<plan::Delete>( auto delete_op = std::make_shared<plan::Delete>(
n.op_, std::vector<Expression *>{n_get}, true); n.op_, std::vector<Expression *>{n_get}, true);
Frame frame(symbol_table.max_position()); Frame frame(symbol_table.max_position());
Context context = MakeContext(storage, symbol_table, dba.get()); auto context = MakeContext(storage, symbol_table, dba.get());
delete_op->MakeCursor(*dba)->Pull(frame, context); delete_op->MakeCursor(*dba)->Pull(frame, context);
dba->AdvanceCommand(); dba->AdvanceCommand();
EXPECT_EQ(3, CountIterable(dba->Vertices(false))); EXPECT_EQ(3, CountIterable(dba->Vertices(false)));
@ -303,7 +303,7 @@ TEST(QueryPlan, Delete) {
symbol_table[*r_get] = r_m.edge_sym_; symbol_table[*r_get] = r_m.edge_sym_;
auto delete_op = std::make_shared<plan::Delete>( auto delete_op = std::make_shared<plan::Delete>(
r_m.op_, std::vector<Expression *>{r_get}, false); r_m.op_, std::vector<Expression *>{r_get}, false);
Context context = MakeContext(storage, symbol_table, dba.get()); auto context = MakeContext(storage, symbol_table, dba.get());
PullAll(*delete_op, &context); PullAll(*delete_op, &context);
dba->AdvanceCommand(); dba->AdvanceCommand();
EXPECT_EQ(3, CountIterable(dba->Vertices(false))); EXPECT_EQ(3, CountIterable(dba->Vertices(false)));
@ -317,7 +317,7 @@ TEST(QueryPlan, Delete) {
symbol_table[*n_get] = n.sym_; symbol_table[*n_get] = n.sym_;
auto delete_op = std::make_shared<plan::Delete>( auto delete_op = std::make_shared<plan::Delete>(
n.op_, std::vector<Expression *>{n_get}, false); n.op_, std::vector<Expression *>{n_get}, false);
Context context = MakeContext(storage, symbol_table, dba.get()); auto context = MakeContext(storage, symbol_table, dba.get());
PullAll(*delete_op, &context); PullAll(*delete_op, &context);
dba->AdvanceCommand(); dba->AdvanceCommand();
EXPECT_EQ(0, CountIterable(dba->Vertices(false))); EXPECT_EQ(0, CountIterable(dba->Vertices(false)));
@ -366,7 +366,7 @@ TEST(QueryPlan, DeleteTwiceDeleteBlockingEdge) {
auto delete_op = std::make_shared<plan::Delete>( auto delete_op = std::make_shared<plan::Delete>(
r_m.op_, std::vector<Expression *>{n_get, r_get, m_get}, detach); r_m.op_, std::vector<Expression *>{n_get, r_get, m_get}, detach);
Context context = MakeContext(storage, symbol_table, dba.get()); auto context = MakeContext(storage, symbol_table, dba.get());
EXPECT_EQ(2, PullAll(*delete_op, &context)); EXPECT_EQ(2, PullAll(*delete_op, &context));
dba->AdvanceCommand(); dba->AdvanceCommand();
EXPECT_EQ(0, CountIterable(dba->Vertices(false))); EXPECT_EQ(0, CountIterable(dba->Vertices(false)));
@ -409,7 +409,7 @@ TEST(QueryPlan, DeleteReturn) {
symbol_table[*n_p] = symbol_table.CreateSymbol("bla", true); symbol_table[*n_p] = symbol_table.CreateSymbol("bla", true);
auto produce = MakeProduce(delete_op, n_p); auto produce = MakeProduce(delete_op, n_p);
Context context = MakeContext(storage, symbol_table, &dba); auto context = MakeContext(storage, symbol_table, &dba);
auto results = CollectProduce(*produce, &context); auto results = CollectProduce(*produce, &context);
EXPECT_EQ(4, results.size()); EXPECT_EQ(4, results.size());
dba.AdvanceCommand(); dba.AdvanceCommand();
@ -426,7 +426,7 @@ TEST(QueryPlan, DeleteNull) {
auto once = std::make_shared<Once>(); auto once = std::make_shared<Once>();
auto delete_op = std::make_shared<plan::Delete>( auto delete_op = std::make_shared<plan::Delete>(
once, std::vector<Expression *>{LITERAL(TypedValue::Null)}, false); once, std::vector<Expression *>{LITERAL(TypedValue::Null)}, false);
Context context = MakeContext(storage, symbol_table, dba.get()); auto context = MakeContext(storage, symbol_table, dba.get());
EXPECT_EQ(1, PullAll(*delete_op, &context)); EXPECT_EQ(1, PullAll(*delete_op, &context));
} }
@ -455,7 +455,7 @@ TEST(QueryPlan, DeleteAdvance) {
n.op_, std::vector<Expression *>{n_get}, false); n.op_, std::vector<Expression *>{n_get}, false);
auto advance = std::make_shared<Accumulate>( auto advance = std::make_shared<Accumulate>(
delete_op, std::vector<Symbol>{n.sym_}, true); delete_op, std::vector<Symbol>{n.sym_}, true);
Context context = MakeContext(storage, symbol_table, dba.get()); auto context = MakeContext(storage, symbol_table, dba.get());
EXPECT_THROW(PullAll(*advance, &context), ReconstructionException); EXPECT_THROW(PullAll(*advance, &context), ReconstructionException);
} }
@ -498,7 +498,7 @@ TEST(QueryPlan, SetProperty) {
symbol_table[*r_p->expression_] = r_m.edge_sym_; symbol_table[*r_p->expression_] = r_m.edge_sym_;
auto set_r_p = auto set_r_p =
std::make_shared<plan::SetProperty>(set_n_p, prop1, r_p, literal); std::make_shared<plan::SetProperty>(set_n_p, prop1, r_p, literal);
Context context = MakeContext(storage, symbol_table, &dba); auto context = MakeContext(storage, symbol_table, &dba);
EXPECT_EQ(2, PullAll(*set_r_p, &context)); EXPECT_EQ(2, PullAll(*set_r_p, &context));
dba.AdvanceCommand(); dba.AdvanceCommand();
@ -552,7 +552,7 @@ TEST(QueryPlan, SetProperties) {
std::make_shared<plan::SetProperties>(r_m.op_, n.sym_, r_ident, op); std::make_shared<plan::SetProperties>(r_m.op_, n.sym_, r_ident, op);
auto set_m_to_r = std::make_shared<plan::SetProperties>( auto set_m_to_r = std::make_shared<plan::SetProperties>(
set_r_to_n, r_m.edge_sym_, m_ident, op); set_r_to_n, r_m.edge_sym_, m_ident, op);
Context context = MakeContext(storage, symbol_table, dba.get()); auto context = MakeContext(storage, symbol_table, dba.get());
EXPECT_EQ(1, PullAll(*set_m_to_r, &context)); EXPECT_EQ(1, PullAll(*set_m_to_r, &context));
dba->AdvanceCommand(); dba->AdvanceCommand();
@ -603,7 +603,7 @@ TEST(QueryPlan, SetLabels) {
auto n = MakeScanAll(storage, symbol_table, "n"); auto n = MakeScanAll(storage, symbol_table, "n");
auto label_set = std::make_shared<plan::SetLabels>( auto label_set = std::make_shared<plan::SetLabels>(
n.op_, n.sym_, std::vector<storage::Label>{label2, label3}); n.op_, n.sym_, std::vector<storage::Label>{label2, label3});
Context context = MakeContext(storage, symbol_table, dba.get()); auto context = MakeContext(storage, symbol_table, dba.get());
EXPECT_EQ(2, PullAll(*label_set, &context)); EXPECT_EQ(2, PullAll(*label_set, &context));
for (VertexAccessor vertex : dba->Vertices(false)) { for (VertexAccessor vertex : dba->Vertices(false)) {
@ -654,7 +654,7 @@ TEST(QueryPlan, RemoveProperty) {
auto r_p = PROPERTY_LOOKUP("r", prop1); auto r_p = PROPERTY_LOOKUP("r", prop1);
symbol_table[*r_p->expression_] = r_m.edge_sym_; symbol_table[*r_p->expression_] = r_m.edge_sym_;
auto set_r_p = std::make_shared<plan::RemoveProperty>(set_n_p, prop1, r_p); auto set_r_p = std::make_shared<plan::RemoveProperty>(set_n_p, prop1, r_p);
Context context = MakeContext(storage, symbol_table, &dba); auto context = MakeContext(storage, symbol_table, &dba);
EXPECT_EQ(2, PullAll(*set_r_p, &context)); EXPECT_EQ(2, PullAll(*set_r_p, &context));
dba.AdvanceCommand(); dba.AdvanceCommand();
@ -691,7 +691,7 @@ TEST(QueryPlan, RemoveLabels) {
auto n = MakeScanAll(storage, symbol_table, "n"); auto n = MakeScanAll(storage, symbol_table, "n");
auto label_remove = std::make_shared<plan::RemoveLabels>( auto label_remove = std::make_shared<plan::RemoveLabels>(
n.op_, n.sym_, std::vector<storage::Label>{label1, label2}); n.op_, n.sym_, std::vector<storage::Label>{label1, label2});
Context context = MakeContext(storage, symbol_table, dba.get()); auto context = MakeContext(storage, symbol_table, dba.get());
EXPECT_EQ(2, PullAll(*label_remove, &context)); EXPECT_EQ(2, PullAll(*label_remove, &context));
for (VertexAccessor vertex : dba->Vertices(false)) { for (VertexAccessor vertex : dba->Vertices(false)) {
@ -738,7 +738,7 @@ TEST(QueryPlan, NodeFilterSet) {
auto add = ADD(set_prop, LITERAL(1)); auto add = ADD(set_prop, LITERAL(1));
auto set = std::make_shared<plan::SetProperty>(node_filter, prop.second, auto set = std::make_shared<plan::SetProperty>(node_filter, prop.second,
set_prop, add); set_prop, add);
Context context = MakeContext(storage, symbol_table, &dba); auto context = MakeContext(storage, symbol_table, &dba);
EXPECT_EQ(2, PullAll(*set, &context)); EXPECT_EQ(2, PullAll(*set, &context));
dba.AdvanceCommand(); dba.AdvanceCommand();
v1.Reconstruct(); v1.Reconstruct();
@ -780,7 +780,7 @@ TEST(QueryPlan, FilterRemove) {
symbol_table[*rem_prop->expression_] = scan_all.sym_; symbol_table[*rem_prop->expression_] = scan_all.sym_;
auto rem = auto rem =
std::make_shared<plan::RemoveProperty>(filter, prop.second, rem_prop); std::make_shared<plan::RemoveProperty>(filter, prop.second, rem_prop);
Context context = MakeContext(storage, symbol_table, &dba); auto context = MakeContext(storage, symbol_table, &dba);
EXPECT_EQ(2, PullAll(*rem, &context)); EXPECT_EQ(2, PullAll(*rem, &context));
dba.AdvanceCommand(); dba.AdvanceCommand();
v1.Reconstruct(); v1.Reconstruct();
@ -804,7 +804,7 @@ TEST(QueryPlan, SetRemove) {
scan_all.op_, scan_all.sym_, std::vector<storage::Label>{label1, label2}); scan_all.op_, scan_all.sym_, std::vector<storage::Label>{label1, label2});
auto rem = std::make_shared<plan::RemoveLabels>( auto rem = std::make_shared<plan::RemoveLabels>(
set, scan_all.sym_, std::vector<storage::Label>{label1, label2}); set, scan_all.sym_, std::vector<storage::Label>{label1, label2});
Context context = MakeContext(storage, symbol_table, dba.get()); auto context = MakeContext(storage, symbol_table, dba.get());
EXPECT_EQ(1, PullAll(*rem, &context)); EXPECT_EQ(1, PullAll(*rem, &context));
dba->AdvanceCommand(); dba->AdvanceCommand();
v.Reconstruct(); v.Reconstruct();
@ -850,7 +850,7 @@ TEST(QueryPlan, Merge) {
std::make_shared<Once>(), prop.second, n_p, LITERAL(2)); std::make_shared<Once>(), prop.second, n_p, LITERAL(2));
auto merge = std::make_shared<plan::Merge>(n.op_, m_set, n_set); auto merge = std::make_shared<plan::Merge>(n.op_, m_set, n_set);
Context context = MakeContext(storage, symbol_table, &dba); auto context = MakeContext(storage, symbol_table, &dba);
ASSERT_EQ(3, PullAll(*merge, &context)); ASSERT_EQ(3, PullAll(*merge, &context));
dba.AdvanceCommand(); dba.AdvanceCommand();
v1.Reconstruct(); v1.Reconstruct();
@ -879,7 +879,7 @@ TEST(QueryPlan, MergeNoInput) {
auto merge = std::make_shared<plan::Merge>(nullptr, create, create); auto merge = std::make_shared<plan::Merge>(nullptr, create, create);
EXPECT_EQ(0, CountIterable(dba->Vertices(false))); EXPECT_EQ(0, CountIterable(dba->Vertices(false)));
Context context = MakeContext(storage, symbol_table, dba.get()); auto context = MakeContext(storage, symbol_table, dba.get());
EXPECT_EQ(1, PullAll(*merge, &context)); EXPECT_EQ(1, PullAll(*merge, &context));
dba->AdvanceCommand(); dba->AdvanceCommand();
EXPECT_EQ(1, CountIterable(dba->Vertices(false))); EXPECT_EQ(1, CountIterable(dba->Vertices(false)));
@ -899,7 +899,7 @@ TEST(QueryPlan, SetPropertyOnNull) {
auto once = std::make_shared<Once>(); auto once = std::make_shared<Once>();
auto set_op = auto set_op =
std::make_shared<plan::SetProperty>(once, prop.second, n_prop, literal); std::make_shared<plan::SetProperty>(once, prop.second, n_prop, literal);
Context context = MakeContext(storage, symbol_table, &dba); auto context = MakeContext(storage, symbol_table, &dba);
EXPECT_EQ(1, PullAll(*set_op, &context)); EXPECT_EQ(1, PullAll(*set_op, &context));
} }
@ -917,7 +917,7 @@ TEST(QueryPlan, SetPropertiesOnNull) {
auto set_op = std::make_shared<plan::SetProperties>( auto set_op = std::make_shared<plan::SetProperties>(
optional, n.sym_, n_ident, plan::SetProperties::Op::REPLACE); optional, n.sym_, n_ident, plan::SetProperties::Op::REPLACE);
EXPECT_EQ(0, CountIterable(dba->Vertices(false))); EXPECT_EQ(0, CountIterable(dba->Vertices(false)));
Context context = MakeContext(storage, symbol_table, dba.get()); auto context = MakeContext(storage, symbol_table, dba.get());
EXPECT_EQ(1, PullAll(*set_op, &context)); EXPECT_EQ(1, PullAll(*set_op, &context));
} }
@ -936,7 +936,7 @@ TEST(QueryPlan, SetLabelsOnNull) {
auto set_op = std::make_shared<plan::SetLabels>( auto set_op = std::make_shared<plan::SetLabels>(
optional, n.sym_, std::vector<storage::Label>{label}); optional, n.sym_, std::vector<storage::Label>{label});
EXPECT_EQ(0, CountIterable(dba->Vertices(false))); EXPECT_EQ(0, CountIterable(dba->Vertices(false)));
Context context = MakeContext(storage, symbol_table, dba.get()); auto context = MakeContext(storage, symbol_table, dba.get());
EXPECT_EQ(1, PullAll(*set_op, &context)); EXPECT_EQ(1, PullAll(*set_op, &context));
} }
@ -953,7 +953,7 @@ TEST(QueryPlan, RemovePropertyOnNull) {
auto once = std::make_shared<Once>(); auto once = std::make_shared<Once>();
auto remove_op = auto remove_op =
std::make_shared<plan::RemoveProperty>(once, prop.second, n_prop); std::make_shared<plan::RemoveProperty>(once, prop.second, n_prop);
Context context = MakeContext(storage, symbol_table, &dba); auto context = MakeContext(storage, symbol_table, &dba);
EXPECT_EQ(1, PullAll(*remove_op, &context)); EXPECT_EQ(1, PullAll(*remove_op, &context));
} }
@ -972,7 +972,7 @@ TEST(QueryPlan, RemoveLabelsOnNull) {
auto remove_op = std::make_shared<plan::RemoveLabels>( auto remove_op = std::make_shared<plan::RemoveLabels>(
optional, n.sym_, std::vector<storage::Label>{label}); optional, n.sym_, std::vector<storage::Label>{label});
EXPECT_EQ(0, CountIterable(dba->Vertices(false))); EXPECT_EQ(0, CountIterable(dba->Vertices(false)));
Context context = MakeContext(storage, symbol_table, dba.get()); auto context = MakeContext(storage, symbol_table, dba.get());
EXPECT_EQ(1, PullAll(*remove_op, &context)); EXPECT_EQ(1, PullAll(*remove_op, &context));
} }
@ -997,7 +997,7 @@ TEST(QueryPlan, DeleteSetProperty) {
symbol_table[*n_prop->expression_] = n.sym_; symbol_table[*n_prop->expression_] = n.sym_;
auto set_op = std::make_shared<plan::SetProperty>(delete_op, prop.second, auto set_op = std::make_shared<plan::SetProperty>(delete_op, prop.second,
n_prop, LITERAL(42)); n_prop, LITERAL(42));
Context context = MakeContext(storage, symbol_table, &dba); auto context = MakeContext(storage, symbol_table, &dba);
EXPECT_THROW(PullAll(*set_op, &context), QueryRuntimeException); EXPECT_THROW(PullAll(*set_op, &context), QueryRuntimeException);
} }
@ -1028,7 +1028,7 @@ TEST(QueryPlan, DeleteSetPropertiesFromMap) {
{plan::SetProperties::Op::REPLACE, plan::SetProperties::Op::UPDATE}) { {plan::SetProperties::Op::REPLACE, plan::SetProperties::Op::UPDATE}) {
auto set_op = auto set_op =
std::make_shared<plan::SetProperties>(delete_op, n.sym_, rhs, op_type); std::make_shared<plan::SetProperties>(delete_op, n.sym_, rhs, op_type);
Context context = MakeContext(storage, symbol_table, &dba); auto context = MakeContext(storage, symbol_table, &dba);
EXPECT_THROW(PullAll(*set_op, &context), QueryRuntimeException); EXPECT_THROW(PullAll(*set_op, &context), QueryRuntimeException);
} }
} }
@ -1061,7 +1061,7 @@ TEST(QueryPlan, DeleteSetPropertiesFromVertex) {
{plan::SetProperties::Op::REPLACE, plan::SetProperties::Op::UPDATE}) { {plan::SetProperties::Op::REPLACE, plan::SetProperties::Op::UPDATE}) {
auto set_op = auto set_op =
std::make_shared<plan::SetProperties>(delete_op, n.sym_, rhs, op_type); std::make_shared<plan::SetProperties>(delete_op, n.sym_, rhs, op_type);
Context context = MakeContext(storage, symbol_table, &dba); auto context = MakeContext(storage, symbol_table, &dba);
EXPECT_THROW(PullAll(*set_op, &context), QueryRuntimeException); EXPECT_THROW(PullAll(*set_op, &context), QueryRuntimeException);
} }
} }
@ -1083,7 +1083,7 @@ TEST(QueryPlan, DeleteRemoveLabels) {
n.op_, std::vector<Expression *>{n_get}, false); n.op_, std::vector<Expression *>{n_get}, false);
std::vector<storage::Label> labels{dba->Label("label")}; std::vector<storage::Label> labels{dba->Label("label")};
auto rem_op = std::make_shared<plan::RemoveLabels>(delete_op, n.sym_, labels); auto rem_op = std::make_shared<plan::RemoveLabels>(delete_op, n.sym_, labels);
Context context = MakeContext(storage, symbol_table, dba.get()); auto context = MakeContext(storage, symbol_table, dba.get());
EXPECT_THROW(PullAll(*rem_op, &context), QueryRuntimeException); EXPECT_THROW(PullAll(*rem_op, &context), QueryRuntimeException);
} }
@ -1108,6 +1108,6 @@ TEST(QueryPlan, DeleteRemoveProperty) {
symbol_table[*n_prop->expression_] = n.sym_; symbol_table[*n_prop->expression_] = n.sym_;
auto rem_op = auto rem_op =
std::make_shared<plan::RemoveProperty>(delete_op, prop.second, n_prop); std::make_shared<plan::RemoveProperty>(delete_op, prop.second, n_prop);
Context context = MakeContext(storage, symbol_table, &dba); auto context = MakeContext(storage, symbol_table, &dba);
EXPECT_THROW(PullAll(*rem_op, &context), QueryRuntimeException); EXPECT_THROW(PullAll(*rem_op, &context), QueryRuntimeException);
} }

View File

@ -38,7 +38,7 @@ class MatchReturnFixture : public testing::Test {
template <typename TResult> template <typename TResult>
std::vector<TResult> Results(std::shared_ptr<Produce> &op) { std::vector<TResult> Results(std::shared_ptr<Produce> &op) {
std::vector<TResult> res; std::vector<TResult> res;
Context context = MakeContext(storage, symbol_table, dba_.get()); auto context = MakeContext(storage, symbol_table, dba_.get());
for (const auto &row : CollectProduce(*op, &context)) for (const auto &row : CollectProduce(*op, &context))
res.emplace_back(row[0].Value<TResult>()); res.emplace_back(row[0].Value<TResult>());
return res; return res;
@ -57,7 +57,7 @@ TEST_F(MatchReturnFixture, MatchReturn) {
symbol_table[*output->expression_] = scan_all.sym_; symbol_table[*output->expression_] = scan_all.sym_;
symbol_table[*output] = symbol_table[*output] =
symbol_table.CreateSymbol("named_expression_1", true); symbol_table.CreateSymbol("named_expression_1", true);
Context context = MakeContext(storage, symbol_table, dba_.get()); auto context = MakeContext(storage, symbol_table, dba_.get());
return PullAll(*produce, &context); return PullAll(*produce, &context);
}; };
@ -113,7 +113,7 @@ TEST(QueryPlan, MatchReturnCartesian) {
symbol_table[*return_m] = symbol_table[*return_m] =
symbol_table.CreateSymbol("named_expression_2", true); symbol_table.CreateSymbol("named_expression_2", true);
auto produce = MakeProduce(m.op_, return_n, return_m); auto produce = MakeProduce(m.op_, return_n, return_m);
Context context = MakeContext(storage, symbol_table, dba.get()); auto context = MakeContext(storage, symbol_table, dba.get());
auto results = CollectProduce(*produce, &context); auto results = CollectProduce(*produce, &context);
EXPECT_EQ(results.size(), 4); EXPECT_EQ(results.size(), 4);
// ensure the result ordering is OK: // ensure the result ordering is OK:
@ -140,7 +140,7 @@ TEST(QueryPlan, StandaloneReturn) {
auto produce = MakeProduce(std::shared_ptr<LogicalOperator>(nullptr), output); auto produce = MakeProduce(std::shared_ptr<LogicalOperator>(nullptr), output);
symbol_table[*output] = symbol_table.CreateSymbol("named_expression_1", true); symbol_table[*output] = symbol_table.CreateSymbol("named_expression_1", true);
Context context = MakeContext(storage, symbol_table, dba.get()); auto context = MakeContext(storage, symbol_table, dba.get());
auto results = CollectProduce(*produce, &context); auto results = CollectProduce(*produce, &context);
EXPECT_EQ(results.size(), 1); EXPECT_EQ(results.size(), 1);
EXPECT_EQ(results[0].size(), 1); EXPECT_EQ(results[0].size(), 1);
@ -194,7 +194,7 @@ TEST(QueryPlan, NodeFilterLabelsAndProperties) {
symbol_table[*output] = symbol_table.CreateSymbol("named_expression_1", true); symbol_table[*output] = symbol_table.CreateSymbol("named_expression_1", true);
auto produce = MakeProduce(node_filter, output); auto produce = MakeProduce(node_filter, output);
Context context = MakeContext(storage, symbol_table, &dba); auto context = MakeContext(storage, symbol_table, &dba);
EXPECT_EQ(1, PullAll(*produce, &context)); EXPECT_EQ(1, PullAll(*produce, &context));
// test that filtering works with old records // test that filtering works with old records
@ -251,7 +251,7 @@ TEST(QueryPlan, NodeFilterMultipleLabels) {
symbol_table[*output] = symbol_table.CreateSymbol("named_expression_1", true); symbol_table[*output] = symbol_table.CreateSymbol("named_expression_1", true);
symbol_table[*output->expression_] = n.sym_; symbol_table[*output->expression_] = n.sym_;
Context context = MakeContext(storage, symbol_table, dba.get()); auto context = MakeContext(storage, symbol_table, dba.get());
auto results = CollectProduce(*produce, &context); auto results = CollectProduce(*produce, &context);
EXPECT_EQ(results.size(), 2); EXPECT_EQ(results.size(), 2);
} }
@ -291,7 +291,7 @@ TEST(QueryPlan, Cartesian) {
auto produce = MakeProduce(cartesian_op, return_n, return_m); auto produce = MakeProduce(cartesian_op, return_n, return_m);
Context context = MakeContext(storage, symbol_table, dba.get()); auto context = MakeContext(storage, symbol_table, dba.get());
auto results = CollectProduce(*produce, &context); auto results = CollectProduce(*produce, &context);
EXPECT_EQ(results.size(), 9); EXPECT_EQ(results.size(), 9);
for (int i = 0; i < 3; ++i) { for (int i = 0; i < 3; ++i) {
@ -326,7 +326,7 @@ TEST(QueryPlan, CartesianEmptySet) {
std::make_shared<Cartesian>(n.op_, left_symbols, m.op_, right_symbols); std::make_shared<Cartesian>(n.op_, left_symbols, m.op_, right_symbols);
auto produce = MakeProduce(cartesian_op, return_n, return_m); auto produce = MakeProduce(cartesian_op, return_n, return_m);
Context context = MakeContext(storage, symbol_table, dba.get()); auto context = MakeContext(storage, symbol_table, dba.get());
auto results = CollectProduce(*produce, &context); auto results = CollectProduce(*produce, &context);
EXPECT_EQ(results.size(), 0); EXPECT_EQ(results.size(), 0);
} }
@ -374,7 +374,7 @@ TEST(QueryPlan, CartesianThreeWay) {
l.op_, l_symbols); l.op_, l_symbols);
auto produce = MakeProduce(cartesian_op_2, return_n, return_m, return_l); auto produce = MakeProduce(cartesian_op_2, return_n, return_m, return_l);
Context context = MakeContext(storage, symbol_table, dba.get()); auto context = MakeContext(storage, symbol_table, dba.get());
auto results = CollectProduce(*produce, &context); auto results = CollectProduce(*produce, &context);
EXPECT_EQ(results.size(), 27); EXPECT_EQ(results.size(), 27);
int id = 0; int id = 0;
@ -425,7 +425,7 @@ TEST_F(ExpandFixture, Expand) {
symbol_table[*output] = symbol_table[*output] =
symbol_table.CreateSymbol("named_expression_1", true); symbol_table.CreateSymbol("named_expression_1", true);
auto produce = MakeProduce(r_m.op_, output); auto produce = MakeProduce(r_m.op_, output);
Context context = MakeContext(storage, symbol_table, dba_.get()); auto context = MakeContext(storage, symbol_table, dba_.get());
return PullAll(*produce, &context); return PullAll(*produce, &context);
}; };
@ -462,7 +462,7 @@ TEST_F(ExpandFixture, ExpandPath) {
auto produce = MakeProduce(path, output); auto produce = MakeProduce(path, output);
std::vector<query::Path> expected_paths{{v1, r2, v3}, {v1, r1, v2}}; std::vector<query::Path> expected_paths{{v1, r2, v3}, {v1, r1, v2}};
Context context = MakeContext(storage, symbol_table, dba_.get()); auto context = MakeContext(storage, symbol_table, dba_.get());
auto results = CollectProduce(*produce, &context); auto results = CollectProduce(*produce, &context);
ASSERT_EQ(results.size(), 2); ASSERT_EQ(results.size(), 2);
std::vector<query::Path> results_paths; std::vector<query::Path> results_paths;
@ -600,7 +600,7 @@ class QueryPlanExpandVariable : public testing::Test {
auto GetResults(std::shared_ptr<LogicalOperator> input_op, Symbol symbol) { auto GetResults(std::shared_ptr<LogicalOperator> input_op, Symbol symbol) {
Frame frame(symbol_table.max_position()); Frame frame(symbol_table.max_position());
auto cursor = input_op->MakeCursor(*dba_); auto cursor = input_op->MakeCursor(*dba_);
Context context = MakeContext(storage, symbol_table, dba_.get()); auto context = MakeContext(storage, symbol_table, dba_.get());
std::vector<TResult> results; std::vector<TResult> results;
while (cursor->Pull(frame, context)) while (cursor->Pull(frame, context))
results.emplace_back(frame[symbol].Value<TResult>()); results.emplace_back(frame[symbol].Value<TResult>());
@ -936,7 +936,7 @@ class QueryPlanExpandWeightedShortestPath : public testing::Test {
Frame frame(symbol_table.max_position()); Frame frame(symbol_table.max_position());
auto cursor = last_op->MakeCursor(dba); auto cursor = last_op->MakeCursor(dba);
std::vector<ResultType> results; std::vector<ResultType> results;
Context context = MakeContext(storage, symbol_table, &dba); auto context = MakeContext(storage, symbol_table, &dba);
while (cursor->Pull(frame, context)) { while (cursor->Pull(frame, context)) {
results.push_back(ResultType{std::vector<EdgeAccessor>(), results.push_back(ResultType{std::vector<EdgeAccessor>(),
frame[node_sym].Value<VertexAccessor>(), frame[node_sym].Value<VertexAccessor>(),
@ -1237,7 +1237,7 @@ TEST(QueryPlan, ExpandOptional) {
symbol_table[*m_ne->expression_] = r_m.node_sym_; symbol_table[*m_ne->expression_] = r_m.node_sym_;
symbol_table[*m_ne] = symbol_table.CreateSymbol("m", true); symbol_table[*m_ne] = symbol_table.CreateSymbol("m", true);
auto produce = MakeProduce(optional, n_ne, r_ne, m_ne); auto produce = MakeProduce(optional, n_ne, r_ne, m_ne);
Context context = MakeContext(storage, symbol_table, dba.get()); auto context = MakeContext(storage, symbol_table, dba.get());
auto results = CollectProduce(*produce, &context); auto results = CollectProduce(*produce, &context);
ASSERT_EQ(4, results.size()); ASSERT_EQ(4, results.size());
int v1_is_n_count = 0; int v1_is_n_count = 0;
@ -1274,7 +1274,7 @@ TEST(QueryPlan, OptionalMatchEmptyDB) {
auto optional = std::make_shared<plan::Optional>(nullptr, n.op_, auto optional = std::make_shared<plan::Optional>(nullptr, n.op_,
std::vector<Symbol>{n.sym_}); std::vector<Symbol>{n.sym_});
auto produce = MakeProduce(optional, n_ne); auto produce = MakeProduce(optional, n_ne);
Context context = MakeContext(storage, symbol_table, dba.get()); auto context = MakeContext(storage, symbol_table, dba.get());
auto results = CollectProduce(*produce, &context); auto results = CollectProduce(*produce, &context);
ASSERT_EQ(1, results.size()); ASSERT_EQ(1, results.size());
EXPECT_EQ(results[0][0].type(), TypedValue::Type::Null); EXPECT_EQ(results[0][0].type(), TypedValue::Type::Null);
@ -1304,7 +1304,7 @@ TEST(QueryPlan, OptionalMatchEmptyDBExpandFromNode) {
symbol_table[*m_ne->expression_] = r_m.node_sym_; symbol_table[*m_ne->expression_] = r_m.node_sym_;
symbol_table[*m_ne] = symbol_table.CreateSymbol("m", true); symbol_table[*m_ne] = symbol_table.CreateSymbol("m", true);
auto produce = MakeProduce(r_m.op_, m_ne); auto produce = MakeProduce(r_m.op_, m_ne);
Context context = MakeContext(storage, symbol_table, dba.get()); auto context = MakeContext(storage, symbol_table, dba.get());
auto results = CollectProduce(*produce, &context); auto results = CollectProduce(*produce, &context);
EXPECT_EQ(0, results.size()); EXPECT_EQ(0, results.size());
} }
@ -1354,7 +1354,7 @@ TEST(QueryPlan, OptionalMatchThenExpandToMissingNode) {
symbol_table[*m_ne->expression_] = m.sym_; symbol_table[*m_ne->expression_] = m.sym_;
symbol_table[*m_ne] = symbol_table.CreateSymbol("m", true); symbol_table[*m_ne] = symbol_table.CreateSymbol("m", true);
auto produce = MakeProduce(expand, m_ne); auto produce = MakeProduce(expand, m_ne);
Context context = MakeContext(storage, symbol_table, dba.get()); auto context = MakeContext(storage, symbol_table, dba.get());
auto results = CollectProduce(*produce, &context); auto results = CollectProduce(*produce, &context);
EXPECT_EQ(0, results.size()); EXPECT_EQ(0, results.size());
} }
@ -1391,7 +1391,7 @@ TEST(QueryPlan, ExpandExistingNode) {
symbol_table[*output] = symbol_table[*output] =
symbol_table.CreateSymbol("named_expression_1", true); symbol_table.CreateSymbol("named_expression_1", true);
auto produce = MakeProduce(r_n.op_, output); auto produce = MakeProduce(r_n.op_, output);
Context context = MakeContext(storage, symbol_table, dba.get()); auto context = MakeContext(storage, symbol_table, dba.get());
auto results = CollectProduce(*produce, &context); auto results = CollectProduce(*produce, &context);
EXPECT_EQ(results.size(), expected_result_count); EXPECT_EQ(results.size(), expected_result_count);
}; };
@ -1417,7 +1417,7 @@ TEST(QueryPlan, ExpandBothCycleEdgeCase) {
auto r_ = auto r_ =
MakeExpand(storage, symbol_table, n.op_, n.sym_, "r", MakeExpand(storage, symbol_table, n.op_, n.sym_, "r",
EdgeAtom::Direction::BOTH, {}, "_", false, GraphView::OLD); EdgeAtom::Direction::BOTH, {}, "_", false, GraphView::OLD);
Context context = MakeContext(storage, symbol_table, dba.get()); auto context = MakeContext(storage, symbol_table, dba.get());
EXPECT_EQ(1, PullAll(*r_.op_, &context)); EXPECT_EQ(1, PullAll(*r_.op_, &context));
} }
@ -1480,7 +1480,7 @@ TEST(QueryPlan, EdgeFilter) {
symbol_table[*output] = symbol_table[*output] =
symbol_table.CreateSymbol("named_expression_1", true); symbol_table.CreateSymbol("named_expression_1", true);
auto produce = MakeProduce(edge_filter, output); auto produce = MakeProduce(edge_filter, output);
Context context = MakeContext(storage, symbol_table, &dba); auto context = MakeContext(storage, symbol_table, &dba);
return PullAll(*produce, &context); return PullAll(*produce, &context);
}; };
@ -1522,7 +1522,7 @@ TEST(QueryPlan, EdgeFilterMultipleTypes) {
// fill up the symbol table // fill up the symbol table
symbol_table[*output] = symbol_table.CreateSymbol("named_expression_1", true); symbol_table[*output] = symbol_table.CreateSymbol("named_expression_1", true);
symbol_table[*output->expression_] = r_m.node_sym_; symbol_table[*output->expression_] = r_m.node_sym_;
Context context = MakeContext(storage, symbol_table, dba.get()); auto context = MakeContext(storage, symbol_table, dba.get());
auto results = CollectProduce(*produce, &context); auto results = CollectProduce(*produce, &context);
EXPECT_EQ(results.size(), 2); EXPECT_EQ(results.size(), 2);
} }
@ -1552,7 +1552,7 @@ TEST(QueryPlan, Filter) {
symbol_table[*output->expression_] = n.sym_; symbol_table[*output->expression_] = n.sym_;
symbol_table[*output] = symbol_table.CreateSymbol("named_expression_1", true); symbol_table[*output] = symbol_table.CreateSymbol("named_expression_1", true);
auto produce = MakeProduce(f, output); auto produce = MakeProduce(f, output);
Context context = MakeContext(storage, symbol_table, &dba); auto context = MakeContext(storage, symbol_table, &dba);
EXPECT_EQ(CollectProduce(*produce, &context).size(), 2); EXPECT_EQ(CollectProduce(*produce, &context).size(), 2);
} }
@ -1584,7 +1584,7 @@ TEST(QueryPlan, EdgeUniquenessFilter) {
if (edge_uniqueness) if (edge_uniqueness)
last_op = std::make_shared<EdgeUniquenessFilter>( last_op = std::make_shared<EdgeUniquenessFilter>(
last_op, r2_n3.edge_sym_, std::vector<Symbol>{r1_n2.edge_sym_}); last_op, r2_n3.edge_sym_, std::vector<Symbol>{r1_n2.edge_sym_});
Context context = MakeContext(storage, symbol_table, dba.get()); auto context = MakeContext(storage, symbol_table, dba.get());
return PullAll(*last_op, &context); return PullAll(*last_op, &context);
}; };
@ -1617,7 +1617,7 @@ TEST(QueryPlan, Distinct) {
auto x_ne = NEXPR("x", x_expr); auto x_ne = NEXPR("x", x_expr);
symbol_table[*x_ne] = symbol_table.CreateSymbol("x_ne", true); symbol_table[*x_ne] = symbol_table.CreateSymbol("x_ne", true);
auto produce = MakeProduce(distinct, x_ne); auto produce = MakeProduce(distinct, x_ne);
Context context = MakeContext(storage, symbol_table, dba.get()); auto context = MakeContext(storage, symbol_table, dba.get());
auto results = CollectProduce(*produce, &context); auto results = CollectProduce(*produce, &context);
ASSERT_EQ(output.size(), results.size()); ASSERT_EQ(output.size(), results.size());
auto output_it = output.begin(); auto output_it = output.begin();
@ -1657,7 +1657,7 @@ TEST(QueryPlan, ScanAllByLabel) {
auto produce = MakeProduce(scan_all_by_label.op_, output); auto produce = MakeProduce(scan_all_by_label.op_, output);
symbol_table[*output->expression_] = scan_all_by_label.sym_; symbol_table[*output->expression_] = scan_all_by_label.sym_;
symbol_table[*output] = symbol_table.CreateSymbol("n", true); symbol_table[*output] = symbol_table.CreateSymbol("n", true);
Context context = MakeContext(storage, symbol_table, dba.get()); auto context = MakeContext(storage, symbol_table, dba.get());
auto results = CollectProduce(*produce, &context); auto results = CollectProduce(*produce, &context);
ASSERT_EQ(results.size(), 1); ASSERT_EQ(results.size(), 1);
auto result_row = results[0]; auto result_row = results[0];
@ -1703,7 +1703,7 @@ TEST(QueryPlan, ScanAllByLabelProperty) {
auto produce = MakeProduce(scan_all.op_, output); auto produce = MakeProduce(scan_all.op_, output);
symbol_table[*output->expression_] = scan_all.sym_; symbol_table[*output->expression_] = scan_all.sym_;
symbol_table[*output] = symbol_table.CreateSymbol("n", true); symbol_table[*output] = symbol_table.CreateSymbol("n", true);
Context context = MakeContext(storage, symbol_table, dba.get()); auto context = MakeContext(storage, symbol_table, dba.get());
auto results = CollectProduce(*produce, &context); auto results = CollectProduce(*produce, &context);
ASSERT_EQ(results.size(), expected.size()); ASSERT_EQ(results.size(), expected.size());
for (size_t i = 0; i < expected.size(); i++) { for (size_t i = 0; i < expected.size(); i++) {
@ -1765,7 +1765,7 @@ TEST(QueryPlan, ScanAllByLabelPropertyEqualityNoError) {
auto produce = MakeProduce(scan_all.op_, output); auto produce = MakeProduce(scan_all.op_, output);
symbol_table[*output->expression_] = scan_all.sym_; symbol_table[*output->expression_] = scan_all.sym_;
symbol_table[*output] = symbol_table.CreateSymbol("n", true); symbol_table[*output] = symbol_table.CreateSymbol("n", true);
Context context = MakeContext(storage, symbol_table, dba.get()); auto context = MakeContext(storage, symbol_table, dba.get());
auto results = CollectProduce(*produce, &context); auto results = CollectProduce(*produce, &context);
ASSERT_EQ(results.size(), 1); ASSERT_EQ(results.size(), 1);
const auto &row = results[0]; const auto &row = results[0];
@ -1800,7 +1800,7 @@ TEST(QueryPlan, ScanAllByLabelPropertyValueError) {
symbol_table[*ident_m] = scan_all.sym_; symbol_table[*ident_m] = scan_all.sym_;
auto scan_index = MakeScanAllByLabelPropertyValue( auto scan_index = MakeScanAllByLabelPropertyValue(
storage, symbol_table, "n", label, prop, "prop", ident_m, scan_all.op_); storage, symbol_table, "n", label, prop, "prop", ident_m, scan_all.op_);
Context context = MakeContext(storage, symbol_table, dba.get()); auto context = MakeContext(storage, symbol_table, dba.get());
EXPECT_THROW(PullAll(*scan_index.op_, &context), QueryRuntimeException); EXPECT_THROW(PullAll(*scan_index.op_, &context), QueryRuntimeException);
} }
@ -1832,7 +1832,7 @@ TEST(QueryPlan, ScanAllByLabelPropertyRangeError) {
storage, symbol_table, "n", label, prop, "prop", storage, symbol_table, "n", label, prop, "prop",
Bound{ident_m, Bound::Type::INCLUSIVE}, std::experimental::nullopt, Bound{ident_m, Bound::Type::INCLUSIVE}, std::experimental::nullopt,
scan_all.op_); scan_all.op_);
Context context = MakeContext(storage, symbol_table, dba.get()); auto context = MakeContext(storage, symbol_table, dba.get());
EXPECT_THROW(PullAll(*scan_index.op_, &context), QueryRuntimeException); EXPECT_THROW(PullAll(*scan_index.op_, &context), QueryRuntimeException);
} }
{ {
@ -1841,7 +1841,7 @@ TEST(QueryPlan, ScanAllByLabelPropertyRangeError) {
storage, symbol_table, "n", label, prop, "prop", storage, symbol_table, "n", label, prop, "prop",
std::experimental::nullopt, Bound{ident_m, Bound::Type::INCLUSIVE}, std::experimental::nullopt, Bound{ident_m, Bound::Type::INCLUSIVE},
scan_all.op_); scan_all.op_);
Context context = MakeContext(storage, symbol_table, dba.get()); auto context = MakeContext(storage, symbol_table, dba.get());
EXPECT_THROW(PullAll(*scan_index.op_, &context), QueryRuntimeException); EXPECT_THROW(PullAll(*scan_index.op_, &context), QueryRuntimeException);
} }
{ {
@ -1850,7 +1850,7 @@ TEST(QueryPlan, ScanAllByLabelPropertyRangeError) {
storage, symbol_table, "n", label, prop, "prop", storage, symbol_table, "n", label, prop, "prop",
Bound{ident_m, Bound::Type::INCLUSIVE}, Bound{ident_m, Bound::Type::INCLUSIVE},
Bound{ident_m, Bound::Type::INCLUSIVE}, scan_all.op_); Bound{ident_m, Bound::Type::INCLUSIVE}, scan_all.op_);
Context context = MakeContext(storage, symbol_table, dba.get()); auto context = MakeContext(storage, symbol_table, dba.get());
EXPECT_THROW(PullAll(*scan_index.op_, &context), QueryRuntimeException); EXPECT_THROW(PullAll(*scan_index.op_, &context), QueryRuntimeException);
} }
} }
@ -1885,7 +1885,7 @@ TEST(QueryPlan, ScanAllByLabelPropertyEqualNull) {
auto produce = MakeProduce(scan_all.op_, output); auto produce = MakeProduce(scan_all.op_, output);
symbol_table[*output->expression_] = scan_all.sym_; symbol_table[*output->expression_] = scan_all.sym_;
symbol_table[*output] = symbol_table.CreateSymbol("n", true); symbol_table[*output] = symbol_table.CreateSymbol("n", true);
Context context = MakeContext(storage, symbol_table, dba.get()); auto context = MakeContext(storage, symbol_table, dba.get());
auto results = CollectProduce(*produce, &context); auto results = CollectProduce(*produce, &context);
EXPECT_EQ(results.size(), 0); EXPECT_EQ(results.size(), 0);
} }
@ -1921,7 +1921,7 @@ TEST(QueryPlan, ScanAllByLabelPropertyRangeNull) {
auto produce = MakeProduce(scan_all.op_, output); auto produce = MakeProduce(scan_all.op_, output);
symbol_table[*output->expression_] = scan_all.sym_; symbol_table[*output->expression_] = scan_all.sym_;
symbol_table[*output] = symbol_table.CreateSymbol("n", true); symbol_table[*output] = symbol_table.CreateSymbol("n", true);
Context context = MakeContext(storage, symbol_table, dba.get()); auto context = MakeContext(storage, symbol_table, dba.get());
auto results = CollectProduce(*produce, &context); auto results = CollectProduce(*produce, &context);
EXPECT_EQ(results.size(), 0); EXPECT_EQ(results.size(), 0);
} }
@ -1955,7 +1955,7 @@ TEST(QueryPlan, ScanAllByLabelPropertyNoValueInIndexContinuation) {
auto scan_all = MakeScanAllByLabelPropertyValue( auto scan_all = MakeScanAllByLabelPropertyValue(
storage, symbol_table, "n", label, prop, "prop", x_expr, unwind); storage, symbol_table, "n", label, prop, "prop", x_expr, unwind);
Context context = MakeContext(storage, symbol_table, dba.get()); auto context = MakeContext(storage, symbol_table, dba.get());
EXPECT_EQ(PullAll(*scan_all.op_, &context), 1); EXPECT_EQ(PullAll(*scan_all.op_, &context), 1);
} }
@ -1996,7 +1996,7 @@ TEST(QueryPlan, ScanAllEqualsScanAllByLabelProperty) {
symbol_table[*output->expression_] = scan_all_by_label_property_value.sym_; symbol_table[*output->expression_] = scan_all_by_label_property_value.sym_;
symbol_table[*output] = symbol_table[*output] =
symbol_table.CreateSymbol("named_expression_1", true); symbol_table.CreateSymbol("named_expression_1", true);
Context context = MakeContext(storage, symbol_table, dba.get()); auto context = MakeContext(storage, symbol_table, dba.get());
EXPECT_EQ(PullAll(*produce, &context), prop_count); EXPECT_EQ(PullAll(*produce, &context), prop_count);
}; };
@ -2016,7 +2016,7 @@ TEST(QueryPlan, ScanAllEqualsScanAllByLabelProperty) {
symbol_table[*output->expression_] = scan_all.sym_; symbol_table[*output->expression_] = scan_all.sym_;
symbol_table[*output] = symbol_table[*output] =
symbol_table.CreateSymbol("named_expression_1", true); symbol_table.CreateSymbol("named_expression_1", true);
Context context = MakeContext(storage, symbol_table, &dba); auto context = MakeContext(storage, symbol_table, &dba);
EXPECT_EQ(PullAll(*produce, &context), prop_count); EXPECT_EQ(PullAll(*produce, &context), prop_count);
}; };

View File

@ -72,7 +72,7 @@ void CheckPlansProduce(
for (const auto &plan : plans) { for (const auto &plan : plans) {
auto *produce = dynamic_cast<Produce *>(plan.get()); auto *produce = dynamic_cast<Produce *>(plan.get());
ASSERT_TRUE(produce); ASSERT_TRUE(produce);
Context context = MakeContext(storage, symbol_table, dba); auto context = MakeContext(storage, symbol_table, dba);
auto results = CollectProduce(*produce, &context); auto results = CollectProduce(*produce, &context);
check(results); check(results);
} }