Add db_accessor to ExpressionEvaluator
Summary: Add db_accessor to ExpressionEvaluator Reviewers: florijan, teon.banek Reviewed By: teon.banek Subscribers: pullbot Differential Revision: https://phabricator.memgraph.io/D310
This commit is contained in:
parent
d29a1f5353
commit
fe36835519
src/query
frontend/ast
interpret
plan
tests/unit
@ -427,12 +427,14 @@ class Function : public Expression {
|
||||
}
|
||||
}
|
||||
|
||||
std::function<TypedValue(const std::vector<TypedValue> &)> function_;
|
||||
std::function<TypedValue(const std::vector<TypedValue> &, GraphDbAccessor &)>
|
||||
function_;
|
||||
std::vector<Expression *> arguments_;
|
||||
|
||||
protected:
|
||||
Function(int uid,
|
||||
std::function<TypedValue(const std::vector<TypedValue> &)> function,
|
||||
Function(int uid, std::function<TypedValue(const std::vector<TypedValue> &,
|
||||
GraphDbAccessor &)>
|
||||
function,
|
||||
const std::vector<Expression *> &arguments)
|
||||
: Expression(uid), function_(function), arguments_(arguments) {}
|
||||
};
|
||||
|
@ -8,7 +8,7 @@
|
||||
namespace query {
|
||||
namespace {
|
||||
|
||||
TypedValue Abs(const std::vector<TypedValue> &args) {
|
||||
TypedValue Abs(const std::vector<TypedValue> &args, GraphDbAccessor &) {
|
||||
if (args.size() != 1U) {
|
||||
throw QueryRuntimeException("ABS requires one argument");
|
||||
}
|
||||
@ -26,8 +26,8 @@ TypedValue Abs(const std::vector<TypedValue> &args) {
|
||||
}
|
||||
}
|
||||
|
||||
std::function<TypedValue(const std::vector<TypedValue> &)> NameToFunction(
|
||||
const std::string &function_name) {
|
||||
std::function<TypedValue(const std::vector<TypedValue> &, GraphDbAccessor &)>
|
||||
NameToFunction(const std::string &function_name) {
|
||||
if (function_name == "ABS") {
|
||||
return Abs;
|
||||
}
|
||||
|
@ -2,10 +2,11 @@
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "database/graph_db_accessor.hpp"
|
||||
#include "query/typed_value.hpp"
|
||||
|
||||
namespace query {
|
||||
|
||||
std::function<TypedValue(const std::vector<TypedValue> &)> NameToFunction(
|
||||
const std::string &function_name);
|
||||
std::function<TypedValue(const std::vector<TypedValue> &, GraphDbAccessor &)>
|
||||
NameToFunction(const std::string &function_name);
|
||||
}
|
||||
|
@ -3,6 +3,7 @@
|
||||
#include <map>
|
||||
#include <vector>
|
||||
|
||||
#include "database/graph_db_accessor.hpp"
|
||||
#include "query/frontend/ast/ast.hpp"
|
||||
#include "query/frontend/semantic/symbol_table.hpp"
|
||||
#include "query/interpret/frame.hpp"
|
||||
@ -14,19 +15,22 @@ namespace query {
|
||||
|
||||
class ExpressionEvaluator : public TreeVisitorBase {
|
||||
public:
|
||||
ExpressionEvaluator(Frame &frame, const SymbolTable &symbol_table)
|
||||
: frame_(frame), symbol_table_(symbol_table) {}
|
||||
ExpressionEvaluator(Frame &frame, const SymbolTable &symbol_table,
|
||||
GraphDbAccessor &db_accessor)
|
||||
: frame_(frame), symbol_table_(symbol_table), db_accessor_(db_accessor) {}
|
||||
|
||||
/** When evaluting @c RecordAccessor, use @c SwitchNew to get the new data, as
|
||||
* modified during the current command.
|
||||
/**
|
||||
* When evaluting @c RecordAccessor, use @c SwitchNew to get the new
|
||||
* data, as modified during the current command.
|
||||
*/
|
||||
auto &SwitchNew() {
|
||||
use_new_ = true;
|
||||
return *this;
|
||||
};
|
||||
|
||||
/** When evaluting @c RecordAccessor, use @c SwitchOld to get the old data,
|
||||
* before the modification done by the current command.
|
||||
/**
|
||||
* When evaluting @c RecordAccessor, use @c SwitchOld to get the old
|
||||
* data, before the modification done by the current command.
|
||||
*/
|
||||
auto &SwitchOld() {
|
||||
use_new_ = false;
|
||||
@ -127,8 +131,8 @@ class ExpressionEvaluator : public TreeVisitorBase {
|
||||
}
|
||||
|
||||
void Visit(Literal &literal) override {
|
||||
// TODO: no need to evaluate constants, we can write it to frame in one of
|
||||
// the previous phases.
|
||||
// TODO: no need to evaluate constants, we can write it to frame in one
|
||||
// of the previous phases.
|
||||
result_stack_.push_back(literal.value_);
|
||||
}
|
||||
|
||||
@ -148,7 +152,7 @@ class ExpressionEvaluator : public TreeVisitorBase {
|
||||
arguments.push_back(PopBack());
|
||||
}
|
||||
reverse(arguments.begin(), arguments.end());
|
||||
result_stack_.emplace_back(function.function_(arguments));
|
||||
result_stack_.emplace_back(function.function_(arguments, db_accessor_));
|
||||
}
|
||||
|
||||
private:
|
||||
@ -188,8 +192,10 @@ class ExpressionEvaluator : public TreeVisitorBase {
|
||||
Frame &frame_;
|
||||
const SymbolTable &symbol_table_;
|
||||
std::list<TypedValue> result_stack_;
|
||||
// If true, use SwitchNew on evaluated record accessors. This should be done
|
||||
// only in expressions which may return one. E.g. identifier, list indexing.
|
||||
// If true, use SwitchNew on evaluated record accessors. This should be
|
||||
// done only in expressions which may return one. E.g. identifier, list
|
||||
// indexing.
|
||||
bool use_new_ = false;
|
||||
GraphDbAccessor &db_accessor_;
|
||||
};
|
||||
}
|
||||
|
@ -26,11 +26,11 @@ void Once::Accept(LogicalOperatorVisitor &visitor) {
|
||||
visitor.PostVisit(*this);
|
||||
}
|
||||
}
|
||||
std::unique_ptr<Cursor> Once::MakeCursor(GraphDbAccessor &db) {
|
||||
std::unique_ptr<Cursor> Once::MakeCursor(GraphDbAccessor &) {
|
||||
return std::make_unique<OnceCursor>();
|
||||
}
|
||||
|
||||
bool Once::OnceCursor::Pull(Frame &frame, const SymbolTable &symbol_table) {
|
||||
bool Once::OnceCursor::Pull(Frame &, const SymbolTable &) {
|
||||
if (!did_pull_) {
|
||||
did_pull_ = true;
|
||||
return true;
|
||||
@ -70,7 +70,7 @@ void CreateNode::CreateNodeCursor::Create(Frame &frame,
|
||||
auto new_node = db_.insert_vertex();
|
||||
for (auto label : self_.node_atom_->labels_) new_node.add_label(label);
|
||||
|
||||
ExpressionEvaluator evaluator(frame, symbol_table);
|
||||
ExpressionEvaluator evaluator(frame, symbol_table, db_);
|
||||
// Evaluator should use the latest accessors, as modified in this query, when
|
||||
// setting properties on new nodes.
|
||||
evaluator.SwitchNew();
|
||||
@ -108,7 +108,7 @@ bool CreateExpand::CreateExpandCursor::Pull(Frame &frame,
|
||||
TypedValue &vertex_value = frame[self_.input_symbol_];
|
||||
auto &v1 = vertex_value.Value<VertexAccessor>();
|
||||
|
||||
ExpressionEvaluator evaluator(frame, symbol_table);
|
||||
ExpressionEvaluator evaluator(frame, symbol_table, db_);
|
||||
// Similarly to CreateNode, newly created edges and nodes should use the
|
||||
// latest accesors.
|
||||
// E.g. we pickup new properties: `CREATE (n {p: 42}) -[:r {ep: n.p}]-> ()`
|
||||
@ -355,7 +355,7 @@ std::unique_ptr<Cursor> NodeFilter::MakeCursor(GraphDbAccessor &db) {
|
||||
|
||||
NodeFilter::NodeFilterCursor::NodeFilterCursor(const NodeFilter &self,
|
||||
GraphDbAccessor &db)
|
||||
: self_(self), input_cursor_(self_.input_->MakeCursor(db)) {}
|
||||
: self_(self), db_(db), input_cursor_(self_.input_->MakeCursor(db)) {}
|
||||
|
||||
bool NodeFilter::NodeFilterCursor::Pull(Frame &frame,
|
||||
const SymbolTable &symbol_table) {
|
||||
@ -377,7 +377,7 @@ bool NodeFilter::NodeFilterCursor::VertexPasses(
|
||||
for (auto label : self_.node_atom_->labels_)
|
||||
if (!vertex.has_label(label)) return false;
|
||||
|
||||
ExpressionEvaluator expression_evaluator(frame, symbol_table);
|
||||
ExpressionEvaluator expression_evaluator(frame, symbol_table, db_);
|
||||
// We don't want newly set properties to affect filtering.
|
||||
expression_evaluator.SwitchOld();
|
||||
for (auto prop_pair : self_.node_atom_->properties_) {
|
||||
@ -401,7 +401,7 @@ std::unique_ptr<Cursor> EdgeFilter::MakeCursor(GraphDbAccessor &db) {
|
||||
}
|
||||
EdgeFilter::EdgeFilterCursor::EdgeFilterCursor(const EdgeFilter &self,
|
||||
GraphDbAccessor &db)
|
||||
: self_(self), input_cursor_(self_.input_->MakeCursor(db)) {}
|
||||
: self_(self), db_(db), input_cursor_(self_.input_->MakeCursor(db)) {}
|
||||
|
||||
bool EdgeFilter::EdgeFilterCursor::Pull(Frame &frame,
|
||||
const SymbolTable &symbol_table) {
|
||||
@ -427,7 +427,7 @@ bool EdgeFilter::EdgeFilterCursor::EdgePasses(const EdgeAccessor &edge,
|
||||
[type](auto t) { return t == type; }))
|
||||
return false;
|
||||
|
||||
ExpressionEvaluator expression_evaluator(frame, symbol_table);
|
||||
ExpressionEvaluator expression_evaluator(frame, symbol_table, db_);
|
||||
// We don't want newly set properties to affect filtering.
|
||||
expression_evaluator.SwitchOld();
|
||||
for (auto prop_pair : self_.edge_atom_->properties_) {
|
||||
@ -451,10 +451,10 @@ std::unique_ptr<Cursor> Filter::MakeCursor(GraphDbAccessor &db) {
|
||||
}
|
||||
|
||||
Filter::FilterCursor::FilterCursor(const Filter &self, GraphDbAccessor &db)
|
||||
: self_(self), input_cursor_(self_.input_->MakeCursor(db)) {}
|
||||
: self_(self), db_(db), input_cursor_(self_.input_->MakeCursor(db)) {}
|
||||
|
||||
bool Filter::FilterCursor::Pull(Frame &frame, const SymbolTable &symbol_table) {
|
||||
ExpressionEvaluator evaluator(frame, symbol_table);
|
||||
ExpressionEvaluator evaluator(frame, symbol_table, db_);
|
||||
// Like all filters, newly set values should not affect filtering of old nodes
|
||||
// and edges.
|
||||
evaluator.SwitchOld();
|
||||
@ -485,12 +485,12 @@ const std::vector<NamedExpression *> &Produce::named_expressions() {
|
||||
}
|
||||
|
||||
Produce::ProduceCursor::ProduceCursor(const Produce &self, GraphDbAccessor &db)
|
||||
: self_(self), input_cursor_(self_.input_->MakeCursor(db)) {}
|
||||
: self_(self), db_(db), input_cursor_(self_.input_->MakeCursor(db)) {}
|
||||
|
||||
bool Produce::ProduceCursor::Pull(Frame &frame,
|
||||
const SymbolTable &symbol_table) {
|
||||
if (input_cursor_->Pull(frame, symbol_table)) {
|
||||
ExpressionEvaluator evaluator(frame, symbol_table);
|
||||
ExpressionEvaluator evaluator(frame, symbol_table, db_);
|
||||
// Produce should always yield the latest results.
|
||||
evaluator.SwitchNew();
|
||||
for (auto named_expr : self_.named_expressions_)
|
||||
@ -518,7 +518,7 @@ Delete::DeleteCursor::DeleteCursor(const Delete &self, GraphDbAccessor &db)
|
||||
bool Delete::DeleteCursor::Pull(Frame &frame, const SymbolTable &symbol_table) {
|
||||
if (!input_cursor_->Pull(frame, symbol_table)) return false;
|
||||
|
||||
ExpressionEvaluator evaluator(frame, symbol_table);
|
||||
ExpressionEvaluator evaluator(frame, symbol_table, db_);
|
||||
// Delete should get the latest information, this way it is also possible to
|
||||
// delete newly added nodes and edges.
|
||||
evaluator.SwitchNew();
|
||||
@ -576,13 +576,13 @@ std::unique_ptr<Cursor> SetProperty::MakeCursor(GraphDbAccessor &db) {
|
||||
|
||||
SetProperty::SetPropertyCursor::SetPropertyCursor(const SetProperty &self,
|
||||
GraphDbAccessor &db)
|
||||
: self_(self), input_cursor_(self.input_->MakeCursor(db)) {}
|
||||
: self_(self), db_(db), input_cursor_(self.input_->MakeCursor(db)) {}
|
||||
|
||||
bool SetProperty::SetPropertyCursor::Pull(Frame &frame,
|
||||
const SymbolTable &symbol_table) {
|
||||
if (!input_cursor_->Pull(frame, symbol_table)) return false;
|
||||
|
||||
ExpressionEvaluator evaluator(frame, symbol_table);
|
||||
ExpressionEvaluator evaluator(frame, symbol_table, db_);
|
||||
// Set, just like Create needs to see the latest changes.
|
||||
evaluator.SwitchNew();
|
||||
self_.lhs_->expression_->Accept(evaluator);
|
||||
@ -631,7 +631,7 @@ bool SetProperties::SetPropertiesCursor::Pull(Frame &frame,
|
||||
|
||||
TypedValue &lhs = frame[self_.input_symbol_];
|
||||
|
||||
ExpressionEvaluator evaluator(frame, symbol_table);
|
||||
ExpressionEvaluator evaluator(frame, symbol_table, db_);
|
||||
// Set, just like Create needs to see the latest changes.
|
||||
evaluator.SwitchNew();
|
||||
self_.rhs_->Accept(evaluator);
|
||||
@ -732,13 +732,13 @@ std::unique_ptr<Cursor> RemoveProperty::MakeCursor(GraphDbAccessor &db) {
|
||||
|
||||
RemoveProperty::RemovePropertyCursor::RemovePropertyCursor(
|
||||
const RemoveProperty &self, GraphDbAccessor &db)
|
||||
: self_(self), input_cursor_(self.input_->MakeCursor(db)) {}
|
||||
: self_(self), db_(db), input_cursor_(self.input_->MakeCursor(db)) {}
|
||||
|
||||
bool RemoveProperty::RemovePropertyCursor::Pull(
|
||||
Frame &frame, const SymbolTable &symbol_table) {
|
||||
if (!input_cursor_->Pull(frame, symbol_table)) return false;
|
||||
|
||||
ExpressionEvaluator evaluator(frame, symbol_table);
|
||||
ExpressionEvaluator evaluator(frame, symbol_table, db_);
|
||||
// Remove, just like Delete needs to see the latest changes.
|
||||
evaluator.SwitchNew();
|
||||
self_.lhs_->expression_->Accept(evaluator);
|
||||
@ -944,7 +944,7 @@ std::unique_ptr<Cursor> Aggregate::MakeCursor(GraphDbAccessor &db) {
|
||||
|
||||
Aggregate::AggregateCursor::AggregateCursor(Aggregate &self,
|
||||
GraphDbAccessor &db)
|
||||
: self_(self), input_cursor_(self_.input_->MakeCursor(db)) {}
|
||||
: self_(self), db_(db), input_cursor_(self_.input_->MakeCursor(db)) {}
|
||||
|
||||
bool Aggregate::AggregateCursor::Pull(Frame &frame,
|
||||
const SymbolTable &symbol_table) {
|
||||
@ -972,7 +972,7 @@ bool Aggregate::AggregateCursor::Pull(Frame &frame,
|
||||
|
||||
void Aggregate::AggregateCursor::ProcessAll(Frame &frame,
|
||||
const SymbolTable &symbol_table) {
|
||||
ExpressionEvaluator evaluator(frame, symbol_table);
|
||||
ExpressionEvaluator evaluator(frame, symbol_table, db_);
|
||||
evaluator.SwitchNew();
|
||||
while (input_cursor_->Pull(frame, symbol_table))
|
||||
ProcessOne(frame, symbol_table, evaluator);
|
||||
@ -1149,14 +1149,14 @@ std::unique_ptr<Cursor> Skip::MakeCursor(GraphDbAccessor &db) {
|
||||
}
|
||||
|
||||
Skip::SkipCursor::SkipCursor(Skip &self, GraphDbAccessor &db)
|
||||
: self_(self), input_cursor_(self_.input_->MakeCursor(db)) {}
|
||||
: self_(self), db_(db), input_cursor_(self_.input_->MakeCursor(db)) {}
|
||||
|
||||
bool Skip::SkipCursor::Pull(Frame &frame, const SymbolTable &symbol_table) {
|
||||
while (input_cursor_->Pull(frame, symbol_table)) {
|
||||
if (to_skip_ == -1) {
|
||||
// first successful pull from the input
|
||||
// evaluate the skip expression
|
||||
ExpressionEvaluator evaluator(frame, symbol_table);
|
||||
ExpressionEvaluator evaluator(frame, symbol_table, db_);
|
||||
self_.expression_->Accept(evaluator);
|
||||
TypedValue to_skip = evaluator.PopBack();
|
||||
if (to_skip.type() != TypedValue::Type::Int)
|
||||
@ -1191,7 +1191,7 @@ std::unique_ptr<Cursor> Limit::MakeCursor(GraphDbAccessor &db) {
|
||||
}
|
||||
|
||||
Limit::LimitCursor::LimitCursor(Limit &self, GraphDbAccessor &db)
|
||||
: self_(self), input_cursor_(self_.input_->MakeCursor(db)) {}
|
||||
: self_(self), db_(db), input_cursor_(self_.input_->MakeCursor(db)) {}
|
||||
|
||||
bool Limit::LimitCursor::Pull(Frame &frame, const SymbolTable &symbol_table) {
|
||||
// we need to evaluate the limit expression before the first input Pull
|
||||
@ -1199,7 +1199,7 @@ bool Limit::LimitCursor::Pull(Frame &frame, const SymbolTable &symbol_table) {
|
||||
// we can do this before Pulling from the input because the limit expression
|
||||
// is not allowed to contain any identifiers
|
||||
if (limit_ == -1) {
|
||||
ExpressionEvaluator evaluator(frame, symbol_table);
|
||||
ExpressionEvaluator evaluator(frame, symbol_table, db_);
|
||||
self_.expression_->Accept(evaluator);
|
||||
TypedValue limit = evaluator.PopBack();
|
||||
if (limit.type() != TypedValue::Type::Int)
|
||||
@ -1245,12 +1245,12 @@ std::unique_ptr<Cursor> OrderBy::MakeCursor(GraphDbAccessor &db) {
|
||||
}
|
||||
|
||||
OrderBy::OrderByCursor::OrderByCursor(OrderBy &self, GraphDbAccessor &db)
|
||||
: self_(self), input_cursor_(self_.input_->MakeCursor(db)) {}
|
||||
: self_(self), db_(db), input_cursor_(self_.input_->MakeCursor(db)) {}
|
||||
|
||||
bool OrderBy::OrderByCursor::Pull(Frame &frame,
|
||||
const SymbolTable &symbol_table) {
|
||||
if (!did_pull_all_) {
|
||||
ExpressionEvaluator evaluator(frame, symbol_table);
|
||||
ExpressionEvaluator evaluator(frame, symbol_table, db_);
|
||||
while (input_cursor_->Pull(frame, symbol_table)) {
|
||||
// collect the order_by elements
|
||||
std::list<TypedValue> order_by;
|
||||
|
@ -420,6 +420,7 @@ class NodeFilter : public LogicalOperator {
|
||||
|
||||
private:
|
||||
const NodeFilter &self_;
|
||||
GraphDbAccessor &db_;
|
||||
const std::unique_ptr<Cursor> input_cursor_;
|
||||
|
||||
/** Helper function for checking if the given vertex
|
||||
@ -460,6 +461,7 @@ class EdgeFilter : public LogicalOperator {
|
||||
|
||||
private:
|
||||
const EdgeFilter &self_;
|
||||
GraphDbAccessor &db_;
|
||||
const std::unique_ptr<Cursor> input_cursor_;
|
||||
|
||||
/** Helper function for checking if the given edge satisfied
|
||||
@ -495,6 +497,7 @@ class Filter : public LogicalOperator {
|
||||
|
||||
private:
|
||||
const Filter &self_;
|
||||
GraphDbAccessor &db_;
|
||||
const std::unique_ptr<Cursor> input_cursor_;
|
||||
};
|
||||
};
|
||||
@ -530,6 +533,7 @@ class Produce : public LogicalOperator {
|
||||
|
||||
private:
|
||||
const Produce &self_;
|
||||
GraphDbAccessor &db_;
|
||||
const std::unique_ptr<Cursor> input_cursor_;
|
||||
};
|
||||
};
|
||||
@ -594,6 +598,7 @@ class SetProperty : public LogicalOperator {
|
||||
|
||||
private:
|
||||
const SetProperty &self_;
|
||||
GraphDbAccessor &db_;
|
||||
const std::unique_ptr<Cursor> input_cursor_;
|
||||
};
|
||||
};
|
||||
@ -704,6 +709,7 @@ class RemoveProperty : public LogicalOperator {
|
||||
|
||||
private:
|
||||
const RemoveProperty &self_;
|
||||
GraphDbAccessor &db_;
|
||||
const std::unique_ptr<Cursor> input_cursor_;
|
||||
};
|
||||
};
|
||||
@ -909,6 +915,7 @@ class Aggregate : public LogicalOperator {
|
||||
};
|
||||
|
||||
const Aggregate &self_;
|
||||
GraphDbAccessor &db_;
|
||||
const std::unique_ptr<Cursor> input_cursor_;
|
||||
// storage for aggregated data
|
||||
// map key is the list of group-by values
|
||||
@ -994,6 +1001,7 @@ class Skip : public LogicalOperator {
|
||||
|
||||
private:
|
||||
const Skip &self_;
|
||||
GraphDbAccessor &db_;
|
||||
const std::unique_ptr<Cursor> input_cursor_;
|
||||
// init to_skip_ to -1, indicating
|
||||
// that it's still unknown (input has not been Pulled yet)
|
||||
@ -1035,6 +1043,7 @@ class Limit : public LogicalOperator {
|
||||
|
||||
private:
|
||||
Limit &self_;
|
||||
GraphDbAccessor &db_;
|
||||
std::unique_ptr<Cursor> input_cursor_;
|
||||
// init limit_ to -1, indicating
|
||||
// that it's still unknown (Cursor has not been Pulled yet)
|
||||
@ -1099,6 +1108,7 @@ class OrderBy : public LogicalOperator {
|
||||
|
||||
private:
|
||||
const OrderBy &self_;
|
||||
GraphDbAccessor &db_;
|
||||
const std::unique_ptr<Cursor> input_cursor_;
|
||||
bool did_pull_all_{false};
|
||||
// a cache of elements pulled from the input
|
||||
|
@ -424,9 +424,6 @@ TEST(CypherMainVisitorTest, Function) {
|
||||
return_clause->body_.named_expressions[0]->expression_);
|
||||
ASSERT_TRUE(function);
|
||||
ASSERT_TRUE(function->function_);
|
||||
// Check if function is abs.
|
||||
ASSERT_EQ(function->function_({-2}).Value<int64_t>(), 2);
|
||||
ASSERT_EQ(function->arguments_.size(), 2);
|
||||
}
|
||||
|
||||
TEST(CypherMainVisitorTest, StringLiteralDoubleQuotes) {
|
||||
|
@ -10,6 +10,8 @@
|
||||
#include "gmock/gmock.h"
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
#include "database/graph_db_accessor.hpp"
|
||||
#include "dbms/dbms.hpp"
|
||||
#include "query/frontend/ast/ast.hpp"
|
||||
#include "query/frontend/opencypher/parser.hpp"
|
||||
#include "query/interpret/awesome_memgraph_functions.hpp"
|
||||
@ -21,7 +23,9 @@ struct NoContextExpressionEvaluator {
|
||||
NoContextExpressionEvaluator() {}
|
||||
Frame frame{0};
|
||||
SymbolTable symbol_table;
|
||||
ExpressionEvaluator eval{frame, symbol_table};
|
||||
Dbms dbms;
|
||||
std::unique_ptr<GraphDbAccessor> dba = dbms.active();
|
||||
ExpressionEvaluator eval{frame, symbol_table, *dba};
|
||||
};
|
||||
|
||||
TEST(ExpressionEvaluator, OrOperator) {
|
||||
@ -290,7 +294,9 @@ TEST(ExpressionEvaluator, Aggregation) {
|
||||
symbol_table[*aggr] = aggr_sym;
|
||||
Frame frame{symbol_table.max_position()};
|
||||
frame[aggr_sym] = TypedValue(1);
|
||||
ExpressionEvaluator eval{frame, symbol_table};
|
||||
Dbms dbms;
|
||||
auto dba = dbms.active();
|
||||
ExpressionEvaluator eval{frame, symbol_table, *dba};
|
||||
aggr->Accept(eval);
|
||||
EXPECT_EQ(eval.PopBack().Value<int64_t>(), 1);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user