Extract QueryVisitor from HierarchicalTreeVisitor

Summary:
This change makes HierarchicalTreeVisitor visit only Cypher related AST
nodes. QueryVisitor can be used to differentiate between various query
types we have. The next step is to either rename HierarchicalTreeVisitor
to something like CypherQueryVisitor, or perhaps extract Clause visiting
from it.

Reviewers: mtomic, llugovic

Reviewed By: llugovic

Subscribers: pullbot

Differential Revision: https://phabricator.memgraph.io/D1710
This commit is contained in:
Teon Banek 2018-10-30 15:29:12 +01:00
parent bbe095d41a
commit 5df4d55ec1
16 changed files with 260 additions and 318 deletions

View File

@ -63,9 +63,7 @@ std::unique_ptr<LogicalPlan> DistributedInterpreter::MakeLogicalPlan(
database::GraphDbAccessor *db_accessor) { database::GraphDbAccessor *db_accessor) {
auto vertex_counts = plan::MakeVertexCountCache(*db_accessor); auto vertex_counts = plan::MakeVertexCountCache(*db_accessor);
SymbolTable symbol_table; auto symbol_table = MakeSymbolTable(query);
SymbolGenerator symbol_generator(symbol_table);
query->Accept(symbol_generator);
auto planning_context = plan::MakePlanningContext(ast_storage, symbol_table, auto planning_context = plan::MakePlanningContext(ast_storage, symbol_table,
query, vertex_counts); query, vertex_counts);

View File

@ -150,14 +150,13 @@ class AstStorage {
}; };
cpp<# cpp<#
(lcp:define-class tree ("::utils::Visitable<HierarchicalTreeVisitor>") (lcp:define-class tree ()
((uid :int32_t :scope :public)) ((uid :int32_t :scope :public))
(:abstractp t) (:abstractp t)
(:public (:public
#>cpp #>cpp
Tree() = default; Tree() = default;
virtual ~Tree() {}
using ::utils::Visitable<HierarchicalTreeVisitor>::Accept;
virtual Tree *Clone(AstStorage &storage) const = 0; virtual Tree *Clone(AstStorage &storage) const = 0;
cpp<#) cpp<#)
@ -189,15 +188,16 @@ cpp<#
;;; Expressions ;;; Expressions
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(lcp:define-class expression (tree "::utils::Visitable<ExpressionVisitor<TypedValue>>" (lcp:define-class expression (tree "::utils::Visitable<HierarchicalTreeVisitor>"
"::utils::Visitable<ExpressionVisitor<TypedValue>>"
"::utils::Visitable<ExpressionVisitor<void>>") "::utils::Visitable<ExpressionVisitor<void>>")
() ()
(:abstractp t) (:abstractp t)
(:public (:public
#>cpp #>cpp
using ::utils::Visitable<HierarchicalTreeVisitor>::Accept;
using ::utils::Visitable<ExpressionVisitor<TypedValue>>::Accept; using ::utils::Visitable<ExpressionVisitor<TypedValue>>::Accept;
using ::utils::Visitable<ExpressionVisitor<void>>::Accept; using ::utils::Visitable<ExpressionVisitor<void>>::Accept;
using Tree::Accept;
Expression() = default; Expression() = default;
@ -213,13 +213,15 @@ cpp<#
cpp<#) cpp<#)
(:serialize :capnp :ignore-other-base-classes t)) (:serialize :capnp :ignore-other-base-classes t))
(lcp:define-class where (tree) (lcp:define-class where (tree "::utils::Visitable<HierarchicalTreeVisitor>")
((expression "Expression *" :initval "nullptr" :scope :public ((expression "Expression *" :initval "nullptr" :scope :public
:capnp-type "Tree" :capnp-init nil :capnp-type "Tree" :capnp-init nil
:capnp-save #'save-ast-pointer :capnp-save #'save-ast-pointer
:capnp-load (load-ast-pointer "Expression *"))) :capnp-load (load-ast-pointer "Expression *")))
(:public (:public
#>cpp #>cpp
using ::utils::Visitable<HierarchicalTreeVisitor>::Accept;
Where() = default; Where() = default;
bool Accept(HierarchicalTreeVisitor &visitor) override { bool Accept(HierarchicalTreeVisitor &visitor) override {
@ -242,7 +244,7 @@ cpp<#
#>cpp #>cpp
friend class AstStorage; friend class AstStorage;
cpp<#) cpp<#)
(:serialize :capnp)) (:serialize :capnp :ignore-other-base-classes t))
(lcp:define-class binary-operator (expression) (lcp:define-class binary-operator (expression)
((expression1 "Expression *" :initval "nullptr" :scope :public ((expression1 "Expression *" :initval "nullptr" :scope :public
@ -1119,7 +1121,8 @@ cpp<#
cpp<#) cpp<#)
(:serialize :capnp)) (:serialize :capnp))
(lcp:define-class named-expression (tree "::utils::Visitable<ExpressionVisitor<TypedValue>>" (lcp:define-class named-expression (tree "::utils::Visitable<HierarchicalTreeVisitor>"
"::utils::Visitable<ExpressionVisitor<TypedValue>>"
"::utils::Visitable<ExpressionVisitor<void>>") "::utils::Visitable<ExpressionVisitor<void>>")
((name "std::string" :scope :public) ((name "std::string" :scope :public)
(expression "Expression *" :initval "nullptr" :scope :public (expression "Expression *" :initval "nullptr" :scope :public
@ -1132,6 +1135,7 @@ cpp<#
#>cpp #>cpp
using ::utils::Visitable<ExpressionVisitor<TypedValue>>::Accept; using ::utils::Visitable<ExpressionVisitor<TypedValue>>::Accept;
using ::utils::Visitable<ExpressionVisitor<void>>::Accept; using ::utils::Visitable<ExpressionVisitor<void>>::Accept;
using ::utils::Visitable<HierarchicalTreeVisitor>::Accept;
NamedExpression() = default; NamedExpression() = default;
@ -1172,7 +1176,7 @@ cpp<#
;;; END Expressions ;;; END Expressions
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(lcp:define-class pattern-atom (tree) (lcp:define-class pattern-atom (tree "::utils::Visitable<HierarchicalTreeVisitor>")
((identifier "Identifier *" :initval "nullptr" :scope :public ((identifier "Identifier *" :initval "nullptr" :scope :public
:capnp-type "Tree" :capnp-init nil :capnp-type "Tree" :capnp-init nil
:capnp-save #'save-ast-pointer :capnp-save #'save-ast-pointer
@ -1180,6 +1184,8 @@ cpp<#
(:abstractp t) (:abstractp t)
(:public (:public
#>cpp #>cpp
using ::utils::Visitable<HierarchicalTreeVisitor>::Accept;
PatternAtom() = default; PatternAtom() = default;
PatternAtom *Clone(AstStorage &storage) const override = 0; PatternAtom *Clone(AstStorage &storage) const override = 0;
@ -1194,7 +1200,7 @@ cpp<#
#>cpp #>cpp
friend class AstStorage; friend class AstStorage;
cpp<#) cpp<#)
(:serialize :capnp)) (:serialize :capnp :ignore-other-base-classes t))
(lcp:define-class node-atom (pattern-atom) (lcp:define-class node-atom (pattern-atom)
((labels "std::vector<storage::Label>" :scope :public ((labels "std::vector<storage::Label>" :scope :public
@ -1383,7 +1389,7 @@ cpp<#
cpp<#) cpp<#)
(:serialize :capnp)) (:serialize :capnp))
(lcp:define-class pattern (tree) (lcp:define-class pattern (tree "::utils::Visitable<HierarchicalTreeVisitor>")
((identifier "Identifier *" :initval "nullptr" :scope :public ((identifier "Identifier *" :initval "nullptr" :scope :public
:capnp-type "Tree" :capnp-init nil :capnp-type "Tree" :capnp-init nil
:capnp-save #'save-ast-pointer :capnp-save #'save-ast-pointer
@ -1395,6 +1401,8 @@ cpp<#
:capnp-load (load-ast-vector "PatternAtom *"))) :capnp-load (load-ast-vector "PatternAtom *")))
(:public (:public
#>cpp #>cpp
using ::utils::Visitable<HierarchicalTreeVisitor>::Accept;
Pattern() = default; Pattern() = default;
bool Accept(HierarchicalTreeVisitor &visitor) override { bool Accept(HierarchicalTreeVisitor &visitor) override {
@ -1426,13 +1434,15 @@ cpp<#
#>cpp #>cpp
friend class AstStorage; friend class AstStorage;
cpp<#) cpp<#)
(:serialize :capnp)) (:serialize :capnp :ignore-other-base-classes t))
(lcp:define-class clause (tree) (lcp:define-class clause (tree "::utils::Visitable<HierarchicalTreeVisitor>")
() ()
(:abstractp t) (:abstractp t)
(:public (:public
#>cpp #>cpp
using ::utils::Visitable<HierarchicalTreeVisitor>::Accept;
Clause() = default; Clause() = default;
Clause *Clone(AstStorage &storage) const override = 0; Clause *Clone(AstStorage &storage) const override = 0;
@ -1445,9 +1455,9 @@ cpp<#
#>cpp #>cpp
friend class AstStorage; friend class AstStorage;
cpp<#) cpp<#)
(:serialize :capnp)) (:serialize :capnp :ignore-other-base-classes t))
(lcp:define-class single-query (tree) (lcp:define-class single-query (tree "::utils::Visitable<HierarchicalTreeVisitor>")
((clauses "std::vector<Clause *>" ((clauses "std::vector<Clause *>"
:scope :public :scope :public
:capnp-type "List(Tree)" :capnp-type "List(Tree)"
@ -1455,6 +1465,8 @@ cpp<#
:capnp-load (load-ast-vector "Clause *"))) :capnp-load (load-ast-vector "Clause *")))
(:public (:public
#>cpp #>cpp
using ::utils::Visitable<HierarchicalTreeVisitor>::Accept;
SingleQuery() = default; SingleQuery() = default;
bool Accept(HierarchicalTreeVisitor &visitor) override { bool Accept(HierarchicalTreeVisitor &visitor) override {
@ -1482,9 +1494,9 @@ cpp<#
#>cpp #>cpp
friend class AstStorage; friend class AstStorage;
cpp<#) cpp<#)
(:serialize :capnp)) (:serialize :capnp :ignore-other-base-classes t))
(lcp:define-class cypher-union (tree) (lcp:define-class cypher-union (tree "::utils::Visitable<HierarchicalTreeVisitor>")
((single-query "SingleQuery *" :initval "nullptr" :scope :public ((single-query "SingleQuery *" :initval "nullptr" :scope :public
:capnp-type "Tree" :capnp-init nil :capnp-type "Tree" :capnp-init nil
:capnp-save #'save-ast-pointer :capnp-save #'save-ast-pointer
@ -1494,6 +1506,8 @@ cpp<#
:documentation "Holds symbols that are created during symbol generation phase. These symbols are used when UNION/UNION ALL combines single query results.")) :documentation "Holds symbols that are created during symbol generation phase. These symbols are used when UNION/UNION ALL combines single query results."))
(:public (:public
#>cpp #>cpp
using ::utils::Visitable<HierarchicalTreeVisitor>::Accept;
CypherUnion() = default; CypherUnion() = default;
bool Accept(HierarchicalTreeVisitor &visitor) override { bool Accept(HierarchicalTreeVisitor &visitor) override {
@ -1525,13 +1539,15 @@ cpp<#
#>cpp #>cpp
friend class AstStorage; friend class AstStorage;
cpp<#) cpp<#)
(:serialize :capnp)) (:serialize :capnp :ignore-other-base-classes t))
(lcp:define-class query (tree) (lcp:define-class query (tree "::utils::Visitable<QueryVisitor<void>>")
() ()
(:abstractp t) (:abstractp t)
(:public (:public
#>cpp #>cpp
using ::utils::Visitable<QueryVisitor<void>>::Accept;
Query() = default; Query() = default;
virtual Query *Clone(AstStorage &storage) const = 0; virtual Query *Clone(AstStorage &storage) const = 0;
@ -1544,7 +1560,7 @@ cpp<#
#>cpp #>cpp
friend class AstStorage; friend class AstStorage;
cpp<#) cpp<#)
(:serialize :capnp)) (:serialize :capnp :ignore-other-base-classes t))
(lcp:define-class cypher-query (query) (lcp:define-class cypher-query (query)
((single-query "SingleQuery *" :initval "nullptr" :scope :public ((single-query "SingleQuery *" :initval "nullptr" :scope :public
@ -1562,17 +1578,7 @@ cpp<#
#>cpp #>cpp
CypherQuery() = default; CypherQuery() = default;
bool Accept(HierarchicalTreeVisitor &visitor) override { DEFVISITABLE(QueryVisitor<void>);
if (visitor.PreVisit(*this)) {
bool should_continue = single_query_->Accept(visitor);
for (auto *cypher_union : cypher_unions_) {
if (should_continue) {
should_continue = cypher_union->Accept(visitor);
}
}
}
return visitor.PostVisit(*this);
}
CypherQuery *Clone(AstStorage &storage) const override { CypherQuery *Clone(AstStorage &storage) const override {
auto *cypher_query = storage.Create<CypherQuery>(); auto *cypher_query = storage.Create<CypherQuery>();
@ -1603,12 +1609,7 @@ cpp<#
#>cpp #>cpp
ExplainQuery() = default; ExplainQuery() = default;
bool Accept(HierarchicalTreeVisitor &visitor) override { DEFVISITABLE(QueryVisitor<void>);
if (visitor.PreVisit(*this)) {
cypher_query_->Accept(visitor);
}
return visitor.PostVisit(*this);
}
ExplainQuery *Clone(AstStorage &storage) const override { ExplainQuery *Clone(AstStorage &storage) const override {
auto *explain_query = storage.Create<ExplainQuery>(); auto *explain_query = storage.Create<ExplainQuery>();
@ -1640,7 +1641,7 @@ cpp<#
#>cpp #>cpp
IndexQuery() = default; IndexQuery() = default;
DEFVISITABLE(HierarchicalTreeVisitor); DEFVISITABLE(QueryVisitor<void>);
IndexQuery *Clone(AstStorage &storage) const override { IndexQuery *Clone(AstStorage &storage) const override {
return storage.Create<IndexQuery>(action_, label_, properties_); return storage.Create<IndexQuery>(action_, label_, properties_);
@ -2279,12 +2280,7 @@ cpp<#
#>cpp #>cpp
AuthQuery() = default; AuthQuery() = default;
bool Accept(HierarchicalTreeVisitor &visitor) override { DEFVISITABLE(QueryVisitor<void>);
if (visitor.PreVisit(*this)) {
if (password_) password_->Accept(visitor);
}
return visitor.PostVisit(*this);
}
AuthQuery *Clone(AstStorage &storage) const override { AuthQuery *Clone(AstStorage &storage) const override {
return storage.Create<AuthQuery>( return storage.Create<AuthQuery>(
@ -2358,24 +2354,7 @@ cpp<#
#>cpp #>cpp
StreamQuery() = default; StreamQuery() = default;
bool Accept(HierarchicalTreeVisitor &visitor) override { DEFVISITABLE(QueryVisitor<void>);
if (visitor.PreVisit(*this)) {
bool cont = true;
if (cont && stream_uri_)
cont = stream_uri_->Accept(visitor);
if (cont && stream_topic_)
cont = stream_topic_->Accept(visitor);
if (cont && transform_uri_)
cont = transform_uri_->Accept(visitor);
if (cont && batch_interval_in_ms_)
cont = batch_interval_in_ms_->Accept(visitor);
if (cont && batch_size_)
cont = batch_size_->Accept(visitor);
if (cont && limit_batches_)
cont = limit_batches_->Accept(visitor);
}
return visitor.PostVisit(*this);
}
StreamQuery *Clone(AstStorage &storage) const override { StreamQuery *Clone(AstStorage &storage) const override {
auto *stream_uri = stream_uri_ ? stream_uri_->Clone(storage) : nullptr; auto *stream_uri = stream_uri_ ? stream_uri_->Clone(storage) : nullptr;

View File

@ -67,21 +67,20 @@ class IndexQuery;
class StreamQuery; class StreamQuery;
using TreeCompositeVisitor = ::utils::CompositeVisitor< using TreeCompositeVisitor = ::utils::CompositeVisitor<
CypherQuery, ExplainQuery, SingleQuery, CypherUnion, NamedExpression, SingleQuery, CypherUnion, NamedExpression, OrOperator, XorOperator,
OrOperator, XorOperator, AndOperator, NotOperator, AdditionOperator, AndOperator, NotOperator, AdditionOperator, SubtractionOperator,
SubtractionOperator, MultiplicationOperator, DivisionOperator, ModOperator, MultiplicationOperator, DivisionOperator, ModOperator, NotEqualOperator,
NotEqualOperator, EqualOperator, LessOperator, GreaterOperator, EqualOperator, LessOperator, GreaterOperator, LessEqualOperator,
LessEqualOperator, GreaterEqualOperator, InListOperator, SubscriptOperator, GreaterEqualOperator, InListOperator, SubscriptOperator,
ListSlicingOperator, IfOperator, UnaryPlusOperator, UnaryMinusOperator, ListSlicingOperator, IfOperator, UnaryPlusOperator, UnaryMinusOperator,
IsNullOperator, ListLiteral, MapLiteral, PropertyLookup, LabelsTest, IsNullOperator, ListLiteral, MapLiteral, PropertyLookup, LabelsTest,
Aggregation, Function, Reduce, Coalesce, Extract, All, Single, Create, Aggregation, Function, Reduce, Coalesce, Extract, All, Single, Create,
Match, Return, With, Pattern, NodeAtom, EdgeAtom, Delete, Where, Match, Return, With, Pattern, NodeAtom, EdgeAtom, Delete, Where,
SetProperty, SetProperties, SetLabels, RemoveProperty, RemoveLabels, Merge, SetProperty, SetProperties, SetLabels, RemoveProperty, RemoveLabels, Merge,
Unwind, AuthQuery, StreamQuery>; Unwind>;
using TreeLeafVisitor = using TreeLeafVisitor =
::utils::LeafVisitor<Identifier, PrimitiveLiteral, ParameterLookup, ::utils::LeafVisitor<Identifier, PrimitiveLiteral, ParameterLookup>;
IndexQuery>;
class HierarchicalTreeVisitor : public TreeCompositeVisitor, class HierarchicalTreeVisitor : public TreeCompositeVisitor,
public TreeLeafVisitor { public TreeLeafVisitor {
@ -106,4 +105,9 @@ class ExpressionVisitor
Extract, All, Single, ParameterLookup, Identifier, PrimitiveLiteral> { Extract, All, Single, ParameterLookup, Identifier, PrimitiveLiteral> {
}; };
template <class TResult>
class QueryVisitor
: public ::utils::Visitor<TResult, CypherQuery, ExplainQuery, IndexQuery,
AuthQuery, StreamQuery> {};
} // namespace query } // namespace query

View File

@ -2,14 +2,39 @@
namespace query { namespace query {
class PrivilegeExtractor : public HierarchicalTreeVisitor { class PrivilegeExtractor : public QueryVisitor<void>,
public HierarchicalTreeVisitor {
public: public:
using HierarchicalTreeVisitor::PostVisit; using HierarchicalTreeVisitor::PostVisit;
using HierarchicalTreeVisitor::PreVisit; using HierarchicalTreeVisitor::PreVisit;
using HierarchicalTreeVisitor::Visit; using HierarchicalTreeVisitor::Visit;
using QueryVisitor<void>::Visit;
std::vector<AuthQuery::Privilege> privileges() { return privileges_; } std::vector<AuthQuery::Privilege> privileges() { return privileges_; }
void Visit(IndexQuery &) override {
AddPrivilege(AuthQuery::Privilege::INDEX);
}
void Visit(AuthQuery &) override {
AddPrivilege(AuthQuery::Privilege::AUTH);
}
void Visit(StreamQuery &) override {
AddPrivilege(AuthQuery::Privilege::STREAM);
}
void Visit(ExplainQuery &query) override {
query.cypher_query_->Accept(*this);
}
void Visit(CypherQuery &query) override {
query.single_query_->Accept(*this);
for (auto *cypher_union : query.cypher_unions_) {
cypher_union->Accept(*this);
}
}
bool PreVisit(Create &) override { bool PreVisit(Create &) override {
AddPrivilege(AuthQuery::Privilege::CREATE); AddPrivilege(AuthQuery::Privilege::CREATE);
return false; return false;
@ -51,21 +76,6 @@ class PrivilegeExtractor : public HierarchicalTreeVisitor {
bool Visit(PrimitiveLiteral &) override { return true; } bool Visit(PrimitiveLiteral &) override { return true; }
bool Visit(ParameterLookup &) override { return true; } bool Visit(ParameterLookup &) override { return true; }
bool Visit(IndexQuery &) override {
AddPrivilege(AuthQuery::Privilege::INDEX);
return true;
}
bool PreVisit(AuthQuery &) override {
AddPrivilege(AuthQuery::Privilege::AUTH);
return false;
}
bool PreVisit(StreamQuery &) override {
AddPrivilege(AuthQuery::Privilege::STREAM);
return false;
}
private: private:
void AddPrivilege(AuthQuery::Privilege privilege) { void AddPrivilege(AuthQuery::Privilege privilege) {
if (!utils::Contains(privileges_, privilege)) { if (!utils::Contains(privileges_, privilege)) {

View File

@ -218,12 +218,6 @@ bool SymbolGenerator::PostVisit(Match &) {
return true; return true;
} }
bool SymbolGenerator::Visit(IndexQuery &) { return true; }
bool SymbolGenerator::PreVisit(AuthQuery &) { return false; }
bool SymbolGenerator::PreVisit(StreamQuery &) { return false; }
// Expressions // Expressions
SymbolGenerator::ReturnType SymbolGenerator::Visit(Identifier &ident) { SymbolGenerator::ReturnType SymbolGenerator::Visit(Identifier &ident) {
@ -333,27 +327,27 @@ bool SymbolGenerator::PostVisit(IfOperator &) {
bool SymbolGenerator::PreVisit(All &all) { bool SymbolGenerator::PreVisit(All &all) {
all.list_expression_->Accept(*this); all.list_expression_->Accept(*this);
VisitWithIdentifiers(*all.where_, {all.identifier_}); VisitWithIdentifiers(all.where_->expression_, {all.identifier_});
return false; return false;
} }
bool SymbolGenerator::PreVisit(Single &single) { bool SymbolGenerator::PreVisit(Single &single) {
single.list_expression_->Accept(*this); single.list_expression_->Accept(*this);
VisitWithIdentifiers(*single.where_, {single.identifier_}); VisitWithIdentifiers(single.where_->expression_, {single.identifier_});
return false; return false;
} }
bool SymbolGenerator::PreVisit(Reduce &reduce) { bool SymbolGenerator::PreVisit(Reduce &reduce) {
reduce.initializer_->Accept(*this); reduce.initializer_->Accept(*this);
reduce.list_->Accept(*this); reduce.list_->Accept(*this);
VisitWithIdentifiers(*reduce.expression_, VisitWithIdentifiers(reduce.expression_,
{reduce.accumulator_, reduce.identifier_}); {reduce.accumulator_, reduce.identifier_});
return false; return false;
} }
bool SymbolGenerator::PreVisit(Extract &extract) { bool SymbolGenerator::PreVisit(Extract &extract) {
extract.list_->Accept(*this); extract.list_->Accept(*this);
VisitWithIdentifiers(*extract.expression_, {extract.identifier_}); VisitWithIdentifiers(extract.expression_, {extract.identifier_});
return false; return false;
} }
@ -435,7 +429,7 @@ bool SymbolGenerator::PreVisit(EdgeAtom &edge_atom) {
scope_.in_edge_range = false; scope_.in_edge_range = false;
scope_.in_pattern = false; scope_.in_pattern = false;
if (edge_atom.filter_lambda_.expression) { if (edge_atom.filter_lambda_.expression) {
VisitWithIdentifiers(*edge_atom.filter_lambda_.expression, VisitWithIdentifiers(edge_atom.filter_lambda_.expression,
{edge_atom.filter_lambda_.inner_edge, {edge_atom.filter_lambda_.inner_edge,
edge_atom.filter_lambda_.inner_node}); edge_atom.filter_lambda_.inner_node});
} else { } else {
@ -449,7 +443,7 @@ bool SymbolGenerator::PreVisit(EdgeAtom &edge_atom) {
inner_node->name_, inner_node->user_declared_, Symbol::Type::Vertex); inner_node->name_, inner_node->user_declared_, Symbol::Type::Vertex);
} }
if (edge_atom.weight_lambda_.expression) { if (edge_atom.weight_lambda_.expression) {
VisitWithIdentifiers(*edge_atom.weight_lambda_.expression, VisitWithIdentifiers(edge_atom.weight_lambda_.expression,
{edge_atom.weight_lambda_.inner_edge, {edge_atom.weight_lambda_.inner_edge,
edge_atom.weight_lambda_.inner_node}); edge_atom.weight_lambda_.inner_node});
} }
@ -476,7 +470,7 @@ bool SymbolGenerator::PostVisit(EdgeAtom &) {
} }
void SymbolGenerator::VisitWithIdentifiers( void SymbolGenerator::VisitWithIdentifiers(
Tree &tree, const std::vector<Identifier *> &identifiers) { Expression *expr, const std::vector<Identifier *> &identifiers) {
std::vector<std::pair<std::experimental::optional<Symbol>, Identifier *>> std::vector<std::pair<std::experimental::optional<Symbol>, Identifier *>>
prev_symbols; prev_symbols;
// Collect previous symbols if they exist. // Collect previous symbols if they exist.
@ -490,8 +484,8 @@ void SymbolGenerator::VisitWithIdentifiers(
CreateSymbol(identifier->name_, identifier->user_declared_); CreateSymbol(identifier->name_, identifier->user_declared_);
prev_symbols.emplace_back(prev_symbol, identifier); prev_symbols.emplace_back(prev_symbol, identifier);
} }
// Visit the tree with the new symbols bound. // Visit the expression with the new symbols bound.
tree.Accept(*this); expr->Accept(*this);
// Restore back to previous symbols. // Restore back to previous symbols.
for (const auto &prev : prev_symbols) { for (const auto &prev : prev_symbols) {
const auto &prev_symbol = prev.first; const auto &prev_symbol = prev.first;

View File

@ -10,7 +10,6 @@
namespace query { namespace query {
///
/// Visits the AST and generates symbols for variables. /// Visits the AST and generates symbols for variables.
/// ///
/// During the process of symbol generation, simple semantic checks are /// During the process of symbol generation, simple semantic checks are
@ -46,9 +45,6 @@ class SymbolGenerator : public HierarchicalTreeVisitor {
bool PostVisit(Unwind &) override; bool PostVisit(Unwind &) override;
bool PreVisit(Match &) override; bool PreVisit(Match &) override;
bool PostVisit(Match &) override; bool PostVisit(Match &) override;
bool Visit(IndexQuery &) override;
bool PreVisit(AuthQuery &) override;
bool PreVisit(StreamQuery &) override;
// Expressions // Expressions
ReturnType Visit(Identifier &) override; ReturnType Visit(Identifier &) override;
@ -128,7 +124,7 @@ class SymbolGenerator : public HierarchicalTreeVisitor {
void VisitReturnBody(ReturnBody &body, Where *where = nullptr); void VisitReturnBody(ReturnBody &body, Where *where = nullptr);
void VisitWithIdentifiers(Tree &, const std::vector<Identifier *> &); void VisitWithIdentifiers(Expression *, const std::vector<Identifier *> &);
SymbolTable &symbol_table_; SymbolTable &symbol_table_;
Scope scope_; Scope scope_;
@ -136,4 +132,14 @@ class SymbolGenerator : public HierarchicalTreeVisitor {
std::unordered_set<std::string> curr_return_names_; std::unordered_set<std::string> curr_return_names_;
}; };
inline SymbolTable MakeSymbolTable(CypherQuery *query) {
SymbolTable symbol_table;
SymbolGenerator symbol_generator(symbol_table);
query->single_query_->Accept(symbol_generator);
for (auto *cypher_union : query->cypher_unions_) {
cypher_union->Accept(symbol_generator);
}
return symbol_table;
}
} // namespace query } // namespace query

View File

@ -815,9 +815,7 @@ std::unique_ptr<LogicalPlan> Interpreter::MakeLogicalPlan(
database::GraphDbAccessor *db_accessor) { database::GraphDbAccessor *db_accessor) {
auto vertex_counts = plan::MakeVertexCountCache(*db_accessor); auto vertex_counts = plan::MakeVertexCountCache(*db_accessor);
SymbolTable symbol_table; auto symbol_table = MakeSymbolTable(query);
SymbolGenerator symbol_generator(symbol_table);
query->Accept(symbol_generator);
auto planning_context = plan::MakePlanningContext(ast_storage, symbol_table, auto planning_context = plan::MakePlanningContext(ast_storage, symbol_table,
query, vertex_counts); query, vertex_counts);

View File

@ -52,9 +52,6 @@ class UsedSymbolsCollector : public HierarchicalTreeVisitor {
bool Visit(PrimitiveLiteral &) override { return true; } bool Visit(PrimitiveLiteral &) override { return true; }
bool Visit(ParameterLookup &) override { return true; } bool Visit(ParameterLookup &) override { return true; }
bool Visit(query::IndexQuery &) override { return true; }
bool PreVisit(query::AuthQuery &) override { return false; }
bool PreVisit(query::StreamQuery &) override { return false; }
std::unordered_set<Symbol> symbols_; std::unordered_set<Symbol> symbols_;
const SymbolTable &symbol_table_; const SymbolTable &symbol_table_;

View File

@ -410,21 +410,6 @@ class ReturnBodyContext : public HierarchicalTreeVisitor {
return true; return true;
} }
bool Visit(query::IndexQuery &) override {
has_aggregation_.emplace_back(false);
return true;
}
bool PreVisit(query::AuthQuery &) override {
has_aggregation_.emplace_back(false);
return false;
}
bool PreVisit(query::StreamQuery &) override {
has_aggregation_.emplace_back(false);
return false;
}
// Creates NamedExpression with an Identifier for each user declared symbol. // Creates NamedExpression with an Identifier for each user declared symbol.
// This should be used when body.all_identifiers is true, to generate // This should be used when body.all_identifiers is true, to generate
// expressions for Produce operator. // expressions for Produce operator.

View File

@ -41,9 +41,7 @@ static void BM_PlanChainedMatches(benchmark::State &state) {
query::AstStorage storage; query::AstStorage storage;
int num_matches = state.range(0); int num_matches = state.range(0);
auto *query = AddChainedMatches(num_matches, storage); auto *query = AddChainedMatches(num_matches, storage);
query::SymbolTable symbol_table; auto symbol_table = query::MakeSymbolTable(query);
query::SymbolGenerator symbol_generator(symbol_table);
query->Accept(symbol_generator);
auto ctx = auto ctx =
query::plan::MakePlanningContext(storage, symbol_table, query, *dba); query::plan::MakePlanningContext(storage, symbol_table, query, *dba);
state.ResumeTiming(); state.ResumeTiming();
@ -121,9 +119,7 @@ static void BM_PlanAndEstimateIndexedMatching(benchmark::State &state) {
query::AstStorage storage; query::AstStorage storage;
auto *query = AddIndexedMatches(index_count, label, auto *query = AddIndexedMatches(index_count, label,
std::make_pair("prop", prop), storage); std::make_pair("prop", prop), storage);
query::SymbolTable symbol_table; auto symbol_table = query::MakeSymbolTable(query);
query::SymbolGenerator symbol_generator(symbol_table);
query->Accept(symbol_generator);
state.ResumeTiming(); state.ResumeTiming();
auto ctx = auto ctx =
query::plan::MakePlanningContext(storage, symbol_table, query, *dba); query::plan::MakePlanningContext(storage, symbol_table, query, *dba);
@ -157,9 +153,7 @@ static void BM_PlanAndEstimateIndexedMatchingWithCachedCounts(
query::AstStorage storage; query::AstStorage storage;
auto *query = AddIndexedMatches(index_count, label, auto *query = AddIndexedMatches(index_count, label,
std::make_pair("prop", prop), storage); std::make_pair("prop", prop), storage);
query::SymbolTable symbol_table; auto symbol_table = query::MakeSymbolTable(query);
query::SymbolGenerator symbol_generator(symbol_table);
query->Accept(symbol_generator);
state.ResumeTiming(); state.ResumeTiming();
auto ctx = query::plan::MakePlanningContext(storage, symbol_table, query, auto ctx = query::plan::MakePlanningContext(storage, symbol_table, query,
vertex_counts); vertex_counts);

View File

@ -444,13 +444,6 @@ query::Query *MakeAst(const std::string &query, query::AstStorage *storage,
return visitor.query(); return visitor.query();
} }
query::SymbolTable MakeSymbolTable(query::Query *query) {
query::SymbolTable symbol_table;
query::SymbolGenerator symbol_generator(symbol_table);
query->Accept(symbol_generator);
return symbol_table;
}
// Returns a list of pairs (plan, estimated cost), sorted in the ascending // Returns a list of pairs (plan, estimated cost), sorted in the ascending
// order by cost. // order by cost.
auto MakeLogicalPlans(query::CypherQuery *query, query::AstStorage &ast, auto MakeLogicalPlans(query::CypherQuery *query, query::AstStorage &ast,
@ -508,7 +501,7 @@ void RunInteractivePlanning(database::GraphDbAccessor *dba) {
"Interactive planning is only avaialable for regular openCypher " "Interactive planning is only avaialable for regular openCypher "
"queries."); "queries.");
} }
auto symbol_table = MakeSymbolTable(query); auto symbol_table = query::MakeSymbolTable(query);
planning_timer.Start(); planning_timer.Start();
auto plans = MakeLogicalPlans(query, ast, symbol_table, interactive_db); auto plans = MakeLogicalPlans(query, ast, symbol_table, interactive_db);
auto planning_time = planning_timer.Elapsed(); auto planning_time = planning_timer.Elapsed();

View File

@ -624,7 +624,7 @@ struct ExpectedDistributedPlan {
template <class TPlanner> template <class TPlanner>
DistributedPlan MakeDistributedPlan(query::CypherQuery *query, DistributedPlan MakeDistributedPlan(query::CypherQuery *query,
query::AstStorage &storage) { query::AstStorage &storage) {
auto symbol_table = MakeSymbolTable(*query); auto symbol_table = query::MakeSymbolTable(query);
FakeDbAccessor dba; FakeDbAccessor dba;
auto planner = MakePlanner<TPlanner>(dba, storage, symbol_table, query); auto planner = MakePlanner<TPlanner>(dba, storage, symbol_table, query);
std::atomic<int64_t> next_plan_id{0}; std::atomic<int64_t> next_plan_id{0};
@ -732,7 +732,7 @@ TYPED_TEST(TestPlanner, MatchNodeReturn) {
AstStorage storage; AstStorage storage;
auto *as_n = NEXPR("n", IDENT("n")); auto *as_n = NEXPR("n", IDENT("n"));
auto *query = QUERY(SINGLE_QUERY(MATCH(PATTERN(NODE("n"))), RETURN(as_n))); auto *query = QUERY(SINGLE_QUERY(MATCH(PATTERN(NODE("n"))), RETURN(as_n)));
auto symbol_table = MakeSymbolTable(*query); auto symbol_table = query::MakeSymbolTable(query);
FakeDbAccessor dba; FakeDbAccessor dba;
auto planner = MakePlanner<TypeParam>(dba, storage, symbol_table, query); auto planner = MakePlanner<TypeParam>(dba, storage, symbol_table, query);
ExpectPullRemote pull({symbol_table.at(*as_n)}); ExpectPullRemote pull({symbol_table.at(*as_n)});
@ -748,7 +748,7 @@ TYPED_TEST(TestPlanner, CreateNodeReturn) {
auto ident_n = IDENT("n"); auto ident_n = IDENT("n");
auto query = auto query =
QUERY(SINGLE_QUERY(CREATE(PATTERN(NODE("n"))), RETURN(ident_n, AS("n")))); QUERY(SINGLE_QUERY(CREATE(PATTERN(NODE("n"))), RETURN(ident_n, AS("n"))));
auto symbol_table = MakeSymbolTable(*query); auto symbol_table = query::MakeSymbolTable(query);
auto acc = ExpectAccumulate({symbol_table.at(*ident_n)}); auto acc = ExpectAccumulate({symbol_table.at(*ident_n)});
FakeDbAccessor dba; FakeDbAccessor dba;
auto planner = MakePlanner<TypeParam>(dba, storage, symbol_table, query); auto planner = MakePlanner<TypeParam>(dba, storage, symbol_table, query);
@ -842,7 +842,7 @@ TYPED_TEST(TestPlanner, MatchLabeledNodes) {
auto *as_n = NEXPR("n", IDENT("n")); auto *as_n = NEXPR("n", IDENT("n"));
auto *query = auto *query =
QUERY(SINGLE_QUERY(MATCH(PATTERN(NODE("n", label))), RETURN(as_n))); QUERY(SINGLE_QUERY(MATCH(PATTERN(NODE("n", label))), RETURN(as_n)));
auto symbol_table = MakeSymbolTable(*query); auto symbol_table = query::MakeSymbolTable(query);
auto planner = MakePlanner<TypeParam>(dba, storage, symbol_table, query); auto planner = MakePlanner<TypeParam>(dba, storage, symbol_table, query);
ExpectPullRemote pull({symbol_table.at(*as_n)}); ExpectPullRemote pull({symbol_table.at(*as_n)});
auto expected = ExpectDistributed( auto expected = ExpectDistributed(
@ -861,7 +861,7 @@ TYPED_TEST(TestPlanner, MatchPathReturn) {
MATCH(PATTERN(NODE("n"), EDGE("r", Direction::BOTH, {relationship}), MATCH(PATTERN(NODE("n"), EDGE("r", Direction::BOTH, {relationship}),
NODE("m"))), NODE("m"))),
RETURN(as_n))); RETURN(as_n)));
auto symbol_table = MakeSymbolTable(*query); auto symbol_table = query::MakeSymbolTable(query);
auto planner = MakePlanner<TypeParam>(dba, storage, symbol_table, query); auto planner = MakePlanner<TypeParam>(dba, storage, symbol_table, query);
ExpectPullRemote pull({symbol_table.at(*as_n)}); ExpectPullRemote pull({symbol_table.at(*as_n)});
auto expected = auto expected =
@ -883,7 +883,7 @@ TYPED_TEST(TestPlanner, MatchNamedPatternReturn) {
EDGE("r", Direction::BOTH, {relationship}), EDGE("r", Direction::BOTH, {relationship}),
NODE("m"))), NODE("m"))),
RETURN(as_p))); RETURN(as_p)));
auto symbol_table = MakeSymbolTable(*query); auto symbol_table = query::MakeSymbolTable(query);
auto planner = MakePlanner<TypeParam>(dba, storage, symbol_table, query); auto planner = MakePlanner<TypeParam>(dba, storage, symbol_table, query);
ExpectPullRemote pull({symbol_table.at(*as_p)}); ExpectPullRemote pull({symbol_table.at(*as_p)});
auto expected = ExpectDistributed( auto expected = ExpectDistributed(
@ -905,7 +905,7 @@ TYPED_TEST(TestPlanner, MatchNamedPatternWithPredicateReturn) {
EDGE("r", Direction::BOTH, {relationship}), EDGE("r", Direction::BOTH, {relationship}),
NODE("m"))), NODE("m"))),
WHERE(EQ(LITERAL(2), IDENT("p"))), RETURN(as_p))); WHERE(EQ(LITERAL(2), IDENT("p"))), RETURN(as_p)));
auto symbol_table = MakeSymbolTable(*query); auto symbol_table = query::MakeSymbolTable(query);
auto planner = MakePlanner<TypeParam>(dba, storage, symbol_table, query); auto planner = MakePlanner<TypeParam>(dba, storage, symbol_table, query);
ExpectPullRemote pull({symbol_table.at(*as_p)}); ExpectPullRemote pull({symbol_table.at(*as_p)});
auto expected = auto expected =
@ -927,7 +927,7 @@ TYPED_TEST(TestPlanner, OptionalMatchNamedPatternReturn) {
auto pattern = NAMED_PATTERN("p", node_n, edge, node_m); auto pattern = NAMED_PATTERN("p", node_n, edge, node_m);
auto as_p = AS("p"); auto as_p = AS("p");
auto *query = QUERY(SINGLE_QUERY(OPTIONAL_MATCH(pattern), RETURN("p", as_p))); auto *query = QUERY(SINGLE_QUERY(OPTIONAL_MATCH(pattern), RETURN("p", as_p)));
auto symbol_table = MakeSymbolTable(*query); auto symbol_table = query::MakeSymbolTable(query);
auto get_symbol = [&symbol_table](const auto *ast_node) { auto get_symbol = [&symbol_table](const auto *ast_node) {
return symbol_table.at(*ast_node->identifier_); return symbol_table.at(*ast_node->identifier_);
}; };
@ -955,7 +955,7 @@ TYPED_TEST(TestPlanner, MatchWhereReturn) {
auto *query = QUERY(SINGLE_QUERY( auto *query = QUERY(SINGLE_QUERY(
MATCH(PATTERN(NODE("n"))), MATCH(PATTERN(NODE("n"))),
WHERE(LESS(PROPERTY_LOOKUP("n", property), LITERAL(42))), RETURN(as_n))); WHERE(LESS(PROPERTY_LOOKUP("n", property), LITERAL(42))), RETURN(as_n)));
auto symbol_table = MakeSymbolTable(*query); auto symbol_table = query::MakeSymbolTable(query);
auto planner = MakePlanner<TypeParam>(dba, storage, symbol_table, query); auto planner = MakePlanner<TypeParam>(dba, storage, symbol_table, query);
ExpectPullRemote pull({symbol_table.at(*as_n)}); ExpectPullRemote pull({symbol_table.at(*as_n)});
auto expected = ExpectDistributed( auto expected = ExpectDistributed(
@ -1023,7 +1023,7 @@ TYPED_TEST(TestPlanner, MultiMatch) {
auto *query = QUERY(SINGLE_QUERY( auto *query = QUERY(SINGLE_QUERY(
MATCH(PATTERN(node_n, edge_r, node_m)), MATCH(PATTERN(node_n, edge_r, node_m)),
MATCH(PATTERN(node_j, edge_e, node_i, edge_f, node_h)), RETURN("n"))); MATCH(PATTERN(node_j, edge_e, node_i, edge_f, node_h)), RETURN("n")));
auto symbol_table = MakeSymbolTable(*query); auto symbol_table = query::MakeSymbolTable(query);
FakeDbAccessor dba; FakeDbAccessor dba;
auto planner = MakePlanner<TypeParam>(dba, storage, symbol_table, query); auto planner = MakePlanner<TypeParam>(dba, storage, symbol_table, query);
auto get_symbol = [&symbol_table](const auto *atom_node) { auto get_symbol = [&symbol_table](const auto *atom_node) {
@ -1058,7 +1058,7 @@ TYPED_TEST(TestPlanner, MultiMatchSameStart) {
MATCH(PATTERN(NODE("n"), EDGE("r"), NODE("m"))), RETURN(as_n))); MATCH(PATTERN(NODE("n"), EDGE("r"), NODE("m"))), RETURN(as_n)));
// Similar to MatchMultiPatternSameStart, we expect only Expand from second // Similar to MatchMultiPatternSameStart, we expect only Expand from second
// MATCH clause. // MATCH clause.
auto symbol_table = MakeSymbolTable(*query); auto symbol_table = query::MakeSymbolTable(query);
FakeDbAccessor dba; FakeDbAccessor dba;
auto planner = MakePlanner<TypeParam>(dba, storage, symbol_table, query); auto planner = MakePlanner<TypeParam>(dba, storage, symbol_table, query);
ExpectPullRemote pull({symbol_table.at(*as_n)}); ExpectPullRemote pull({symbol_table.at(*as_n)});
@ -1077,7 +1077,7 @@ TYPED_TEST(TestPlanner, MatchWithReturn) {
auto *query = QUERY(SINGLE_QUERY(MATCH(PATTERN(NODE("old"))), auto *query = QUERY(SINGLE_QUERY(MATCH(PATTERN(NODE("old"))),
WITH("old", AS("new")), RETURN(as_new))); WITH("old", AS("new")), RETURN(as_new)));
// No accumulation since we only do reads. // No accumulation since we only do reads.
auto symbol_table = MakeSymbolTable(*query); auto symbol_table = query::MakeSymbolTable(query);
FakeDbAccessor dba; FakeDbAccessor dba;
auto planner = MakePlanner<TypeParam>(dba, storage, symbol_table, query); auto planner = MakePlanner<TypeParam>(dba, storage, symbol_table, query);
ExpectPullRemote pull({symbol_table.at(*as_new)}); ExpectPullRemote pull({symbol_table.at(*as_new)});
@ -1097,7 +1097,7 @@ TYPED_TEST(TestPlanner, MatchWithWhereReturn) {
MATCH(PATTERN(NODE("old"))), WITH("old", AS("new")), MATCH(PATTERN(NODE("old"))), WITH("old", AS("new")),
WHERE(LESS(PROPERTY_LOOKUP("new", prop), LITERAL(42))), RETURN(as_new))); WHERE(LESS(PROPERTY_LOOKUP("new", prop), LITERAL(42))), RETURN(as_new)));
// No accumulation since we only do reads. // No accumulation since we only do reads.
auto symbol_table = MakeSymbolTable(*query); auto symbol_table = query::MakeSymbolTable(query);
auto planner = MakePlanner<TypeParam>(dba, storage, symbol_table, query); auto planner = MakePlanner<TypeParam>(dba, storage, symbol_table, query);
ExpectPullRemote pull({symbol_table.at(*as_new)}); ExpectPullRemote pull({symbol_table.at(*as_new)});
auto expected = auto expected =
@ -1136,7 +1136,7 @@ TYPED_TEST(TestPlanner, MatchReturnSum) {
auto *query = QUERY(SINGLE_QUERY( auto *query = QUERY(SINGLE_QUERY(
MATCH(PATTERN(NODE("n"))), RETURN(sum, AS("sum"), n_prop2, AS("group")))); MATCH(PATTERN(NODE("n"))), RETURN(sum, AS("sum"), n_prop2, AS("group"))));
auto aggr = ExpectAggregate({sum}, {n_prop2}); auto aggr = ExpectAggregate({sum}, {n_prop2});
auto symbol_table = MakeSymbolTable(*query); auto symbol_table = query::MakeSymbolTable(query);
auto planner = MakePlanner<TypeParam>(dba, storage, symbol_table, query); auto planner = MakePlanner<TypeParam>(dba, storage, symbol_table, query);
std::atomic<int64_t> next_plan_id{0}; std::atomic<int64_t> next_plan_id{0};
auto distributed_plan = auto distributed_plan =
@ -1176,7 +1176,7 @@ TYPED_TEST(TestPlanner, MatchReturnSkipLimit) {
auto *query = auto *query =
QUERY(SINGLE_QUERY(MATCH(PATTERN(NODE("n"))), QUERY(SINGLE_QUERY(MATCH(PATTERN(NODE("n"))),
RETURN(as_n, SKIP(LITERAL(2)), LIMIT(LITERAL(1))))); RETURN(as_n, SKIP(LITERAL(2)), LIMIT(LITERAL(1)))));
auto symbol_table = MakeSymbolTable(*query); auto symbol_table = query::MakeSymbolTable(query);
FakeDbAccessor dba; FakeDbAccessor dba;
auto planner = MakePlanner<TypeParam>(dba, storage, symbol_table, query); auto planner = MakePlanner<TypeParam>(dba, storage, symbol_table, query);
ExpectPullRemote pull({symbol_table.at(*as_n)}); ExpectPullRemote pull({symbol_table.at(*as_n)});
@ -1194,7 +1194,7 @@ TYPED_TEST(TestPlanner, CreateWithSkipReturnLimit) {
auto query = QUERY(SINGLE_QUERY(CREATE(PATTERN(NODE("n"))), auto query = QUERY(SINGLE_QUERY(CREATE(PATTERN(NODE("n"))),
WITH(ident_n, AS("m"), SKIP(LITERAL(2))), WITH(ident_n, AS("m"), SKIP(LITERAL(2))),
RETURN("m", LIMIT(LITERAL(1))))); RETURN("m", LIMIT(LITERAL(1)))));
auto symbol_table = MakeSymbolTable(*query); auto symbol_table = query::MakeSymbolTable(query);
auto acc = ExpectAccumulate({symbol_table.at(*ident_n)}); auto acc = ExpectAccumulate({symbol_table.at(*ident_n)});
FakeDbAccessor dba; FakeDbAccessor dba;
auto planner = MakePlanner<TypeParam>(dba, storage, symbol_table, query); auto planner = MakePlanner<TypeParam>(dba, storage, symbol_table, query);
@ -1215,7 +1215,7 @@ TYPED_TEST(TestPlanner, MatchReturnOrderBy) {
auto *node_n = NODE("n"); auto *node_n = NODE("n");
auto ret = RETURN(as_m, ORDER_BY(PROPERTY_LOOKUP("n", prop))); auto ret = RETURN(as_m, ORDER_BY(PROPERTY_LOOKUP("n", prop)));
auto *query = QUERY(SINGLE_QUERY(MATCH(PATTERN(node_n)), ret)); auto *query = QUERY(SINGLE_QUERY(MATCH(PATTERN(node_n)), ret));
auto symbol_table = MakeSymbolTable(*query); auto symbol_table = query::MakeSymbolTable(query);
auto planner = MakePlanner<TypeParam>(dba, storage, symbol_table, query); auto planner = MakePlanner<TypeParam>(dba, storage, symbol_table, query);
ExpectPullRemoteOrderBy pull_order_by( ExpectPullRemoteOrderBy pull_order_by(
{symbol_table.at(*as_m), symbol_table.at(*node_n->identifier_)}); {symbol_table.at(*as_m), symbol_table.at(*node_n->identifier_)});
@ -1246,7 +1246,7 @@ TYPED_TEST(TestPlanner, CreateWithOrderByWhere) {
PATTERN(NODE("n"), EDGE("r", Direction::OUT, {r_type}), NODE("m"))), PATTERN(NODE("n"), EDGE("r", Direction::OUT, {r_type}), NODE("m"))),
WITH(ident_n, AS("new"), ORDER_BY(new_prop, r_prop)), WITH(ident_n, AS("new"), ORDER_BY(new_prop, r_prop)),
WHERE(LESS(m_prop, LITERAL(42))))); WHERE(LESS(m_prop, LITERAL(42)))));
auto symbol_table = MakeSymbolTable(*query); auto symbol_table = query::MakeSymbolTable(query);
// Since this is a write query, we expect to accumulate to old used symbols. // Since this is a write query, we expect to accumulate to old used symbols.
auto acc = ExpectAccumulate({ auto acc = ExpectAccumulate({
symbol_table.at(*ident_n), // `n` in WITH symbol_table.at(*ident_n), // `n` in WITH
@ -1283,7 +1283,7 @@ TYPED_TEST(TestPlanner, MatchUnwindReturn) {
SINGLE_QUERY(MATCH(PATTERN(NODE("n"))), SINGLE_QUERY(MATCH(PATTERN(NODE("n"))),
UNWIND(LIST(LITERAL(1), LITERAL(2), LITERAL(3)), AS("x")), UNWIND(LIST(LITERAL(1), LITERAL(2), LITERAL(3)), AS("x")),
RETURN(as_n, as_x))); RETURN(as_n, as_x)));
auto symbol_table = MakeSymbolTable(*query); auto symbol_table = query::MakeSymbolTable(query);
FakeDbAccessor dba; FakeDbAccessor dba;
auto planner = MakePlanner<TypeParam>(dba, storage, symbol_table, query); auto planner = MakePlanner<TypeParam>(dba, storage, symbol_table, query);
ExpectPullRemote pull({symbol_table.at(*as_n), symbol_table.at(*as_x)}); ExpectPullRemote pull({symbol_table.at(*as_n), symbol_table.at(*as_x)});
@ -1315,7 +1315,7 @@ TYPED_TEST(TestPlanner, MatchWhereBeforeExpand) {
MATCH(PATTERN(NODE("n"), EDGE("r"), NODE("m"))), MATCH(PATTERN(NODE("n"), EDGE("r"), NODE("m"))),
WHERE(LESS(PROPERTY_LOOKUP("n", prop), LITERAL(42))), RETURN(as_n))); WHERE(LESS(PROPERTY_LOOKUP("n", prop), LITERAL(42))), RETURN(as_n)));
// We expect Filter to come immediately after ScanAll, since it only uses `n`. // We expect Filter to come immediately after ScanAll, since it only uses `n`.
auto symbol_table = MakeSymbolTable(*query); auto symbol_table = query::MakeSymbolTable(query);
auto planner = MakePlanner<TypeParam>(dba, storage, symbol_table, query); auto planner = MakePlanner<TypeParam>(dba, storage, symbol_table, query);
ExpectPullRemote pull({symbol_table.at(*as_n)}); ExpectPullRemote pull({symbol_table.at(*as_n)});
auto expected = ExpectDistributed( auto expected = ExpectDistributed(
@ -1361,7 +1361,7 @@ TYPED_TEST(TestPlanner, MatchBfs) {
auto *as_r = NEXPR("r", IDENT("r")); auto *as_r = NEXPR("r", IDENT("r"));
auto *query = QUERY( auto *query = QUERY(
SINGLE_QUERY(MATCH(PATTERN(NODE("n"), bfs, NODE("m"))), RETURN(as_r))); SINGLE_QUERY(MATCH(PATTERN(NODE("n"), bfs, NODE("m"))), RETURN(as_r)));
auto symbol_table = MakeSymbolTable(*query); auto symbol_table = query::MakeSymbolTable(query);
ExpectPullRemote pull({symbol_table.at(*as_r)}); ExpectPullRemote pull({symbol_table.at(*as_r)});
auto expected = ExpectDistributed( auto expected = ExpectDistributed(
MakeCheckers(ExpectScanAll(), ExpectDistributedExpandBfs(), MakeCheckers(ExpectScanAll(), ExpectDistributedExpandBfs(),
@ -1431,7 +1431,7 @@ TYPED_TEST(TestPlanner, DistributedMatchCreateReturn) {
auto *query = auto *query =
QUERY(SINGLE_QUERY(MATCH(PATTERN(NODE("n"))), CREATE(PATTERN(NODE("m"))), QUERY(SINGLE_QUERY(MATCH(PATTERN(NODE("n"))), CREATE(PATTERN(NODE("m"))),
RETURN(ident_m, AS("m")))); RETURN(ident_m, AS("m"))));
auto symbol_table = MakeSymbolTable(*query); auto symbol_table = query::MakeSymbolTable(query);
auto acc = ExpectAccumulate({symbol_table.at(*ident_m)}); auto acc = ExpectAccumulate({symbol_table.at(*ident_m)});
FakeDbAccessor dba; FakeDbAccessor dba;
auto planner = MakePlanner<TypeParam>(dba, storage, symbol_table, query); auto planner = MakePlanner<TypeParam>(dba, storage, symbol_table, query);
@ -1455,7 +1455,7 @@ TYPED_TEST(TestPlanner, DistributedCartesianCreateExpand) {
CREATE(PATTERN(NODE("a"), EDGE("e", Direction::OUT, {relationship}), CREATE(PATTERN(NODE("a"), EDGE("e", Direction::OUT, {relationship}),
NODE("b"))), NODE("b"))),
RETURN("e"))); RETURN("e")));
auto symbol_table = MakeSymbolTable(*query); auto symbol_table = query::MakeSymbolTable(query);
auto left_cart = auto left_cart =
MakeCheckers(ExpectScanAll(), MakeCheckers(ExpectScanAll(),
ExpectPullRemote({symbol_table.at(*node_a->identifier_)})); ExpectPullRemote({symbol_table.at(*node_a->identifier_)}));
@ -1480,7 +1480,7 @@ TYPED_TEST(TestPlanner, DistributedCartesianExpand) {
auto *node_c = NODE("c"); auto *node_c = NODE("c");
auto *query = QUERY(SINGLE_QUERY( auto *query = QUERY(SINGLE_QUERY(
MATCH(PATTERN(node_a), PATTERN(node_b, edge_e, node_c)), RETURN("c"))); MATCH(PATTERN(node_a), PATTERN(node_b, edge_e, node_c)), RETURN("c")));
auto symbol_table = MakeSymbolTable(*query); auto symbol_table = query::MakeSymbolTable(query);
auto sym_a = symbol_table.at(*node_a->identifier_); auto sym_a = symbol_table.at(*node_a->identifier_);
auto left_cart = MakeCheckers(ExpectScanAll(), ExpectPullRemote({sym_a})); auto left_cart = MakeCheckers(ExpectScanAll(), ExpectPullRemote({sym_a}));
auto sym_b = symbol_table.at(*node_b->identifier_); auto sym_b = symbol_table.at(*node_b->identifier_);
@ -1506,7 +1506,7 @@ TYPED_TEST(TestPlanner, DistributedCartesianExpandToExisting) {
auto *query = QUERY(SINGLE_QUERY( auto *query = QUERY(SINGLE_QUERY(
MATCH(PATTERN(node_a), PATTERN(node_b, EDGE("e"), NODE("a"))), MATCH(PATTERN(node_a), PATTERN(node_b, EDGE("e"), NODE("a"))),
RETURN("e"))); RETURN("e")));
auto symbol_table = MakeSymbolTable(*query); auto symbol_table = query::MakeSymbolTable(query);
auto sym_a = symbol_table.at(*node_a->identifier_); auto sym_a = symbol_table.at(*node_a->identifier_);
auto left_cart = MakeCheckers(ExpectScanAll(), ExpectPullRemote({sym_a})); auto left_cart = MakeCheckers(ExpectScanAll(), ExpectPullRemote({sym_a}));
auto sym_b = symbol_table.at(*node_b->identifier_); auto sym_b = symbol_table.at(*node_b->identifier_);
@ -1529,7 +1529,7 @@ TYPED_TEST(TestPlanner, DistributedCartesianExpandFromExisting) {
QUERY(SINGLE_QUERY(MATCH(PATTERN(node_a), PATTERN(node_b), QUERY(SINGLE_QUERY(MATCH(PATTERN(node_a), PATTERN(node_b),
PATTERN(NODE("a"), EDGE("e"), NODE("b"))), PATTERN(NODE("a"), EDGE("e"), NODE("b"))),
RETURN("e"))); RETURN("e")));
auto symbol_table = MakeSymbolTable(*query); auto symbol_table = query::MakeSymbolTable(query);
auto sym_a = symbol_table.at(*node_a->identifier_); auto sym_a = symbol_table.at(*node_a->identifier_);
auto left_cart = MakeCheckers(ExpectScanAll(), ExpectPullRemote({sym_a})); auto left_cart = MakeCheckers(ExpectScanAll(), ExpectPullRemote({sym_a}));
auto sym_b = symbol_table.at(*node_b->identifier_); auto sym_b = symbol_table.at(*node_b->identifier_);
@ -1554,7 +1554,7 @@ TYPED_TEST(TestPlanner, DistributedCartesianFilter) {
WHERE(AND(AND(EQ(IDENT("a"), LITERAL(42)), EQ(IDENT("b"), IDENT("a"))), WHERE(AND(AND(EQ(IDENT("a"), LITERAL(42)), EQ(IDENT("b"), IDENT("a"))),
EQ(IDENT("c"), IDENT("b")))), EQ(IDENT("c"), IDENT("b")))),
RETURN("c"))); RETURN("c")));
auto symbol_table = MakeSymbolTable(*query); auto symbol_table = query::MakeSymbolTable(query);
auto sym_a = symbol_table.at(*node_a->identifier_); auto sym_a = symbol_table.at(*node_a->identifier_);
auto sym_b = symbol_table.at(*node_b->identifier_); auto sym_b = symbol_table.at(*node_b->identifier_);
auto sym_c = symbol_table.at(*node_c->identifier_); auto sym_c = symbol_table.at(*node_c->identifier_);
@ -1588,7 +1588,7 @@ TYPED_TEST(TestPlanner, DistributedCartesianIndexedScanByProperty) {
auto *query = QUERY(SINGLE_QUERY( auto *query = QUERY(SINGLE_QUERY(
MATCH(PATTERN(node_a), PATTERN(node_b)), MATCH(PATTERN(node_a), PATTERN(node_b)),
WHERE(EQ(PROPERTY_LOOKUP("b", prop), IDENT("a"))), RETURN("b"))); WHERE(EQ(PROPERTY_LOOKUP("b", prop), IDENT("a"))), RETURN("b")));
auto symbol_table = MakeSymbolTable(*query); auto symbol_table = query::MakeSymbolTable(query);
auto sym_a = symbol_table.at(*node_a->identifier_); auto sym_a = symbol_table.at(*node_a->identifier_);
auto sym_b = symbol_table.at(*node_b->identifier_); auto sym_b = symbol_table.at(*node_b->identifier_);
auto left_cart = MakeCheckers(ExpectScanAll(), ExpectPullRemote({sym_a})); auto left_cart = MakeCheckers(ExpectScanAll(), ExpectPullRemote({sym_a}));
@ -1618,7 +1618,7 @@ TYPED_TEST(TestPlanner, DistributedCartesianIndexedScanByLowerBound) {
auto *query = QUERY(SINGLE_QUERY( auto *query = QUERY(SINGLE_QUERY(
MATCH(PATTERN(node_a), PATTERN(node_b)), MATCH(PATTERN(node_a), PATTERN(node_b)),
WHERE(LESS(IDENT("a"), PROPERTY_LOOKUP("b", prop))), RETURN("b"))); WHERE(LESS(IDENT("a"), PROPERTY_LOOKUP("b", prop))), RETURN("b")));
auto symbol_table = MakeSymbolTable(*query); auto symbol_table = query::MakeSymbolTable(query);
auto sym_a = symbol_table.at(*node_a->identifier_); auto sym_a = symbol_table.at(*node_a->identifier_);
auto sym_b = symbol_table.at(*node_b->identifier_); auto sym_b = symbol_table.at(*node_b->identifier_);
auto left_cart = MakeCheckers(ExpectScanAll(), ExpectPullRemote({sym_a})); auto left_cart = MakeCheckers(ExpectScanAll(), ExpectPullRemote({sym_a}));
@ -1648,7 +1648,7 @@ TYPED_TEST(TestPlanner, DistributedCartesianIndexedScanByUpperBound) {
auto *query = QUERY(SINGLE_QUERY( auto *query = QUERY(SINGLE_QUERY(
MATCH(PATTERN(node_a), PATTERN(node_b)), MATCH(PATTERN(node_a), PATTERN(node_b)),
WHERE(GREATER(IDENT("a"), PROPERTY_LOOKUP("b", prop))), RETURN("b"))); WHERE(GREATER(IDENT("a"), PROPERTY_LOOKUP("b", prop))), RETURN("b")));
auto symbol_table = MakeSymbolTable(*query); auto symbol_table = query::MakeSymbolTable(query);
auto sym_a = symbol_table.at(*node_a->identifier_); auto sym_a = symbol_table.at(*node_a->identifier_);
auto sym_b = symbol_table.at(*node_b->identifier_); auto sym_b = symbol_table.at(*node_b->identifier_);
auto left_cart = MakeCheckers(ExpectScanAll(), ExpectPullRemote({sym_a})); auto left_cart = MakeCheckers(ExpectScanAll(), ExpectPullRemote({sym_a}));
@ -1792,7 +1792,7 @@ TYPED_TEST(TestPlanner, DistributedCartesianProduce) {
auto *query = QUERY( auto *query = QUERY(
SINGLE_QUERY(MATCH(PATTERN(NODE("a"))), with_a, MATCH(PATTERN(node_b)), SINGLE_QUERY(MATCH(PATTERN(NODE("a"))), with_a, MATCH(PATTERN(node_b)),
WHERE(EQ(IDENT("b"), IDENT("a"))), RETURN("b"))); WHERE(EQ(IDENT("b"), IDENT("a"))), RETURN("b")));
auto symbol_table = MakeSymbolTable(*query); auto symbol_table = query::MakeSymbolTable(query);
auto sym_a = symbol_table.at(*with_a->body_.named_expressions[0]); auto sym_a = symbol_table.at(*with_a->body_.named_expressions[0]);
auto left_cart = auto left_cart =
MakeCheckers(ExpectScanAll(), ExpectProduce(), ExpectPullRemote({sym_a})); MakeCheckers(ExpectScanAll(), ExpectProduce(), ExpectPullRemote({sym_a}));
@ -1815,7 +1815,7 @@ TYPED_TEST(TestPlanner, DistributedCartesianUnwind) {
auto *node_b = NODE("b"); auto *node_b = NODE("b");
auto *query = QUERY(SINGLE_QUERY(MATCH(PATTERN(node_a), PATTERN(node_b)), auto *query = QUERY(SINGLE_QUERY(MATCH(PATTERN(node_a), PATTERN(node_b)),
UNWIND(IDENT("a"), AS("x")), RETURN("x"))); UNWIND(IDENT("a"), AS("x")), RETURN("x")));
auto symbol_table = MakeSymbolTable(*query); auto symbol_table = query::MakeSymbolTable(query);
auto sym_a = symbol_table.at(*node_a->identifier_); auto sym_a = symbol_table.at(*node_a->identifier_);
auto left_cart = MakeCheckers(ExpectScanAll(), ExpectPullRemote({sym_a})); auto left_cart = MakeCheckers(ExpectScanAll(), ExpectPullRemote({sym_a}));
auto sym_b = symbol_table.at(*node_b->identifier_); auto sym_b = symbol_table.at(*node_b->identifier_);
@ -1837,7 +1837,7 @@ TYPED_TEST(TestPlanner, DistributedCartesianMatchCreateNode) {
auto *query = QUERY(SINGLE_QUERY( auto *query = QUERY(SINGLE_QUERY(
MATCH(PATTERN(NODE("a"))), CREATE(PATTERN(node_b)), WITH("b"), MATCH(PATTERN(NODE("a"))), CREATE(PATTERN(node_b)), WITH("b"),
MATCH(PATTERN(node_c)), CREATE(PATTERN(NODE("d"))))); MATCH(PATTERN(node_c)), CREATE(PATTERN(NODE("d")))));
auto symbol_table = MakeSymbolTable(*query); auto symbol_table = query::MakeSymbolTable(query);
auto sym_b = symbol_table.at(*node_b->identifier_); auto sym_b = symbol_table.at(*node_b->identifier_);
auto left_cart = auto left_cart =
MakeCheckers(ExpectScanAll(), ExpectDistributedCreateNode(), MakeCheckers(ExpectScanAll(), ExpectDistributedCreateNode(),
@ -1861,7 +1861,7 @@ TYPED_TEST(TestPlanner, DistributedCartesianCreateNode) {
auto *node_b = NODE("b"); auto *node_b = NODE("b");
auto *query = QUERY(SINGLE_QUERY(CREATE(PATTERN(node_a)), WITH("a"), auto *query = QUERY(SINGLE_QUERY(CREATE(PATTERN(node_a)), WITH("a"),
MATCH(PATTERN(node_b)), RETURN("b"))); MATCH(PATTERN(node_b)), RETURN("b")));
auto symbol_table = MakeSymbolTable(*query); auto symbol_table = query::MakeSymbolTable(query);
auto sym_a = symbol_table.at(*node_a->identifier_); auto sym_a = symbol_table.at(*node_a->identifier_);
auto left_cart = MakeCheckers(ExpectDistributedCreateNode(true), auto left_cart = MakeCheckers(ExpectDistributedCreateNode(true),
ExpectSynchronize(true), ExpectProduce()); ExpectSynchronize(true), ExpectProduce());
@ -1886,7 +1886,7 @@ TYPED_TEST(TestPlanner, DistributedOptionalExpand) {
auto *query = QUERY( auto *query = QUERY(
SINGLE_QUERY(MATCH(PATTERN(node_n)), SINGLE_QUERY(MATCH(PATTERN(node_n)),
OPTIONAL_MATCH(PATTERN(node_n, edge_e, node_m)), ret_e)); OPTIONAL_MATCH(PATTERN(node_n, edge_e, node_m)), ret_e));
auto symbol_table = MakeSymbolTable(*query); auto symbol_table = query::MakeSymbolTable(query);
auto sym_e = symbol_table.at(*ret_e->body_.named_expressions[0]); auto sym_e = symbol_table.at(*ret_e->body_.named_expressions[0]);
std::list<BaseOpChecker *> optional{new ExpectDistributedExpand()}; std::list<BaseOpChecker *> optional{new ExpectDistributedExpand()};
auto expected = ExpectDistributed( auto expected = ExpectDistributed(
@ -1908,7 +1908,7 @@ TYPED_TEST(TestPlanner, DistributedOptionalCartesian) {
auto *query = QUERY(SINGLE_QUERY( auto *query = QUERY(SINGLE_QUERY(
MATCH(PATTERN(node_a)), OPTIONAL_MATCH(PATTERN(node_b), PATTERN(node_c)), MATCH(PATTERN(node_a)), OPTIONAL_MATCH(PATTERN(node_b), PATTERN(node_c)),
WHERE(GREATER(node_b->identifier_, node_a->identifier_)), RETURN("c"))); WHERE(GREATER(node_b->identifier_, node_a->identifier_)), RETURN("c")));
auto symbol_table = MakeSymbolTable(*query); auto symbol_table = query::MakeSymbolTable(query);
auto sym_a = symbol_table.at(*node_a->identifier_); auto sym_a = symbol_table.at(*node_a->identifier_);
auto sym_b = symbol_table.at(*node_b->identifier_); auto sym_b = symbol_table.at(*node_b->identifier_);
auto sym_c = symbol_table.at(*node_c->identifier_); auto sym_c = symbol_table.at(*node_c->identifier_);
@ -1941,7 +1941,7 @@ TYPED_TEST(TestPlanner, DistributedCartesianTransitiveDependency) {
auto *edge_b = EDGE("b"); auto *edge_b = EDGE("b");
auto *query = QUERY(SINGLE_QUERY( auto *query = QUERY(SINGLE_QUERY(
MATCH(PATTERN(node_n, edge_a, node_m, edge_b, node_l)), RETURN("l"))); MATCH(PATTERN(node_n, edge_a, node_m, edge_b, node_l)), RETURN("l")));
auto symbol_table = MakeSymbolTable(*query); auto symbol_table = query::MakeSymbolTable(query);
auto sym_a = symbol_table.at(*edge_a->identifier_); auto sym_a = symbol_table.at(*edge_a->identifier_);
auto sym_b = symbol_table.at(*edge_b->identifier_); auto sym_b = symbol_table.at(*edge_b->identifier_);
auto sym_n = symbol_table.at(*node_n->identifier_); auto sym_n = symbol_table.at(*node_n->identifier_);
@ -1979,7 +1979,7 @@ TYPED_TEST(TestPlanner, DistributedOptionalScanExpandExisting) {
auto *query = QUERY(SINGLE_QUERY( auto *query = QUERY(SINGLE_QUERY(
MATCH(PATTERN(node_a)), MATCH(PATTERN(node_a)),
OPTIONAL_MATCH(PATTERN(node_b, EDGE("e"), NODE("a"))), RETURN("e"))); OPTIONAL_MATCH(PATTERN(node_b, EDGE("e"), NODE("a"))), RETURN("e")));
auto symbol_table = MakeSymbolTable(*query); auto symbol_table = query::MakeSymbolTable(query);
auto sym_a = symbol_table.at(*node_a->identifier_); auto sym_a = symbol_table.at(*node_a->identifier_);
auto sym_b = symbol_table.at(*node_b->identifier_); auto sym_b = symbol_table.at(*node_b->identifier_);
std::list<BaseOpChecker *> optional{new ExpectScanAll(), std::list<BaseOpChecker *> optional{new ExpectScanAll(),

View File

@ -66,7 +66,7 @@ auto CheckPlan(LogicalOperator &plan, const SymbolTable &symbol_table,
template <class TPlanner, class... TChecker> template <class TPlanner, class... TChecker>
auto CheckPlan(query::CypherQuery *query, AstStorage &storage, auto CheckPlan(query::CypherQuery *query, AstStorage &storage,
TChecker... checker) { TChecker... checker) {
auto symbol_table = MakeSymbolTable(*query); auto symbol_table = query::MakeSymbolTable(query);
FakeDbAccessor dba; FakeDbAccessor dba;
auto planner = MakePlanner<TPlanner>(dba, storage, symbol_table, query); auto planner = MakePlanner<TPlanner>(dba, storage, symbol_table, query);
CheckPlan(planner.plan(), symbol_table, checker...); CheckPlan(planner.plan(), symbol_table, checker...);
@ -84,7 +84,7 @@ TYPED_TEST(TestPlanner, MatchNodeReturn) {
AstStorage storage; AstStorage storage;
auto *as_n = NEXPR("n", IDENT("n")); auto *as_n = NEXPR("n", IDENT("n"));
auto *query = QUERY(SINGLE_QUERY(MATCH(PATTERN(NODE("n"))), RETURN(as_n))); auto *query = QUERY(SINGLE_QUERY(MATCH(PATTERN(NODE("n"))), RETURN(as_n)));
auto symbol_table = MakeSymbolTable(*query); auto symbol_table = query::MakeSymbolTable(query);
FakeDbAccessor dba; FakeDbAccessor dba;
auto planner = MakePlanner<TypeParam>(dba, storage, symbol_table, query); auto planner = MakePlanner<TypeParam>(dba, storage, symbol_table, query);
CheckPlan(planner.plan(), symbol_table, ExpectScanAll(), ExpectProduce()); CheckPlan(planner.plan(), symbol_table, ExpectScanAll(), ExpectProduce());
@ -96,7 +96,7 @@ TYPED_TEST(TestPlanner, CreateNodeReturn) {
auto ident_n = IDENT("n"); auto ident_n = IDENT("n");
auto query = auto query =
QUERY(SINGLE_QUERY(CREATE(PATTERN(NODE("n"))), RETURN(ident_n, AS("n")))); QUERY(SINGLE_QUERY(CREATE(PATTERN(NODE("n"))), RETURN(ident_n, AS("n"))));
auto symbol_table = MakeSymbolTable(*query); auto symbol_table = query::MakeSymbolTable(query);
auto acc = ExpectAccumulate({symbol_table.at(*ident_n)}); auto acc = ExpectAccumulate({symbol_table.at(*ident_n)});
FakeDbAccessor dba; FakeDbAccessor dba;
auto planner = MakePlanner<TypeParam>(dba, storage, symbol_table, query); auto planner = MakePlanner<TypeParam>(dba, storage, symbol_table, query);
@ -166,7 +166,7 @@ TYPED_TEST(TestPlanner, MatchLabeledNodes) {
auto *as_n = NEXPR("n", IDENT("n")); auto *as_n = NEXPR("n", IDENT("n"));
auto *query = auto *query =
QUERY(SINGLE_QUERY(MATCH(PATTERN(NODE("n", label))), RETURN(as_n))); QUERY(SINGLE_QUERY(MATCH(PATTERN(NODE("n", label))), RETURN(as_n)));
auto symbol_table = MakeSymbolTable(*query); auto symbol_table = query::MakeSymbolTable(query);
auto planner = MakePlanner<TypeParam>(dba, storage, symbol_table, query); auto planner = MakePlanner<TypeParam>(dba, storage, symbol_table, query);
CheckPlan(planner.plan(), symbol_table, ExpectScanAllByLabel(), CheckPlan(planner.plan(), symbol_table, ExpectScanAllByLabel(),
ExpectProduce()); ExpectProduce());
@ -182,7 +182,7 @@ TYPED_TEST(TestPlanner, MatchPathReturn) {
MATCH(PATTERN(NODE("n"), EDGE("r", Direction::BOTH, {relationship}), MATCH(PATTERN(NODE("n"), EDGE("r", Direction::BOTH, {relationship}),
NODE("m"))), NODE("m"))),
RETURN(as_n))); RETURN(as_n)));
auto symbol_table = MakeSymbolTable(*query); auto symbol_table = query::MakeSymbolTable(query);
auto planner = MakePlanner<TypeParam>(dba, storage, symbol_table, query); auto planner = MakePlanner<TypeParam>(dba, storage, symbol_table, query);
CheckPlan(planner.plan(), symbol_table, ExpectScanAll(), ExpectExpand(), CheckPlan(planner.plan(), symbol_table, ExpectScanAll(), ExpectExpand(),
ExpectProduce()); ExpectProduce());
@ -199,7 +199,7 @@ TYPED_TEST(TestPlanner, MatchNamedPatternReturn) {
EDGE("r", Direction::BOTH, {relationship}), EDGE("r", Direction::BOTH, {relationship}),
NODE("m"))), NODE("m"))),
RETURN(as_p))); RETURN(as_p)));
auto symbol_table = MakeSymbolTable(*query); auto symbol_table = query::MakeSymbolTable(query);
auto planner = MakePlanner<TypeParam>(dba, storage, symbol_table, query); auto planner = MakePlanner<TypeParam>(dba, storage, symbol_table, query);
CheckPlan(planner.plan(), symbol_table, ExpectScanAll(), ExpectExpand(), CheckPlan(planner.plan(), symbol_table, ExpectScanAll(), ExpectExpand(),
ExpectConstructNamedPath(), ExpectProduce()); ExpectConstructNamedPath(), ExpectProduce());
@ -216,7 +216,7 @@ TYPED_TEST(TestPlanner, MatchNamedPatternWithPredicateReturn) {
EDGE("r", Direction::BOTH, {relationship}), EDGE("r", Direction::BOTH, {relationship}),
NODE("m"))), NODE("m"))),
WHERE(EQ(LITERAL(2), IDENT("p"))), RETURN(as_p))); WHERE(EQ(LITERAL(2), IDENT("p"))), RETURN(as_p)));
auto symbol_table = MakeSymbolTable(*query); auto symbol_table = query::MakeSymbolTable(query);
auto planner = MakePlanner<TypeParam>(dba, storage, symbol_table, query); auto planner = MakePlanner<TypeParam>(dba, storage, symbol_table, query);
CheckPlan(planner.plan(), symbol_table, ExpectScanAll(), ExpectExpand(), CheckPlan(planner.plan(), symbol_table, ExpectScanAll(), ExpectExpand(),
ExpectConstructNamedPath(), ExpectFilter(), ExpectProduce()); ExpectConstructNamedPath(), ExpectFilter(), ExpectProduce());
@ -231,7 +231,7 @@ TYPED_TEST(TestPlanner, OptionalMatchNamedPatternReturn) {
auto pattern = NAMED_PATTERN("p", node_n, edge, node_m); auto pattern = NAMED_PATTERN("p", node_n, edge, node_m);
auto as_p = AS("p"); auto as_p = AS("p");
auto *query = QUERY(SINGLE_QUERY(OPTIONAL_MATCH(pattern), RETURN("p", as_p))); auto *query = QUERY(SINGLE_QUERY(OPTIONAL_MATCH(pattern), RETURN("p", as_p)));
auto symbol_table = MakeSymbolTable(*query); auto symbol_table = query::MakeSymbolTable(query);
auto get_symbol = [&symbol_table](const auto *ast_node) { auto get_symbol = [&symbol_table](const auto *ast_node) {
return symbol_table.at(*ast_node->identifier_); return symbol_table.at(*ast_node->identifier_);
}; };
@ -254,7 +254,7 @@ TYPED_TEST(TestPlanner, MatchWhereReturn) {
auto *query = QUERY(SINGLE_QUERY( auto *query = QUERY(SINGLE_QUERY(
MATCH(PATTERN(NODE("n"))), MATCH(PATTERN(NODE("n"))),
WHERE(LESS(PROPERTY_LOOKUP("n", property), LITERAL(42))), RETURN(as_n))); WHERE(LESS(PROPERTY_LOOKUP("n", property), LITERAL(42))), RETURN(as_n)));
auto symbol_table = MakeSymbolTable(*query); auto symbol_table = query::MakeSymbolTable(query);
auto planner = MakePlanner<TypeParam>(dba, storage, symbol_table, query); auto planner = MakePlanner<TypeParam>(dba, storage, symbol_table, query);
CheckPlan(planner.plan(), symbol_table, ExpectScanAll(), ExpectFilter(), CheckPlan(planner.plan(), symbol_table, ExpectScanAll(), ExpectFilter(),
ExpectProduce()); ExpectProduce());
@ -350,7 +350,7 @@ TYPED_TEST(TestPlanner, MultiMatch) {
auto *query = QUERY(SINGLE_QUERY( auto *query = QUERY(SINGLE_QUERY(
MATCH(PATTERN(node_n, edge_r, node_m)), MATCH(PATTERN(node_n, edge_r, node_m)),
MATCH(PATTERN(node_j, edge_e, node_i, edge_f, node_h)), RETURN("n"))); MATCH(PATTERN(node_j, edge_e, node_i, edge_f, node_h)), RETURN("n")));
auto symbol_table = MakeSymbolTable(*query); auto symbol_table = query::MakeSymbolTable(query);
FakeDbAccessor dba; FakeDbAccessor dba;
auto planner = MakePlanner<TypeParam>(dba, storage, symbol_table, query); auto planner = MakePlanner<TypeParam>(dba, storage, symbol_table, query);
// Multiple MATCH clauses form a Cartesian product, so the uniqueness should // Multiple MATCH clauses form a Cartesian product, so the uniqueness should
@ -369,7 +369,7 @@ TYPED_TEST(TestPlanner, MultiMatchSameStart) {
MATCH(PATTERN(NODE("n"), EDGE("r"), NODE("m"))), RETURN(as_n))); MATCH(PATTERN(NODE("n"), EDGE("r"), NODE("m"))), RETURN(as_n)));
// Similar to MatchMultiPatternSameStart, we expect only Expand from second // Similar to MatchMultiPatternSameStart, we expect only Expand from second
// MATCH clause. // MATCH clause.
auto symbol_table = MakeSymbolTable(*query); auto symbol_table = query::MakeSymbolTable(query);
FakeDbAccessor dba; FakeDbAccessor dba;
auto planner = MakePlanner<TypeParam>(dba, storage, symbol_table, query); auto planner = MakePlanner<TypeParam>(dba, storage, symbol_table, query);
CheckPlan(planner.plan(), symbol_table, ExpectScanAll(), ExpectExpand(), CheckPlan(planner.plan(), symbol_table, ExpectScanAll(), ExpectExpand(),
@ -383,7 +383,7 @@ TYPED_TEST(TestPlanner, MatchWithReturn) {
auto *query = QUERY(SINGLE_QUERY(MATCH(PATTERN(NODE("old"))), auto *query = QUERY(SINGLE_QUERY(MATCH(PATTERN(NODE("old"))),
WITH("old", AS("new")), RETURN(as_new))); WITH("old", AS("new")), RETURN(as_new)));
// No accumulation since we only do reads. // No accumulation since we only do reads.
auto symbol_table = MakeSymbolTable(*query); auto symbol_table = query::MakeSymbolTable(query);
FakeDbAccessor dba; FakeDbAccessor dba;
auto planner = MakePlanner<TypeParam>(dba, storage, symbol_table, query); auto planner = MakePlanner<TypeParam>(dba, storage, symbol_table, query);
CheckPlan(planner.plan(), symbol_table, ExpectScanAll(), ExpectProduce(), CheckPlan(planner.plan(), symbol_table, ExpectScanAll(), ExpectProduce(),
@ -400,7 +400,7 @@ TYPED_TEST(TestPlanner, MatchWithWhereReturn) {
MATCH(PATTERN(NODE("old"))), WITH("old", AS("new")), MATCH(PATTERN(NODE("old"))), WITH("old", AS("new")),
WHERE(LESS(PROPERTY_LOOKUP("new", prop), LITERAL(42))), RETURN(as_new))); WHERE(LESS(PROPERTY_LOOKUP("new", prop), LITERAL(42))), RETURN(as_new)));
// No accumulation since we only do reads. // No accumulation since we only do reads.
auto symbol_table = MakeSymbolTable(*query); auto symbol_table = query::MakeSymbolTable(query);
auto planner = MakePlanner<TypeParam>(dba, storage, symbol_table, query); auto planner = MakePlanner<TypeParam>(dba, storage, symbol_table, query);
CheckPlan(planner.plan(), symbol_table, ExpectScanAll(), ExpectProduce(), CheckPlan(planner.plan(), symbol_table, ExpectScanAll(), ExpectProduce(),
ExpectFilter(), ExpectProduce()); ExpectFilter(), ExpectProduce());
@ -446,7 +446,7 @@ TYPED_TEST(TestPlanner, MatchReturnSum) {
auto *query = QUERY(SINGLE_QUERY( auto *query = QUERY(SINGLE_QUERY(
MATCH(PATTERN(NODE("n"))), RETURN(sum, AS("sum"), n_prop2, AS("group")))); MATCH(PATTERN(NODE("n"))), RETURN(sum, AS("sum"), n_prop2, AS("group"))));
auto aggr = ExpectAggregate({sum}, {n_prop2}); auto aggr = ExpectAggregate({sum}, {n_prop2});
auto symbol_table = MakeSymbolTable(*query); auto symbol_table = query::MakeSymbolTable(query);
auto planner = MakePlanner<TypeParam>(dba, storage, symbol_table, query); auto planner = MakePlanner<TypeParam>(dba, storage, symbol_table, query);
CheckPlan(planner.plan(), symbol_table, ExpectScanAll(), aggr, CheckPlan(planner.plan(), symbol_table, ExpectScanAll(), aggr,
ExpectProduce()); ExpectProduce());
@ -461,7 +461,7 @@ TYPED_TEST(TestPlanner, CreateWithSum) {
auto sum = SUM(n_prop); auto sum = SUM(n_prop);
auto query = auto query =
QUERY(SINGLE_QUERY(CREATE(PATTERN(NODE("n"))), WITH(sum, AS("sum")))); QUERY(SINGLE_QUERY(CREATE(PATTERN(NODE("n"))), WITH(sum, AS("sum"))));
auto symbol_table = MakeSymbolTable(*query); auto symbol_table = query::MakeSymbolTable(query);
auto acc = ExpectAccumulate({symbol_table.at(*n_prop->expression_)}); auto acc = ExpectAccumulate({symbol_table.at(*n_prop->expression_)});
auto aggr = ExpectAggregate({sum}, {}); auto aggr = ExpectAggregate({sum}, {});
auto planner = MakePlanner<TypeParam>(dba, storage, symbol_table, query); auto planner = MakePlanner<TypeParam>(dba, storage, symbol_table, query);
@ -491,7 +491,7 @@ TYPED_TEST(TestPlanner, MatchReturnSkipLimit) {
auto *query = auto *query =
QUERY(SINGLE_QUERY(MATCH(PATTERN(NODE("n"))), QUERY(SINGLE_QUERY(MATCH(PATTERN(NODE("n"))),
RETURN(as_n, SKIP(LITERAL(2)), LIMIT(LITERAL(1))))); RETURN(as_n, SKIP(LITERAL(2)), LIMIT(LITERAL(1)))));
auto symbol_table = MakeSymbolTable(*query); auto symbol_table = query::MakeSymbolTable(query);
FakeDbAccessor dba; FakeDbAccessor dba;
auto planner = MakePlanner<TypeParam>(dba, storage, symbol_table, query); auto planner = MakePlanner<TypeParam>(dba, storage, symbol_table, query);
CheckPlan(planner.plan(), symbol_table, ExpectScanAll(), ExpectProduce(), CheckPlan(planner.plan(), symbol_table, ExpectScanAll(), ExpectProduce(),
@ -505,7 +505,7 @@ TYPED_TEST(TestPlanner, CreateWithSkipReturnLimit) {
auto query = QUERY(SINGLE_QUERY(CREATE(PATTERN(NODE("n"))), auto query = QUERY(SINGLE_QUERY(CREATE(PATTERN(NODE("n"))),
WITH(ident_n, AS("m"), SKIP(LITERAL(2))), WITH(ident_n, AS("m"), SKIP(LITERAL(2))),
RETURN("m", LIMIT(LITERAL(1))))); RETURN("m", LIMIT(LITERAL(1)))));
auto symbol_table = MakeSymbolTable(*query); auto symbol_table = query::MakeSymbolTable(query);
auto acc = ExpectAccumulate({symbol_table.at(*ident_n)}); auto acc = ExpectAccumulate({symbol_table.at(*ident_n)});
FakeDbAccessor dba; FakeDbAccessor dba;
auto planner = MakePlanner<TypeParam>(dba, storage, symbol_table, query); auto planner = MakePlanner<TypeParam>(dba, storage, symbol_table, query);
@ -528,7 +528,7 @@ TYPED_TEST(TestPlanner, CreateReturnSumSkipLimit) {
auto query = QUERY( auto query = QUERY(
SINGLE_QUERY(CREATE(PATTERN(NODE("n"))), SINGLE_QUERY(CREATE(PATTERN(NODE("n"))),
RETURN(sum, AS("s"), SKIP(LITERAL(2)), LIMIT(LITERAL(1))))); RETURN(sum, AS("s"), SKIP(LITERAL(2)), LIMIT(LITERAL(1)))));
auto symbol_table = MakeSymbolTable(*query); auto symbol_table = query::MakeSymbolTable(query);
auto acc = ExpectAccumulate({symbol_table.at(*n_prop->expression_)}); auto acc = ExpectAccumulate({symbol_table.at(*n_prop->expression_)});
auto aggr = ExpectAggregate({sum}, {}); auto aggr = ExpectAggregate({sum}, {});
auto planner = MakePlanner<TypeParam>(dba, storage, symbol_table, query); auto planner = MakePlanner<TypeParam>(dba, storage, symbol_table, query);
@ -545,7 +545,7 @@ TYPED_TEST(TestPlanner, MatchReturnOrderBy) {
auto *node_n = NODE("n"); auto *node_n = NODE("n");
auto ret = RETURN(as_m, ORDER_BY(PROPERTY_LOOKUP("n", prop))); auto ret = RETURN(as_m, ORDER_BY(PROPERTY_LOOKUP("n", prop)));
auto *query = QUERY(SINGLE_QUERY(MATCH(PATTERN(node_n)), ret)); auto *query = QUERY(SINGLE_QUERY(MATCH(PATTERN(node_n)), ret));
auto symbol_table = MakeSymbolTable(*query); auto symbol_table = query::MakeSymbolTable(query);
auto planner = MakePlanner<TypeParam>(dba, storage, symbol_table, query); auto planner = MakePlanner<TypeParam>(dba, storage, symbol_table, query);
CheckPlan(planner.plan(), symbol_table, ExpectScanAll(), ExpectProduce(), CheckPlan(planner.plan(), symbol_table, ExpectScanAll(), ExpectProduce(),
ExpectOrderBy()); ExpectOrderBy());
@ -567,7 +567,7 @@ TYPED_TEST(TestPlanner, CreateWithOrderByWhere) {
PATTERN(NODE("n"), EDGE("r", Direction::OUT, {r_type}), NODE("m"))), PATTERN(NODE("n"), EDGE("r", Direction::OUT, {r_type}), NODE("m"))),
WITH(ident_n, AS("new"), ORDER_BY(new_prop, r_prop)), WITH(ident_n, AS("new"), ORDER_BY(new_prop, r_prop)),
WHERE(LESS(m_prop, LITERAL(42))))); WHERE(LESS(m_prop, LITERAL(42)))));
auto symbol_table = MakeSymbolTable(*query); auto symbol_table = query::MakeSymbolTable(query);
// Since this is a write query, we expect to accumulate to old used symbols. // Since this is a write query, we expect to accumulate to old used symbols.
auto acc = ExpectAccumulate({ auto acc = ExpectAccumulate({
symbol_table.at(*ident_n), // `n` in WITH symbol_table.at(*ident_n), // `n` in WITH
@ -610,7 +610,7 @@ TYPED_TEST(TestPlanner, MatchMerge) {
new ExpectSetProperty()}; new ExpectSetProperty()};
std::list<BaseOpChecker *> on_create{new ExpectCreateExpand(), std::list<BaseOpChecker *> on_create{new ExpectCreateExpand(),
new ExpectSetProperties()}; new ExpectSetProperties()};
auto symbol_table = MakeSymbolTable(*query); auto symbol_table = query::MakeSymbolTable(query);
// We expect Accumulate after Merge, because it is considered as a write. // We expect Accumulate after Merge, because it is considered as a write.
auto acc = ExpectAccumulate({symbol_table.at(*ident_n)}); auto acc = ExpectAccumulate({symbol_table.at(*ident_n)});
auto planner = MakePlanner<TypeParam>(dba, storage, symbol_table, query); auto planner = MakePlanner<TypeParam>(dba, storage, symbol_table, query);
@ -646,7 +646,7 @@ TYPED_TEST(TestPlanner, MatchUnwindReturn) {
SINGLE_QUERY(MATCH(PATTERN(NODE("n"))), SINGLE_QUERY(MATCH(PATTERN(NODE("n"))),
UNWIND(LIST(LITERAL(1), LITERAL(2), LITERAL(3)), AS("x")), UNWIND(LIST(LITERAL(1), LITERAL(2), LITERAL(3)), AS("x")),
RETURN(as_n, as_x))); RETURN(as_n, as_x)));
auto symbol_table = MakeSymbolTable(*query); auto symbol_table = query::MakeSymbolTable(query);
FakeDbAccessor dba; FakeDbAccessor dba;
auto planner = MakePlanner<TypeParam>(dba, storage, symbol_table, query); auto planner = MakePlanner<TypeParam>(dba, storage, symbol_table, query);
CheckPlan(planner.plan(), symbol_table, ExpectScanAll(), ExpectUnwind(), CheckPlan(planner.plan(), symbol_table, ExpectScanAll(), ExpectUnwind(),
@ -673,7 +673,7 @@ TYPED_TEST(TestPlanner, CreateWithDistinctSumWhereReturn) {
auto query = auto query =
QUERY(SINGLE_QUERY(CREATE(PATTERN(node_n)), WITH_DISTINCT(sum, AS("s")), QUERY(SINGLE_QUERY(CREATE(PATTERN(node_n)), WITH_DISTINCT(sum, AS("s")),
WHERE(LESS(IDENT("s"), LITERAL(42))), RETURN("s"))); WHERE(LESS(IDENT("s"), LITERAL(42))), RETURN("s")));
auto symbol_table = MakeSymbolTable(*query); auto symbol_table = query::MakeSymbolTable(query);
auto acc = ExpectAccumulate({symbol_table.at(*node_n->identifier_)}); auto acc = ExpectAccumulate({symbol_table.at(*node_n->identifier_)});
auto aggr = ExpectAggregate({sum}, {}); auto aggr = ExpectAggregate({sum}, {});
auto planner = MakePlanner<TypeParam>(dba, storage, symbol_table, query); auto planner = MakePlanner<TypeParam>(dba, storage, symbol_table, query);
@ -710,7 +710,7 @@ TYPED_TEST(TestPlanner, MatchWhereBeforeExpand) {
MATCH(PATTERN(NODE("n"), EDGE("r"), NODE("m"))), MATCH(PATTERN(NODE("n"), EDGE("r"), NODE("m"))),
WHERE(LESS(PROPERTY_LOOKUP("n", prop), LITERAL(42))), RETURN(as_n))); WHERE(LESS(PROPERTY_LOOKUP("n", prop), LITERAL(42))), RETURN(as_n)));
// We expect Filter to come immediately after ScanAll, since it only uses `n`. // We expect Filter to come immediately after ScanAll, since it only uses `n`.
auto symbol_table = MakeSymbolTable(*query); auto symbol_table = query::MakeSymbolTable(query);
auto planner = MakePlanner<TypeParam>(dba, storage, symbol_table, query); auto planner = MakePlanner<TypeParam>(dba, storage, symbol_table, query);
CheckPlan(planner.plan(), symbol_table, ExpectScanAll(), ExpectFilter(), CheckPlan(planner.plan(), symbol_table, ExpectScanAll(), ExpectFilter(),
ExpectExpand(), ExpectProduce()); ExpectExpand(), ExpectProduce());
@ -757,7 +757,7 @@ TYPED_TEST(TestPlanner, MatchReturnAsterisk) {
ret->body_.all_identifiers = true; ret->body_.all_identifiers = true;
auto query = auto query =
QUERY(SINGLE_QUERY(MATCH(PATTERN(NODE("n"), EDGE("e"), NODE("m"))), ret)); QUERY(SINGLE_QUERY(MATCH(PATTERN(NODE("n"), EDGE("e"), NODE("m"))), ret));
auto symbol_table = MakeSymbolTable(*query); auto symbol_table = query::MakeSymbolTable(query);
auto planner = MakePlanner<TypeParam>(dba, storage, symbol_table, query); auto planner = MakePlanner<TypeParam>(dba, storage, symbol_table, query);
CheckPlan(planner.plan(), symbol_table, ExpectScanAll(), ExpectExpand(), CheckPlan(planner.plan(), symbol_table, ExpectScanAll(), ExpectExpand(),
ExpectProduce()); ExpectProduce());
@ -778,7 +778,7 @@ TYPED_TEST(TestPlanner, MatchReturnAsteriskSum) {
auto ret = RETURN(sum, AS("s")); auto ret = RETURN(sum, AS("s"));
ret->body_.all_identifiers = true; ret->body_.all_identifiers = true;
auto query = QUERY(SINGLE_QUERY(MATCH(PATTERN(NODE("n"))), ret)); auto query = QUERY(SINGLE_QUERY(MATCH(PATTERN(NODE("n"))), ret));
auto symbol_table = MakeSymbolTable(*query); auto symbol_table = query::MakeSymbolTable(query);
auto planner = MakePlanner<TypeParam>(dba, storage, symbol_table, query); auto planner = MakePlanner<TypeParam>(dba, storage, symbol_table, query);
auto *produce = dynamic_cast<Produce *>(&planner.plan()); auto *produce = dynamic_cast<Produce *>(&planner.plan());
ASSERT_TRUE(produce); ASSERT_TRUE(produce);
@ -949,7 +949,7 @@ TYPED_TEST(TestPlanner, AtomIndexedLabelProperty) {
node->properties_[property] = lit_42; node->properties_[property] = lit_42;
node->properties_[not_indexed] = LITERAL(0); node->properties_[not_indexed] = LITERAL(0);
auto *query = QUERY(SINGLE_QUERY(MATCH(PATTERN(node)), RETURN("n"))); auto *query = QUERY(SINGLE_QUERY(MATCH(PATTERN(node)), RETURN("n")));
auto symbol_table = MakeSymbolTable(*query); auto symbol_table = query::MakeSymbolTable(query);
auto planner = MakePlanner<TypeParam>(dba, storage, symbol_table, query); auto planner = MakePlanner<TypeParam>(dba, storage, symbol_table, query);
CheckPlan(planner.plan(), symbol_table, CheckPlan(planner.plan(), symbol_table,
ExpectScanAllByLabelPropertyValue(label, property, lit_42), ExpectScanAllByLabelPropertyValue(label, property, lit_42),
@ -973,7 +973,7 @@ TYPED_TEST(TestPlanner, AtomPropertyWhereLabelIndexing) {
storage.Create<query::LabelsTest>( storage.Create<query::LabelsTest>(
IDENT("n"), std::vector<storage::Label>{label}))), IDENT("n"), std::vector<storage::Label>{label}))),
RETURN("n"))); RETURN("n")));
auto symbol_table = MakeSymbolTable(*query); auto symbol_table = query::MakeSymbolTable(query);
auto planner = MakePlanner<TypeParam>(dba, storage, symbol_table, query); auto planner = MakePlanner<TypeParam>(dba, storage, symbol_table, query);
CheckPlan(planner.plan(), symbol_table, CheckPlan(planner.plan(), symbol_table,
ExpectScanAllByLabelPropertyValue(label, property, lit_42), ExpectScanAllByLabelPropertyValue(label, property, lit_42),
@ -991,7 +991,7 @@ TYPED_TEST(TestPlanner, WhereIndexedLabelProperty) {
auto *query = QUERY(SINGLE_QUERY( auto *query = QUERY(SINGLE_QUERY(
MATCH(PATTERN(NODE("n", label))), MATCH(PATTERN(NODE("n", label))),
WHERE(EQ(PROPERTY_LOOKUP("n", property), lit_42)), RETURN("n"))); WHERE(EQ(PROPERTY_LOOKUP("n", property), lit_42)), RETURN("n")));
auto symbol_table = MakeSymbolTable(*query); auto symbol_table = query::MakeSymbolTable(query);
auto planner = MakePlanner<TypeParam>(dba, storage, symbol_table, query); auto planner = MakePlanner<TypeParam>(dba, storage, symbol_table, query);
CheckPlan(planner.plan(), symbol_table, CheckPlan(planner.plan(), symbol_table,
ExpectScanAllByLabelPropertyValue(label, property, lit_42), ExpectScanAllByLabelPropertyValue(label, property, lit_42),
@ -1015,7 +1015,7 @@ TYPED_TEST(TestPlanner, BestPropertyIndexed) {
WHERE(AND(EQ(PROPERTY_LOOKUP("n", property), LITERAL(1)), WHERE(AND(EQ(PROPERTY_LOOKUP("n", property), LITERAL(1)),
EQ(PROPERTY_LOOKUP("n", better), lit_42))), EQ(PROPERTY_LOOKUP("n", better), lit_42))),
RETURN("n"))); RETURN("n")));
auto symbol_table = MakeSymbolTable(*query); auto symbol_table = query::MakeSymbolTable(query);
auto planner = MakePlanner<TypeParam>(dba, storage, symbol_table, query); auto planner = MakePlanner<TypeParam>(dba, storage, symbol_table, query);
CheckPlan(planner.plan(), symbol_table, CheckPlan(planner.plan(), symbol_table,
ExpectScanAllByLabelPropertyValue(label, better, lit_42), ExpectScanAllByLabelPropertyValue(label, better, lit_42),
@ -1040,7 +1040,7 @@ TYPED_TEST(TestPlanner, MultiPropertyIndexScan) {
WHERE(AND(EQ(PROPERTY_LOOKUP("n", prop1), lit_1), WHERE(AND(EQ(PROPERTY_LOOKUP("n", prop1), lit_1),
EQ(PROPERTY_LOOKUP("m", prop2), lit_2))), EQ(PROPERTY_LOOKUP("m", prop2), lit_2))),
RETURN("n", "m"))); RETURN("n", "m")));
auto symbol_table = MakeSymbolTable(*query); auto symbol_table = query::MakeSymbolTable(query);
auto planner = MakePlanner<TypeParam>(dba, storage, symbol_table, query); auto planner = MakePlanner<TypeParam>(dba, storage, symbol_table, query);
CheckPlan(planner.plan(), symbol_table, CheckPlan(planner.plan(), symbol_table,
ExpectScanAllByLabelPropertyValue(label1, prop1, lit_1), ExpectScanAllByLabelPropertyValue(label1, prop1, lit_1),
@ -1065,7 +1065,7 @@ TYPED_TEST(TestPlanner, WhereIndexedLabelPropertyRange) {
AstStorage storage; AstStorage storage;
auto *query = QUERY(SINGLE_QUERY(MATCH(PATTERN(NODE("n", label))), auto *query = QUERY(SINGLE_QUERY(MATCH(PATTERN(NODE("n", label))),
WHERE(rel_expr), RETURN("n"))); WHERE(rel_expr), RETURN("n")));
auto symbol_table = MakeSymbolTable(*query); auto symbol_table = query::MakeSymbolTable(query);
auto planner = MakePlanner<TypeParam>(dba, storage, symbol_table, query); auto planner = MakePlanner<TypeParam>(dba, storage, symbol_table, query);
CheckPlan(planner.plan(), symbol_table, CheckPlan(planner.plan(), symbol_table,
ExpectScanAllByLabelPropertyRange(label, property, lower_bound, ExpectScanAllByLabelPropertyRange(label, property, lower_bound,
@ -1109,7 +1109,7 @@ TYPED_TEST(TestPlanner, UnableToUsePropertyIndex) {
MATCH(PATTERN(NODE("n", label))), MATCH(PATTERN(NODE("n", label))),
WHERE(EQ(PROPERTY_LOOKUP("n", property), PROPERTY_LOOKUP("n", property))), WHERE(EQ(PROPERTY_LOOKUP("n", property), PROPERTY_LOOKUP("n", property))),
RETURN("n"))); RETURN("n")));
auto symbol_table = MakeSymbolTable(*query); auto symbol_table = query::MakeSymbolTable(query);
auto planner = MakePlanner<TypeParam>(dba, storage, symbol_table, query); auto planner = MakePlanner<TypeParam>(dba, storage, symbol_table, query);
// We can only get ScanAllByLabelIndex, because we are comparing properties // We can only get ScanAllByLabelIndex, because we are comparing properties
// with those on the same node. // with those on the same node.
@ -1129,7 +1129,7 @@ TYPED_TEST(TestPlanner, SecondPropertyIndex) {
auto *query = QUERY( auto *query = QUERY(
SINGLE_QUERY(MATCH(PATTERN(NODE("n", label)), PATTERN(NODE("m", label))), SINGLE_QUERY(MATCH(PATTERN(NODE("n", label)), PATTERN(NODE("m", label))),
WHERE(EQ(m_prop, n_prop)), RETURN("n"))); WHERE(EQ(m_prop, n_prop)), RETURN("n")));
auto symbol_table = MakeSymbolTable(*query); auto symbol_table = query::MakeSymbolTable(query);
auto planner = MakePlanner<TypeParam>(dba, storage, symbol_table, query); auto planner = MakePlanner<TypeParam>(dba, storage, symbol_table, query);
CheckPlan( CheckPlan(
planner.plan(), symbol_table, ExpectScanAllByLabel(), planner.plan(), symbol_table, ExpectScanAllByLabel(),
@ -1210,7 +1210,7 @@ TYPED_TEST(TestPlanner, MatchExpandVariableTotalWeightSymbol) {
IDENT("total_weight")); IDENT("total_weight"));
auto *query = QUERY( auto *query = QUERY(
SINGLE_QUERY(MATCH(PATTERN(NODE("n"), edge, NODE("m"))), RETURN("*"))); SINGLE_QUERY(MATCH(PATTERN(NODE("n"), edge, NODE("m"))), RETURN("*")));
auto symbol_table = MakeSymbolTable(*query); auto symbol_table = query::MakeSymbolTable(query);
auto planner = MakePlanner<TypeParam>(dba, storage, symbol_table, query); auto planner = MakePlanner<TypeParam>(dba, storage, symbol_table, query);
auto *root = dynamic_cast<Produce *>(&planner.plan()); auto *root = dynamic_cast<Produce *>(&planner.plan());
@ -1258,7 +1258,7 @@ TYPED_TEST(TestPlanner, MatchBfs) {
auto *as_r = NEXPR("r", IDENT("r")); auto *as_r = NEXPR("r", IDENT("r"));
auto *query = QUERY( auto *query = QUERY(
SINGLE_QUERY(MATCH(PATTERN(NODE("n"), bfs, NODE("m"))), RETURN(as_r))); SINGLE_QUERY(MATCH(PATTERN(NODE("n"), bfs, NODE("m"))), RETURN(as_r)));
auto symbol_table = MakeSymbolTable(*query); auto symbol_table = query::MakeSymbolTable(query);
auto planner = MakePlanner<TypeParam>(dba, storage, symbol_table, query); auto planner = MakePlanner<TypeParam>(dba, storage, symbol_table, query);
CheckPlan(planner.plan(), symbol_table, ExpectScanAll(), ExpectExpandBfs(), CheckPlan(planner.plan(), symbol_table, ExpectScanAll(), ExpectExpandBfs(),
ExpectProduce()); ExpectProduce());
@ -1271,7 +1271,7 @@ TYPED_TEST(TestPlanner, MatchDoubleScanToExpandExisting) {
AstStorage storage; AstStorage storage;
auto *query = QUERY(SINGLE_QUERY( auto *query = QUERY(SINGLE_QUERY(
MATCH(PATTERN(NODE("n"), EDGE("r"), NODE("m", label))), RETURN("r"))); MATCH(PATTERN(NODE("n"), EDGE("r"), NODE("m", label))), RETURN("r")));
auto symbol_table = MakeSymbolTable(*query); auto symbol_table = query::MakeSymbolTable(query);
auto planner = MakePlanner<TypeParam>(dba, storage, symbol_table, query); auto planner = MakePlanner<TypeParam>(dba, storage, symbol_table, query);
// We expect 2x ScanAll and then Expand, since we are guessing that is // We expect 2x ScanAll and then Expand, since we are guessing that is
// faster (due to low label index vertex count). // faster (due to low label index vertex count).
@ -1293,7 +1293,7 @@ TYPED_TEST(TestPlanner, MatchScanToExpand) {
node_m->properties_[std::make_pair("property", property)] = LITERAL(1); node_m->properties_[std::make_pair("property", property)] = LITERAL(1);
auto *query = QUERY( auto *query = QUERY(
SINGLE_QUERY(MATCH(PATTERN(NODE("n"), EDGE("r"), node_m)), RETURN("r"))); SINGLE_QUERY(MATCH(PATTERN(NODE("n"), EDGE("r"), node_m)), RETURN("r")));
auto symbol_table = MakeSymbolTable(*query); auto symbol_table = query::MakeSymbolTable(query);
auto planner = MakePlanner<TypeParam>(dba, storage, symbol_table, query); auto planner = MakePlanner<TypeParam>(dba, storage, symbol_table, query);
// We expect 1x ScanAll and then Expand, since we are guessing that // We expect 1x ScanAll and then Expand, since we are guessing that
// is faster (due to high label index vertex count). // is faster (due to high label index vertex count).
@ -1326,7 +1326,7 @@ TYPED_TEST(TestPlanner, ReturnAsteriskOmitsLambdaSymbols) {
ret->body_.all_identifiers = true; ret->body_.all_identifiers = true;
auto *query = auto *query =
QUERY(SINGLE_QUERY(MATCH(PATTERN(NODE("n"), edge, NODE("m"))), ret)); QUERY(SINGLE_QUERY(MATCH(PATTERN(NODE("n"), edge, NODE("m"))), ret));
auto symbol_table = MakeSymbolTable(*query); auto symbol_table = query::MakeSymbolTable(query);
FakeDbAccessor dba; FakeDbAccessor dba;
auto planner = MakePlanner<TypeParam>(dba, storage, symbol_table, query); auto planner = MakePlanner<TypeParam>(dba, storage, symbol_table, query);
auto *produce = dynamic_cast<Produce *>(&planner.plan()); auto *produce = dynamic_cast<Produce *>(&planner.plan());

View File

@ -343,13 +343,6 @@ std::list<std::unique_ptr<BaseOpChecker>> MakeCheckers(T arg, Rest &&... rest) {
return std::move(l); return std::move(l);
} }
auto MakeSymbolTable(query::Query &query) {
SymbolTable symbol_table;
SymbolGenerator symbol_generator(symbol_table);
query.Accept(symbol_generator);
return symbol_table;
}
template <class TPlanner, class TDbAccessor> template <class TPlanner, class TDbAccessor>
TPlanner MakePlanner(const TDbAccessor &dba, AstStorage &storage, TPlanner MakePlanner(const TDbAccessor &dba, AstStorage &storage,
SymbolTable &symbol_table, CypherQuery *query) { SymbolTable &symbol_table, CypherQuery *query) {

View File

@ -18,8 +18,6 @@ class TestSymbolGenerator : public ::testing::Test {
database::GraphDb db; database::GraphDb db;
std::unique_ptr<database::GraphDbAccessor> dba_ptr{db.Access()}; std::unique_ptr<database::GraphDbAccessor> dba_ptr{db.Access()};
database::GraphDbAccessor &dba{*dba_ptr}; database::GraphDbAccessor &dba{*dba_ptr};
SymbolTable symbol_table;
SymbolGenerator symbol_generator{symbol_table};
AstStorage storage; AstStorage storage;
}; };
@ -27,7 +25,7 @@ TEST_F(TestSymbolGenerator, MatchNodeReturn) {
// MATCH (node_atom_1) RETURN node_atom_1 // MATCH (node_atom_1) RETURN node_atom_1
auto query_ast = QUERY( auto query_ast = QUERY(
SINGLE_QUERY(MATCH(PATTERN(NODE("node_atom_1"))), RETURN("node_atom_1"))); SINGLE_QUERY(MATCH(PATTERN(NODE("node_atom_1"))), RETURN("node_atom_1")));
query_ast->Accept(symbol_generator); auto symbol_table = query::MakeSymbolTable(query_ast);
// symbols for pattern, node_atom_1 and named_expr in return // symbols for pattern, node_atom_1 and named_expr in return
EXPECT_EQ(symbol_table.max_position(), 3); EXPECT_EQ(symbol_table.max_position(), 3);
auto match = dynamic_cast<Match *>(query_ast->single_query_->clauses_[0]); auto match = dynamic_cast<Match *>(query_ast->single_query_->clauses_[0]);
@ -52,7 +50,7 @@ TEST_F(TestSymbolGenerator, MatchNamedPattern) {
// MATCH p = (node_atom_1) RETURN node_atom_1 // MATCH p = (node_atom_1) RETURN node_atom_1
auto query_ast = QUERY(SINGLE_QUERY( auto query_ast = QUERY(SINGLE_QUERY(
MATCH(NAMED_PATTERN("p", NODE("node_atom_1"))), RETURN("p"))); MATCH(NAMED_PATTERN("p", NODE("node_atom_1"))), RETURN("p")));
query_ast->Accept(symbol_generator); auto symbol_table = query::MakeSymbolTable(query_ast);
// symbols for p, node_atom_1 and named_expr in return // symbols for p, node_atom_1 and named_expr in return
EXPECT_EQ(symbol_table.max_position(), 3); EXPECT_EQ(symbol_table.max_position(), 3);
auto match = dynamic_cast<Match *>(query_ast->single_query_->clauses_[0]); auto match = dynamic_cast<Match *>(query_ast->single_query_->clauses_[0]);
@ -69,13 +67,13 @@ TEST_F(TestSymbolGenerator, MatchUnboundMultiReturn) {
// MATCH (node_atom_1) RETURN node_atom_1 AS n, n // MATCH (node_atom_1) RETURN node_atom_1 AS n, n
auto query_ast = QUERY(SINGLE_QUERY(MATCH(PATTERN(NODE("node_atom_1"))), auto query_ast = QUERY(SINGLE_QUERY(MATCH(PATTERN(NODE("node_atom_1"))),
RETURN("node_atom_1", AS("n"), "n"))); RETURN("node_atom_1", AS("n"), "n")));
EXPECT_THROW(query_ast->Accept(symbol_generator), UnboundVariableError); EXPECT_THROW(query::MakeSymbolTable(query_ast), UnboundVariableError);
} }
TEST_F(TestSymbolGenerator, MatchNodeUnboundReturn) { TEST_F(TestSymbolGenerator, MatchNodeUnboundReturn) {
// AST with unbound variable in return: MATCH (n) RETURN x // AST with unbound variable in return: MATCH (n) RETURN x
auto query_ast = QUERY(SINGLE_QUERY(MATCH(PATTERN(NODE("n"))), RETURN("x"))); auto query_ast = QUERY(SINGLE_QUERY(MATCH(PATTERN(NODE("n"))), RETURN("x")));
EXPECT_THROW(query_ast->Accept(symbol_generator), UnboundVariableError); EXPECT_THROW(query::MakeSymbolTable(query_ast), UnboundVariableError);
} }
TEST_F(TestSymbolGenerator, CreatePropertyUnbound) { TEST_F(TestSymbolGenerator, CreatePropertyUnbound) {
@ -83,13 +81,13 @@ TEST_F(TestSymbolGenerator, CreatePropertyUnbound) {
auto node = NODE("anon"); auto node = NODE("anon");
node->properties_[PROPERTY_PAIR("prop")] = IDENT("x"); node->properties_[PROPERTY_PAIR("prop")] = IDENT("x");
auto query_ast = QUERY(SINGLE_QUERY(CREATE(PATTERN(node)))); auto query_ast = QUERY(SINGLE_QUERY(CREATE(PATTERN(node))));
EXPECT_THROW(query_ast->Accept(symbol_generator), UnboundVariableError); EXPECT_THROW(query::MakeSymbolTable(query_ast), UnboundVariableError);
} }
TEST_F(TestSymbolGenerator, CreateNodeReturn) { TEST_F(TestSymbolGenerator, CreateNodeReturn) {
// Simple AST returning a created node: CREATE (n) RETURN n // Simple AST returning a created node: CREATE (n) RETURN n
auto query_ast = QUERY(SINGLE_QUERY(CREATE(PATTERN(NODE("n"))), RETURN("n"))); auto query_ast = QUERY(SINGLE_QUERY(CREATE(PATTERN(NODE("n"))), RETURN("n")));
query_ast->Accept(symbol_generator); auto symbol_table = query::MakeSymbolTable(query_ast);
// symbols for pattern, `n` and named_expr // symbols for pattern, `n` and named_expr
EXPECT_EQ(symbol_table.max_position(), 3); EXPECT_EQ(symbol_table.max_position(), 3);
auto create = dynamic_cast<Create *>(query_ast->single_query_->clauses_[0]); auto create = dynamic_cast<Create *>(query_ast->single_query_->clauses_[0]);
@ -111,7 +109,7 @@ TEST_F(TestSymbolGenerator, CreateRedeclareNode) {
// AST with redeclaring a variable when creating nodes: CREATE (n), (n) // AST with redeclaring a variable when creating nodes: CREATE (n), (n)
auto query_ast = auto query_ast =
QUERY(SINGLE_QUERY(CREATE(PATTERN(NODE("n")), PATTERN(NODE("n"))))); QUERY(SINGLE_QUERY(CREATE(PATTERN(NODE("n")), PATTERN(NODE("n")))));
EXPECT_THROW(query_ast->Accept(symbol_generator), RedeclareVariableError); EXPECT_THROW(query::MakeSymbolTable(query_ast), RedeclareVariableError);
} }
TEST_F(TestSymbolGenerator, MultiCreateRedeclareNode) { TEST_F(TestSymbolGenerator, MultiCreateRedeclareNode) {
@ -119,14 +117,14 @@ TEST_F(TestSymbolGenerator, MultiCreateRedeclareNode) {
// CREATE (n) CREATE (n) // CREATE (n) CREATE (n)
auto query_ast = QUERY( auto query_ast = QUERY(
SINGLE_QUERY(CREATE(PATTERN(NODE("n"))), CREATE(PATTERN(NODE("n"))))); SINGLE_QUERY(CREATE(PATTERN(NODE("n"))), CREATE(PATTERN(NODE("n")))));
EXPECT_THROW(query_ast->Accept(symbol_generator), RedeclareVariableError); EXPECT_THROW(query::MakeSymbolTable(query_ast), RedeclareVariableError);
} }
TEST_F(TestSymbolGenerator, MatchCreateRedeclareNode) { TEST_F(TestSymbolGenerator, MatchCreateRedeclareNode) {
// AST with redeclaring a match node variable in create: MATCH (n) CREATE (n) // AST with redeclaring a match node variable in create: MATCH (n) CREATE (n)
auto query_ast = QUERY( auto query_ast = QUERY(
SINGLE_QUERY(MATCH(PATTERN(NODE("n"))), CREATE(PATTERN(NODE("n"))))); SINGLE_QUERY(MATCH(PATTERN(NODE("n"))), CREATE(PATTERN(NODE("n")))));
EXPECT_THROW(query_ast->Accept(symbol_generator), RedeclareVariableError); EXPECT_THROW(query::MakeSymbolTable(query_ast), RedeclareVariableError);
} }
TEST_F(TestSymbolGenerator, MatchCreateRedeclareEdge) { TEST_F(TestSymbolGenerator, MatchCreateRedeclareEdge) {
@ -138,7 +136,7 @@ TEST_F(TestSymbolGenerator, MatchCreateRedeclareEdge) {
CREATE(PATTERN(NODE("n"), CREATE(PATTERN(NODE("n"),
EDGE("r", EdgeAtom::Direction::OUT, {relationship}), EDGE("r", EdgeAtom::Direction::OUT, {relationship}),
NODE("l"))))); NODE("l")))));
EXPECT_THROW(query->Accept(symbol_generator), RedeclareVariableError); EXPECT_THROW(query::MakeSymbolTable(query), RedeclareVariableError);
} }
TEST_F(TestSymbolGenerator, MatchTypeMismatch) { TEST_F(TestSymbolGenerator, MatchTypeMismatch) {
@ -146,7 +144,7 @@ TEST_F(TestSymbolGenerator, MatchTypeMismatch) {
// MATCH (n) -[r]-> (r) // MATCH (n) -[r]-> (r)
auto query = auto query =
QUERY(SINGLE_QUERY(MATCH(PATTERN(NODE("n"), EDGE("r"), NODE("r"))))); QUERY(SINGLE_QUERY(MATCH(PATTERN(NODE("n"), EDGE("r"), NODE("r")))));
EXPECT_THROW(query->Accept(symbol_generator), TypeMismatchError); EXPECT_THROW(query::MakeSymbolTable(query), TypeMismatchError);
} }
TEST_F(TestSymbolGenerator, MatchCreateTypeMismatch) { TEST_F(TestSymbolGenerator, MatchCreateTypeMismatch) {
@ -156,7 +154,7 @@ TEST_F(TestSymbolGenerator, MatchCreateTypeMismatch) {
MATCH(PATTERN(NODE("n1"), EDGE("r1"), NODE("n2"))), MATCH(PATTERN(NODE("n1"), EDGE("r1"), NODE("n2"))),
CREATE(PATTERN(NODE("r1"), EDGE("r2", EdgeAtom::Direction::OUT), CREATE(PATTERN(NODE("r1"), EDGE("r2", EdgeAtom::Direction::OUT),
NODE("n2"))))); NODE("n2")))));
EXPECT_THROW(query->Accept(symbol_generator), TypeMismatchError); EXPECT_THROW(query::MakeSymbolTable(query), TypeMismatchError);
} }
TEST_F(TestSymbolGenerator, CreateMultipleEdgeType) { TEST_F(TestSymbolGenerator, CreateMultipleEdgeType) {
@ -167,7 +165,7 @@ TEST_F(TestSymbolGenerator, CreateMultipleEdgeType) {
auto edge = EDGE("r", EdgeAtom::Direction::OUT, {rel1}); auto edge = EDGE("r", EdgeAtom::Direction::OUT, {rel1});
edge->edge_types_.emplace_back(rel2); edge->edge_types_.emplace_back(rel2);
auto query = QUERY(SINGLE_QUERY(CREATE(PATTERN(NODE("n"), edge, NODE("m"))))); auto query = QUERY(SINGLE_QUERY(CREATE(PATTERN(NODE("n"), edge, NODE("m")))));
EXPECT_THROW(query->Accept(symbol_generator), SemanticException); EXPECT_THROW(query::MakeSymbolTable(query), SemanticException);
} }
TEST_F(TestSymbolGenerator, CreateBidirectionalEdge) { TEST_F(TestSymbolGenerator, CreateBidirectionalEdge) {
@ -176,7 +174,7 @@ TEST_F(TestSymbolGenerator, CreateBidirectionalEdge) {
auto rel1 = dba.EdgeType("rel1"); auto rel1 = dba.EdgeType("rel1");
auto query = QUERY(SINGLE_QUERY(CREATE(PATTERN( auto query = QUERY(SINGLE_QUERY(CREATE(PATTERN(
NODE("n"), EDGE("r", EdgeAtom::Direction::BOTH, {rel1}), NODE("m"))))); NODE("n"), EDGE("r", EdgeAtom::Direction::BOTH, {rel1}), NODE("m")))));
EXPECT_THROW(query->Accept(symbol_generator), SemanticException); EXPECT_THROW(query::MakeSymbolTable(query), SemanticException);
} }
TEST_F(TestSymbolGenerator, MatchWhereUnbound) { TEST_F(TestSymbolGenerator, MatchWhereUnbound) {
@ -184,7 +182,7 @@ TEST_F(TestSymbolGenerator, MatchWhereUnbound) {
auto query = QUERY(SINGLE_QUERY(MATCH(PATTERN(NODE("n"))), auto query = QUERY(SINGLE_QUERY(MATCH(PATTERN(NODE("n"))),
WHERE(LESS(IDENT("missing"), LITERAL(42))), WHERE(LESS(IDENT("missing"), LITERAL(42))),
RETURN("n"))); RETURN("n")));
EXPECT_THROW(query->Accept(symbol_generator), UnboundVariableError); EXPECT_THROW(query::MakeSymbolTable(query), UnboundVariableError);
} }
TEST_F(TestSymbolGenerator, CreateDelete) { TEST_F(TestSymbolGenerator, CreateDelete) {
@ -192,7 +190,7 @@ TEST_F(TestSymbolGenerator, CreateDelete) {
auto node = NODE("n"); auto node = NODE("n");
auto ident = IDENT("n"); auto ident = IDENT("n");
auto query = QUERY(SINGLE_QUERY(CREATE(PATTERN(node)), DELETE(ident))); auto query = QUERY(SINGLE_QUERY(CREATE(PATTERN(node)), DELETE(ident)));
query->Accept(symbol_generator); auto symbol_table = query::MakeSymbolTable(query);
// symbols for pattern and `n` // symbols for pattern and `n`
EXPECT_EQ(symbol_table.max_position(), 2); EXPECT_EQ(symbol_table.max_position(), 2);
auto node_symbol = symbol_table.at(*node->identifier_); auto node_symbol = symbol_table.at(*node->identifier_);
@ -205,7 +203,7 @@ TEST_F(TestSymbolGenerator, CreateDeleteUnbound) {
// Test CREATE (n) DELETE missing // Test CREATE (n) DELETE missing
auto query = auto query =
QUERY(SINGLE_QUERY(CREATE(PATTERN(NODE("n"))), DELETE(IDENT("missing")))); QUERY(SINGLE_QUERY(CREATE(PATTERN(NODE("n"))), DELETE(IDENT("missing"))));
EXPECT_THROW(query->Accept(symbol_generator), UnboundVariableError); EXPECT_THROW(query::MakeSymbolTable(query), UnboundVariableError);
} }
TEST_F(TestSymbolGenerator, MatchWithReturn) { TEST_F(TestSymbolGenerator, MatchWithReturn) {
@ -218,7 +216,7 @@ TEST_F(TestSymbolGenerator, MatchWithReturn) {
auto query = auto query =
QUERY(SINGLE_QUERY(MATCH(PATTERN(node)), WITH(old_ident, with_as_n), QUERY(SINGLE_QUERY(MATCH(PATTERN(node)), WITH(old_ident, with_as_n),
RETURN(n_ident, ret_as_n))); RETURN(n_ident, ret_as_n)));
query->Accept(symbol_generator); auto symbol_table = query::MakeSymbolTable(query);
// symbols for pattern, `old`, `n` and named_expr in return // symbols for pattern, `old`, `n` and named_expr in return
EXPECT_EQ(symbol_table.max_position(), 4); EXPECT_EQ(symbol_table.max_position(), 4);
auto node_symbol = symbol_table.at(*node->identifier_); auto node_symbol = symbol_table.at(*node->identifier_);
@ -236,7 +234,7 @@ TEST_F(TestSymbolGenerator, MatchWithReturnUnbound) {
// Test MATCH (old) WITH old AS n RETURN old // Test MATCH (old) WITH old AS n RETURN old
auto query = QUERY(SINGLE_QUERY(MATCH(PATTERN(NODE("old"))), auto query = QUERY(SINGLE_QUERY(MATCH(PATTERN(NODE("old"))),
WITH("old", AS("n")), RETURN("old"))); WITH("old", AS("n")), RETURN("old")));
EXPECT_THROW(query->Accept(symbol_generator), UnboundVariableError); EXPECT_THROW(query::MakeSymbolTable(query), UnboundVariableError);
} }
TEST_F(TestSymbolGenerator, MatchWithWhere) { TEST_F(TestSymbolGenerator, MatchWithWhere) {
@ -249,7 +247,7 @@ TEST_F(TestSymbolGenerator, MatchWithWhere) {
auto query = auto query =
QUERY(SINGLE_QUERY(MATCH(PATTERN(node)), WITH(old_ident, with_as_n), QUERY(SINGLE_QUERY(MATCH(PATTERN(node)), WITH(old_ident, with_as_n),
WHERE(LESS(n_prop, LITERAL(42))))); WHERE(LESS(n_prop, LITERAL(42)))));
query->Accept(symbol_generator); auto symbol_table = query::MakeSymbolTable(query);
// symbols for pattern, `old` and `n` // symbols for pattern, `old` and `n`
EXPECT_EQ(symbol_table.max_position(), 3); EXPECT_EQ(symbol_table.max_position(), 3);
auto node_symbol = symbol_table.at(*node->identifier_); auto node_symbol = symbol_table.at(*node->identifier_);
@ -267,7 +265,7 @@ TEST_F(TestSymbolGenerator, MatchWithWhereUnbound) {
auto query = QUERY(SINGLE_QUERY( auto query = QUERY(SINGLE_QUERY(
MATCH(PATTERN(NODE("old"))), WITH(COUNT(IDENT("old")), AS("c")), MATCH(PATTERN(NODE("old"))), WITH(COUNT(IDENT("old")), AS("c")),
WHERE(LESS(PROPERTY_LOOKUP("old", prop), LITERAL(42))))); WHERE(LESS(PROPERTY_LOOKUP("old", prop), LITERAL(42)))));
EXPECT_THROW(query->Accept(symbol_generator), UnboundVariableError); EXPECT_THROW(query::MakeSymbolTable(query), UnboundVariableError);
} }
TEST_F(TestSymbolGenerator, CreateMultiExpand) { TEST_F(TestSymbolGenerator, CreateMultiExpand) {
@ -282,7 +280,7 @@ TEST_F(TestSymbolGenerator, CreateMultiExpand) {
auto node_l = NODE("l"); auto node_l = NODE("l");
auto query = QUERY(SINGLE_QUERY(CREATE(PATTERN(node_n1, edge_r, node_m), auto query = QUERY(SINGLE_QUERY(CREATE(PATTERN(node_n1, edge_r, node_m),
PATTERN(node_n2, edge_p, node_l)))); PATTERN(node_n2, edge_p, node_l))));
query->Accept(symbol_generator); auto symbol_table = query::MakeSymbolTable(query);
// symbols for pattern * 2, `n`, `r`, `m`, `p`, `l` // symbols for pattern * 2, `n`, `r`, `m`, `p`, `l`
EXPECT_EQ(symbol_table.max_position(), 7); EXPECT_EQ(symbol_table.max_position(), 7);
auto n1 = symbol_table.at(*node_n1->identifier_); auto n1 = symbol_table.at(*node_n1->identifier_);
@ -311,7 +309,7 @@ TEST_F(TestSymbolGenerator, MatchCreateExpandLabel) {
MATCH(PATTERN(NODE("n"))), MATCH(PATTERN(NODE("n"))),
CREATE(PATTERN(NODE("m"), EDGE("r", EdgeAtom::Direction::OUT, {r_type}), CREATE(PATTERN(NODE("m"), EDGE("r", EdgeAtom::Direction::OUT, {r_type}),
NODE("n", label))))); NODE("n", label)))));
EXPECT_THROW(query->Accept(symbol_generator), SemanticException); EXPECT_THROW(query::MakeSymbolTable(query), SemanticException);
} }
TEST_F(TestSymbolGenerator, CreateExpandProperty) { TEST_F(TestSymbolGenerator, CreateExpandProperty) {
@ -321,7 +319,7 @@ TEST_F(TestSymbolGenerator, CreateExpandProperty) {
n_prop->properties_[PROPERTY_PAIR("prop")] = LITERAL(42); n_prop->properties_[PROPERTY_PAIR("prop")] = LITERAL(42);
auto query = QUERY(SINGLE_QUERY(CREATE(PATTERN( auto query = QUERY(SINGLE_QUERY(CREATE(PATTERN(
NODE("n"), EDGE("r", EdgeAtom::Direction::OUT, {r_type}), n_prop)))); NODE("n"), EDGE("r", EdgeAtom::Direction::OUT, {r_type}), n_prop))));
EXPECT_THROW(query->Accept(symbol_generator), SemanticException); EXPECT_THROW(query::MakeSymbolTable(query), SemanticException);
} }
TEST_F(TestSymbolGenerator, MatchReturnSum) { TEST_F(TestSymbolGenerator, MatchReturnSum) {
@ -332,7 +330,7 @@ TEST_F(TestSymbolGenerator, MatchReturnSum) {
auto as_result = AS("result"); auto as_result = AS("result");
auto query = QUERY(SINGLE_QUERY(MATCH(PATTERN(node)), auto query = QUERY(SINGLE_QUERY(MATCH(PATTERN(node)),
RETURN(ADD(sum, LITERAL(42)), as_result))); RETURN(ADD(sum, LITERAL(42)), as_result)));
query->Accept(symbol_generator); auto symbol_table = query::MakeSymbolTable(query);
// 3 symbols for: pattern, 'n', 'sum' and 'result'. // 3 symbols for: pattern, 'n', 'sum' and 'result'.
EXPECT_EQ(symbol_table.max_position(), 4); EXPECT_EQ(symbol_table.max_position(), 4);
auto node_symbol = symbol_table.at(*node->identifier_); auto node_symbol = symbol_table.at(*node->identifier_);
@ -349,7 +347,7 @@ TEST_F(TestSymbolGenerator, NestedAggregation) {
auto query = QUERY(SINGLE_QUERY( auto query = QUERY(SINGLE_QUERY(
MATCH(PATTERN(NODE("n"))), MATCH(PATTERN(NODE("n"))),
RETURN(SUM(ADD(LITERAL(42), SUM(PROPERTY_LOOKUP("n", prop)))), AS("s")))); RETURN(SUM(ADD(LITERAL(42), SUM(PROPERTY_LOOKUP("n", prop)))), AS("s"))));
EXPECT_THROW(query->Accept(symbol_generator), SemanticException); EXPECT_THROW(query::MakeSymbolTable(query), SemanticException);
} }
TEST_F(TestSymbolGenerator, WrongAggregationContext) { TEST_F(TestSymbolGenerator, WrongAggregationContext) {
@ -358,7 +356,7 @@ TEST_F(TestSymbolGenerator, WrongAggregationContext) {
auto query = QUERY(SINGLE_QUERY( auto query = QUERY(SINGLE_QUERY(
MATCH(PATTERN(NODE("n"))), WITH(PROPERTY_LOOKUP("n", prop), AS("prop")), MATCH(PATTERN(NODE("n"))), WITH(PROPERTY_LOOKUP("n", prop), AS("prop")),
WHERE(LESS(SUM(IDENT("prop")), LITERAL(42))))); WHERE(LESS(SUM(IDENT("prop")), LITERAL(42)))));
EXPECT_THROW(query->Accept(symbol_generator), SemanticException); EXPECT_THROW(query::MakeSymbolTable(query), SemanticException);
} }
TEST_F(TestSymbolGenerator, MatchPropCreateNodeProp) { TEST_F(TestSymbolGenerator, MatchPropCreateNodeProp) {
@ -370,7 +368,7 @@ TEST_F(TestSymbolGenerator, MatchPropCreateNodeProp) {
node_m->properties_[prop] = n_prop; node_m->properties_[prop] = n_prop;
auto query = auto query =
QUERY(SINGLE_QUERY(MATCH(PATTERN(node_n)), CREATE(PATTERN(node_m)))); QUERY(SINGLE_QUERY(MATCH(PATTERN(node_n)), CREATE(PATTERN(node_m))));
query->Accept(symbol_generator); auto symbol_table = query::MakeSymbolTable(query);
// symbols: pattern * 2, `node_n`, `node_m` // symbols: pattern * 2, `node_n`, `node_m`
EXPECT_EQ(symbol_table.max_position(), 4); EXPECT_EQ(symbol_table.max_position(), 4);
auto n = symbol_table.at(*node_n->identifier_); auto n = symbol_table.at(*node_n->identifier_);
@ -388,7 +386,7 @@ TEST_F(TestSymbolGenerator, CreateNodeEdge) {
auto node_3 = NODE("n"); auto node_3 = NODE("n");
auto query = QUERY( auto query = QUERY(
SINGLE_QUERY(CREATE(PATTERN(node_1), PATTERN(node_2, edge, node_3)))); SINGLE_QUERY(CREATE(PATTERN(node_1), PATTERN(node_2, edge, node_3))));
query->Accept(symbol_generator); auto symbol_table = query::MakeSymbolTable(query);
// symbols: pattern * 2, `n`, `r` // symbols: pattern * 2, `n`, `r`
EXPECT_EQ(symbol_table.max_position(), 4); EXPECT_EQ(symbol_table.max_position(), 4);
auto n = symbol_table.at(*node_1->identifier_); auto n = symbol_table.at(*node_1->identifier_);
@ -406,7 +404,7 @@ TEST_F(TestSymbolGenerator, MatchWithCreate) {
auto node_3 = NODE("m"); auto node_3 = NODE("m");
auto query = QUERY(SINGLE_QUERY(MATCH(PATTERN(node_1)), WITH("n", AS("m")), auto query = QUERY(SINGLE_QUERY(MATCH(PATTERN(node_1)), WITH("n", AS("m")),
CREATE(PATTERN(node_2, edge, node_3)))); CREATE(PATTERN(node_2, edge, node_3))));
query->Accept(symbol_generator); auto symbol_table = query::MakeSymbolTable(query);
// symbols: pattern * 2, `n`, `m`, `r` // symbols: pattern * 2, `n`, `m`, `r`
EXPECT_EQ(symbol_table.max_position(), 5); EXPECT_EQ(symbol_table.max_position(), 5);
auto n = symbol_table.at(*node_1->identifier_); auto n = symbol_table.at(*node_1->identifier_);
@ -422,34 +420,34 @@ TEST_F(TestSymbolGenerator, SameResultsWith) {
// Test MATCH (n) WITH n AS m, n AS m // Test MATCH (n) WITH n AS m, n AS m
auto query = QUERY(SINGLE_QUERY(MATCH(PATTERN(NODE("n"))), auto query = QUERY(SINGLE_QUERY(MATCH(PATTERN(NODE("n"))),
WITH("n", AS("m"), "n", AS("m")))); WITH("n", AS("m"), "n", AS("m"))));
EXPECT_THROW(query->Accept(symbol_generator), SemanticException); EXPECT_THROW(query::MakeSymbolTable(query), SemanticException);
} }
TEST_F(TestSymbolGenerator, SameResults) { TEST_F(TestSymbolGenerator, SameResults) {
// Test MATCH (n) RETURN n, n // Test MATCH (n) RETURN n, n
auto query = QUERY(SINGLE_QUERY(MATCH(PATTERN(NODE("n"))), RETURN("n", "n"))); auto query = QUERY(SINGLE_QUERY(MATCH(PATTERN(NODE("n"))), RETURN("n", "n")));
EXPECT_THROW(query->Accept(symbol_generator), SemanticException); EXPECT_THROW(query::MakeSymbolTable(query), SemanticException);
} }
TEST_F(TestSymbolGenerator, SkipUsingIdentifier) { TEST_F(TestSymbolGenerator, SkipUsingIdentifier) {
// Test MATCH (old) WITH old AS new SKIP old // Test MATCH (old) WITH old AS new SKIP old
auto query = QUERY(SINGLE_QUERY(MATCH(PATTERN(NODE("old"))), auto query = QUERY(SINGLE_QUERY(MATCH(PATTERN(NODE("old"))),
WITH("old", AS("new"), SKIP(IDENT("old"))))); WITH("old", AS("new"), SKIP(IDENT("old")))));
EXPECT_THROW(query->Accept(symbol_generator), SemanticException); EXPECT_THROW(query::MakeSymbolTable(query), SemanticException);
} }
TEST_F(TestSymbolGenerator, SkipUsingIdentifierAlias) { TEST_F(TestSymbolGenerator, SkipUsingIdentifierAlias) {
// Test MATCH (old) WITH old AS new SKIP new // Test MATCH (old) WITH old AS new SKIP new
auto query = QUERY(SINGLE_QUERY(MATCH(PATTERN(NODE("old"))), auto query = QUERY(SINGLE_QUERY(MATCH(PATTERN(NODE("old"))),
WITH("old", AS("new"), SKIP(IDENT("new"))))); WITH("old", AS("new"), SKIP(IDENT("new")))));
EXPECT_THROW(query->Accept(symbol_generator), SemanticException); EXPECT_THROW(query::MakeSymbolTable(query), SemanticException);
} }
TEST_F(TestSymbolGenerator, LimitUsingIdentifier) { TEST_F(TestSymbolGenerator, LimitUsingIdentifier) {
// Test MATCH (n) RETURN n AS n LIMIT n // Test MATCH (n) RETURN n AS n LIMIT n
auto query = QUERY( auto query = QUERY(
SINGLE_QUERY(MATCH(PATTERN(NODE("n"))), RETURN("n", LIMIT(IDENT("n"))))); SINGLE_QUERY(MATCH(PATTERN(NODE("n"))), RETURN("n", LIMIT(IDENT("n")))));
EXPECT_THROW(query->Accept(symbol_generator), SemanticException); EXPECT_THROW(query::MakeSymbolTable(query), SemanticException);
} }
TEST_F(TestSymbolGenerator, OrderByAggregation) { TEST_F(TestSymbolGenerator, OrderByAggregation) {
@ -457,7 +455,7 @@ TEST_F(TestSymbolGenerator, OrderByAggregation) {
auto query = QUERY( auto query = QUERY(
SINGLE_QUERY(MATCH(PATTERN(NODE("old"))), SINGLE_QUERY(MATCH(PATTERN(NODE("old"))),
RETURN("old", AS("new"), ORDER_BY(COUNT(LITERAL(1)))))); RETURN("old", AS("new"), ORDER_BY(COUNT(LITERAL(1))))));
EXPECT_THROW(query->Accept(symbol_generator), SemanticException); EXPECT_THROW(query::MakeSymbolTable(query), SemanticException);
} }
TEST_F(TestSymbolGenerator, OrderByUnboundVariable) { TEST_F(TestSymbolGenerator, OrderByUnboundVariable) {
@ -465,7 +463,7 @@ TEST_F(TestSymbolGenerator, OrderByUnboundVariable) {
auto query = QUERY(SINGLE_QUERY( auto query = QUERY(SINGLE_QUERY(
MATCH(PATTERN(NODE("old"))), MATCH(PATTERN(NODE("old"))),
RETURN(COUNT(IDENT("old")), AS("new"), ORDER_BY(IDENT("old"))))); RETURN(COUNT(IDENT("old")), AS("new"), ORDER_BY(IDENT("old")))));
EXPECT_THROW(query->Accept(symbol_generator), UnboundVariableError); EXPECT_THROW(query::MakeSymbolTable(query), UnboundVariableError);
} }
TEST_F(TestSymbolGenerator, AggregationOrderBy) { TEST_F(TestSymbolGenerator, AggregationOrderBy) {
@ -477,7 +475,7 @@ TEST_F(TestSymbolGenerator, AggregationOrderBy) {
auto query = auto query =
QUERY(SINGLE_QUERY(MATCH(PATTERN(node)), RETURN(COUNT(ident_old), as_new, QUERY(SINGLE_QUERY(MATCH(PATTERN(node)), RETURN(COUNT(ident_old), as_new,
ORDER_BY(ident_new)))); ORDER_BY(ident_new))));
query->Accept(symbol_generator); auto symbol_table = query::MakeSymbolTable(query);
// Symbols for pattern, `old`, `count(old)` and `new` // Symbols for pattern, `old`, `count(old)` and `new`
EXPECT_EQ(symbol_table.max_position(), 4); EXPECT_EQ(symbol_table.max_position(), 4);
auto old = symbol_table.at(*node->identifier_); auto old = symbol_table.at(*node->identifier_);
@ -495,7 +493,7 @@ TEST_F(TestSymbolGenerator, OrderByOldVariable) {
auto by_old = IDENT("old"); auto by_old = IDENT("old");
auto query = QUERY(SINGLE_QUERY(MATCH(PATTERN(node)), auto query = QUERY(SINGLE_QUERY(MATCH(PATTERN(node)),
RETURN(ident_old, as_new, ORDER_BY(by_old)))); RETURN(ident_old, as_new, ORDER_BY(by_old))));
query->Accept(symbol_generator); auto symbol_table = query::MakeSymbolTable(query);
// Symbols for pattern, `old` and `new` // Symbols for pattern, `old` and `new`
EXPECT_EQ(symbol_table.max_position(), 3); EXPECT_EQ(symbol_table.max_position(), 3);
auto old = symbol_table.at(*node->identifier_); auto old = symbol_table.at(*node->identifier_);
@ -509,7 +507,7 @@ TEST_F(TestSymbolGenerator, MergeVariableError) {
// Test MATCH (n) MERGE (n) // Test MATCH (n) MERGE (n)
auto query = auto query =
QUERY(SINGLE_QUERY(MATCH(PATTERN(NODE("n"))), MERGE(PATTERN(NODE("n"))))); QUERY(SINGLE_QUERY(MATCH(PATTERN(NODE("n"))), MERGE(PATTERN(NODE("n")))));
EXPECT_THROW(query->Accept(symbol_generator), RedeclareVariableError); EXPECT_THROW(query::MakeSymbolTable(query), RedeclareVariableError);
} }
TEST_F(TestSymbolGenerator, MergeVariableErrorEdge) { TEST_F(TestSymbolGenerator, MergeVariableErrorEdge) {
@ -519,7 +517,7 @@ TEST_F(TestSymbolGenerator, MergeVariableErrorEdge) {
MATCH(PATTERN(NODE("n"), EDGE("r"), NODE("m"))), MATCH(PATTERN(NODE("n"), EDGE("r"), NODE("m"))),
MERGE(PATTERN(NODE("a"), EDGE("r", EdgeAtom::Direction::BOTH, {rel}), MERGE(PATTERN(NODE("a"), EDGE("r", EdgeAtom::Direction::BOTH, {rel}),
NODE("b"))))); NODE("b")))));
EXPECT_THROW(query->Accept(symbol_generator), RedeclareVariableError); EXPECT_THROW(query::MakeSymbolTable(query), RedeclareVariableError);
} }
TEST_F(TestSymbolGenerator, MergeEdgeWithoutType) { TEST_F(TestSymbolGenerator, MergeEdgeWithoutType) {
@ -527,7 +525,7 @@ TEST_F(TestSymbolGenerator, MergeEdgeWithoutType) {
auto query = auto query =
QUERY(SINGLE_QUERY(MERGE(PATTERN(NODE("a"), EDGE("r"), NODE("b"))))); QUERY(SINGLE_QUERY(MERGE(PATTERN(NODE("a"), EDGE("r"), NODE("b")))));
// Edge must have a type, since it doesn't we raise. // Edge must have a type, since it doesn't we raise.
EXPECT_THROW(query->Accept(symbol_generator), SemanticException); EXPECT_THROW(query::MakeSymbolTable(query), SemanticException);
} }
TEST_F(TestSymbolGenerator, MergeOnMatchOnCreate) { TEST_F(TestSymbolGenerator, MergeOnMatchOnCreate) {
@ -548,7 +546,7 @@ TEST_F(TestSymbolGenerator, MergeOnMatchOnCreate) {
ON_MATCH(SET(n_prop, LITERAL(42))), ON_MATCH(SET(n_prop, LITERAL(42))),
ON_CREATE(SET(m_prop, LITERAL(42)))), ON_CREATE(SET(m_prop, LITERAL(42)))),
RETURN(ident_r, as_r))); RETURN(ident_r, as_r)));
query->Accept(symbol_generator); auto symbol_table = query::MakeSymbolTable(query);
// Symbols for: pattern * 2, `n`, `r`, `m` and `AS r`. // Symbols for: pattern * 2, `n`, `r`, `m` and `AS r`.
EXPECT_EQ(symbol_table.max_position(), 6); EXPECT_EQ(symbol_table.max_position(), 6);
auto n = symbol_table.at(*match_n->identifier_); auto n = symbol_table.at(*match_n->identifier_);
@ -570,7 +568,7 @@ TEST_F(TestSymbolGenerator, WithUnwindRedeclareReturn) {
auto query = auto query =
QUERY(SINGLE_QUERY(WITH(LIST(LITERAL(1), LITERAL(2)), AS("list")), QUERY(SINGLE_QUERY(WITH(LIST(LITERAL(1), LITERAL(2)), AS("list")),
UNWIND(IDENT("list"), AS("list")), RETURN("list"))); UNWIND(IDENT("list"), AS("list")), RETURN("list")));
EXPECT_THROW(query->Accept(symbol_generator), RedeclareVariableError); EXPECT_THROW(query::MakeSymbolTable(query), RedeclareVariableError);
} }
TEST_F(TestSymbolGenerator, WithUnwindReturn) { TEST_F(TestSymbolGenerator, WithUnwindReturn) {
@ -584,7 +582,7 @@ TEST_F(TestSymbolGenerator, WithUnwindReturn) {
auto query = QUERY( auto query = QUERY(
SINGLE_QUERY(WITH(LIST(LITERAL(1), LITERAL(2)), with_as_list), unwind, SINGLE_QUERY(WITH(LIST(LITERAL(1), LITERAL(2)), with_as_list), unwind,
RETURN(ret_list, ret_as_list, ret_elem, ret_as_elem))); RETURN(ret_list, ret_as_list, ret_elem, ret_as_elem)));
query->Accept(symbol_generator); auto symbol_table = query::MakeSymbolTable(query);
// Symbols for: `list`, `elem`, `AS list`, `AS elem` // Symbols for: `list`, `elem`, `AS list`, `AS elem`
EXPECT_EQ(symbol_table.max_position(), 4); EXPECT_EQ(symbol_table.max_position(), 4);
const auto &list = symbol_table.at(*with_as_list); const auto &list = symbol_table.at(*with_as_list);
@ -610,7 +608,7 @@ TEST_F(TestSymbolGenerator, MatchCrossReferenceVariable) {
auto as_n = AS("n"); auto as_n = AS("n");
auto query = QUERY(SINGLE_QUERY(MATCH(PATTERN(node_n), PATTERN(node_m)), auto query = QUERY(SINGLE_QUERY(MATCH(PATTERN(node_n), PATTERN(node_m)),
RETURN(ident_n, as_n))); RETURN(ident_n, as_n)));
query->Accept(symbol_generator); auto symbol_table = query::MakeSymbolTable(query);
// Symbols for pattern * 2, `n`, `m` and `AS n` // Symbols for pattern * 2, `n`, `m` and `AS n`
EXPECT_EQ(symbol_table.max_position(), 5); EXPECT_EQ(symbol_table.max_position(), 5);
auto n = symbol_table.at(*node_n->identifier_); auto n = symbol_table.at(*node_n->identifier_);
@ -636,7 +634,7 @@ TEST_F(TestSymbolGenerator, MatchWithAsteriskReturnAsterisk) {
with->body_.all_identifiers = true; with->body_.all_identifiers = true;
auto query = auto query =
QUERY(SINGLE_QUERY(MATCH(PATTERN(node_n, edge, node_m)), with, ret)); QUERY(SINGLE_QUERY(MATCH(PATTERN(node_n, edge, node_m)), with, ret));
query->Accept(symbol_generator); auto symbol_table = query::MakeSymbolTable(query);
// Symbols for pattern, `n`, `e`, `m`, `AS n.prop`. // Symbols for pattern, `n`, `e`, `m`, `AS n.prop`.
EXPECT_EQ(symbol_table.max_position(), 5); EXPECT_EQ(symbol_table.max_position(), 5);
auto n = symbol_table.at(*node_n->identifier_); auto n = symbol_table.at(*node_n->identifier_);
@ -648,7 +646,7 @@ TEST_F(TestSymbolGenerator, MatchReturnAsteriskSameResult) {
auto ret = RETURN("n"); auto ret = RETURN("n");
ret->body_.all_identifiers = true; ret->body_.all_identifiers = true;
auto query = QUERY(SINGLE_QUERY(MATCH(PATTERN(NODE("n"))), ret)); auto query = QUERY(SINGLE_QUERY(MATCH(PATTERN(NODE("n"))), ret));
EXPECT_THROW(query->Accept(symbol_generator), SemanticException); EXPECT_THROW(query::MakeSymbolTable(query), SemanticException);
} }
TEST_F(TestSymbolGenerator, MatchReturnAsteriskNoUserVariables) { TEST_F(TestSymbolGenerator, MatchReturnAsteriskNoUserVariables) {
@ -658,7 +656,7 @@ TEST_F(TestSymbolGenerator, MatchReturnAsteriskNoUserVariables) {
auto ident_n = storage.Create<Identifier>("anon", false); auto ident_n = storage.Create<Identifier>("anon", false);
auto node = storage.Create<NodeAtom>(ident_n); auto node = storage.Create<NodeAtom>(ident_n);
auto query = QUERY(SINGLE_QUERY(MATCH(PATTERN(node)), ret)); auto query = QUERY(SINGLE_QUERY(MATCH(PATTERN(node)), ret));
EXPECT_THROW(query->Accept(symbol_generator), SemanticException); EXPECT_THROW(query::MakeSymbolTable(query), SemanticException);
} }
TEST_F(TestSymbolGenerator, MatchMergeExpandLabel) { TEST_F(TestSymbolGenerator, MatchMergeExpandLabel) {
@ -669,7 +667,7 @@ TEST_F(TestSymbolGenerator, MatchMergeExpandLabel) {
MATCH(PATTERN(NODE("n"))), MATCH(PATTERN(NODE("n"))),
MERGE(PATTERN(NODE("m"), EDGE("r", EdgeAtom::Direction::OUT, {r_type}), MERGE(PATTERN(NODE("m"), EDGE("r", EdgeAtom::Direction::OUT, {r_type}),
NODE("n", label))))); NODE("n", label)))));
EXPECT_THROW(query->Accept(symbol_generator), SemanticException); EXPECT_THROW(query::MakeSymbolTable(query), SemanticException);
} }
TEST_F(TestSymbolGenerator, MatchEdgeWithIdentifierInProperty) { TEST_F(TestSymbolGenerator, MatchEdgeWithIdentifierInProperty) {
@ -681,7 +679,7 @@ TEST_F(TestSymbolGenerator, MatchEdgeWithIdentifierInProperty) {
auto node_n = NODE("n"); auto node_n = NODE("n");
auto query = auto query =
QUERY(SINGLE_QUERY(MATCH(PATTERN(node_n, edge, NODE("m"))), RETURN("r"))); QUERY(SINGLE_QUERY(MATCH(PATTERN(node_n, edge, NODE("m"))), RETURN("r")));
query->Accept(symbol_generator); auto symbol_table = query::MakeSymbolTable(query);
// Symbols for pattern, `n`, `r`, `m` and implicit in RETURN `r AS r` // Symbols for pattern, `n`, `r`, `m` and implicit in RETURN `r AS r`
EXPECT_EQ(symbol_table.max_position(), 5); EXPECT_EQ(symbol_table.max_position(), 5);
auto n = symbol_table.at(*node_n->identifier_); auto n = symbol_table.at(*node_n->identifier_);
@ -698,7 +696,7 @@ TEST_F(TestSymbolGenerator, MatchVariablePathUsingIdentifier) {
auto query = QUERY( auto query = QUERY(
SINGLE_QUERY(MATCH(PATTERN(NODE("n"), edge, NODE("m")), PATTERN(node_l)), SINGLE_QUERY(MATCH(PATTERN(NODE("n"), edge, NODE("m")), PATTERN(node_l)),
RETURN("r"))); RETURN("r")));
query->Accept(symbol_generator); auto symbol_table = query::MakeSymbolTable(query);
// Symbols for pattern * 2, `n`, `r`, inner_node, inner_edge, `m`, `l` and // Symbols for pattern * 2, `n`, `r`, inner_node, inner_edge, `m`, `l` and
// implicit in RETURN `r AS r` // implicit in RETURN `r AS r`
EXPECT_EQ(symbol_table.max_position(), 9); EXPECT_EQ(symbol_table.max_position(), 9);
@ -717,7 +715,7 @@ TEST_F(TestSymbolGenerator, MatchVariablePathUsingUnboundIdentifier) {
auto node_l = NODE("l"); auto node_l = NODE("l");
auto query = QUERY(SINGLE_QUERY(MATCH(PATTERN(NODE("n"), edge, NODE("m"))), auto query = QUERY(SINGLE_QUERY(MATCH(PATTERN(NODE("n"), edge, NODE("m"))),
MATCH(PATTERN(node_l)), RETURN("r"))); MATCH(PATTERN(node_l)), RETURN("r")));
EXPECT_THROW(query->Accept(symbol_generator), SemanticException); EXPECT_THROW(query::MakeSymbolTable(query), SemanticException);
} }
TEST_F(TestSymbolGenerator, CreateVariablePath) { TEST_F(TestSymbolGenerator, CreateVariablePath) {
@ -726,7 +724,7 @@ TEST_F(TestSymbolGenerator, CreateVariablePath) {
auto edge = auto edge =
EDGE_VARIABLE("r", EdgeAtom::Type::DEPTH_FIRST, EdgeAtom::Direction::OUT); EDGE_VARIABLE("r", EdgeAtom::Type::DEPTH_FIRST, EdgeAtom::Direction::OUT);
auto query = QUERY(SINGLE_QUERY(CREATE(PATTERN(NODE("n"), edge, NODE("m"))))); auto query = QUERY(SINGLE_QUERY(CREATE(PATTERN(NODE("n"), edge, NODE("m")))));
EXPECT_THROW(query->Accept(symbol_generator), SemanticException); EXPECT_THROW(query::MakeSymbolTable(query), SemanticException);
} }
TEST_F(TestSymbolGenerator, MergeVariablePath) { TEST_F(TestSymbolGenerator, MergeVariablePath) {
@ -735,7 +733,7 @@ TEST_F(TestSymbolGenerator, MergeVariablePath) {
auto edge = auto edge =
EDGE_VARIABLE("r", EdgeAtom::Type::DEPTH_FIRST, EdgeAtom::Direction::OUT); EDGE_VARIABLE("r", EdgeAtom::Type::DEPTH_FIRST, EdgeAtom::Direction::OUT);
auto query = QUERY(SINGLE_QUERY(MERGE(PATTERN(NODE("n"), edge, NODE("m"))))); auto query = QUERY(SINGLE_QUERY(MERGE(PATTERN(NODE("n"), edge, NODE("m")))));
EXPECT_THROW(query->Accept(symbol_generator), SemanticException); EXPECT_THROW(query::MakeSymbolTable(query), SemanticException);
} }
TEST_F(TestSymbolGenerator, RedeclareVariablePath) { TEST_F(TestSymbolGenerator, RedeclareVariablePath) {
@ -747,7 +745,7 @@ TEST_F(TestSymbolGenerator, RedeclareVariablePath) {
EDGE_VARIABLE("n", EdgeAtom::Type::DEPTH_FIRST, EdgeAtom::Direction::OUT); EDGE_VARIABLE("n", EdgeAtom::Type::DEPTH_FIRST, EdgeAtom::Direction::OUT);
auto query = QUERY( auto query = QUERY(
SINGLE_QUERY(MATCH(PATTERN(NODE("n"), edge, NODE("m"))), RETURN("n"))); SINGLE_QUERY(MATCH(PATTERN(NODE("n"), edge, NODE("m"))), RETURN("n")));
EXPECT_THROW(query->Accept(symbol_generator), RedeclareVariableError); EXPECT_THROW(query::MakeSymbolTable(query), RedeclareVariableError);
} }
TEST_F(TestSymbolGenerator, VariablePathSameIdentifier) { TEST_F(TestSymbolGenerator, VariablePathSameIdentifier) {
@ -760,7 +758,7 @@ TEST_F(TestSymbolGenerator, VariablePathSameIdentifier) {
edge->lower_bound_ = PROPERTY_LOOKUP("r", prop); edge->lower_bound_ = PROPERTY_LOOKUP("r", prop);
auto query = QUERY( auto query = QUERY(
SINGLE_QUERY(MATCH(PATTERN(NODE("n"), edge, NODE("m"))), RETURN("r"))); SINGLE_QUERY(MATCH(PATTERN(NODE("n"), edge, NODE("m"))), RETURN("r")));
EXPECT_THROW(query->Accept(symbol_generator), UnboundVariableError); EXPECT_THROW(query::MakeSymbolTable(query), UnboundVariableError);
} }
TEST_F(TestSymbolGenerator, MatchPropertySameIdentifier) { TEST_F(TestSymbolGenerator, MatchPropertySameIdentifier) {
@ -772,7 +770,7 @@ TEST_F(TestSymbolGenerator, MatchPropertySameIdentifier) {
auto n_prop = PROPERTY_LOOKUP("n", prop.second); auto n_prop = PROPERTY_LOOKUP("n", prop.second);
node_n->properties_[prop] = n_prop; node_n->properties_[prop] = n_prop;
auto query = QUERY(SINGLE_QUERY(MATCH(PATTERN(node_n)), RETURN("n"))); auto query = QUERY(SINGLE_QUERY(MATCH(PATTERN(node_n)), RETURN("n")));
query->Accept(symbol_generator); auto symbol_table = query::MakeSymbolTable(query);
auto n = symbol_table.at(*node_n->identifier_); auto n = symbol_table.at(*node_n->identifier_);
EXPECT_EQ(n, symbol_table.at(*n_prop->expression_)); EXPECT_EQ(n, symbol_table.at(*n_prop->expression_));
} }
@ -787,7 +785,7 @@ TEST_F(TestSymbolGenerator, WithReturnAll) {
auto *ret_x = IDENT("x"); auto *ret_x = IDENT("x");
auto query = QUERY(SINGLE_QUERY(WITH(LITERAL(42), with_as_x), auto query = QUERY(SINGLE_QUERY(WITH(LITERAL(42), with_as_x),
RETURN(all, ret_as_x, ret_x, AS("y")))); RETURN(all, ret_as_x, ret_x, AS("y"))));
query->Accept(symbol_generator); auto symbol_table = query::MakeSymbolTable(query);
// Symbols for `WITH .. AS x`, `ALL(x ...)`, `ALL(...) AS x` and `AS y`. // Symbols for `WITH .. AS x`, `ALL(x ...)`, `ALL(...) AS x` and `AS y`.
EXPECT_EQ(symbol_table.max_position(), 4); EXPECT_EQ(symbol_table.max_position(), 4);
// Check `WITH .. AS x` is the same as `[x]` and `RETURN ... x AS y` // Check `WITH .. AS x` is the same as `[x]` and `RETURN ... x AS y`
@ -810,7 +808,7 @@ TEST_F(TestSymbolGenerator, WithReturnSingle) {
auto *ret_x = IDENT("x"); auto *ret_x = IDENT("x");
auto query = QUERY(SINGLE_QUERY(WITH(LITERAL(42), with_as_x), auto query = QUERY(SINGLE_QUERY(WITH(LITERAL(42), with_as_x),
RETURN(single, ret_as_x, ret_x, AS("y")))); RETURN(single, ret_as_x, ret_x, AS("y"))));
query->Accept(symbol_generator); auto symbol_table = query::MakeSymbolTable(query);
// Symbols for `WITH .. AS x`, `SINGLE(x ...)`, `SINGLE(...) AS x` and `AS y`. // Symbols for `WITH .. AS x`, `SINGLE(x ...)`, `SINGLE(...) AS x` and `AS y`.
EXPECT_EQ(symbol_table.max_position(), 4); EXPECT_EQ(symbol_table.max_position(), 4);
// Check `WITH .. AS x` is the same as `[x]` and `RETURN ... x AS y` // Check `WITH .. AS x` is the same as `[x]` and `RETURN ... x AS y`
@ -836,7 +834,7 @@ TEST_F(TestSymbolGenerator, WithReturnReduce) {
auto *ret_as_y = AS("y"); auto *ret_as_y = AS("y");
auto query = QUERY(SINGLE_QUERY(WITH(LITERAL(42), with_as_x), auto query = QUERY(SINGLE_QUERY(WITH(LITERAL(42), with_as_x),
RETURN(reduce, ret_as_x, ret_x, ret_as_y))); RETURN(reduce, ret_as_x, ret_x, ret_as_y)));
query->Accept(symbol_generator); auto symbol_table = query::MakeSymbolTable(query);
// Symbols for `WITH .. AS x`, `REDUCE(y, x ...)`, `REDUCE(...) AS x` and `AS // Symbols for `WITH .. AS x`, `REDUCE(y, x ...)`, `REDUCE(...) AS x` and `AS
// y`. // y`.
EXPECT_EQ(symbol_table.max_position(), 5); EXPECT_EQ(symbol_table.max_position(), 5);
@ -864,7 +862,7 @@ TEST_F(TestSymbolGenerator, WithReturnExtract) {
auto query = QUERY( auto query = QUERY(
SINGLE_QUERY(WITH(LIST(LITERAL(1), LITERAL(2), LITERAL(3)), with_as_x), SINGLE_QUERY(WITH(LIST(LITERAL(1), LITERAL(2), LITERAL(3)), with_as_x),
RETURN(extract, ret_as_x, ret_x, ret_as_y))); RETURN(extract, ret_as_x, ret_x, ret_as_y)));
query->Accept(symbol_generator); auto symbol_table = query::MakeSymbolTable(query);
// Symbols for `WITH .. AS x`, `EXTRACT(x ...)`, `EXTRACT(...) AS x` and // Symbols for `WITH .. AS x`, `EXTRACT(x ...)`, `EXTRACT(...) AS x` and
// `AS y`. // `AS y`.
EXPECT_EQ(symbol_table.max_position(), 4); EXPECT_EQ(symbol_table.max_position(), 4);
@ -895,7 +893,7 @@ TEST_F(TestSymbolGenerator, MatchBfsReturn) {
auto *ret_r = IDENT("r"); auto *ret_r = IDENT("r");
auto *query = QUERY(SINGLE_QUERY(MATCH(PATTERN(node_n, bfs, NODE("m"))), auto *query = QUERY(SINGLE_QUERY(MATCH(PATTERN(node_n, bfs, NODE("m"))),
RETURN(ret_r, AS("r")))); RETURN(ret_r, AS("r"))));
query->Accept(symbol_generator); auto symbol_table = query::MakeSymbolTable(query);
// Symbols for pattern, `n`, `[r]`, `r|`, `n|`, `m` and `AS r`. // Symbols for pattern, `n`, `[r]`, `r|`, `n|`, `m` and `AS r`.
EXPECT_EQ(symbol_table.max_position(), 7); EXPECT_EQ(symbol_table.max_position(), 7);
EXPECT_EQ(symbol_table.at(*ret_r), symbol_table.at(*bfs->identifier_)); EXPECT_EQ(symbol_table.at(*ret_r), symbol_table.at(*bfs->identifier_));
@ -921,7 +919,7 @@ TEST_F(TestSymbolGenerator, MatchBfsUsesEdgeSymbolError) {
bfs->upper_bound_ = LITERAL(10); bfs->upper_bound_ = LITERAL(10);
auto *query = QUERY( auto *query = QUERY(
SINGLE_QUERY(MATCH(PATTERN(NODE("n"), bfs, NODE("m"))), RETURN("r"))); SINGLE_QUERY(MATCH(PATTERN(NODE("n"), bfs, NODE("m"))), RETURN("r")));
EXPECT_THROW(query->Accept(symbol_generator), UnboundVariableError); EXPECT_THROW(query::MakeSymbolTable(query), UnboundVariableError);
} }
TEST_F(TestSymbolGenerator, MatchBfsUsesPreviousOuterSymbol) { TEST_F(TestSymbolGenerator, MatchBfsUsesPreviousOuterSymbol) {
@ -935,7 +933,7 @@ TEST_F(TestSymbolGenerator, MatchBfsUsesPreviousOuterSymbol) {
bfs->upper_bound_ = LITERAL(10); bfs->upper_bound_ = LITERAL(10);
auto *query = auto *query =
QUERY(SINGLE_QUERY(MATCH(PATTERN(node_a, bfs, NODE("m"))), RETURN("r"))); QUERY(SINGLE_QUERY(MATCH(PATTERN(node_a, bfs, NODE("m"))), RETURN("r")));
query->Accept(symbol_generator); auto symbol_table = query::MakeSymbolTable(query);
EXPECT_EQ(symbol_table.at(*node_a->identifier_), EXPECT_EQ(symbol_table.at(*node_a->identifier_),
symbol_table.at(*bfs->filter_lambda_.expression)); symbol_table.at(*bfs->filter_lambda_.expression));
} }
@ -950,7 +948,7 @@ TEST_F(TestSymbolGenerator, MatchBfsUsesLaterSymbolError) {
bfs->upper_bound_ = LITERAL(10); bfs->upper_bound_ = LITERAL(10);
auto *query = QUERY( auto *query = QUERY(
SINGLE_QUERY(MATCH(PATTERN(NODE("n"), bfs, NODE("m"))), RETURN("r"))); SINGLE_QUERY(MATCH(PATTERN(NODE("n"), bfs, NODE("m"))), RETURN("r")));
EXPECT_THROW(query->Accept(symbol_generator), UnboundVariableError); EXPECT_THROW(query::MakeSymbolTable(query), UnboundVariableError);
} }
TEST_F(TestSymbolGenerator, MatchVariableLambdaSymbols) { TEST_F(TestSymbolGenerator, MatchVariableLambdaSymbols) {
@ -968,7 +966,7 @@ TEST_F(TestSymbolGenerator, MatchVariableLambdaSymbols) {
storage.Create<NodeAtom>(storage.Create<Identifier>("anon_end", false)); storage.Create<NodeAtom>(storage.Create<Identifier>("anon_end", false));
auto query = QUERY(SINGLE_QUERY(MATCH(PATTERN(node, edge, end_node)), auto query = QUERY(SINGLE_QUERY(MATCH(PATTERN(node, edge, end_node)),
RETURN(LITERAL(42), AS("res")))); RETURN(LITERAL(42), AS("res"))));
query->Accept(symbol_generator); auto symbol_table = query::MakeSymbolTable(query);
// Symbols for `anon_n`, `anon_r`, `anon_inner_e`, `anon_inner_n`, `anon_end` // Symbols for `anon_n`, `anon_r`, `anon_inner_e`, `anon_inner_n`, `anon_end`
// `AS res` and the auto-generated path name symbol. // `AS res` and the auto-generated path name symbol.
EXPECT_EQ(symbol_table.max_position(), 7); EXPECT_EQ(symbol_table.max_position(), 7);
@ -1008,7 +1006,7 @@ TEST_F(TestSymbolGenerator, MatchWShortestReturn) {
auto *ret_r = IDENT("r"); auto *ret_r = IDENT("r");
auto *query = QUERY(SINGLE_QUERY(MATCH(PATTERN(node_n, shortest, NODE("m"))), auto *query = QUERY(SINGLE_QUERY(MATCH(PATTERN(node_n, shortest, NODE("m"))),
RETURN(ret_r, AS("r")))); RETURN(ret_r, AS("r"))));
query->Accept(symbol_generator); auto symbol_table = query::MakeSymbolTable(query);
// Symbols for pattern, `n`, `[r]`, `total_weight`, (`r|`, `n|`)x2, `m` and // Symbols for pattern, `n`, `[r]`, `total_weight`, (`r|`, `n|`)x2, `m` and
// `AS r`. // `AS r`.
EXPECT_EQ(symbol_table.max_position(), 10); EXPECT_EQ(symbol_table.max_position(), 10);
@ -1035,7 +1033,7 @@ TEST_F(TestSymbolGenerator, MatchUnionSymbols) {
// RETURN 5 as X UNION RETURN 6 AS x // RETURN 5 as X UNION RETURN 6 AS x
auto query = QUERY(SINGLE_QUERY(RETURN(LITERAL(5), AS("X"))), auto query = QUERY(SINGLE_QUERY(RETURN(LITERAL(5), AS("X"))),
UNION(SINGLE_QUERY(RETURN(LITERAL(6), AS("X"))))); UNION(SINGLE_QUERY(RETURN(LITERAL(6), AS("X")))));
query->Accept(symbol_generator); auto symbol_table = query::MakeSymbolTable(query);
EXPECT_EQ(symbol_table.max_position(), 3); EXPECT_EQ(symbol_table.max_position(), 3);
} }
@ -1044,7 +1042,7 @@ TEST_F(TestSymbolGenerator, MatchUnionMultipleSymbols) {
auto query = QUERY( auto query = QUERY(
SINGLE_QUERY(RETURN(LITERAL(5), AS("X"), LITERAL(6), AS("Y"))), SINGLE_QUERY(RETURN(LITERAL(5), AS("X"), LITERAL(6), AS("Y"))),
UNION(SINGLE_QUERY(RETURN(LITERAL(5), AS("Y"), LITERAL(6), AS("X"))))); UNION(SINGLE_QUERY(RETURN(LITERAL(5), AS("Y"), LITERAL(6), AS("X")))));
query->Accept(symbol_generator); auto symbol_table = query::MakeSymbolTable(query);
EXPECT_EQ(symbol_table.max_position(), 6); EXPECT_EQ(symbol_table.max_position(), 6);
} }
@ -1052,7 +1050,7 @@ TEST_F(TestSymbolGenerator, MatchUnionAllSymbols) {
// RETURN 5 as X UNION ALL RETURN 6 AS x // RETURN 5 as X UNION ALL RETURN 6 AS x
auto query = QUERY(SINGLE_QUERY(RETURN(LITERAL(5), AS("X"))), auto query = QUERY(SINGLE_QUERY(RETURN(LITERAL(5), AS("X"))),
UNION_ALL(SINGLE_QUERY(RETURN(LITERAL(6), AS("X"))))); UNION_ALL(SINGLE_QUERY(RETURN(LITERAL(6), AS("X")))));
query->Accept(symbol_generator); auto symbol_table = query::MakeSymbolTable(query);
EXPECT_EQ(symbol_table.max_position(), 3); EXPECT_EQ(symbol_table.max_position(), 3);
} }
@ -1062,7 +1060,7 @@ TEST_F(TestSymbolGenerator, MatchUnionAllMultipleSymbols) {
SINGLE_QUERY(RETURN(LITERAL(5), AS("X"), LITERAL(6), AS("Y"))), SINGLE_QUERY(RETURN(LITERAL(5), AS("X"), LITERAL(6), AS("Y"))),
UNION_ALL( UNION_ALL(
SINGLE_QUERY(RETURN(LITERAL(5), AS("Y"), LITERAL(6), AS("X"))))); SINGLE_QUERY(RETURN(LITERAL(5), AS("Y"), LITERAL(6), AS("X")))));
query->Accept(symbol_generator); auto symbol_table = query::MakeSymbolTable(query);
EXPECT_EQ(symbol_table.max_position(), 6); EXPECT_EQ(symbol_table.max_position(), 6);
} }
@ -1073,7 +1071,7 @@ TEST_F(TestSymbolGenerator, MatchUnionReturnAllSymbols) {
auto query = QUERY( auto query = QUERY(
SINGLE_QUERY(WITH(LITERAL(1), AS("X"), LITERAL(2), AS("Y")), ret), SINGLE_QUERY(WITH(LITERAL(1), AS("X"), LITERAL(2), AS("Y")), ret),
UNION(SINGLE_QUERY(RETURN(LITERAL(3), AS("X"), LITERAL(4), AS("Y"))))); UNION(SINGLE_QUERY(RETURN(LITERAL(3), AS("X"), LITERAL(4), AS("Y")))));
query->Accept(symbol_generator); auto symbol_table = query::MakeSymbolTable(query);
EXPECT_EQ(symbol_table.max_position(), 6); EXPECT_EQ(symbol_table.max_position(), 6);
} }
@ -1083,7 +1081,7 @@ TEST_F(TestSymbolGenerator, MatchUnionReturnSymbols) {
SINGLE_QUERY(WITH(LITERAL(1), AS("X"), LITERAL(2), AS("Y")), SINGLE_QUERY(WITH(LITERAL(1), AS("X"), LITERAL(2), AS("Y")),
RETURN("Y", "X")), RETURN("Y", "X")),
UNION(SINGLE_QUERY(RETURN(LITERAL(3), AS("X"), LITERAL(4), AS("Y"))))); UNION(SINGLE_QUERY(RETURN(LITERAL(3), AS("X"), LITERAL(4), AS("Y")))));
query->Accept(symbol_generator); auto symbol_table = query::MakeSymbolTable(query);
EXPECT_EQ(symbol_table.max_position(), 8); EXPECT_EQ(symbol_table.max_position(), 8);
} }
@ -1094,7 +1092,7 @@ TEST_F(TestSymbolGenerator, MatchUnionParameterNameThrowSemanticExpcetion) {
auto query = QUERY( auto query = QUERY(
SINGLE_QUERY(WITH(LITERAL(1), AS("X"), LITERAL(2), AS("Y")), ret), SINGLE_QUERY(WITH(LITERAL(1), AS("X"), LITERAL(2), AS("Y")), ret),
UNION(SINGLE_QUERY(RETURN(LITERAL(3), AS("Z"), LITERAL(4), AS("Y"))))); UNION(SINGLE_QUERY(RETURN(LITERAL(3), AS("Z"), LITERAL(4), AS("Y")))));
EXPECT_THROW(query->Accept(symbol_generator), SemanticException); EXPECT_THROW(query::MakeSymbolTable(query), SemanticException);
} }
TEST_F(TestSymbolGenerator, MatchUnionParameterNumberThrowSemanticExpcetion) { TEST_F(TestSymbolGenerator, MatchUnionParameterNumberThrowSemanticExpcetion) {
@ -1104,7 +1102,7 @@ TEST_F(TestSymbolGenerator, MatchUnionParameterNumberThrowSemanticExpcetion) {
auto query = auto query =
QUERY(SINGLE_QUERY(WITH(LITERAL(1), AS("X"), LITERAL(2), AS("Y")), ret), QUERY(SINGLE_QUERY(WITH(LITERAL(1), AS("X"), LITERAL(2), AS("Y")), ret),
UNION(SINGLE_QUERY(RETURN(LITERAL(4), AS("Y"))))); UNION(SINGLE_QUERY(RETURN(LITERAL(4), AS("Y")))));
EXPECT_THROW(query->Accept(symbol_generator), SemanticException); EXPECT_THROW(query::MakeSymbolTable(query), SemanticException);
} }
TEST_F(TestSymbolGenerator, MatchUnion) { TEST_F(TestSymbolGenerator, MatchUnion) {
@ -1115,6 +1113,6 @@ TEST_F(TestSymbolGenerator, MatchUnion) {
QUERY(SINGLE_QUERY(WITH(LITERAL(5), AS("X"), LITERAL(3), AS("Y")), ret), QUERY(SINGLE_QUERY(WITH(LITERAL(5), AS("X"), LITERAL(3), AS("Y")), ret),
UNION(SINGLE_QUERY(WITH(LITERAL(9), AS("Y"), LITERAL(4), AS("X")), UNION(SINGLE_QUERY(WITH(LITERAL(9), AS("Y"), LITERAL(4), AS("X")),
RETURN("Y", "X")))); RETURN("Y", "X"))));
query->Accept(symbol_generator); auto symbol_table = query::MakeSymbolTable(query);
EXPECT_EQ(symbol_table.max_position(), 8); EXPECT_EQ(symbol_table.max_position(), 8);
} }

View File

@ -32,13 +32,6 @@ std::ostream &operator<<(std::ostream &stream,
namespace { namespace {
auto MakeSymbolTable(query::Query &query) {
query::SymbolTable symbol_table;
query::SymbolGenerator symbol_generator(symbol_table);
query.Accept(symbol_generator);
return symbol_table;
}
void AssertRows(const std::vector<std::vector<TypedValue>> &datum, void AssertRows(const std::vector<std::vector<TypedValue>> &datum,
std::vector<std::vector<TypedValue>> expected) { std::vector<std::vector<TypedValue>> expected) {
auto row_equal = [](const auto &row1, const auto &row2) { auto row_equal = [](const auto &row1, const auto &row2) {
@ -67,7 +60,7 @@ void CheckPlansProduce(
size_t expected_plan_count, query::CypherQuery *query, AstStorage &storage, size_t expected_plan_count, query::CypherQuery *query, AstStorage &storage,
database::GraphDbAccessor &dba, database::GraphDbAccessor &dba,
std::function<void(const std::vector<std::vector<TypedValue>> &)> check) { std::function<void(const std::vector<std::vector<TypedValue>> &)> check) {
auto symbol_table = MakeSymbolTable(*query); auto symbol_table = query::MakeSymbolTable(query);
auto planning_context = auto planning_context =
MakePlanningContext(storage, symbol_table, query, dba); MakePlanningContext(storage, symbol_table, query, dba);
auto query_parts = CollectQueryParts(symbol_table, storage, query); auto query_parts = CollectQueryParts(symbol_table, storage, query);