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) {
auto vertex_counts = plan::MakeVertexCountCache(*db_accessor);
SymbolTable symbol_table;
SymbolGenerator symbol_generator(symbol_table);
query->Accept(symbol_generator);
auto symbol_table = MakeSymbolTable(query);
auto planning_context = plan::MakePlanningContext(ast_storage, symbol_table,
query, vertex_counts);

View File

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

View File

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

View File

@ -2,14 +2,39 @@
namespace query {
class PrivilegeExtractor : public HierarchicalTreeVisitor {
class PrivilegeExtractor : public QueryVisitor<void>,
public HierarchicalTreeVisitor {
public:
using HierarchicalTreeVisitor::PostVisit;
using HierarchicalTreeVisitor::PreVisit;
using HierarchicalTreeVisitor::Visit;
using QueryVisitor<void>::Visit;
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 {
AddPrivilege(AuthQuery::Privilege::CREATE);
return false;
@ -51,21 +76,6 @@ class PrivilegeExtractor : public HierarchicalTreeVisitor {
bool Visit(PrimitiveLiteral &) 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:
void AddPrivilege(AuthQuery::Privilege privilege) {
if (!utils::Contains(privileges_, privilege)) {

View File

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

View File

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

View File

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

View File

@ -52,9 +52,6 @@ class UsedSymbolsCollector : public HierarchicalTreeVisitor {
bool Visit(PrimitiveLiteral &) 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_;
const SymbolTable &symbol_table_;

View File

@ -410,21 +410,6 @@ class ReturnBodyContext : public HierarchicalTreeVisitor {
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.
// This should be used when body.all_identifiers is true, to generate
// expressions for Produce operator.

View File

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

View File

@ -444,13 +444,6 @@ query::Query *MakeAst(const std::string &query, query::AstStorage *storage,
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
// order by cost.
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 "
"queries.");
}
auto symbol_table = MakeSymbolTable(query);
auto symbol_table = query::MakeSymbolTable(query);
planning_timer.Start();
auto plans = MakeLogicalPlans(query, ast, symbol_table, interactive_db);
auto planning_time = planning_timer.Elapsed();

View File

@ -624,7 +624,7 @@ struct ExpectedDistributedPlan {
template <class TPlanner>
DistributedPlan MakeDistributedPlan(query::CypherQuery *query,
query::AstStorage &storage) {
auto symbol_table = MakeSymbolTable(*query);
auto symbol_table = query::MakeSymbolTable(query);
FakeDbAccessor dba;
auto planner = MakePlanner<TPlanner>(dba, storage, symbol_table, query);
std::atomic<int64_t> next_plan_id{0};
@ -732,7 +732,7 @@ TYPED_TEST(TestPlanner, MatchNodeReturn) {
AstStorage storage;
auto *as_n = NEXPR("n", IDENT("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;
auto planner = MakePlanner<TypeParam>(dba, storage, symbol_table, query);
ExpectPullRemote pull({symbol_table.at(*as_n)});
@ -748,7 +748,7 @@ TYPED_TEST(TestPlanner, CreateNodeReturn) {
auto ident_n = IDENT("n");
auto query =
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)});
FakeDbAccessor dba;
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 *query =
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);
ExpectPullRemote pull({symbol_table.at(*as_n)});
auto expected = ExpectDistributed(
@ -861,7 +861,7 @@ TYPED_TEST(TestPlanner, MatchPathReturn) {
MATCH(PATTERN(NODE("n"), EDGE("r", Direction::BOTH, {relationship}),
NODE("m"))),
RETURN(as_n)));
auto symbol_table = MakeSymbolTable(*query);
auto symbol_table = query::MakeSymbolTable(query);
auto planner = MakePlanner<TypeParam>(dba, storage, symbol_table, query);
ExpectPullRemote pull({symbol_table.at(*as_n)});
auto expected =
@ -883,7 +883,7 @@ TYPED_TEST(TestPlanner, MatchNamedPatternReturn) {
EDGE("r", Direction::BOTH, {relationship}),
NODE("m"))),
RETURN(as_p)));
auto symbol_table = MakeSymbolTable(*query);
auto symbol_table = query::MakeSymbolTable(query);
auto planner = MakePlanner<TypeParam>(dba, storage, symbol_table, query);
ExpectPullRemote pull({symbol_table.at(*as_p)});
auto expected = ExpectDistributed(
@ -905,7 +905,7 @@ TYPED_TEST(TestPlanner, MatchNamedPatternWithPredicateReturn) {
EDGE("r", Direction::BOTH, {relationship}),
NODE("m"))),
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);
ExpectPullRemote pull({symbol_table.at(*as_p)});
auto expected =
@ -927,7 +927,7 @@ TYPED_TEST(TestPlanner, OptionalMatchNamedPatternReturn) {
auto pattern = NAMED_PATTERN("p", node_n, edge, node_m);
auto as_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) {
return symbol_table.at(*ast_node->identifier_);
};
@ -955,7 +955,7 @@ TYPED_TEST(TestPlanner, MatchWhereReturn) {
auto *query = QUERY(SINGLE_QUERY(
MATCH(PATTERN(NODE("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);
ExpectPullRemote pull({symbol_table.at(*as_n)});
auto expected = ExpectDistributed(
@ -1023,7 +1023,7 @@ TYPED_TEST(TestPlanner, MultiMatch) {
auto *query = QUERY(SINGLE_QUERY(
MATCH(PATTERN(node_n, edge_r, node_m)),
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;
auto planner = MakePlanner<TypeParam>(dba, storage, symbol_table, query);
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)));
// Similar to MatchMultiPatternSameStart, we expect only Expand from second
// MATCH clause.
auto symbol_table = MakeSymbolTable(*query);
auto symbol_table = query::MakeSymbolTable(query);
FakeDbAccessor dba;
auto planner = MakePlanner<TypeParam>(dba, storage, symbol_table, query);
ExpectPullRemote pull({symbol_table.at(*as_n)});
@ -1077,7 +1077,7 @@ TYPED_TEST(TestPlanner, MatchWithReturn) {
auto *query = QUERY(SINGLE_QUERY(MATCH(PATTERN(NODE("old"))),
WITH("old", AS("new")), RETURN(as_new)));
// No accumulation since we only do reads.
auto symbol_table = MakeSymbolTable(*query);
auto symbol_table = query::MakeSymbolTable(query);
FakeDbAccessor dba;
auto planner = MakePlanner<TypeParam>(dba, storage, symbol_table, query);
ExpectPullRemote pull({symbol_table.at(*as_new)});
@ -1097,7 +1097,7 @@ TYPED_TEST(TestPlanner, MatchWithWhereReturn) {
MATCH(PATTERN(NODE("old"))), WITH("old", AS("new")),
WHERE(LESS(PROPERTY_LOOKUP("new", prop), LITERAL(42))), RETURN(as_new)));
// 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);
ExpectPullRemote pull({symbol_table.at(*as_new)});
auto expected =
@ -1136,7 +1136,7 @@ TYPED_TEST(TestPlanner, MatchReturnSum) {
auto *query = QUERY(SINGLE_QUERY(
MATCH(PATTERN(NODE("n"))), RETURN(sum, AS("sum"), n_prop2, AS("group"))));
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);
std::atomic<int64_t> next_plan_id{0};
auto distributed_plan =
@ -1176,7 +1176,7 @@ TYPED_TEST(TestPlanner, MatchReturnSkipLimit) {
auto *query =
QUERY(SINGLE_QUERY(MATCH(PATTERN(NODE("n"))),
RETURN(as_n, SKIP(LITERAL(2)), LIMIT(LITERAL(1)))));
auto symbol_table = MakeSymbolTable(*query);
auto symbol_table = query::MakeSymbolTable(query);
FakeDbAccessor dba;
auto planner = MakePlanner<TypeParam>(dba, storage, symbol_table, query);
ExpectPullRemote pull({symbol_table.at(*as_n)});
@ -1194,7 +1194,7 @@ TYPED_TEST(TestPlanner, CreateWithSkipReturnLimit) {
auto query = QUERY(SINGLE_QUERY(CREATE(PATTERN(NODE("n"))),
WITH(ident_n, AS("m"), SKIP(LITERAL(2))),
RETURN("m", LIMIT(LITERAL(1)))));
auto symbol_table = MakeSymbolTable(*query);
auto symbol_table = query::MakeSymbolTable(query);
auto acc = ExpectAccumulate({symbol_table.at(*ident_n)});
FakeDbAccessor dba;
auto planner = MakePlanner<TypeParam>(dba, storage, symbol_table, query);
@ -1215,7 +1215,7 @@ TYPED_TEST(TestPlanner, MatchReturnOrderBy) {
auto *node_n = NODE("n");
auto ret = RETURN(as_m, ORDER_BY(PROPERTY_LOOKUP("n", prop)));
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);
ExpectPullRemoteOrderBy pull_order_by(
{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"))),
WITH(ident_n, AS("new"), ORDER_BY(new_prop, r_prop)),
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.
auto acc = ExpectAccumulate({
symbol_table.at(*ident_n), // `n` in WITH
@ -1283,7 +1283,7 @@ TYPED_TEST(TestPlanner, MatchUnwindReturn) {
SINGLE_QUERY(MATCH(PATTERN(NODE("n"))),
UNWIND(LIST(LITERAL(1), LITERAL(2), LITERAL(3)), AS("x")),
RETURN(as_n, as_x)));
auto symbol_table = MakeSymbolTable(*query);
auto symbol_table = query::MakeSymbolTable(query);
FakeDbAccessor dba;
auto planner = MakePlanner<TypeParam>(dba, storage, symbol_table, query);
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"))),
WHERE(LESS(PROPERTY_LOOKUP("n", prop), LITERAL(42))), RETURN(as_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);
ExpectPullRemote pull({symbol_table.at(*as_n)});
auto expected = ExpectDistributed(
@ -1361,7 +1361,7 @@ TYPED_TEST(TestPlanner, MatchBfs) {
auto *as_r = NEXPR("r", IDENT("r"));
auto *query = QUERY(
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)});
auto expected = ExpectDistributed(
MakeCheckers(ExpectScanAll(), ExpectDistributedExpandBfs(),
@ -1431,7 +1431,7 @@ TYPED_TEST(TestPlanner, DistributedMatchCreateReturn) {
auto *query =
QUERY(SINGLE_QUERY(MATCH(PATTERN(NODE("n"))), CREATE(PATTERN(NODE("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)});
FakeDbAccessor dba;
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}),
NODE("b"))),
RETURN("e")));
auto symbol_table = MakeSymbolTable(*query);
auto symbol_table = query::MakeSymbolTable(query);
auto left_cart =
MakeCheckers(ExpectScanAll(),
ExpectPullRemote({symbol_table.at(*node_a->identifier_)}));
@ -1480,7 +1480,7 @@ TYPED_TEST(TestPlanner, DistributedCartesianExpand) {
auto *node_c = NODE("c");
auto *query = QUERY(SINGLE_QUERY(
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 left_cart = MakeCheckers(ExpectScanAll(), ExpectPullRemote({sym_a}));
auto sym_b = symbol_table.at(*node_b->identifier_);
@ -1506,7 +1506,7 @@ TYPED_TEST(TestPlanner, DistributedCartesianExpandToExisting) {
auto *query = QUERY(SINGLE_QUERY(
MATCH(PATTERN(node_a), 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 left_cart = MakeCheckers(ExpectScanAll(), ExpectPullRemote({sym_a}));
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),
PATTERN(NODE("a"), EDGE("e"), NODE("b"))),
RETURN("e")));
auto symbol_table = MakeSymbolTable(*query);
auto symbol_table = query::MakeSymbolTable(query);
auto sym_a = symbol_table.at(*node_a->identifier_);
auto left_cart = MakeCheckers(ExpectScanAll(), ExpectPullRemote({sym_a}));
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"))),
EQ(IDENT("c"), IDENT("b")))),
RETURN("c")));
auto symbol_table = MakeSymbolTable(*query);
auto symbol_table = query::MakeSymbolTable(query);
auto sym_a = symbol_table.at(*node_a->identifier_);
auto sym_b = symbol_table.at(*node_b->identifier_);
auto sym_c = symbol_table.at(*node_c->identifier_);
@ -1588,7 +1588,7 @@ TYPED_TEST(TestPlanner, DistributedCartesianIndexedScanByProperty) {
auto *query = QUERY(SINGLE_QUERY(
MATCH(PATTERN(node_a), PATTERN(node_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_b = symbol_table.at(*node_b->identifier_);
auto left_cart = MakeCheckers(ExpectScanAll(), ExpectPullRemote({sym_a}));
@ -1618,7 +1618,7 @@ TYPED_TEST(TestPlanner, DistributedCartesianIndexedScanByLowerBound) {
auto *query = QUERY(SINGLE_QUERY(
MATCH(PATTERN(node_a), PATTERN(node_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_b = symbol_table.at(*node_b->identifier_);
auto left_cart = MakeCheckers(ExpectScanAll(), ExpectPullRemote({sym_a}));
@ -1648,7 +1648,7 @@ TYPED_TEST(TestPlanner, DistributedCartesianIndexedScanByUpperBound) {
auto *query = QUERY(SINGLE_QUERY(
MATCH(PATTERN(node_a), PATTERN(node_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_b = symbol_table.at(*node_b->identifier_);
auto left_cart = MakeCheckers(ExpectScanAll(), ExpectPullRemote({sym_a}));
@ -1792,7 +1792,7 @@ TYPED_TEST(TestPlanner, DistributedCartesianProduce) {
auto *query = QUERY(
SINGLE_QUERY(MATCH(PATTERN(NODE("a"))), with_a, MATCH(PATTERN(node_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 left_cart =
MakeCheckers(ExpectScanAll(), ExpectProduce(), ExpectPullRemote({sym_a}));
@ -1815,7 +1815,7 @@ TYPED_TEST(TestPlanner, DistributedCartesianUnwind) {
auto *node_b = NODE("b");
auto *query = QUERY(SINGLE_QUERY(MATCH(PATTERN(node_a), PATTERN(node_b)),
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 left_cart = MakeCheckers(ExpectScanAll(), ExpectPullRemote({sym_a}));
auto sym_b = symbol_table.at(*node_b->identifier_);
@ -1837,7 +1837,7 @@ TYPED_TEST(TestPlanner, DistributedCartesianMatchCreateNode) {
auto *query = QUERY(SINGLE_QUERY(
MATCH(PATTERN(NODE("a"))), CREATE(PATTERN(node_b)), WITH("b"),
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 left_cart =
MakeCheckers(ExpectScanAll(), ExpectDistributedCreateNode(),
@ -1861,7 +1861,7 @@ TYPED_TEST(TestPlanner, DistributedCartesianCreateNode) {
auto *node_b = NODE("b");
auto *query = QUERY(SINGLE_QUERY(CREATE(PATTERN(node_a)), WITH("a"),
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 left_cart = MakeCheckers(ExpectDistributedCreateNode(true),
ExpectSynchronize(true), ExpectProduce());
@ -1886,7 +1886,7 @@ TYPED_TEST(TestPlanner, DistributedOptionalExpand) {
auto *query = QUERY(
SINGLE_QUERY(MATCH(PATTERN(node_n)),
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]);
std::list<BaseOpChecker *> optional{new ExpectDistributedExpand()};
auto expected = ExpectDistributed(
@ -1908,7 +1908,7 @@ TYPED_TEST(TestPlanner, DistributedOptionalCartesian) {
auto *query = QUERY(SINGLE_QUERY(
MATCH(PATTERN(node_a)), OPTIONAL_MATCH(PATTERN(node_b), PATTERN(node_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_b = symbol_table.at(*node_b->identifier_);
auto sym_c = symbol_table.at(*node_c->identifier_);
@ -1941,7 +1941,7 @@ TYPED_TEST(TestPlanner, DistributedCartesianTransitiveDependency) {
auto *edge_b = EDGE("b");
auto *query = QUERY(SINGLE_QUERY(
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_b = symbol_table.at(*edge_b->identifier_);
auto sym_n = symbol_table.at(*node_n->identifier_);
@ -1979,7 +1979,7 @@ TYPED_TEST(TestPlanner, DistributedOptionalScanExpandExisting) {
auto *query = QUERY(SINGLE_QUERY(
MATCH(PATTERN(node_a)),
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_b = symbol_table.at(*node_b->identifier_);
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>
auto CheckPlan(query::CypherQuery *query, AstStorage &storage,
TChecker... checker) {
auto symbol_table = MakeSymbolTable(*query);
auto symbol_table = query::MakeSymbolTable(query);
FakeDbAccessor dba;
auto planner = MakePlanner<TPlanner>(dba, storage, symbol_table, query);
CheckPlan(planner.plan(), symbol_table, checker...);
@ -84,7 +84,7 @@ TYPED_TEST(TestPlanner, MatchNodeReturn) {
AstStorage storage;
auto *as_n = NEXPR("n", IDENT("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;
auto planner = MakePlanner<TypeParam>(dba, storage, symbol_table, query);
CheckPlan(planner.plan(), symbol_table, ExpectScanAll(), ExpectProduce());
@ -96,7 +96,7 @@ TYPED_TEST(TestPlanner, CreateNodeReturn) {
auto ident_n = IDENT("n");
auto query =
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)});
FakeDbAccessor dba;
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 *query =
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);
CheckPlan(planner.plan(), symbol_table, ExpectScanAllByLabel(),
ExpectProduce());
@ -182,7 +182,7 @@ TYPED_TEST(TestPlanner, MatchPathReturn) {
MATCH(PATTERN(NODE("n"), EDGE("r", Direction::BOTH, {relationship}),
NODE("m"))),
RETURN(as_n)));
auto symbol_table = MakeSymbolTable(*query);
auto symbol_table = query::MakeSymbolTable(query);
auto planner = MakePlanner<TypeParam>(dba, storage, symbol_table, query);
CheckPlan(planner.plan(), symbol_table, ExpectScanAll(), ExpectExpand(),
ExpectProduce());
@ -199,7 +199,7 @@ TYPED_TEST(TestPlanner, MatchNamedPatternReturn) {
EDGE("r", Direction::BOTH, {relationship}),
NODE("m"))),
RETURN(as_p)));
auto symbol_table = MakeSymbolTable(*query);
auto symbol_table = query::MakeSymbolTable(query);
auto planner = MakePlanner<TypeParam>(dba, storage, symbol_table, query);
CheckPlan(planner.plan(), symbol_table, ExpectScanAll(), ExpectExpand(),
ExpectConstructNamedPath(), ExpectProduce());
@ -216,7 +216,7 @@ TYPED_TEST(TestPlanner, MatchNamedPatternWithPredicateReturn) {
EDGE("r", Direction::BOTH, {relationship}),
NODE("m"))),
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);
CheckPlan(planner.plan(), symbol_table, ExpectScanAll(), ExpectExpand(),
ExpectConstructNamedPath(), ExpectFilter(), ExpectProduce());
@ -231,7 +231,7 @@ TYPED_TEST(TestPlanner, OptionalMatchNamedPatternReturn) {
auto pattern = NAMED_PATTERN("p", node_n, edge, node_m);
auto as_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) {
return symbol_table.at(*ast_node->identifier_);
};
@ -254,7 +254,7 @@ TYPED_TEST(TestPlanner, MatchWhereReturn) {
auto *query = QUERY(SINGLE_QUERY(
MATCH(PATTERN(NODE("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);
CheckPlan(planner.plan(), symbol_table, ExpectScanAll(), ExpectFilter(),
ExpectProduce());
@ -350,7 +350,7 @@ TYPED_TEST(TestPlanner, MultiMatch) {
auto *query = QUERY(SINGLE_QUERY(
MATCH(PATTERN(node_n, edge_r, node_m)),
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;
auto planner = MakePlanner<TypeParam>(dba, storage, symbol_table, query);
// 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)));
// Similar to MatchMultiPatternSameStart, we expect only Expand from second
// MATCH clause.
auto symbol_table = MakeSymbolTable(*query);
auto symbol_table = query::MakeSymbolTable(query);
FakeDbAccessor dba;
auto planner = MakePlanner<TypeParam>(dba, storage, symbol_table, query);
CheckPlan(planner.plan(), symbol_table, ExpectScanAll(), ExpectExpand(),
@ -383,7 +383,7 @@ TYPED_TEST(TestPlanner, MatchWithReturn) {
auto *query = QUERY(SINGLE_QUERY(MATCH(PATTERN(NODE("old"))),
WITH("old", AS("new")), RETURN(as_new)));
// No accumulation since we only do reads.
auto symbol_table = MakeSymbolTable(*query);
auto symbol_table = query::MakeSymbolTable(query);
FakeDbAccessor dba;
auto planner = MakePlanner<TypeParam>(dba, storage, symbol_table, query);
CheckPlan(planner.plan(), symbol_table, ExpectScanAll(), ExpectProduce(),
@ -400,7 +400,7 @@ TYPED_TEST(TestPlanner, MatchWithWhereReturn) {
MATCH(PATTERN(NODE("old"))), WITH("old", AS("new")),
WHERE(LESS(PROPERTY_LOOKUP("new", prop), LITERAL(42))), RETURN(as_new)));
// 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);
CheckPlan(planner.plan(), symbol_table, ExpectScanAll(), ExpectProduce(),
ExpectFilter(), ExpectProduce());
@ -446,7 +446,7 @@ TYPED_TEST(TestPlanner, MatchReturnSum) {
auto *query = QUERY(SINGLE_QUERY(
MATCH(PATTERN(NODE("n"))), RETURN(sum, AS("sum"), n_prop2, AS("group"))));
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);
CheckPlan(planner.plan(), symbol_table, ExpectScanAll(), aggr,
ExpectProduce());
@ -461,7 +461,7 @@ TYPED_TEST(TestPlanner, CreateWithSum) {
auto sum = SUM(n_prop);
auto query =
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 aggr = ExpectAggregate({sum}, {});
auto planner = MakePlanner<TypeParam>(dba, storage, symbol_table, query);
@ -491,7 +491,7 @@ TYPED_TEST(TestPlanner, MatchReturnSkipLimit) {
auto *query =
QUERY(SINGLE_QUERY(MATCH(PATTERN(NODE("n"))),
RETURN(as_n, SKIP(LITERAL(2)), LIMIT(LITERAL(1)))));
auto symbol_table = MakeSymbolTable(*query);
auto symbol_table = query::MakeSymbolTable(query);
FakeDbAccessor dba;
auto planner = MakePlanner<TypeParam>(dba, storage, symbol_table, query);
CheckPlan(planner.plan(), symbol_table, ExpectScanAll(), ExpectProduce(),
@ -505,7 +505,7 @@ TYPED_TEST(TestPlanner, CreateWithSkipReturnLimit) {
auto query = QUERY(SINGLE_QUERY(CREATE(PATTERN(NODE("n"))),
WITH(ident_n, AS("m"), SKIP(LITERAL(2))),
RETURN("m", LIMIT(LITERAL(1)))));
auto symbol_table = MakeSymbolTable(*query);
auto symbol_table = query::MakeSymbolTable(query);
auto acc = ExpectAccumulate({symbol_table.at(*ident_n)});
FakeDbAccessor dba;
auto planner = MakePlanner<TypeParam>(dba, storage, symbol_table, query);
@ -528,7 +528,7 @@ TYPED_TEST(TestPlanner, CreateReturnSumSkipLimit) {
auto query = QUERY(
SINGLE_QUERY(CREATE(PATTERN(NODE("n"))),
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 aggr = ExpectAggregate({sum}, {});
auto planner = MakePlanner<TypeParam>(dba, storage, symbol_table, query);
@ -545,7 +545,7 @@ TYPED_TEST(TestPlanner, MatchReturnOrderBy) {
auto *node_n = NODE("n");
auto ret = RETURN(as_m, ORDER_BY(PROPERTY_LOOKUP("n", prop)));
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);
CheckPlan(planner.plan(), symbol_table, ExpectScanAll(), ExpectProduce(),
ExpectOrderBy());
@ -567,7 +567,7 @@ TYPED_TEST(TestPlanner, CreateWithOrderByWhere) {
PATTERN(NODE("n"), EDGE("r", Direction::OUT, {r_type}), NODE("m"))),
WITH(ident_n, AS("new"), ORDER_BY(new_prop, r_prop)),
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.
auto acc = ExpectAccumulate({
symbol_table.at(*ident_n), // `n` in WITH
@ -610,7 +610,7 @@ TYPED_TEST(TestPlanner, MatchMerge) {
new ExpectSetProperty()};
std::list<BaseOpChecker *> on_create{new ExpectCreateExpand(),
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.
auto acc = ExpectAccumulate({symbol_table.at(*ident_n)});
auto planner = MakePlanner<TypeParam>(dba, storage, symbol_table, query);
@ -646,7 +646,7 @@ TYPED_TEST(TestPlanner, MatchUnwindReturn) {
SINGLE_QUERY(MATCH(PATTERN(NODE("n"))),
UNWIND(LIST(LITERAL(1), LITERAL(2), LITERAL(3)), AS("x")),
RETURN(as_n, as_x)));
auto symbol_table = MakeSymbolTable(*query);
auto symbol_table = query::MakeSymbolTable(query);
FakeDbAccessor dba;
auto planner = MakePlanner<TypeParam>(dba, storage, symbol_table, query);
CheckPlan(planner.plan(), symbol_table, ExpectScanAll(), ExpectUnwind(),
@ -673,7 +673,7 @@ TYPED_TEST(TestPlanner, CreateWithDistinctSumWhereReturn) {
auto query =
QUERY(SINGLE_QUERY(CREATE(PATTERN(node_n)), WITH_DISTINCT(sum, AS("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 aggr = ExpectAggregate({sum}, {});
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"))),
WHERE(LESS(PROPERTY_LOOKUP("n", prop), LITERAL(42))), RETURN(as_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);
CheckPlan(planner.plan(), symbol_table, ExpectScanAll(), ExpectFilter(),
ExpectExpand(), ExpectProduce());
@ -757,7 +757,7 @@ TYPED_TEST(TestPlanner, MatchReturnAsterisk) {
ret->body_.all_identifiers = true;
auto query =
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);
CheckPlan(planner.plan(), symbol_table, ExpectScanAll(), ExpectExpand(),
ExpectProduce());
@ -778,7 +778,7 @@ TYPED_TEST(TestPlanner, MatchReturnAsteriskSum) {
auto ret = RETURN(sum, AS("s"));
ret->body_.all_identifiers = true;
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 *produce = dynamic_cast<Produce *>(&planner.plan());
ASSERT_TRUE(produce);
@ -949,7 +949,7 @@ TYPED_TEST(TestPlanner, AtomIndexedLabelProperty) {
node->properties_[property] = lit_42;
node->properties_[not_indexed] = LITERAL(0);
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);
CheckPlan(planner.plan(), symbol_table,
ExpectScanAllByLabelPropertyValue(label, property, lit_42),
@ -973,7 +973,7 @@ TYPED_TEST(TestPlanner, AtomPropertyWhereLabelIndexing) {
storage.Create<query::LabelsTest>(
IDENT("n"), std::vector<storage::Label>{label}))),
RETURN("n")));
auto symbol_table = MakeSymbolTable(*query);
auto symbol_table = query::MakeSymbolTable(query);
auto planner = MakePlanner<TypeParam>(dba, storage, symbol_table, query);
CheckPlan(planner.plan(), symbol_table,
ExpectScanAllByLabelPropertyValue(label, property, lit_42),
@ -991,7 +991,7 @@ TYPED_TEST(TestPlanner, WhereIndexedLabelProperty) {
auto *query = QUERY(SINGLE_QUERY(
MATCH(PATTERN(NODE("n", label))),
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);
CheckPlan(planner.plan(), symbol_table,
ExpectScanAllByLabelPropertyValue(label, property, lit_42),
@ -1015,7 +1015,7 @@ TYPED_TEST(TestPlanner, BestPropertyIndexed) {
WHERE(AND(EQ(PROPERTY_LOOKUP("n", property), LITERAL(1)),
EQ(PROPERTY_LOOKUP("n", better), lit_42))),
RETURN("n")));
auto symbol_table = MakeSymbolTable(*query);
auto symbol_table = query::MakeSymbolTable(query);
auto planner = MakePlanner<TypeParam>(dba, storage, symbol_table, query);
CheckPlan(planner.plan(), symbol_table,
ExpectScanAllByLabelPropertyValue(label, better, lit_42),
@ -1040,7 +1040,7 @@ TYPED_TEST(TestPlanner, MultiPropertyIndexScan) {
WHERE(AND(EQ(PROPERTY_LOOKUP("n", prop1), lit_1),
EQ(PROPERTY_LOOKUP("m", prop2), lit_2))),
RETURN("n", "m")));
auto symbol_table = MakeSymbolTable(*query);
auto symbol_table = query::MakeSymbolTable(query);
auto planner = MakePlanner<TypeParam>(dba, storage, symbol_table, query);
CheckPlan(planner.plan(), symbol_table,
ExpectScanAllByLabelPropertyValue(label1, prop1, lit_1),
@ -1065,7 +1065,7 @@ TYPED_TEST(TestPlanner, WhereIndexedLabelPropertyRange) {
AstStorage storage;
auto *query = QUERY(SINGLE_QUERY(MATCH(PATTERN(NODE("n", label))),
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);
CheckPlan(planner.plan(), symbol_table,
ExpectScanAllByLabelPropertyRange(label, property, lower_bound,
@ -1109,7 +1109,7 @@ TYPED_TEST(TestPlanner, UnableToUsePropertyIndex) {
MATCH(PATTERN(NODE("n", label))),
WHERE(EQ(PROPERTY_LOOKUP("n", property), PROPERTY_LOOKUP("n", property))),
RETURN("n")));
auto symbol_table = MakeSymbolTable(*query);
auto symbol_table = query::MakeSymbolTable(query);
auto planner = MakePlanner<TypeParam>(dba, storage, symbol_table, query);
// We can only get ScanAllByLabelIndex, because we are comparing properties
// with those on the same node.
@ -1129,7 +1129,7 @@ TYPED_TEST(TestPlanner, SecondPropertyIndex) {
auto *query = QUERY(
SINGLE_QUERY(MATCH(PATTERN(NODE("n", label)), PATTERN(NODE("m", label))),
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);
CheckPlan(
planner.plan(), symbol_table, ExpectScanAllByLabel(),
@ -1210,7 +1210,7 @@ TYPED_TEST(TestPlanner, MatchExpandVariableTotalWeightSymbol) {
IDENT("total_weight"));
auto *query = QUERY(
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 *root = dynamic_cast<Produce *>(&planner.plan());
@ -1258,7 +1258,7 @@ TYPED_TEST(TestPlanner, MatchBfs) {
auto *as_r = NEXPR("r", IDENT("r"));
auto *query = QUERY(
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);
CheckPlan(planner.plan(), symbol_table, ExpectScanAll(), ExpectExpandBfs(),
ExpectProduce());
@ -1271,7 +1271,7 @@ TYPED_TEST(TestPlanner, MatchDoubleScanToExpandExisting) {
AstStorage storage;
auto *query = QUERY(SINGLE_QUERY(
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);
// We expect 2x ScanAll and then Expand, since we are guessing that is
// 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);
auto *query = QUERY(
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);
// We expect 1x ScanAll and then Expand, since we are guessing that
// is faster (due to high label index vertex count).
@ -1326,7 +1326,7 @@ TYPED_TEST(TestPlanner, ReturnAsteriskOmitsLambdaSymbols) {
ret->body_.all_identifiers = true;
auto *query =
QUERY(SINGLE_QUERY(MATCH(PATTERN(NODE("n"), edge, NODE("m"))), ret));
auto symbol_table = MakeSymbolTable(*query);
auto symbol_table = query::MakeSymbolTable(query);
FakeDbAccessor dba;
auto planner = MakePlanner<TypeParam>(dba, storage, symbol_table, query);
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);
}
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>
TPlanner MakePlanner(const TDbAccessor &dba, AstStorage &storage,
SymbolTable &symbol_table, CypherQuery *query) {

View File

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

View File

@ -32,13 +32,6 @@ std::ostream &operator<<(std::ostream &stream,
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,
std::vector<std::vector<TypedValue>> expected) {
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,
database::GraphDbAccessor &dba,
std::function<void(const std::vector<std::vector<TypedValue>> &)> check) {
auto symbol_table = MakeSymbolTable(*query);
auto symbol_table = query::MakeSymbolTable(query);
auto planning_context =
MakePlanningContext(storage, symbol_table, query, dba);
auto query_parts = CollectQueryParts(symbol_table, storage, query);