Remove UID tracking from AstStorage
Summary: All AST nodes had a member `uid_` that was used as a key in `SymbolTable`. It is renamed to `symbol_pos_` and it appears only in `Identifier`, `NamedExpression` and `Aggregation`, since only those types were used in `SymbolTable`. SymbolGenerator is now responsible for creating symbols in `SymbolTable` and assigning positions to AST nodes. Cloning and serialization code is now simpler since there is no need to track UIDs. Reviewers: teon.banek Reviewed By: teon.banek Subscribers: pullbot Differential Revision: https://phabricator.memgraph.io/D1836
This commit is contained in:
parent
145c81376f
commit
c03ca5f8f0
src
distributed
query
tests/unit
@ -45,26 +45,14 @@ cpp<#
|
||||
:capnp-load (lcp:capnp-load-vector "::storage::capnp::EdgeType"
|
||||
"storage::EdgeType"))
|
||||
(filter-lambda "query::plan::ExpansionLambda"
|
||||
:slk-save (lambda (member)
|
||||
#>cpp
|
||||
std::vector<int32_t> saved_ast_uids;
|
||||
slk::Save(self.${member}, builder, &saved_ast_uids);
|
||||
cpp<#)
|
||||
:slk-load (lambda (member)
|
||||
#>cpp
|
||||
std::vector<int32_t> loaded_ast_uids;
|
||||
slk::Load(&self->${member}, reader, ast_storage, &loaded_ast_uids);
|
||||
slk::Load(&self->${member}, reader, ast_storage);
|
||||
cpp<#)
|
||||
:capnp-type "DistOps.ExpansionLambda"
|
||||
:capnp-save (lambda (builder member capnp-name)
|
||||
#>cpp
|
||||
std::vector<int> saved_ast_uids;
|
||||
Save(${member}, &${builder}, &saved_ast_uids);
|
||||
cpp<#)
|
||||
:capnp-load (lambda (reader member capnp-name)
|
||||
#>cpp
|
||||
std::vector<int> loaded_ast_uids;
|
||||
Load(&${member}, ${reader}, ast_storage, &loaded_ast_uids);
|
||||
Load(&${member}, ${reader}, ast_storage);
|
||||
cpp<#))
|
||||
(symbol-table "query::SymbolTable" :capnp-type "Query.SymbolTable")
|
||||
(timestamp :int64_t)
|
||||
|
@ -30,20 +30,20 @@ cpp<#
|
||||
|
||||
(defun slk-save-ast-pointer (member)
|
||||
#>cpp
|
||||
query::SaveAstPointer(self.${member}, builder, saved_uids);
|
||||
query::SaveAstPointer(self.${member}, builder);
|
||||
cpp<#)
|
||||
|
||||
(defun slk-load-ast-pointer (type)
|
||||
(lambda (member)
|
||||
#>cpp
|
||||
self->${member} = query::LoadAstPointer<query::${type}>(storage, reader, loaded_uids);
|
||||
self->${member} = query::LoadAstPointer<query::${type}>(storage, reader);
|
||||
cpp<#))
|
||||
|
||||
(defun save-ast-pointer (builder member capnp-name)
|
||||
#>cpp
|
||||
if (${member}) {
|
||||
auto ${capnp-name}_builder = ${builder}->init${capnp-name}();
|
||||
Save(*${member}, &${capnp-name}_builder, saved_uids);
|
||||
Save(*${member}, &${capnp-name}_builder);
|
||||
}
|
||||
cpp<#)
|
||||
|
||||
@ -52,7 +52,7 @@ cpp<#
|
||||
#>cpp
|
||||
if (${reader}.has${capnp-name}()) {
|
||||
${member} = static_cast<${type}>(
|
||||
Load(storage, ${reader}.get${capnp-name}(), loaded_uids));
|
||||
Load(storage, ${reader}.get${capnp-name}()));
|
||||
} else {
|
||||
${member} = nullptr;
|
||||
}
|
||||
@ -63,7 +63,7 @@ cpp<#
|
||||
size_t size = self.${member}.size();
|
||||
slk::Save(size, builder);
|
||||
for (const auto *val : self.${member}) {
|
||||
query::SaveAstPointer(val, builder, saved_uids);
|
||||
query::SaveAstPointer(val, builder);
|
||||
}
|
||||
cpp<#)
|
||||
|
||||
@ -76,22 +76,22 @@ cpp<#
|
||||
for (size_t i = 0;
|
||||
i < size;
|
||||
++i) {
|
||||
self->${member}[i] = query::LoadAstPointer<query::${type}>(storage, reader, loaded_uids);
|
||||
self->${member}[i] = query::LoadAstPointer<query::${type}>(storage, reader);
|
||||
}
|
||||
cpp<#))
|
||||
|
||||
(defun save-ast-vector (type)
|
||||
(lcp:capnp-save-vector "capnp::Tree" type
|
||||
"[saved_uids](auto *builder, const auto &val) {
|
||||
Save(*val, builder, saved_uids);
|
||||
"[](auto *builder, const auto &val) {
|
||||
Save(*val, builder);
|
||||
}"))
|
||||
|
||||
(defun load-ast-vector (type)
|
||||
(lcp:capnp-load-vector "capnp::Tree" type
|
||||
(format
|
||||
nil
|
||||
"[storage, loaded_uids](const auto &reader) {
|
||||
return static_cast<~A>(Load(storage, reader, loaded_uids));
|
||||
"[storage](const auto &reader) {
|
||||
return static_cast<~A>(Load(storage, reader));
|
||||
}"
|
||||
type)))
|
||||
|
||||
@ -101,7 +101,7 @@ cpp<#
|
||||
slk::Save(size, builder);
|
||||
for (const auto &entry : self.${member}) {
|
||||
slk::Save(entry.first, builder);
|
||||
query::SaveAstPointer(entry.second, builder, saved_uids);
|
||||
query::SaveAstPointer(entry.second, builder);
|
||||
}
|
||||
cpp<#)
|
||||
|
||||
@ -114,7 +114,7 @@ cpp<#
|
||||
++i) {
|
||||
query::PropertyIx key;
|
||||
slk::Load(&key, reader, storage);
|
||||
auto *value = query::LoadAstPointer<query::Expression>(storage, reader, loaded_uids);
|
||||
auto *value = query::LoadAstPointer<query::Expression>(storage, reader);
|
||||
self->${member}.emplace(key, value);
|
||||
}
|
||||
cpp<#)
|
||||
@ -127,7 +127,7 @@ cpp<#
|
||||
auto key_builder = entries_builder[i].initKey();
|
||||
Save(entry.first, &key_builder);
|
||||
auto value_builder = entries_builder[i].initValue();
|
||||
Save(*entry.second, &value_builder, saved_uids);
|
||||
Save(*entry.second, &value_builder);
|
||||
++i;
|
||||
}
|
||||
cpp<#)
|
||||
@ -138,7 +138,7 @@ cpp<#
|
||||
PropertyIx prop;
|
||||
Load(&prop, entry.getKey(), storage);
|
||||
${member}.emplace(prop, static_cast<Expression *>(
|
||||
Load(storage, entry.getValue(), loaded_uids)));
|
||||
Load(storage, entry.getValue())));
|
||||
}
|
||||
cpp<#)
|
||||
|
||||
@ -280,18 +280,9 @@ class AstStorage {
|
||||
AstStorage(AstStorage &&) = default;
|
||||
AstStorage &operator=(AstStorage &&) = default;
|
||||
|
||||
template <typename T>
|
||||
T *Create() {
|
||||
T *ptr = new T();
|
||||
ptr->uid_ = ++max_existing_uid_;
|
||||
std::unique_ptr<T> tmp(ptr);
|
||||
storage_.emplace_back(std::move(tmp));
|
||||
return ptr;
|
||||
}
|
||||
|
||||
template <typename T, typename... Args>
|
||||
T *Create(Args &&... args) {
|
||||
T *ptr = new T(++max_existing_uid_, std::forward<Args>(args)...);
|
||||
T *ptr = new T(std::forward<Args>(args)...);
|
||||
std::unique_ptr<T> tmp(ptr);
|
||||
storage_.emplace_back(std::move(tmp));
|
||||
return ptr;
|
||||
@ -315,7 +306,6 @@ class AstStorage {
|
||||
|
||||
// Public only for serialization access
|
||||
std::vector<std::unique_ptr<Tree>> storage_;
|
||||
int max_existing_uid_ = -1;
|
||||
|
||||
private:
|
||||
int64_t FindOrAddName(const std::string &name,
|
||||
@ -332,14 +322,7 @@ class AstStorage {
|
||||
cpp<#
|
||||
|
||||
(lcp:define-class tree ()
|
||||
((uid :int32_t :scope :public
|
||||
:clone (lambda (source dest)
|
||||
#>cpp
|
||||
${dest} = ${source};
|
||||
// TODO(mtomic): This is a hack. Adopting existing UIDs breaks everything
|
||||
// because `AstStorage` keeps a counter for generating when `Create` is called.
|
||||
storage->max_existing_uid_ = std::max(storage->max_existing_uid_, ${source});
|
||||
cpp<#)))
|
||||
()
|
||||
(:abstractp t)
|
||||
(:public
|
||||
#>cpp
|
||||
@ -350,28 +333,8 @@ cpp<#
|
||||
#>cpp
|
||||
friend class AstStorage;
|
||||
cpp<#)
|
||||
(:protected
|
||||
#>cpp
|
||||
explicit Tree(int uid) : uid_(uid) {}
|
||||
cpp<#)
|
||||
(:serialize (:slk :save-args '((saved-uids "std::vector<int32_t> *"))
|
||||
:load-args '((storage "query::AstStorage *")
|
||||
(loaded-uids "std::vector<int32_t> *")))
|
||||
(:capnp
|
||||
:save-args '((saved-uids "std::vector<int32_t> *"))
|
||||
:load-args '((storage "AstStorage *")
|
||||
(loaded-uids "std::vector<int32_t> *"))
|
||||
:post-save (lambda (builder)
|
||||
(declare (ignore builder))
|
||||
;; This is a bit hacky because it relies on the fact that parent class
|
||||
;; serialization is inlined so we can short-circuit and avoid serializing
|
||||
;; the derived class.
|
||||
#>cpp
|
||||
if (utils::Contains(*saved_uids, self.uid_)) {
|
||||
return;
|
||||
}
|
||||
saved_uids->push_back(self.uid_);
|
||||
cpp<#)))
|
||||
(:serialize (:slk :load-args '((storage "query::AstStorage *")))
|
||||
(:capnp :load-args '((storage "AstStorage *"))))
|
||||
(:clone :return-type (lambda (typename)
|
||||
(format nil "~A*" typename))
|
||||
:args '((storage "AstStorage *"))
|
||||
@ -396,10 +359,6 @@ cpp<#
|
||||
|
||||
Expression() = default;
|
||||
cpp<#)
|
||||
(:protected
|
||||
#>cpp
|
||||
explicit Expression(int uid) : Tree(uid) {}
|
||||
cpp<#)
|
||||
(:private
|
||||
#>cpp
|
||||
friend class AstStorage;
|
||||
@ -431,8 +390,7 @@ cpp<#
|
||||
cpp<#)
|
||||
(:protected
|
||||
#>cpp
|
||||
explicit Where(int uid) : Tree(uid) {}
|
||||
Where(int uid, Expression *expression) : Tree(uid), expression_(expression) {}
|
||||
explicit Where(Expression *expression) : expression_(expression) {}
|
||||
cpp<#)
|
||||
(:private
|
||||
#>cpp
|
||||
@ -463,9 +421,8 @@ cpp<#
|
||||
cpp<#)
|
||||
(:protected
|
||||
#>cpp
|
||||
explicit BinaryOperator(int uid) : Expression(uid) {}
|
||||
BinaryOperator(int uid, Expression *expression1, Expression *expression2)
|
||||
: Expression(uid), expression1_(expression1), expression2_(expression2) {}
|
||||
BinaryOperator(Expression *expression1, Expression *expression2)
|
||||
: expression1_(expression1), expression2_(expression2) {}
|
||||
cpp<#)
|
||||
(:private
|
||||
#>cpp
|
||||
@ -488,9 +445,7 @@ cpp<#
|
||||
cpp<#)
|
||||
(:protected
|
||||
#>cpp
|
||||
explicit UnaryOperator(int uid) : Expression(uid) {}
|
||||
UnaryOperator(int uid, Expression *expression)
|
||||
: Expression(uid), expression_(expression) {}
|
||||
explicit UnaryOperator(Expression *expression) : expression_(expression) {}
|
||||
cpp<#)
|
||||
(:private
|
||||
#>cpp
|
||||
@ -567,7 +522,9 @@ cpp<#
|
||||
(define-unary-operators))
|
||||
|
||||
(lcp:define-class aggregation (binary-operator)
|
||||
((op "Op" :scope :public))
|
||||
((op "Op" :scope :public)
|
||||
(symbol-pos :int32_t :initval -1 :scope :public
|
||||
:documentation "Symbol table position of the symbol this Aggregation is mapped to."))
|
||||
(:public
|
||||
(lcp:define-enum op
|
||||
(count min max sum avg collect-list collect-map)
|
||||
@ -597,17 +554,21 @@ cpp<#
|
||||
}
|
||||
return visitor.PostVisit(*this);
|
||||
}
|
||||
|
||||
Aggregation *MapTo(const Symbol &symbol) {
|
||||
symbol_pos_ = symbol.position();
|
||||
return this;
|
||||
}
|
||||
cpp<#)
|
||||
(:protected
|
||||
#>cpp
|
||||
// Use only for serialization.
|
||||
Aggregation(int uid) : BinaryOperator(uid) {}
|
||||
Aggregation(int uid, Op op) : BinaryOperator(uid), op_(op) {}
|
||||
explicit Aggregation(Op op) : op_(op) {}
|
||||
|
||||
/// Aggregation's first expression is the value being aggregated. The second
|
||||
/// expression is the key used only in COLLECT_MAP.
|
||||
Aggregation(int uid, Expression *expression1, Expression *expression2, Op op)
|
||||
: BinaryOperator(uid, expression1, expression2), op_(op) {
|
||||
Aggregation(Expression *expression1, Expression *expression2, Op op)
|
||||
: BinaryOperator(expression1, expression2), op_(op) {
|
||||
// COUNT without expression denotes COUNT(*) in cypher.
|
||||
DCHECK(expression1 || op == Aggregation::Op::COUNT)
|
||||
<< "All aggregations, except COUNT require expression";
|
||||
@ -663,14 +624,9 @@ cpp<#
|
||||
cpp<#)
|
||||
(:protected
|
||||
#>cpp
|
||||
explicit ListSlicingOperator(int uid) : Expression(uid) {}
|
||||
|
||||
ListSlicingOperator(int uid, Expression *list, Expression *lower_bound,
|
||||
ListSlicingOperator(Expression *list, Expression *lower_bound,
|
||||
Expression *upper_bound)
|
||||
: Expression(uid),
|
||||
list_(list),
|
||||
lower_bound_(lower_bound),
|
||||
upper_bound_(upper_bound) {}
|
||||
: list_(list), lower_bound_(lower_bound), upper_bound_(upper_bound) {}
|
||||
cpp<#)
|
||||
(:private
|
||||
#>cpp
|
||||
@ -715,12 +671,9 @@ cpp<#
|
||||
cpp<#)
|
||||
(:protected
|
||||
#>cpp
|
||||
explicit IfOperator(int uid) : Expression(uid) {}
|
||||
|
||||
IfOperator(int uid, Expression *condition, Expression *then_expression,
|
||||
IfOperator(Expression *condition, Expression *then_expression,
|
||||
Expression *else_expression)
|
||||
: Expression(uid),
|
||||
condition_(condition),
|
||||
: condition_(condition),
|
||||
then_expression_(then_expression),
|
||||
else_expression_(else_expression) {}
|
||||
cpp<#)
|
||||
@ -738,10 +691,6 @@ cpp<#
|
||||
#>cpp
|
||||
BaseLiteral() = default;
|
||||
cpp<#)
|
||||
(:protected
|
||||
#>cpp
|
||||
explicit BaseLiteral(int uid) : Expression(uid) {}
|
||||
cpp<#)
|
||||
(:private
|
||||
#>cpp
|
||||
friend class AstStorage;
|
||||
@ -775,12 +724,11 @@ cpp<#
|
||||
cpp<#)
|
||||
(:protected
|
||||
#>cpp
|
||||
explicit PrimitiveLiteral(int uid) : BaseLiteral(uid) {}
|
||||
template <typename T>
|
||||
PrimitiveLiteral(int uid, T value) : BaseLiteral(uid), value_(value) {}
|
||||
explicit PrimitiveLiteral(T value) : value_(value) {}
|
||||
template <typename T>
|
||||
PrimitiveLiteral(int uid, T value, int token_position)
|
||||
: BaseLiteral(uid), value_(value), token_position_(token_position) {}
|
||||
PrimitiveLiteral(T value, int token_position)
|
||||
: value_(value), token_position_(token_position) {}
|
||||
cpp<#)
|
||||
(:serialize (:slk) (:capnp))
|
||||
(:clone))
|
||||
@ -809,9 +757,8 @@ cpp<#
|
||||
cpp<#)
|
||||
(:protected
|
||||
#>cpp
|
||||
explicit ListLiteral(int uid) : BaseLiteral(uid) {}
|
||||
ListLiteral(int uid, const std::vector<Expression *> &elements)
|
||||
: BaseLiteral(uid), elements_(elements) {}
|
||||
explicit ListLiteral(const std::vector<Expression *> &elements)
|
||||
: elements_(elements) {}
|
||||
cpp<#)
|
||||
(:private
|
||||
#>cpp
|
||||
@ -845,10 +792,9 @@ cpp<#
|
||||
cpp<#)
|
||||
(:protected
|
||||
#>cpp
|
||||
explicit MapLiteral(int uid) : BaseLiteral(uid) {}
|
||||
MapLiteral(int uid,
|
||||
const std::unordered_map<PropertyIx, Expression *> &elements)
|
||||
: BaseLiteral(uid), elements_(elements) {}
|
||||
explicit MapLiteral(
|
||||
const std::unordered_map<PropertyIx, Expression *> &elements)
|
||||
: elements_(elements) {}
|
||||
cpp<#)
|
||||
(:private
|
||||
#>cpp
|
||||
@ -859,7 +805,9 @@ cpp<#
|
||||
|
||||
(lcp:define-class identifier (expression)
|
||||
((name "std::string" :scope :public)
|
||||
(user-declared :bool :initval "true" :scope :public))
|
||||
(user-declared :bool :initval "true" :scope :public)
|
||||
(symbol-pos :int32_t :initval -1 :scope :public
|
||||
:documentation "Symbol table position of the symbol this Identifier is mapped to."))
|
||||
(:public
|
||||
#>cpp
|
||||
Identifier() = default;
|
||||
@ -867,14 +815,17 @@ cpp<#
|
||||
DEFVISITABLE(ExpressionVisitor<TypedValue>);
|
||||
DEFVISITABLE(ExpressionVisitor<void>);
|
||||
DEFVISITABLE(HierarchicalTreeVisitor);
|
||||
|
||||
Identifier *MapTo(const Symbol &symbol) {
|
||||
symbol_pos_ = symbol.position();
|
||||
return this;
|
||||
}
|
||||
cpp<#)
|
||||
(:protected
|
||||
#>cpp
|
||||
Identifier(int uid) : Expression(uid) {}
|
||||
|
||||
Identifier(int uid, const std::string &name) : Expression(uid), name_(name) {}
|
||||
Identifier(int uid, const std::string &name, bool user_declared)
|
||||
: Expression(uid), name_(name), user_declared_(user_declared) {}
|
||||
explicit Identifier(const std::string &name) : name_(name) {}
|
||||
Identifier(const std::string &name, bool user_declared)
|
||||
: name_(name), user_declared_(user_declared) {}
|
||||
cpp<#)
|
||||
(:private
|
||||
#>cpp
|
||||
@ -914,11 +865,8 @@ cpp<#
|
||||
cpp<#)
|
||||
(:protected
|
||||
#>cpp
|
||||
PropertyLookup(int uid) : Expression(uid) {}
|
||||
PropertyLookup(int uid, Expression *expression, PropertyIx property)
|
||||
: Expression(uid),
|
||||
expression_(expression),
|
||||
property_(property) {}
|
||||
PropertyLookup(Expression *expression, PropertyIx property)
|
||||
: expression_(expression), property_(property) {}
|
||||
cpp<#)
|
||||
(:private
|
||||
#>cpp
|
||||
@ -967,11 +915,8 @@ cpp<#
|
||||
cpp<#)
|
||||
(:protected
|
||||
#>cpp
|
||||
LabelsTest(int uid) : Expression(uid) {}
|
||||
|
||||
LabelsTest(int uid, Expression *expression,
|
||||
const std::vector<LabelIx> &labels)
|
||||
: Expression(uid), expression_(expression), labels_(labels) {}
|
||||
LabelsTest(Expression *expression, const std::vector<LabelIx> &labels)
|
||||
: expression_(expression), labels_(labels) {}
|
||||
cpp<#)
|
||||
(:private
|
||||
#>cpp
|
||||
@ -1019,12 +964,9 @@ cpp<#
|
||||
cpp<#)
|
||||
(:protected
|
||||
#>cpp
|
||||
explicit Function(int uid) : Expression(uid) {}
|
||||
|
||||
Function(int uid, const std::string &function_name,
|
||||
Function(const std::string &function_name,
|
||||
const std::vector<Expression *> &arguments)
|
||||
: Expression(uid),
|
||||
arguments_(arguments),
|
||||
: arguments_(arguments),
|
||||
function_name_(function_name),
|
||||
function_(NameToFunction(function_name_)) {
|
||||
DCHECK(function_) << "Unexpected missing function: " << function_name_;
|
||||
@ -1090,10 +1032,9 @@ cpp<#
|
||||
cpp<#)
|
||||
(:protected
|
||||
#>cpp
|
||||
Reduce(int uid, Identifier *accumulator, Expression *initializer,
|
||||
Identifier *identifier, Expression *list, Expression *expression)
|
||||
: Expression(uid),
|
||||
accumulator_(accumulator),
|
||||
Reduce(Identifier *accumulator, Expression *initializer, Identifier *identifier,
|
||||
Expression *list, Expression *expression)
|
||||
: accumulator_(accumulator),
|
||||
initializer_(initializer),
|
||||
identifier_(identifier),
|
||||
list_(list),
|
||||
@ -1133,10 +1074,8 @@ cpp<#
|
||||
)
|
||||
(:private
|
||||
#>cpp
|
||||
Coalesce(int uid) : Expression(uid_) {}
|
||||
|
||||
Coalesce(int uid, const std::vector<Expression *> &expressions)
|
||||
: Expression(uid), expressions_(expressions) {}
|
||||
explicit Coalesce(const std::vector<Expression *> &expressions)
|
||||
: expressions_(expressions) {}
|
||||
|
||||
friend class AstStorage;
|
||||
cpp<#)
|
||||
@ -1181,14 +1120,8 @@ cpp<#
|
||||
cpp<#)
|
||||
(:protected
|
||||
#>cpp
|
||||
Extract(int uid) : Expression(uid) {}
|
||||
|
||||
Extract(int uid, Identifier *identifier, Expression *list,
|
||||
Expression *expression)
|
||||
: Expression(uid),
|
||||
identifier_(identifier),
|
||||
list_(list),
|
||||
expression_(expression) {}
|
||||
Extract(Identifier *identifier, Expression *list, Expression *expression)
|
||||
: identifier_(identifier), list_(list), expression_(expression) {}
|
||||
cpp<#)
|
||||
(:private
|
||||
#>cpp
|
||||
@ -1232,12 +1165,8 @@ cpp<#
|
||||
cpp<#)
|
||||
(:protected
|
||||
#>cpp
|
||||
All(int uid) : Expression(uid) {}
|
||||
|
||||
All(int uid, Identifier *identifier, Expression *list_expression,
|
||||
Where *where)
|
||||
: Expression(uid),
|
||||
identifier_(identifier),
|
||||
All(Identifier *identifier, Expression *list_expression, Where *where)
|
||||
: identifier_(identifier),
|
||||
list_expression_(list_expression),
|
||||
where_(where) {}
|
||||
cpp<#)
|
||||
@ -1286,10 +1215,8 @@ cpp<#
|
||||
cpp<#)
|
||||
(:protected
|
||||
#>cpp
|
||||
Single(int uid, Identifier *identifier, Expression *list_expression,
|
||||
Where *where)
|
||||
: Expression(uid),
|
||||
identifier_(identifier),
|
||||
Single(Identifier *identifier, Expression *list_expression, Where *where)
|
||||
: identifier_(identifier),
|
||||
list_expression_(list_expression),
|
||||
where_(where) {}
|
||||
cpp<#)
|
||||
@ -1313,9 +1240,8 @@ cpp<#
|
||||
cpp<#)
|
||||
(:protected
|
||||
#>cpp
|
||||
explicit ParameterLookup(int uid) : Expression(uid) {}
|
||||
ParameterLookup(int uid, int token_position)
|
||||
: Expression(uid), token_position_(token_position) {}
|
||||
explicit ParameterLookup(int token_position)
|
||||
: token_position_(token_position) {}
|
||||
cpp<#)
|
||||
(:private
|
||||
#>cpp
|
||||
@ -1335,7 +1261,9 @@ cpp<#
|
||||
:capnp-save #'save-ast-pointer
|
||||
:capnp-load (load-ast-pointer "Expression *"))
|
||||
(token-position :int32_t :initval -1 :scope :public
|
||||
:documentation "This field contains token position of first token in named expression used to create name_. If NamedExpression object is not created from query or it is aliased leave this value at -1."))
|
||||
:documentation "This field contains token position of first token in named expression used to create name_. If NamedExpression object is not created from query or it is aliased leave this value at -1.")
|
||||
(symbol-pos :int32_t :initval -1 :scope :public
|
||||
:documentation "Symbol table position of the symbol this NamedExpression is mapped to."))
|
||||
(:public
|
||||
#>cpp
|
||||
using ::utils::Visitable<ExpressionVisitor<TypedValue>>::Accept;
|
||||
@ -1352,19 +1280,20 @@ cpp<#
|
||||
}
|
||||
return visitor.PostVisit(*this);
|
||||
}
|
||||
|
||||
NamedExpression *MapTo(const Symbol &symbol) {
|
||||
symbol_pos_ = symbol.position();
|
||||
return this;
|
||||
}
|
||||
cpp<#)
|
||||
(:protected
|
||||
#>cpp
|
||||
explicit NamedExpression(int uid) : Tree(uid) {}
|
||||
NamedExpression(int uid, const std::string &name) : Tree(uid), name_(name) {}
|
||||
NamedExpression(int uid, const std::string &name, Expression *expression)
|
||||
: Tree(uid), name_(name), expression_(expression) {}
|
||||
NamedExpression(int uid, const std::string &name, Expression *expression,
|
||||
explicit NamedExpression(const std::string &name) : name_(name) {}
|
||||
NamedExpression(const std::string &name, Expression *expression)
|
||||
: name_(name), expression_(expression) {}
|
||||
NamedExpression(const std::string &name, Expression *expression,
|
||||
int token_position)
|
||||
: Tree(uid),
|
||||
name_(name),
|
||||
expression_(expression),
|
||||
token_position_(token_position) {}
|
||||
: name_(name), expression_(expression), token_position_(token_position) {}
|
||||
cpp<#)
|
||||
(:private
|
||||
#>cpp
|
||||
@ -1395,9 +1324,7 @@ cpp<#
|
||||
cpp<#)
|
||||
(:protected
|
||||
#>cpp
|
||||
explicit PatternAtom(int uid) : Tree(uid) {}
|
||||
PatternAtom(int uid, Identifier *identifier)
|
||||
: Tree(uid), identifier_(identifier) {}
|
||||
explicit PatternAtom(Identifier *identifier) : identifier_(identifier) {}
|
||||
cpp<#)
|
||||
(:private
|
||||
#>cpp
|
||||
@ -1505,23 +1432,15 @@ cpp<#
|
||||
:documentation "Evaluated to upper bound in variable length expands.")
|
||||
(filter-lambda "Lambda" :scope :public
|
||||
:documentation "Filter lambda for variable length expands. Can have an empty expression, but identifiers must be valid, because an optimization pass may inline other expressions into this lambda."
|
||||
:slk-save (lambda (member)
|
||||
#>cpp
|
||||
slk::Save(self.${member}, builder, saved_uids);
|
||||
cpp<#)
|
||||
:slk-load (lambda (member)
|
||||
#>cpp
|
||||
slk::Load(&self->${member}, reader, storage, loaded_uids);
|
||||
slk::Load(&self->${member}, reader, storage);
|
||||
cpp<#))
|
||||
(weight-lambda "Lambda" :scope :public
|
||||
:documentation "Used in weighted shortest path. It must have valid expressions and identifiers. In all other expand types, it is empty."
|
||||
:slk-save (lambda (member)
|
||||
#>cpp
|
||||
slk::Save(self.${member}, builder, saved_uids);
|
||||
cpp<#)
|
||||
:slk-load (lambda (member)
|
||||
#>cpp
|
||||
slk::Load(&self->${member}, reader, storage, loaded_uids);
|
||||
slk::Load(&self->${member}, reader, storage);
|
||||
cpp<#))
|
||||
(total-weight "Identifier *" :initval "nullptr" :scope :public
|
||||
:slk-save #'slk-save-ast-pointer
|
||||
@ -1560,13 +1479,8 @@ cpp<#
|
||||
:capnp-load (load-ast-pointer "Expression *")
|
||||
:documentation "Evaluates the result of the lambda."))
|
||||
(:documentation "Lambda for use in filtering or weight calculation during variable expand.")
|
||||
(:serialize (:slk :save-args '((saved-uids "std::vector<int32_t> *"))
|
||||
:load-args '((storage "query::AstStorage *")
|
||||
(loaded-uids "std::vector<int32_t> *")))
|
||||
(:capnp
|
||||
:save-args '((saved-uids "std::vector<int32_t> *"))
|
||||
:load-args '((storage "AstStorage *")
|
||||
(loaded-uids "std::vector<int32_t> *"))))
|
||||
(:serialize (:slk :load-args '((storage "query::AstStorage *")))
|
||||
(:capnp :load-args '((storage "AstStorage *"))))
|
||||
(:clone :args '((storage "AstStorage *"))))
|
||||
#>cpp
|
||||
bool Accept(HierarchicalTreeVisitor &visitor) override {
|
||||
@ -1604,13 +1518,13 @@ cpp<#
|
||||
(:protected
|
||||
#>cpp
|
||||
using PatternAtom::PatternAtom;
|
||||
EdgeAtom(int uid, Identifier *identifier, Type type, Direction direction)
|
||||
: PatternAtom(uid, identifier), type_(type), direction_(direction) {}
|
||||
EdgeAtom(Identifier *identifier, Type type, Direction direction)
|
||||
: PatternAtom(identifier), type_(type), direction_(direction) {}
|
||||
|
||||
// Creates an edge atom for a SINGLE expansion with the given .
|
||||
EdgeAtom(int uid, Identifier *identifier, Type type, Direction direction,
|
||||
EdgeAtom(Identifier *identifier, Type type, Direction direction,
|
||||
const std::vector<EdgeTypeIx> &edge_types)
|
||||
: PatternAtom(uid, identifier),
|
||||
: PatternAtom(identifier),
|
||||
type_(type),
|
||||
direction_(direction),
|
||||
edge_types_(edge_types) {}
|
||||
@ -1654,10 +1568,6 @@ cpp<#
|
||||
return visitor.PostVisit(*this);
|
||||
}
|
||||
cpp<#)
|
||||
(:protected
|
||||
#>cpp
|
||||
explicit Pattern(int uid) : Tree(uid) {}
|
||||
cpp<#)
|
||||
(:private
|
||||
#>cpp
|
||||
friend class AstStorage;
|
||||
@ -1676,10 +1586,6 @@ cpp<#
|
||||
|
||||
Clause() = default;
|
||||
cpp<#)
|
||||
(:protected
|
||||
#>cpp
|
||||
explicit Clause(int uid) : Tree(uid) {}
|
||||
cpp<#)
|
||||
(:private
|
||||
#>cpp
|
||||
friend class AstStorage;
|
||||
@ -1712,10 +1618,6 @@ cpp<#
|
||||
return visitor.PostVisit(*this);
|
||||
}
|
||||
cpp<#)
|
||||
(:protected
|
||||
#>cpp
|
||||
explicit SingleQuery(int uid) : Tree(uid) {}
|
||||
cpp<#)
|
||||
(:private
|
||||
#>cpp
|
||||
friend class AstStorage;
|
||||
@ -1750,12 +1652,10 @@ cpp<#
|
||||
cpp<#)
|
||||
(:protected
|
||||
#>cpp
|
||||
explicit CypherUnion(int uid) : Tree(uid) {}
|
||||
CypherUnion(int uid, bool distinct) : Tree(uid), distinct_(distinct) {}
|
||||
CypherUnion(int uid, bool distinct, SingleQuery *single_query,
|
||||
explicit CypherUnion(bool distinct) : distinct_(distinct) {}
|
||||
CypherUnion(bool distinct, SingleQuery *single_query,
|
||||
std::vector<Symbol> union_symbols)
|
||||
: Tree(uid),
|
||||
single_query_(single_query),
|
||||
: single_query_(single_query),
|
||||
distinct_(distinct),
|
||||
union_symbols_(union_symbols) {}
|
||||
cpp<#)
|
||||
@ -1777,10 +1677,6 @@ cpp<#
|
||||
|
||||
Query() = default;
|
||||
cpp<#)
|
||||
(:protected
|
||||
#>cpp
|
||||
explicit Query(int uid) : Tree(uid) {}
|
||||
cpp<#)
|
||||
(:private
|
||||
#>cpp
|
||||
friend class AstStorage;
|
||||
@ -1812,10 +1708,6 @@ cpp<#
|
||||
|
||||
DEFVISITABLE(QueryVisitor<void>);
|
||||
cpp<#)
|
||||
(:protected
|
||||
#>cpp
|
||||
explicit CypherQuery(int uid) : Query(uid) {}
|
||||
cpp<#)
|
||||
(:private
|
||||
#>cpp
|
||||
friend class AstStorage;
|
||||
@ -1837,10 +1729,6 @@ cpp<#
|
||||
|
||||
DEFVISITABLE(QueryVisitor<void>);
|
||||
cpp<#)
|
||||
(:protected
|
||||
#>cpp
|
||||
explicit ExplainQuery(int uid) : Query(uid) {}
|
||||
cpp<#)
|
||||
(:private
|
||||
#>cpp
|
||||
friend class AstStorage;
|
||||
@ -1867,7 +1755,6 @@ cpp<#
|
||||
cpp<#)
|
||||
(:private
|
||||
#>cpp
|
||||
explicit ProfileQuery(int uid) : Query(uid) {}
|
||||
friend class AstStorage;
|
||||
cpp<#)
|
||||
(:serialize (:slk) (:capnp))
|
||||
@ -1914,10 +1801,8 @@ cpp<#
|
||||
cpp<#)
|
||||
(:protected
|
||||
#>cpp
|
||||
explicit IndexQuery(int uid) : Query(uid) {}
|
||||
IndexQuery(int uid, Action action, LabelIx label,
|
||||
std::vector<PropertyIx> properties)
|
||||
: Query(uid), action_(action), label_(label), properties_(properties) {}
|
||||
IndexQuery(Action action, LabelIx label, std::vector<PropertyIx> properties)
|
||||
: action_(action), label_(label), properties_(properties) {}
|
||||
cpp<#)
|
||||
(:private
|
||||
#>cpp
|
||||
@ -1949,9 +1834,7 @@ cpp<#
|
||||
cpp<#)
|
||||
(:protected
|
||||
#>cpp
|
||||
explicit Create(int uid) : Clause(uid) {}
|
||||
Create(int uid, std::vector<Pattern *> patterns)
|
||||
: Clause(uid), patterns_(patterns) {}
|
||||
explicit Create(std::vector<Pattern *> patterns) : patterns_(patterns) {}
|
||||
cpp<#)
|
||||
(:private
|
||||
#>cpp
|
||||
@ -1997,10 +1880,9 @@ cpp<#
|
||||
cpp<#)
|
||||
(:protected
|
||||
#>cpp
|
||||
explicit Match(int uid) : Clause(uid) {}
|
||||
Match(int uid, bool optional) : Clause(uid), optional_(optional) {}
|
||||
Match(int uid, bool optional, Where *where, std::vector<Pattern *> patterns)
|
||||
: Clause(uid), patterns_(patterns), where_(where), optional_(optional) {}
|
||||
explicit Match(bool optional) : optional_(optional) {}
|
||||
Match(bool optional, Where *where, std::vector<Pattern *> patterns)
|
||||
: patterns_(patterns), where_(where), optional_(optional) {}
|
||||
cpp<#)
|
||||
(:private
|
||||
#>cpp
|
||||
@ -2022,13 +1904,8 @@ cpp<#
|
||||
:capnp-type "Tree" :capnp-init nil
|
||||
:capnp-save #'save-ast-pointer
|
||||
:capnp-load (load-ast-pointer "Expression *")))
|
||||
(:serialize (:slk :save-args '((saved-uids "std::vector<int32_t> *"))
|
||||
:load-args '((storage "query::AstStorage *")
|
||||
(loaded-uids "std::vector<int32_t> *")))
|
||||
(:capnp
|
||||
:save-args '((saved-uids "std::vector<int32_t> *"))
|
||||
:load-args '((storage "AstStorage *")
|
||||
(loaded-uids "std::vector<int32_t> *"))))
|
||||
(:serialize (:slk :load-args '((storage "query::AstStorage *")))
|
||||
(:capnp :load-args '((storage "AstStorage *"))))
|
||||
(:clone :args '((storage "AstStorage *"))))
|
||||
|
||||
(lcp:define-struct return-body ()
|
||||
@ -2044,14 +1921,6 @@ cpp<#
|
||||
:capnp-load (load-ast-vector "NamedExpression *")
|
||||
:documentation "Expressions which are used to produce results.")
|
||||
(order-by "std::vector<SortItem>"
|
||||
:slk-save (lambda (member)
|
||||
#>cpp
|
||||
size_t size = self.${member}.size();
|
||||
slk::Save(size, builder);
|
||||
for (const auto &v : self.${member}) {
|
||||
slk::Save(v, builder, saved_uids);
|
||||
}
|
||||
cpp<#)
|
||||
:slk-load (lambda (member)
|
||||
#>cpp
|
||||
size_t size = 0;
|
||||
@ -2060,21 +1929,15 @@ cpp<#
|
||||
for (size_t i = 0;
|
||||
i < size;
|
||||
++i) {
|
||||
slk::Load(&self->${member}[i], reader, storage, loaded_uids);
|
||||
slk::Load(&self->${member}[i], reader, storage);
|
||||
}
|
||||
cpp<#)
|
||||
:capnp-save (lcp:capnp-save-vector
|
||||
"capnp::SortItem"
|
||||
"SortItem"
|
||||
"[saved_uids](auto *builder, const auto &val) {
|
||||
Save(val, builder, saved_uids);
|
||||
}")
|
||||
:capnp-load (lcp:capnp-load-vector
|
||||
"capnp::SortItem"
|
||||
"SortItem"
|
||||
"[storage, loaded_uids](const auto &reader) {
|
||||
"[storage](const auto &reader) {
|
||||
SortItem val;
|
||||
Load(&val, reader, storage, loaded_uids);
|
||||
Load(&val, reader, storage);
|
||||
return val;
|
||||
}")
|
||||
:documentation "Expressions used for ordering the results.")
|
||||
@ -2093,24 +1956,15 @@ cpp<#
|
||||
:capnp-load (load-ast-pointer "Expression *")
|
||||
:documentation "Optional expression on how many results to produce."))
|
||||
(:documentation "Contents common to @c Return and @c With clauses.")
|
||||
(:serialize (:slk :save-args '((saved-uids "std::vector<int32_t> *"))
|
||||
:load-args '((storage "query::AstStorage *")
|
||||
(loaded-uids "std::vector<int32_t> *")))
|
||||
(:capnp
|
||||
:save-args '((saved-uids "std::vector<int32_t> *"))
|
||||
:load-args '((storage "AstStorage *")
|
||||
(loaded-uids "std::vector<int32_t> *"))))
|
||||
(:serialize (:slk :load-args '((storage "query::AstStorage *")))
|
||||
(:capnp :load-args '((storage "AstStorage *"))))
|
||||
(:clone :args '((storage "AstStorage *"))))
|
||||
|
||||
(lcp:define-class return (clause)
|
||||
((body "ReturnBody" :scope :public
|
||||
:slk-save (lambda (member)
|
||||
#>cpp
|
||||
slk::Save(self.${member}, builder, saved_uids);
|
||||
cpp<#)
|
||||
:slk-load (lambda (member)
|
||||
#>cpp
|
||||
slk::Load(&self->${member}, reader, storage, loaded_uids);
|
||||
slk::Load(&self->${member}, reader, storage);
|
||||
cpp<#)))
|
||||
(:public
|
||||
#>cpp
|
||||
@ -2141,8 +1995,7 @@ cpp<#
|
||||
cpp<#)
|
||||
(:protected
|
||||
#>cpp
|
||||
explicit Return(int uid) : Clause(uid) {}
|
||||
Return(int uid, ReturnBody &body) : Clause(uid), body_(body) {}
|
||||
explicit Return(ReturnBody &body) : body_(body) {}
|
||||
cpp<#)
|
||||
(:private
|
||||
#>cpp
|
||||
@ -2153,13 +2006,9 @@ cpp<#
|
||||
|
||||
(lcp:define-class with (clause)
|
||||
((body "ReturnBody" :scope :public
|
||||
:slk-save (lambda (member)
|
||||
#>cpp
|
||||
slk::Save(self.${member}, builder, saved_uids);
|
||||
cpp<#)
|
||||
:slk-load (lambda (member)
|
||||
#>cpp
|
||||
slk::Load(&self->${member}, reader, storage, loaded_uids);
|
||||
slk::Load(&self->${member}, reader, storage);
|
||||
cpp<#))
|
||||
(where "Where *" :initval "nullptr" :scope :public
|
||||
:slk-save #'slk-save-ast-pointer
|
||||
@ -2197,9 +2046,7 @@ cpp<#
|
||||
cpp<#)
|
||||
(:protected
|
||||
#>cpp
|
||||
explicit With(int uid) : Clause(uid) {}
|
||||
With(int uid, ReturnBody &body, Where *where)
|
||||
: Clause(uid), body_(body), where_(where) {}
|
||||
With(ReturnBody &body, Where *where) : body_(body), where_(where) {}
|
||||
cpp<#)
|
||||
(:private
|
||||
#>cpp
|
||||
@ -2232,9 +2079,8 @@ cpp<#
|
||||
cpp<#)
|
||||
(:protected
|
||||
#>cpp
|
||||
explicit Delete(int uid) : Clause(uid) {}
|
||||
Delete(int uid, bool detach, std::vector<Expression *> expressions)
|
||||
: Clause(uid), expressions_(expressions), detach_(detach) {}
|
||||
Delete(bool detach, std::vector<Expression *> expressions)
|
||||
: expressions_(expressions), detach_(detach) {}
|
||||
cpp<#)
|
||||
(:private
|
||||
#>cpp
|
||||
@ -2269,11 +2115,8 @@ cpp<#
|
||||
cpp<#)
|
||||
(:protected
|
||||
#>cpp
|
||||
explicit SetProperty(int uid) : Clause(uid) {}
|
||||
SetProperty(int uid, PropertyLookup *property_lookup, Expression *expression)
|
||||
: Clause(uid),
|
||||
property_lookup_(property_lookup),
|
||||
expression_(expression) {}
|
||||
SetProperty(PropertyLookup *property_lookup, Expression *expression)
|
||||
: property_lookup_(property_lookup), expression_(expression) {}
|
||||
cpp<#)
|
||||
(:private
|
||||
#>cpp
|
||||
@ -2309,13 +2152,9 @@ cpp<#
|
||||
cpp<#)
|
||||
(:protected
|
||||
#>cpp
|
||||
explicit SetProperties(int uid) : Clause(uid) {}
|
||||
SetProperties(int uid, Identifier *identifier, Expression *expression,
|
||||
SetProperties(Identifier *identifier, Expression *expression,
|
||||
bool update = false)
|
||||
: Clause(uid),
|
||||
identifier_(identifier),
|
||||
expression_(expression),
|
||||
update_(update) {}
|
||||
: identifier_(identifier), expression_(expression), update_(update) {}
|
||||
cpp<#)
|
||||
(:private
|
||||
#>cpp
|
||||
@ -2362,10 +2201,8 @@ cpp<#
|
||||
cpp<#)
|
||||
(:protected
|
||||
#>cpp
|
||||
explicit SetLabels(int uid) : Clause(uid) {}
|
||||
SetLabels(int uid, Identifier *identifier,
|
||||
const std::vector<LabelIx> &labels)
|
||||
: Clause(uid), identifier_(identifier), labels_(labels) {}
|
||||
SetLabels(Identifier *identifier, const std::vector<LabelIx> &labels)
|
||||
: identifier_(identifier), labels_(labels) {}
|
||||
cpp<#)
|
||||
(:private
|
||||
#>cpp
|
||||
@ -2394,9 +2231,8 @@ cpp<#
|
||||
cpp<#)
|
||||
(:protected
|
||||
#>cpp
|
||||
explicit RemoveProperty(int uid) : Clause(uid) {}
|
||||
RemoveProperty(int uid, PropertyLookup *property_lookup)
|
||||
: Clause(uid), property_lookup_(property_lookup) {}
|
||||
explicit RemoveProperty(PropertyLookup *property_lookup)
|
||||
: property_lookup_(property_lookup) {}
|
||||
cpp<#)
|
||||
(:private
|
||||
#>cpp
|
||||
@ -2443,10 +2279,8 @@ cpp<#
|
||||
cpp<#)
|
||||
(:protected
|
||||
#>cpp
|
||||
explicit RemoveLabels(int uid) : Clause(uid) {}
|
||||
RemoveLabels(int uid, Identifier *identifier,
|
||||
const std::vector<LabelIx> &labels)
|
||||
: Clause(uid), identifier_(identifier), labels_(labels) {}
|
||||
RemoveLabels(Identifier *identifier, const std::vector<LabelIx> &labels)
|
||||
: identifier_(identifier), labels_(labels) {}
|
||||
cpp<#)
|
||||
(:private
|
||||
#>cpp
|
||||
@ -2505,13 +2339,9 @@ cpp<#
|
||||
cpp<#)
|
||||
(:protected
|
||||
#>cpp
|
||||
explicit Merge(int uid) : Clause(uid) {}
|
||||
Merge(int uid, Pattern *pattern, std::vector<Clause *> on_match,
|
||||
Merge(Pattern *pattern, std::vector<Clause *> on_match,
|
||||
std::vector<Clause *> on_create)
|
||||
: Clause(uid),
|
||||
pattern_(pattern),
|
||||
on_match_(on_match),
|
||||
on_create_(on_create) {}
|
||||
: pattern_(pattern), on_match_(on_match), on_create_(on_create) {}
|
||||
cpp<#)
|
||||
(:private
|
||||
#>cpp
|
||||
@ -2540,12 +2370,9 @@ cpp<#
|
||||
cpp<#)
|
||||
(:protected
|
||||
#>cpp
|
||||
explicit Unwind(int uid) : Clause(uid) {}
|
||||
|
||||
Unwind(int uid, NamedExpression *named_expression)
|
||||
: Clause(uid), named_expression_(named_expression) {
|
||||
DCHECK(named_expression)
|
||||
<< "Unwind cannot take nullptr for named_expression";
|
||||
explicit Unwind(NamedExpression *named_expression)
|
||||
: named_expression_(named_expression) {
|
||||
DCHECK(named_expression) << "Unwind cannot take nullptr for named_expression";
|
||||
}
|
||||
cpp<#)
|
||||
(:private
|
||||
@ -2584,13 +2411,10 @@ cpp<#
|
||||
cpp<#)
|
||||
(:protected
|
||||
#>cpp
|
||||
explicit AuthQuery(int uid) : Query(uid) {}
|
||||
|
||||
explicit AuthQuery(int uid, Action action, std::string user, std::string role,
|
||||
std::string user_or_role, Expression *password,
|
||||
std::vector<Privilege> privileges)
|
||||
: Query(uid),
|
||||
action_(action),
|
||||
AuthQuery(Action action, std::string user, std::string role,
|
||||
std::string user_or_role, Expression *password,
|
||||
std::vector<Privilege> privileges)
|
||||
: action_(action),
|
||||
user_(user),
|
||||
role_(role),
|
||||
user_or_role_(user_or_role),
|
||||
@ -2667,13 +2491,11 @@ cpp<#
|
||||
cpp<#)
|
||||
(:protected
|
||||
#>cpp
|
||||
StreamQuery(int uid) : Query(uid) {}
|
||||
StreamQuery(int uid, Action action, std::string stream_name,
|
||||
Expression *stream_uri, Expression *stream_topic,
|
||||
Expression *transform_uri, Expression *batch_interval_in_ms,
|
||||
Expression *batch_size, Expression *limit_batches)
|
||||
: Query(uid),
|
||||
action_(action),
|
||||
StreamQuery(Action action, std::string stream_name, Expression *stream_uri,
|
||||
Expression *stream_topic, Expression *transform_uri,
|
||||
Expression *batch_interval_in_ms, Expression *batch_size,
|
||||
Expression *limit_batches)
|
||||
: action_(action),
|
||||
stream_name_(std::move(stream_name)),
|
||||
stream_uri_(stream_uri),
|
||||
stream_topic_(stream_topic),
|
||||
|
@ -15,26 +15,22 @@ cpp<#
|
||||
|
||||
#>cpp
|
||||
/// Primary function for saving Ast nodes via SLK.
|
||||
void SaveAstPointer(const Tree *ast, slk::Builder *builder,
|
||||
std::vector<int32_t> *saved_uids);
|
||||
void SaveAstPointer(const Tree *ast, slk::Builder *builder);
|
||||
|
||||
Tree *Load(AstStorage *ast, const capnp::Tree::Reader &tree,
|
||||
std::vector<int32_t> *loaded_uids);
|
||||
Tree *Load(AstStorage *ast, const capnp::Tree::Reader &tree);
|
||||
|
||||
Tree *Load(AstStorage *ast, slk::Reader *reader,
|
||||
std::vector<int32_t> *loaded_uids);
|
||||
Tree *Load(AstStorage *ast, slk::Reader *reader);
|
||||
|
||||
/// Primary function for loading Ast nodes via SLK.
|
||||
template <class TAst>
|
||||
TAst *LoadAstPointer(AstStorage *ast, slk::Reader *reader,
|
||||
std::vector<int32_t> *loaded_uids) {
|
||||
TAst *LoadAstPointer(AstStorage *ast, slk::Reader *reader) {
|
||||
static_assert(std::is_base_of<query::Tree, TAst>::value);
|
||||
bool has_ptr = false;
|
||||
slk::Load(&has_ptr, reader);
|
||||
if (!has_ptr) {
|
||||
return nullptr;
|
||||
}
|
||||
auto *ret = utils::Downcast<TAst>(Load(ast, reader, loaded_uids));
|
||||
auto *ret = utils::Downcast<TAst>(Load(ast, reader));
|
||||
if (!ret) {
|
||||
throw slk::SlkDecodeException("Loading unknown Ast node type");
|
||||
}
|
||||
@ -44,58 +40,25 @@ cpp<#
|
||||
|
||||
(lcp:in-impl
|
||||
#>cpp
|
||||
void SaveAstPointer(const Tree *ast, slk::Builder *builder,
|
||||
std::vector<int32_t> *saved_uids) {
|
||||
void SaveAstPointer(const Tree *ast, slk::Builder *builder) {
|
||||
slk::Save(static_cast<bool>(ast), builder);
|
||||
if (!ast) {
|
||||
return;
|
||||
}
|
||||
slk::Save(ast->uid_, builder);
|
||||
if (utils::Contains(*saved_uids, ast->uid_)) {
|
||||
return;
|
||||
}
|
||||
slk::Save(*ast, builder, saved_uids);
|
||||
CHECK(!utils::Contains(*saved_uids, ast->uid_)) << "Serializing cyclic AST";
|
||||
saved_uids->push_back(ast->uid_);
|
||||
slk::Save(*ast, builder);
|
||||
}
|
||||
|
||||
Tree *Load(AstStorage *ast, slk::Reader *reader,
|
||||
std::vector<int32_t> *loaded_uids) {
|
||||
// Check if element already deserialized and if yes, return existing
|
||||
// element from storage.
|
||||
int32_t uid;
|
||||
slk::Load(&uid, reader);
|
||||
if (utils::Contains(*loaded_uids, uid)) {
|
||||
auto found = std::find_if(ast->storage_.begin(), ast->storage_.end(),
|
||||
[&](const auto &n) { return n->uid_ == uid; });
|
||||
CHECK(found != ast->storage_.end());
|
||||
return found->get();
|
||||
}
|
||||
Tree *Load(AstStorage *ast, slk::Reader *reader) {
|
||||
std::unique_ptr<Tree> root;
|
||||
slk::ConstructAndLoad(&root, reader, ast, loaded_uids);
|
||||
root->uid_ = uid;
|
||||
slk::ConstructAndLoad(&root, reader, ast);
|
||||
ast->storage_.emplace_back(std::move(root));
|
||||
loaded_uids->push_back(uid);
|
||||
ast->max_existing_uid_ = std::max(ast->max_existing_uid_, uid);
|
||||
return ast->storage_.back().get();
|
||||
}
|
||||
|
||||
Tree *Load(AstStorage *ast, const capnp::Tree::Reader &tree,
|
||||
std::vector<int> *loaded_uids) {
|
||||
// Check if element already deserialized and if yes, return existing
|
||||
// element from storage.
|
||||
auto uid = tree.getUid();
|
||||
if (utils::Contains(*loaded_uids, uid)) {
|
||||
auto found = std::find_if(ast->storage_.begin(), ast->storage_.end(),
|
||||
[&](const auto &n) { return n->uid_ == uid; });
|
||||
CHECK(found != ast->storage_.end());
|
||||
return found->get();
|
||||
}
|
||||
Tree *Load(AstStorage *ast, const capnp::Tree::Reader &tree) {
|
||||
std::unique_ptr<Tree> root;
|
||||
::query::Load(&root, tree, ast, loaded_uids);
|
||||
::query::Load(&root, tree, ast);
|
||||
ast->storage_.emplace_back(std::move(root));
|
||||
loaded_uids->emplace_back(uid);
|
||||
ast->max_existing_uid_ = std::max(ast->max_existing_uid_, uid);
|
||||
return ast->storage_.back().get();
|
||||
}
|
||||
cpp<#)
|
||||
|
@ -51,7 +51,8 @@ void SymbolGenerator::VisitReturnBody(ReturnBody &body, Where *where) {
|
||||
user_symbols.emplace_back(sym_pair.second);
|
||||
}
|
||||
if (user_symbols.empty()) {
|
||||
throw SemanticException("There are no variables in scope to use for '*'.");
|
||||
throw SemanticException(
|
||||
"There are no variables in scope to use for '*'.");
|
||||
}
|
||||
}
|
||||
// WITH/RETURN clause removes declarations of all the previous variables and
|
||||
@ -79,8 +80,8 @@ void SymbolGenerator::VisitReturnBody(ReturnBody &body, Where *where) {
|
||||
}
|
||||
// An improvement would be to infer the type of the expression, so that the
|
||||
// new symbol would have a more specific type.
|
||||
symbol_table_[*named_expr] = CreateSymbol(name, true, Symbol::Type::ANY,
|
||||
named_expr->token_position_);
|
||||
named_expr->MapTo(CreateSymbol(name, true, Symbol::Type::ANY,
|
||||
named_expr->token_position_));
|
||||
}
|
||||
scope_.in_order_by = true;
|
||||
for (const auto &order_pair : body.order_by) {
|
||||
@ -198,7 +199,7 @@ bool SymbolGenerator::PostVisit(Unwind &unwind) {
|
||||
if (HasSymbol(name)) {
|
||||
throw RedeclareVariableError(name);
|
||||
}
|
||||
symbol_table_[*unwind.named_expression_] = CreateSymbol(name, true);
|
||||
unwind.named_expression_->MapTo(CreateSymbol(name, true));
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -212,7 +213,7 @@ bool SymbolGenerator::PostVisit(Match &) {
|
||||
// reference symbols out of bind order.
|
||||
for (auto &ident : scope_.identifiers_in_match) {
|
||||
if (!HasSymbol(ident->name_)) throw UnboundVariableError(ident->name_);
|
||||
symbol_table_[*ident] = scope_.symbols[ident->name_];
|
||||
ident->MapTo(scope_.symbols[ident->name_]);
|
||||
}
|
||||
scope_.identifiers_in_match.clear();
|
||||
return true;
|
||||
@ -270,7 +271,7 @@ SymbolGenerator::ReturnType SymbolGenerator::Visit(Identifier &ident) {
|
||||
if (!HasSymbol(ident.name_)) throw UnboundVariableError(ident.name_);
|
||||
symbol = scope_.symbols[ident.name_];
|
||||
}
|
||||
symbol_table_[ident] = symbol;
|
||||
ident.MapTo(symbol);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -302,9 +303,8 @@ bool SymbolGenerator::PreVisit(Aggregation &aggr) {
|
||||
// Create a virtual symbol for aggregation result.
|
||||
// Currently, we only have aggregation operators which return numbers.
|
||||
auto aggr_name =
|
||||
Aggregation::OpToString(aggr.op_) + std::to_string(aggr.uid_);
|
||||
symbol_table_[aggr] =
|
||||
symbol_table_.CreateSymbol(aggr_name, false, Symbol::Type::NUMBER);
|
||||
Aggregation::OpToString(aggr.op_) + std::to_string(aggr.symbol_pos_);
|
||||
aggr.MapTo(CreateSymbol(aggr_name, false, Symbol::Type::NUMBER));
|
||||
scope_.in_aggregation = true;
|
||||
scope_.has_aggregation = true;
|
||||
return true;
|
||||
@ -435,12 +435,12 @@ bool SymbolGenerator::PreVisit(EdgeAtom &edge_atom) {
|
||||
} else {
|
||||
// Create inner symbols, but don't bind them in scope, since they are to
|
||||
// be used in the missing filter expression.
|
||||
const auto *inner_edge = edge_atom.filter_lambda_.inner_edge;
|
||||
symbol_table_[*inner_edge] = symbol_table_.CreateSymbol(
|
||||
inner_edge->name_, inner_edge->user_declared_, Symbol::Type::EDGE);
|
||||
const auto *inner_node = edge_atom.filter_lambda_.inner_node;
|
||||
symbol_table_[*inner_node] = symbol_table_.CreateSymbol(
|
||||
inner_node->name_, inner_node->user_declared_, Symbol::Type::VERTEX);
|
||||
auto *inner_edge = edge_atom.filter_lambda_.inner_edge;
|
||||
inner_edge->MapTo(symbol_table_.CreateSymbol(
|
||||
inner_edge->name_, inner_edge->user_declared_, Symbol::Type::EDGE));
|
||||
auto *inner_node = edge_atom.filter_lambda_.inner_node;
|
||||
inner_node->MapTo(symbol_table_.CreateSymbol(
|
||||
inner_node->name_, inner_node->user_declared_, Symbol::Type::VERTEX));
|
||||
}
|
||||
if (edge_atom.weight_lambda_.expression) {
|
||||
VisitWithIdentifiers(edge_atom.weight_lambda_.expression,
|
||||
@ -456,9 +456,9 @@ bool SymbolGenerator::PreVisit(EdgeAtom &edge_atom) {
|
||||
if (HasSymbol(edge_atom.total_weight_->name_)) {
|
||||
throw RedeclareVariableError(edge_atom.total_weight_->name_);
|
||||
}
|
||||
symbol_table_[*edge_atom.total_weight_] = GetOrCreateSymbol(
|
||||
edge_atom.total_weight_->MapTo(GetOrCreateSymbol(
|
||||
edge_atom.total_weight_->name_, edge_atom.total_weight_->user_declared_,
|
||||
Symbol::Type::NUMBER);
|
||||
Symbol::Type::NUMBER));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@ -480,8 +480,8 @@ void SymbolGenerator::VisitWithIdentifiers(
|
||||
if (prev_symbol_it != scope_.symbols.end()) {
|
||||
prev_symbol = prev_symbol_it->second;
|
||||
}
|
||||
symbol_table_[*identifier] =
|
||||
CreateSymbol(identifier->name_, identifier->user_declared_);
|
||||
identifier->MapTo(
|
||||
CreateSymbol(identifier->name_, identifier->user_declared_));
|
||||
prev_symbols.emplace_back(prev_symbol, identifier);
|
||||
}
|
||||
// Visit the expression with the new symbols bound.
|
||||
|
@ -11,25 +11,32 @@ namespace query {
|
||||
class SymbolTable final {
|
||||
public:
|
||||
SymbolTable() {}
|
||||
Symbol CreateSymbol(const std::string &name, bool user_declared,
|
||||
Symbol::Type type = Symbol::Type::ANY,
|
||||
int32_t token_position = -1) {
|
||||
int32_t position = position_++;
|
||||
return Symbol(name, position, user_declared, type, token_position);
|
||||
const Symbol &CreateSymbol(const std::string &name, bool user_declared,
|
||||
Symbol::Type type = Symbol::Type::ANY,
|
||||
int32_t token_position = -1) {
|
||||
CHECK(table_.size() <= std::numeric_limits<int32_t>::max())
|
||||
<< "SymbolTable size doesn't fit into 32-bit integer!";
|
||||
int32_t position = static_cast<int32_t>(table_.size());
|
||||
table_.emplace_back(name, position, user_declared, type, token_position);
|
||||
return table_.back();
|
||||
}
|
||||
|
||||
auto &operator[](const Tree &tree) { return table_[tree.uid_]; }
|
||||
|
||||
Symbol &at(const Tree &tree) { return table_.at(tree.uid_); }
|
||||
const Symbol &at(const Tree &tree) const { return table_.at(tree.uid_); }
|
||||
const Symbol &at(const Identifier &ident) const {
|
||||
return table_.at(ident.symbol_pos_);
|
||||
}
|
||||
const Symbol &at(const NamedExpression &nexpr) const {
|
||||
return table_.at(nexpr.symbol_pos_);
|
||||
}
|
||||
const Symbol &at(const Aggregation &aggr) const {
|
||||
return table_.at(aggr.symbol_pos_);
|
||||
}
|
||||
|
||||
// TODO: Remove these since members are public
|
||||
int32_t max_position() const { return position_; }
|
||||
int32_t max_position() const { return static_cast<int32_t>(table_.size()); }
|
||||
|
||||
const auto &table() const { return table_; }
|
||||
|
||||
int32_t position_{0};
|
||||
std::map<int32_t, Symbol> table_;
|
||||
std::vector<Symbol> table_;
|
||||
};
|
||||
|
||||
} // namespace query
|
||||
|
@ -127,9 +127,10 @@ class IndependentSubtreeFinder : public DistributedOperatorVisitor {
|
||||
// a) Extract to ScanAllByLabel + Filter x2
|
||||
|
||||
auto make_prop_lookup = [&]() {
|
||||
auto ident = storage_->Create<Identifier>(
|
||||
scan.output_symbol_.name(), scan.output_symbol_.user_declared());
|
||||
(*symbol_table_)[*ident] = scan.output_symbol_;
|
||||
auto ident = storage_
|
||||
->Create<Identifier>(scan.output_symbol_.name(),
|
||||
scan.output_symbol_.user_declared())
|
||||
->MapTo(scan.output_symbol_);
|
||||
// TODO: When this extraction of a filter is removed, also remove
|
||||
// property_name from ScanAll operators.
|
||||
return storage_->Create<PropertyLookup>(
|
||||
@ -224,9 +225,10 @@ class IndependentSubtreeFinder : public DistributedOperatorVisitor {
|
||||
// Split to ScanAllByLabel + Filter on property
|
||||
auto subtree = std::make_shared<ScanAllByLabel>(
|
||||
scan.input(), scan.output_symbol_, scan.label_, scan.graph_view_);
|
||||
auto ident = storage_->Create<Identifier>(
|
||||
scan.output_symbol_.name(), scan.output_symbol_.user_declared());
|
||||
(*symbol_table_)[*ident] = scan.output_symbol_;
|
||||
auto ident = storage_
|
||||
->Create<Identifier>(scan.output_symbol_.name(),
|
||||
scan.output_symbol_.user_declared())
|
||||
->MapTo(scan.output_symbol_);
|
||||
auto prop_lookup = storage_->Create<PropertyLookup>(
|
||||
ident, storage_->GetPropertyIx(scan.property_name_));
|
||||
auto prop_equal =
|
||||
@ -1259,20 +1261,21 @@ class DistributedPlanner : public HierarchicalLogicalOperatorVisitor {
|
||||
}
|
||||
auto make_ident = [this](const auto &symbol) {
|
||||
auto *ident =
|
||||
distributed_plan_.ast_storage.Create<Identifier>(symbol.name());
|
||||
distributed_plan_.symbol_table[*ident] = symbol;
|
||||
distributed_plan_.ast_storage.Create<Identifier>(symbol.name())
|
||||
->MapTo(symbol);
|
||||
return ident;
|
||||
};
|
||||
auto make_named_expr = [&](const auto &in_sym, const auto &out_sym) {
|
||||
auto *nexpr = distributed_plan_.ast_storage.Create<NamedExpression>(
|
||||
out_sym.name(), make_ident(in_sym));
|
||||
distributed_plan_.symbol_table[*nexpr] = out_sym;
|
||||
auto *nexpr =
|
||||
distributed_plan_.ast_storage
|
||||
.Create<NamedExpression>(out_sym.name(), make_ident(in_sym))
|
||||
->MapTo(out_sym);
|
||||
return nexpr;
|
||||
};
|
||||
auto make_merge_aggregation = [&](auto op, const auto &worker_sym) {
|
||||
auto *worker_ident = make_ident(worker_sym);
|
||||
auto merge_name = Aggregation::OpToString(op) +
|
||||
std::to_string(worker_ident->uid_) + "<-" +
|
||||
std::to_string(worker_ident->symbol_pos_) + "<-" +
|
||||
worker_sym.name();
|
||||
auto merge_sym = distributed_plan_.symbol_table.CreateSymbol(
|
||||
merge_name, false, Symbol::Type::NUMBER);
|
||||
@ -1338,9 +1341,10 @@ class DistributedPlanner : public HierarchicalLogicalOperatorVisitor {
|
||||
auto *div_expr =
|
||||
distributed_plan_.ast_storage.Create<DivisionOperator>(
|
||||
master_sum_ident, to_float);
|
||||
auto *as_avg = distributed_plan_.ast_storage.Create<NamedExpression>(
|
||||
aggr.output_sym.name(), div_expr);
|
||||
distributed_plan_.symbol_table[*as_avg] = aggr.output_sym;
|
||||
auto *as_avg =
|
||||
distributed_plan_.ast_storage
|
||||
.Create<NamedExpression>(aggr.output_sym.name(), div_expr)
|
||||
->MapTo(aggr.output_sym);
|
||||
produce_exprs.emplace_back(as_avg);
|
||||
break;
|
||||
}
|
||||
|
@ -291,22 +291,14 @@ by having only one result from each worker.")
|
||||
:capnp-load (load-ast-pointer "Expression *"))
|
||||
(filter-lambda "ExpansionLambda" :scope :public
|
||||
:documentation "Filter that must be satisfied for expansion to succeed."
|
||||
:slk-save (lambda (member)
|
||||
#>cpp
|
||||
slk::Save(self.${member}, builder, &helper->saved_ast_uids);
|
||||
cpp<#)
|
||||
:slk-load (lambda (member)
|
||||
#>cpp
|
||||
slk::Load(&self->${member}, reader, &helper->ast_storage, &helper->loaded_ast_uids);
|
||||
slk::Load(&self->${member}, reader, &helper->ast_storage);
|
||||
cpp<#)
|
||||
:capnp-type "ExpansionLambda"
|
||||
:capnp-save (lambda (builder member capnp-name)
|
||||
#>cpp
|
||||
Save(${member}, &${builder}, &helper->saved_ast_uids);
|
||||
cpp<#)
|
||||
:capnp-load (lambda (reader member capnp-name)
|
||||
#>cpp
|
||||
Load(&${member}, ${reader}, &helper->ast_storage, &helper->loaded_ast_uids);
|
||||
Load(&${member}, ${reader}, &helper->ast_storage);
|
||||
cpp<#)))
|
||||
(:documentation "BFS expansion operator suited for distributed execution.")
|
||||
(:public
|
||||
|
@ -206,20 +206,17 @@ can serve as inputs to others and thus a sequence of operations is formed.")
|
||||
virtual void set_input(std::shared_ptr<LogicalOperator>) = 0;
|
||||
|
||||
struct SaveHelper {
|
||||
std::vector<int32_t> saved_ast_uids;
|
||||
std::vector<LogicalOperator *> saved_ops;
|
||||
};
|
||||
|
||||
struct LoadHelper {
|
||||
AstStorage ast_storage;
|
||||
std::vector<int32_t> loaded_ast_uids;
|
||||
std::vector<std::pair<uint64_t, std::shared_ptr<LogicalOperator>>>
|
||||
loaded_ops;
|
||||
};
|
||||
|
||||
struct SlkLoadHelper {
|
||||
AstStorage ast_storage;
|
||||
std::vector<int32_t> loaded_ast_uids;
|
||||
std::vector<std::shared_ptr<LogicalOperator>> loaded_ops;
|
||||
};
|
||||
cpp<#)
|
||||
@ -236,21 +233,21 @@ can serve as inputs to others and thus a sequence of operations is formed.")
|
||||
|
||||
(defun slk-save-ast-pointer (member)
|
||||
#>cpp
|
||||
query::SaveAstPointer(self.${member}, builder, &helper->saved_ast_uids);
|
||||
query::SaveAstPointer(self.${member}, builder);
|
||||
cpp<#)
|
||||
|
||||
(defun slk-load-ast-pointer (type)
|
||||
(lambda (member)
|
||||
#>cpp
|
||||
self->${member} = query::LoadAstPointer<query::${type}>(
|
||||
&helper->ast_storage, reader, &helper->loaded_ast_uids);
|
||||
&helper->ast_storage, reader);
|
||||
cpp<#))
|
||||
|
||||
(defun save-ast-pointer (builder member capnp-name)
|
||||
#>cpp
|
||||
if (${member}) {
|
||||
auto ${capnp-name}_builder = ${builder}->init${capnp-name}();
|
||||
Save(*${member}, &${capnp-name}_builder, &helper->saved_ast_uids);
|
||||
Save(*${member}, &${capnp-name}_builder);
|
||||
}
|
||||
cpp<#)
|
||||
|
||||
@ -259,8 +256,7 @@ can serve as inputs to others and thus a sequence of operations is formed.")
|
||||
#>cpp
|
||||
if (${reader}.has${capnp-name}()) {
|
||||
${member} = static_cast<${ast-type}>(Load(&helper->ast_storage,
|
||||
${reader}.get${capnp-name}(),
|
||||
&helper->loaded_ast_uids));
|
||||
${reader}.get${capnp-name}()));
|
||||
} else {
|
||||
${member} = nullptr;
|
||||
}
|
||||
@ -271,7 +267,7 @@ can serve as inputs to others and thus a sequence of operations is formed.")
|
||||
size_t size = self.${member}.size();
|
||||
slk::Save(size, builder);
|
||||
for (const auto *val : self.${member}) {
|
||||
query::SaveAstPointer(val, builder, &helper->saved_ast_uids);
|
||||
query::SaveAstPointer(val, builder);
|
||||
}
|
||||
cpp<#)
|
||||
|
||||
@ -285,14 +281,14 @@ can serve as inputs to others and thus a sequence of operations is formed.")
|
||||
i < size;
|
||||
++i) {
|
||||
self->${member}[i] = query::LoadAstPointer<query::${type}>(
|
||||
&helper->ast_storage, reader, &helper->loaded_ast_uids);
|
||||
&helper->ast_storage, reader);
|
||||
}
|
||||
cpp<#))
|
||||
|
||||
(defun save-ast-vector (ast-type)
|
||||
(lcp:capnp-save-vector "::query::capnp::Tree" ast-type
|
||||
"[helper](auto *builder, const auto &val) {
|
||||
Save(*val, builder, &helper->saved_ast_uids);
|
||||
Save(*val, builder);
|
||||
}"))
|
||||
|
||||
(defun load-ast-vector (ast-type)
|
||||
@ -300,8 +296,7 @@ can serve as inputs to others and thus a sequence of operations is formed.")
|
||||
(format
|
||||
nil
|
||||
"[helper](const auto &reader) {
|
||||
return static_cast<~A>(Load(&helper->ast_storage, reader,
|
||||
&helper->loaded_ast_uids));
|
||||
return static_cast<~A>(Load(&helper->ast_storage, reader));
|
||||
}"
|
||||
ast-type)))
|
||||
|
||||
@ -383,7 +378,7 @@ and false on every following Pull.")
|
||||
slk::Save(size, builder);
|
||||
for (const auto &kv : self.${member}) {
|
||||
slk::Save(kv.first, builder);
|
||||
query::SaveAstPointer(kv.second, builder, &helper->saved_ast_uids);
|
||||
query::SaveAstPointer(kv.second, builder);
|
||||
}
|
||||
cpp<#)
|
||||
|
||||
@ -396,7 +391,7 @@ and false on every following Pull.")
|
||||
storage::Property prop;
|
||||
slk::Load(&prop, reader);
|
||||
auto *expr = query::LoadAstPointer<query::Expression>(
|
||||
&helper->ast_storage, reader, &helper->loaded_ast_uids);
|
||||
&helper->ast_storage, reader);
|
||||
self->${member}[i] = {prop, expr};
|
||||
}
|
||||
cpp<#)
|
||||
@ -407,7 +402,7 @@ and false on every following Pull.")
|
||||
auto prop_builder = ${builder}[i].initFirst();
|
||||
storage::Save(${member}[i].first, &prop_builder);
|
||||
auto expr_builder = ${builder}[i].initSecond();
|
||||
Save(*${member}[i].second, &expr_builder, &helper->saved_ast_uids);
|
||||
Save(*${member}[i].second, &expr_builder);
|
||||
}
|
||||
cpp<#)
|
||||
|
||||
@ -418,7 +413,7 @@ and false on every following Pull.")
|
||||
storage::Property prop;
|
||||
storage::Load(&prop, prop_reader);
|
||||
auto *expr = static_cast<Expression *>(Load(
|
||||
&helper->ast_storage, pair_reader.getSecond(), &helper->loaded_ast_uids));
|
||||
&helper->ast_storage, pair_reader.getSecond()));
|
||||
${member}.emplace_back(prop, expr);
|
||||
}
|
||||
cpp<#)
|
||||
@ -725,7 +720,7 @@ given label.
|
||||
break;
|
||||
}
|
||||
slk::Save(bound_type, builder);
|
||||
query::SaveAstPointer(bound.value(), builder, &helper->saved_ast_uids);
|
||||
query::SaveAstPointer(bound.value(), builder);
|
||||
cpp<#)
|
||||
|
||||
(defun slk-load-optional-bound (member)
|
||||
@ -750,7 +745,7 @@ given label.
|
||||
throw slk::SlkDecodeException("Loading unknown BoundType");
|
||||
}
|
||||
auto *value = query::LoadAstPointer<query::Expression>(
|
||||
&helper->ast_storage, reader, &helper->loaded_ast_uids);
|
||||
&helper->ast_storage, reader);
|
||||
self->${member}.emplace(utils::Bound<query::Expression *>(value, bound_type));
|
||||
cpp<#)
|
||||
|
||||
@ -761,7 +756,7 @@ given label.
|
||||
::utils::capnp::Bound<::query::capnp::Tree>::Type::INCLUSIVE :
|
||||
::utils::capnp::Bound<::query::capnp::Tree>::Type::EXCLUSIVE);
|
||||
auto value_builder = builder->initValue();
|
||||
Save(*bound.value(), &value_builder, &helper->saved_ast_uids);
|
||||
Save(*bound.value(), &value_builder);
|
||||
}"))
|
||||
(funcall (lcp:capnp-save-optional "::utils::capnp::Bound<::query::capnp::Tree>"
|
||||
"utils::Bound<Expression *>"
|
||||
@ -776,7 +771,7 @@ given label.
|
||||
? utils::BoundType::INCLUSIVE
|
||||
: utils::BoundType::EXCLUSIVE;
|
||||
auto *value = static_cast<Expression *>(
|
||||
Load(&helper->ast_storage, reader.getValue(), &helper->loaded_ast_uids));
|
||||
Load(&helper->ast_storage, reader.getValue()));
|
||||
return utils::Bound<Expression *>(value, type);
|
||||
}"))
|
||||
(funcall (lcp:capnp-load-optional "::utils::capnp::Bound<::query::capnp::Tree>"
|
||||
@ -1023,40 +1018,25 @@ pulled.")
|
||||
((inner-edge-symbol "Symbol" :documentation "Currently expanded edge symbol.")
|
||||
(inner-node-symbol "Symbol" :documentation "Currently expanded node symbol.")
|
||||
(expression "Expression *" :documentation "Expression used in lambda during expansion."
|
||||
:slk-save (lambda (member)
|
||||
#>cpp
|
||||
query::SaveAstPointer(self.${member}, builder, saved_ast_uids);
|
||||
cpp<#)
|
||||
:slk-save #'slk-save-ast-pointer
|
||||
:slk-load (lambda (member)
|
||||
#>cpp
|
||||
self->${member} = query::LoadAstPointer<query::Expression>(
|
||||
ast_storage, reader, loaded_ast_uids);
|
||||
ast_storage, reader);
|
||||
cpp<#)
|
||||
:capnp-type "Ast.Tree" :capnp-init nil
|
||||
:capnp-save (lambda (builder member capnp-name)
|
||||
#>cpp
|
||||
if (${member}) {
|
||||
auto ${capnp-name}_builder = ${builder}->init${capnp-name}();
|
||||
Save(*${member}, &${capnp-name}_builder, saved_ast_uids);
|
||||
}
|
||||
cpp<#)
|
||||
:capnp-save #'save-ast-pointer
|
||||
:capnp-load (lambda (reader member capnp-name)
|
||||
#>cpp
|
||||
if (${reader}.has${capnp-name}()) {
|
||||
${member} = static_cast<Expression *>(Load(ast_storage,
|
||||
${reader}.get${capnp-name}(),
|
||||
loaded_ast_uids));
|
||||
${reader}.get${capnp-name}()));
|
||||
} else {
|
||||
${member} = nullptr;
|
||||
}
|
||||
cpp<#)))
|
||||
(:serialize (:slk :save-args '((saved-ast-uids "std::vector<int32_t> *"))
|
||||
:load-args '((ast-storage "query::AstStorage *")
|
||||
(loaded-ast-uids "std::vector<int32_t> *")))
|
||||
(:capnp
|
||||
:save-args '((saved-ast-uids "std::vector<int32_t> *"))
|
||||
:load-args '((ast-storage "AstStorage *")
|
||||
(loaded-ast-uids "std::vector<int32_t> *"))))
|
||||
(:serialize (:slk :load-args '((ast-storage "query::AstStorage *")))
|
||||
(:capnp :load-args '((ast-storage "AstStorage *"))))
|
||||
(:clone :args '((storage "AstStorage *"))))
|
||||
|
||||
(lcp:define-class expand-variable (logical-operator)
|
||||
@ -1089,31 +1069,15 @@ pulled.")
|
||||
:documentation "Optional upper bound of the variable length expansion, defaults are (1, inf)")
|
||||
(filter-lambda "ExpansionLambda"
|
||||
:scope :public
|
||||
:slk-save (lambda (member)
|
||||
#>cpp
|
||||
slk::Save(self.${member}, builder, &helper->saved_ast_uids);
|
||||
cpp<#)
|
||||
:slk-load (lambda (member)
|
||||
#>cpp
|
||||
slk::Load(&self->${member}, reader, &helper->ast_storage, &helper->loaded_ast_uids);
|
||||
slk::Load(&self->${member}, reader, &helper->ast_storage);
|
||||
cpp<#)
|
||||
:capnp-save (lambda (builder member capnp-name)
|
||||
#>cpp
|
||||
Save(${member}, &${builder}, &helper->saved_ast_uids);
|
||||
cpp<#)
|
||||
:capnp-load (lambda (reader member capnp-name)
|
||||
#>cpp
|
||||
Load(&${member}, ${reader}, &helper->ast_storage, &helper->loaded_ast_uids);
|
||||
Load(&${member}, ${reader}, &helper->ast_storage);
|
||||
cpp<#))
|
||||
(weight-lambda "std::experimental::optional<ExpansionLambda>" :scope :public
|
||||
:slk-save (lambda (member)
|
||||
#>cpp
|
||||
slk::Save(static_cast<bool>(self.${member}), builder);
|
||||
if (!self.${member}) {
|
||||
return;
|
||||
}
|
||||
slk::Save(*self.${member}, builder, &helper->saved_ast_uids);
|
||||
cpp<#)
|
||||
:slk-load (lambda (member)
|
||||
#>cpp
|
||||
bool has_value;
|
||||
@ -1123,19 +1087,17 @@ pulled.")
|
||||
return;
|
||||
}
|
||||
query::plan::ExpansionLambda lambda;
|
||||
slk::Load(&lambda, reader, &helper->ast_storage, &helper->loaded_ast_uids);
|
||||
slk::Load(&lambda, reader, &helper->ast_storage);
|
||||
self->${member}.emplace(lambda);
|
||||
cpp<#)
|
||||
:capnp-save (lcp:capnp-save-optional
|
||||
"capnp::ExpansionLambda" "ExpansionLambda"
|
||||
"[helper](auto *builder, const auto &val) {
|
||||
Save(val, builder, &helper->saved_ast_uids);
|
||||
}")
|
||||
"capnp::ExpansionLambda"
|
||||
"ExpansionLambda")
|
||||
:capnp-load (lcp:capnp-load-optional
|
||||
"capnp::ExpansionLambda" "ExpansionLambda"
|
||||
"[helper](const auto &reader) {
|
||||
ExpansionLambda val;
|
||||
Load(&val, reader, &helper->ast_storage, &helper->loaded_ast_uids);
|
||||
Load(&val, reader, &helper->ast_storage);
|
||||
return val;
|
||||
}"))
|
||||
(total-weight "std::experimental::optional<Symbol>" :scope :public
|
||||
|
@ -161,8 +161,7 @@ PropertyFilter::PropertyFilter(const SymbolTable &symbol_table,
|
||||
}
|
||||
|
||||
PropertyFilter::PropertyFilter(
|
||||
const SymbolTable &symbol_table, const Symbol &symbol,
|
||||
PropertyIx property,
|
||||
const SymbolTable &symbol_table, const Symbol &symbol, PropertyIx property,
|
||||
const std::experimental::optional<PropertyFilter::Bound> &lower_bound,
|
||||
const std::experimental::optional<PropertyFilter::Bound> &upper_bound)
|
||||
: symbol_(symbol),
|
||||
@ -251,10 +250,12 @@ void Filters::CollectPatternFilters(Pattern &pattern, SymbolTable &symbol_table,
|
||||
collector.symbols_.insert(symbol); // PropertyLookup uses the symbol.
|
||||
// Now handle the post-expansion filter.
|
||||
// Create a new identifier and a symbol which will be filled in All.
|
||||
auto *identifier = storage.Create<Identifier>(
|
||||
atom->identifier_->name_, atom->identifier_->user_declared_);
|
||||
symbol_table[*identifier] =
|
||||
symbol_table.CreateSymbol(identifier->name_, false);
|
||||
auto *identifier =
|
||||
storage
|
||||
.Create<Identifier>(atom->identifier_->name_,
|
||||
atom->identifier_->user_declared_)
|
||||
->MapTo(
|
||||
symbol_table.CreateSymbol(atom->identifier_->name_, false));
|
||||
// Create an equality expression and store it in all_filters_.
|
||||
auto *property_lookup =
|
||||
storage.Create<PropertyLookup>(identifier, prop_pair.first);
|
||||
@ -282,8 +283,8 @@ void Filters::CollectPatternFilters(Pattern &pattern, SymbolTable &symbol_table,
|
||||
FilterInfo filter_info{FilterInfo::Type::Property, prop_equal,
|
||||
collector.symbols_};
|
||||
// Store a PropertyFilter on the value of the property.
|
||||
filter_info.property_filter.emplace(
|
||||
symbol_table, symbol, prop_pair.first, prop_pair.second);
|
||||
filter_info.property_filter.emplace(symbol_table, symbol, prop_pair.first,
|
||||
prop_pair.second);
|
||||
all_filters_.emplace_back(filter_info);
|
||||
}
|
||||
};
|
||||
|
@ -370,10 +370,9 @@ class ReturnBodyContext : public HierarchicalTreeVisitor {
|
||||
if (!symbol.user_declared()) {
|
||||
continue;
|
||||
}
|
||||
auto *ident = storage_.Create<Identifier>(symbol.name());
|
||||
symbol_table_[*ident] = symbol;
|
||||
auto *named_expr = storage_.Create<NamedExpression>(symbol.name(), ident);
|
||||
symbol_table_[*named_expr] = symbol;
|
||||
auto *ident = storage_.Create<Identifier>(symbol.name())->MapTo(symbol);
|
||||
auto *named_expr =
|
||||
storage_.Create<NamedExpression>(symbol.name(), ident)->MapTo(symbol);
|
||||
// Fill output expressions and symbols with expanded identifiers.
|
||||
named_expressions_.emplace_back(named_expr);
|
||||
output_symbols_.emplace_back(symbol);
|
||||
|
@ -43,11 +43,5 @@ struct TypedValue {
|
||||
}
|
||||
|
||||
struct SymbolTable {
|
||||
position @0 :Int32;
|
||||
table @1 :List(Entry);
|
||||
|
||||
struct Entry {
|
||||
key @0 :Int32;
|
||||
val @1 :Sem.Symbol;
|
||||
}
|
||||
table @0 :List(Sem.Symbol);
|
||||
}
|
||||
|
@ -7,6 +7,7 @@
|
||||
#include "query/serialization.capnp.h"
|
||||
#include "query/typed_value.hpp"
|
||||
#include "storage/distributed/rpc/serialization.hpp"
|
||||
#include "utils/serialization.hpp"
|
||||
|
||||
namespace distributed {
|
||||
class DataManager;
|
||||
@ -31,27 +32,20 @@ void Load(TypedValueVectorCompare *comparator,
|
||||
|
||||
inline void Save(const SymbolTable &symbol_table,
|
||||
capnp::SymbolTable::Builder *builder) {
|
||||
builder->setPosition(symbol_table.max_position());
|
||||
auto list_builder = builder->initTable(symbol_table.table().size());
|
||||
size_t i = 0;
|
||||
for (const auto &entry : symbol_table.table()) {
|
||||
auto entry_builder = list_builder[i++];
|
||||
entry_builder.setKey(entry.first);
|
||||
auto sym_builder = entry_builder.initVal();
|
||||
Save(entry.second, &sym_builder);
|
||||
}
|
||||
utils::SaveVector<capnp::Symbol, Symbol>(
|
||||
symbol_table.table(), &list_builder,
|
||||
[](auto *builder, const auto &symbol) { Save(symbol, builder); });
|
||||
}
|
||||
|
||||
inline void Load(SymbolTable *symbol_table,
|
||||
const capnp::SymbolTable::Reader &reader) {
|
||||
symbol_table->position_ = reader.getPosition();
|
||||
symbol_table->table_.clear();
|
||||
for (const auto &entry_reader : reader.getTable()) {
|
||||
int key = entry_reader.getKey();
|
||||
Symbol val;
|
||||
Load(&val, entry_reader.getVal());
|
||||
symbol_table->table_[key] = val;
|
||||
}
|
||||
utils::LoadVector<capnp::Symbol, Symbol>(
|
||||
&symbol_table->table_, reader.getTable(), [](const auto &reader) {
|
||||
Symbol val;
|
||||
Load(&val, reader);
|
||||
return val;
|
||||
});
|
||||
}
|
||||
|
||||
void Save(const Parameters ¶meters,
|
||||
@ -69,12 +63,10 @@ namespace slk {
|
||||
|
||||
inline void Save(const query::SymbolTable &symbol_table,
|
||||
slk::Builder *builder) {
|
||||
slk::Save(symbol_table.position_, builder);
|
||||
slk::Save(symbol_table.table_, builder);
|
||||
}
|
||||
|
||||
inline void Load(query::SymbolTable *symbol_table, slk::Reader *reader) {
|
||||
slk::Load(&symbol_table->position_, reader);
|
||||
slk::Load(&symbol_table->table_, reader);
|
||||
}
|
||||
|
||||
|
@ -86,15 +86,13 @@ class CapnpAstGenerator : public Base {
|
||||
{
|
||||
query::capnp::Tree::Builder builder =
|
||||
message.initRoot<query::capnp::Tree>();
|
||||
std::vector<int> saved_uids;
|
||||
Save(*visitor.query(), &builder, &saved_uids);
|
||||
Save(*visitor.query(), &builder);
|
||||
}
|
||||
|
||||
{
|
||||
const query::capnp::Tree::Reader reader =
|
||||
message.getRoot<query::capnp::Tree>();
|
||||
std::vector<int> loaded_uids;
|
||||
query_ = dynamic_cast<Query *>(Load(&storage_, reader, &loaded_uids));
|
||||
query_ = dynamic_cast<Query *>(Load(&storage_, reader));
|
||||
}
|
||||
}
|
||||
|
||||
@ -124,14 +122,12 @@ class SlkAstGenerator : public Base {
|
||||
|
||||
slk::Builder builder;
|
||||
{
|
||||
std::vector<int32_t> saved_uids;
|
||||
SaveAstPointer(visitor.query(), &builder, &saved_uids);
|
||||
SaveAstPointer(visitor.query(), &builder);
|
||||
}
|
||||
|
||||
{
|
||||
slk::Reader reader(builder.data(), builder.size());
|
||||
std::vector<int32_t> loaded_uids;
|
||||
query_ = LoadAstPointer<Query>(&storage_, &reader, &loaded_uids);
|
||||
query_ = LoadAstPointer<Query>(&storage_, &reader);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -322,12 +322,9 @@ void BfsTest(Database *db, int lower_bound, int upper_bound,
|
||||
context.symbol_table.CreateSymbol("inner_node", true);
|
||||
query::Symbol inner_edge_sym =
|
||||
context.symbol_table.CreateSymbol("inner_edge", true);
|
||||
query::Identifier *blocked = IDENT("blocked");
|
||||
query::Identifier *inner_node = IDENT("inner_node");
|
||||
query::Identifier *inner_edge = IDENT("inner_edge");
|
||||
context.symbol_table[*blocked] = blocked_sym;
|
||||
context.symbol_table[*inner_node] = inner_node_sym;
|
||||
context.symbol_table[*inner_edge] = inner_edge_sym;
|
||||
query::Identifier *blocked = IDENT("blocked")->MapTo(blocked_sym);
|
||||
query::Identifier *inner_node = IDENT("inner_node")->MapTo(inner_node_sym);
|
||||
query::Identifier *inner_edge = IDENT("inner_edge")->MapTo(inner_edge_sym);
|
||||
|
||||
std::vector<VertexAddress> vertices;
|
||||
std::vector<EdgeAddress> edges;
|
||||
|
@ -45,11 +45,11 @@ ExpandTuple MakeDistributedExpand(
|
||||
GraphView graph_view) {
|
||||
auto edge = EDGE(edge_identifier, direction);
|
||||
auto edge_sym = symbol_table.CreateSymbol(edge_identifier, true);
|
||||
symbol_table[*edge->identifier_] = edge_sym;
|
||||
edge->identifier_->MapTo(edge_sym);
|
||||
|
||||
auto node = NODE(node_identifier);
|
||||
auto node_sym = symbol_table.CreateSymbol(node_identifier, true);
|
||||
symbol_table[*node->identifier_] = node_sym;
|
||||
node->identifier_->MapTo(node_sym);
|
||||
|
||||
auto op = std::make_shared<DistributedExpand>(input, input_symbol, node_sym,
|
||||
edge_sym, direction, edge_types,
|
||||
@ -75,10 +75,9 @@ TEST_F(DistributedQueryPlan, PullProduceRpc) {
|
||||
LIST(LITERAL(42), LITERAL(true), LITERAL("bla"), LITERAL(1), LITERAL(2));
|
||||
auto x = symbol_table.CreateSymbol("x", true);
|
||||
auto unwind = std::make_shared<plan::Unwind>(nullptr, list, x);
|
||||
auto x_expr = IDENT("x");
|
||||
symbol_table[*x_expr] = x;
|
||||
auto x_ne = NEXPR("x", x_expr);
|
||||
symbol_table[*x_ne] = symbol_table.CreateSymbol("x_ne", true);
|
||||
auto x_expr = IDENT("x")->MapTo(x);
|
||||
auto x_ne =
|
||||
NEXPR("x", x_expr)->MapTo(symbol_table.CreateSymbol("x_ne", true));
|
||||
auto produce = MakeProduce(unwind, x_ne);
|
||||
|
||||
// Test that the plan works locally.
|
||||
@ -91,7 +90,7 @@ TEST_F(DistributedQueryPlan, PullProduceRpc) {
|
||||
|
||||
tx::CommandId command_id = dba->transaction().cid();
|
||||
auto &evaluation_context = ctx.evaluation_context;
|
||||
std::vector<query::Symbol> symbols{ctx.symbol_table[*x_ne]};
|
||||
std::vector<query::Symbol> symbols{ctx.symbol_table.at(*x_ne)};
|
||||
auto remote_pull = [this, &command_id, &evaluation_context, &symbols](
|
||||
GraphDbAccessor &dba, int worker_id) {
|
||||
return master().pull_clients().Pull(&dba, worker_id, plan_id, command_id,
|
||||
@ -168,18 +167,14 @@ TEST_F(DistributedQueryPlan, PullProduceRpcWithGraphElements) {
|
||||
auto p = std::make_shared<query::plan::ConstructNamedPath>(
|
||||
r_m.op_, p_sym,
|
||||
std::vector<Symbol>{n.sym_, r_m.edge_sym_, r_m.node_sym_});
|
||||
auto return_n = IDENT("n");
|
||||
symbol_table[*return_n] = n.sym_;
|
||||
auto return_r = IDENT("r");
|
||||
symbol_table[*return_r] = r_m.edge_sym_;
|
||||
auto return_n_r = NEXPR("[n, r]", LIST(return_n, return_r));
|
||||
symbol_table[*return_n_r] = symbol_table.CreateSymbol("", true);
|
||||
auto return_m = NEXPR("m", IDENT("m"));
|
||||
symbol_table[*return_m->expression_] = r_m.node_sym_;
|
||||
symbol_table[*return_m] = symbol_table.CreateSymbol("", true);
|
||||
auto return_p = NEXPR("p", IDENT("p"));
|
||||
symbol_table[*return_p->expression_] = p_sym;
|
||||
symbol_table[*return_p] = symbol_table.CreateSymbol("", true);
|
||||
auto return_n = IDENT("n")->MapTo(n.sym_);
|
||||
auto return_r = IDENT("r")->MapTo(r_m.edge_sym_);
|
||||
auto return_n_r = NEXPR("[n, r]", LIST(return_n, return_r))
|
||||
->MapTo(symbol_table.CreateSymbol("", true));
|
||||
auto return_m = NEXPR("m", IDENT("m")->MapTo(r_m.node_sym_))
|
||||
->MapTo(symbol_table.CreateSymbol("", true));
|
||||
auto return_p = NEXPR("p", IDENT("p")->MapTo(p_sym))
|
||||
->MapTo(symbol_table.CreateSymbol("", true));
|
||||
auto produce = MakeProduce(p, return_n_r, return_m, return_p);
|
||||
|
||||
auto check_result = [prop](int worker_id,
|
||||
@ -211,8 +206,8 @@ TEST_F(DistributedQueryPlan, PullProduceRpcWithGraphElements) {
|
||||
|
||||
tx::CommandId command_id = dba->transaction().cid();
|
||||
auto &evaluation_context = ctx.evaluation_context;
|
||||
std::vector<query::Symbol> symbols{ctx.symbol_table[*return_n_r],
|
||||
ctx.symbol_table[*return_m], p_sym};
|
||||
std::vector<query::Symbol> symbols{ctx.symbol_table.at(*return_n_r),
|
||||
ctx.symbol_table.at(*return_m), p_sym};
|
||||
auto remote_pull = [this, &command_id, &evaluation_context, &symbols](
|
||||
GraphDbAccessor &dba, int worker_id) {
|
||||
return master().pull_clients().Pull(&dba, worker_id, plan_id, command_id,
|
||||
@ -246,8 +241,7 @@ TEST_F(DistributedQueryPlan, Synchronize) {
|
||||
// SET
|
||||
auto literal = LITERAL(42);
|
||||
auto prop = PROPERTY_PAIR("prop");
|
||||
auto m_p = PROPERTY_LOOKUP("m", prop);
|
||||
symbol_table[*m_p->expression_] = r_m.node_sym_;
|
||||
auto m_p = PROPERTY_LOOKUP(IDENT("m")->MapTo(r_m.node_sym_), prop);
|
||||
auto set_m_p =
|
||||
std::make_shared<plan::SetProperty>(r_m.op_, prop.second, m_p, literal);
|
||||
|
||||
@ -261,11 +255,9 @@ TEST_F(DistributedQueryPlan, Synchronize) {
|
||||
std::make_shared<query::plan::Synchronize>(set_m_p, pull_remote, true);
|
||||
|
||||
// RETURN
|
||||
auto n_p = PROPERTY_LOOKUP("n", prop);
|
||||
symbol_table[*n_p->expression_] = n.sym_;
|
||||
auto return_n_p = NEXPR("n.prop", n_p);
|
||||
auto return_n_p_sym = symbol_table.CreateSymbol("n.p", true);
|
||||
symbol_table[*return_n_p] = return_n_p_sym;
|
||||
auto n_p = PROPERTY_LOOKUP(IDENT("n")->MapTo(n.sym_), prop);
|
||||
auto return_n_p =
|
||||
NEXPR("n.prop", n_p)->MapTo(symbol_table.CreateSymbol("n.p", true));
|
||||
auto produce = MakeProduce(synchronize, return_n_p);
|
||||
auto ctx = MakeContext(storage, symbol_table, &dba);
|
||||
auto results = CollectProduce(*produce, &ctx);
|
||||
@ -331,8 +323,7 @@ TEST_F(DistributedQueryPlan, PullRemoteOrderBy) {
|
||||
|
||||
// Query plan for: MATCH (n) RETURN n.prop ORDER BY n.prop;
|
||||
auto n = MakeScanAll(storage, symbol_table, "n");
|
||||
auto n_p = PROPERTY_LOOKUP("n", prop);
|
||||
symbol_table[*n_p->expression_] = n.sym_;
|
||||
auto n_p = PROPERTY_LOOKUP(IDENT("n")->MapTo(n.sym_), prop);
|
||||
auto order_by = std::make_shared<plan::OrderBy>(
|
||||
n.op_, std::vector<SortItem>{{Ordering::ASC, n_p}},
|
||||
std::vector<Symbol>{n.sym_});
|
||||
@ -344,8 +335,8 @@ TEST_F(DistributedQueryPlan, PullRemoteOrderBy) {
|
||||
order_by, plan_id, std::vector<SortItem>{{Ordering::ASC, n_p}},
|
||||
std::vector<Symbol>{n.sym_});
|
||||
|
||||
auto n_p_ne = NEXPR("n.prop", n_p);
|
||||
symbol_table[*n_p_ne] = symbol_table.CreateSymbol("n.prop", true);
|
||||
auto n_p_ne =
|
||||
NEXPR("n.prop", n_p)->MapTo(symbol_table.CreateSymbol("n.prop", true));
|
||||
auto produce = MakeProduce(pull_remote_order_by, n_p_ne);
|
||||
auto ctx = MakeContext(storage, symbol_table, &dba);
|
||||
auto results = CollectProduce(*produce, &ctx);
|
||||
@ -374,10 +365,10 @@ TEST_F(DistributedTransactionTimeout, Timeout) {
|
||||
|
||||
// Make distributed plan for MATCH (n) RETURN n
|
||||
auto scan_all = MakeScanAll(storage, symbol_table, "n");
|
||||
auto output = NEXPR("n", IDENT("n"));
|
||||
auto output =
|
||||
NEXPR("n", IDENT("n")->MapTo(scan_all.sym_))
|
||||
->MapTo(symbol_table.CreateSymbol("named_expression_1", true));
|
||||
auto produce = MakeProduce(scan_all.op_, output);
|
||||
symbol_table[*output->expression_] = scan_all.sym_;
|
||||
symbol_table[*output] = symbol_table.CreateSymbol("named_expression_1", true);
|
||||
|
||||
const int plan_id = 42;
|
||||
master().plan_dispatcher().DispatchPlan(plan_id, produce, symbol_table);
|
||||
@ -387,7 +378,7 @@ TEST_F(DistributedTransactionTimeout, Timeout) {
|
||||
evaluation_context.properties =
|
||||
NamesToProperties(storage.properties_, dba.get());
|
||||
evaluation_context.labels = NamesToLabels(storage.labels_, dba.get());
|
||||
std::vector<query::Symbol> symbols{symbol_table[*output]};
|
||||
std::vector<query::Symbol> symbols{symbol_table.at(*output)};
|
||||
auto remote_pull = [this, &command_id, &evaluation_context, &symbols,
|
||||
&dba]() {
|
||||
return master()
|
||||
@ -1205,7 +1196,8 @@ TYPED_TEST(TestPlanner, MatchReturnSum) {
|
||||
auto merge_sum = SUM(IDENT("worker_sum"));
|
||||
auto master_aggr = ExpectMasterAggregate({merge_sum}, {n_prop2});
|
||||
ExpectPullRemote pull(
|
||||
{symbol_table.at(*sum), symbol_table.at(*n_prop2->expression_)});
|
||||
{symbol_table.at(*sum),
|
||||
symbol_table.at(*dynamic_cast<Identifier *>(n_prop2->expression_))});
|
||||
auto expected =
|
||||
ExpectDistributed(MakeCheckers(ExpectScanAll(), aggr, pull, master_aggr,
|
||||
ExpectProduce(), ExpectProduce()),
|
||||
@ -1314,9 +1306,11 @@ TYPED_TEST(TestPlanner, CreateWithOrderByWhere) {
|
||||
auto r_type = "r";
|
||||
AstStorage storage;
|
||||
auto ident_n = IDENT("n");
|
||||
auto ident_r = IDENT("r");
|
||||
auto ident_m = IDENT("m");
|
||||
auto new_prop = PROPERTY_LOOKUP("new", prop);
|
||||
auto r_prop = PROPERTY_LOOKUP("r", prop);
|
||||
auto m_prop = PROPERTY_LOOKUP("m", prop);
|
||||
auto r_prop = PROPERTY_LOOKUP(ident_r, prop);
|
||||
auto m_prop = PROPERTY_LOOKUP(ident_m, prop);
|
||||
auto query = QUERY(SINGLE_QUERY(
|
||||
CREATE(
|
||||
PATTERN(NODE("n"), EDGE("r", Direction::OUT, {r_type}), NODE("m"))),
|
||||
@ -1325,9 +1319,9 @@ TYPED_TEST(TestPlanner, CreateWithOrderByWhere) {
|
||||
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
|
||||
symbol_table.at(*r_prop->expression_), // `r` in ORDER BY
|
||||
symbol_table.at(*m_prop->expression_), // `m` in WHERE
|
||||
symbol_table.at(*ident_n), // `n` in WITH
|
||||
symbol_table.at(*ident_r), // `r` in ORDER BY
|
||||
symbol_table.at(*ident_m), // `m` in WHERE
|
||||
});
|
||||
auto planner = MakePlanner<TypeParam>(&dba, storage, symbol_table, query);
|
||||
auto expected = ExpectDistributed(
|
||||
@ -1480,8 +1474,8 @@ TYPED_TEST(TestPlanner, DistributedAvg) {
|
||||
auto worker_aggr_op = std::dynamic_pointer_cast<Aggregate>(worker_plan);
|
||||
ASSERT_TRUE(worker_aggr_op);
|
||||
ASSERT_EQ(worker_aggr_op->aggregations_.size(), 2U);
|
||||
symbol_table[*worker_sum] = worker_aggr_op->aggregations_[0].output_sym;
|
||||
symbol_table[*worker_count] = worker_aggr_op->aggregations_[1].output_sym;
|
||||
worker_sum->MapTo(worker_aggr_op->aggregations_[0].output_sym);
|
||||
worker_count->MapTo(worker_aggr_op->aggregations_[1].output_sym);
|
||||
}
|
||||
auto worker_aggr = ExpectAggregate({worker_sum, worker_count}, {});
|
||||
auto merge_sum = SUM(IDENT("worker_sum"));
|
||||
@ -1817,16 +1811,13 @@ TEST(TestPlanner, DistributedCartesianIndexedScanByBothBounds) {
|
||||
auto sym_a = symbol_table.CreateSymbol("a", true);
|
||||
auto scan_a = std::make_shared<ScanAll>(nullptr, sym_a);
|
||||
auto sym_b = symbol_table.CreateSymbol("b", true);
|
||||
query::Expression *lower_expr = IDENT("a");
|
||||
symbol_table[*lower_expr] = sym_a;
|
||||
query::Expression *lower_expr = IDENT("a")->MapTo(sym_a);
|
||||
auto lower_bound = utils::MakeBoundExclusive(lower_expr);
|
||||
query::Expression *upper_expr = IDENT("a");
|
||||
symbol_table[*upper_expr] = sym_a;
|
||||
query::Expression *upper_expr = IDENT("a")->MapTo(sym_a);
|
||||
auto upper_bound = utils::MakeBoundExclusive(upper_expr);
|
||||
auto scan_b = std::make_shared<ScanAllByLabelPropertyRange>(
|
||||
scan_a, sym_b, label, prop, "prop", lower_bound, upper_bound);
|
||||
auto ident_b = IDENT("b");
|
||||
symbol_table[*ident_b] = sym_b;
|
||||
auto ident_b = IDENT("b")->MapTo(sym_b);
|
||||
auto as_b = NEXPR("b", ident_b);
|
||||
auto produce = std::make_shared<Produce>(
|
||||
scan_b, std::vector<query::NamedExpression *>{as_b});
|
||||
@ -1863,13 +1854,11 @@ TEST(TestPlanner, DistributedCartesianIndexedScanByLowerWithBothBounds) {
|
||||
auto sym_b = symbol_table.CreateSymbol("b", true);
|
||||
query::Expression *lower_expr = LITERAL(42);
|
||||
auto lower_bound = utils::MakeBoundExclusive(lower_expr);
|
||||
query::Expression *upper_expr = IDENT("a");
|
||||
symbol_table[*upper_expr] = sym_a;
|
||||
query::Expression *upper_expr = IDENT("a")->MapTo(sym_a);
|
||||
auto upper_bound = utils::MakeBoundExclusive(upper_expr);
|
||||
auto scan_b = std::make_shared<ScanAllByLabelPropertyRange>(
|
||||
scan_a, sym_b, label, prop, "prop", lower_bound, upper_bound);
|
||||
auto ident_b = IDENT("b");
|
||||
symbol_table[*ident_b] = sym_b;
|
||||
auto ident_b = IDENT("b")->MapTo(sym_b);
|
||||
auto as_b = NEXPR("b", ident_b);
|
||||
auto produce = std::make_shared<Produce>(
|
||||
scan_b, std::vector<query::NamedExpression *>{as_b});
|
||||
@ -1908,15 +1897,13 @@ TEST(TestPlanner, DistributedCartesianIndexedScanByUpperWithBothBounds) {
|
||||
auto sym_a = symbol_table.CreateSymbol("a", true);
|
||||
auto scan_a = std::make_shared<ScanAll>(nullptr, sym_a);
|
||||
auto sym_b = symbol_table.CreateSymbol("b", true);
|
||||
query::Expression *lower_expr = IDENT("a");
|
||||
symbol_table[*lower_expr] = sym_a;
|
||||
query::Expression *lower_expr = IDENT("a")->MapTo(sym_a);
|
||||
auto lower_bound = utils::MakeBoundExclusive(lower_expr);
|
||||
query::Expression *upper_expr = LITERAL(42);
|
||||
auto upper_bound = utils::MakeBoundExclusive(upper_expr);
|
||||
auto scan_b = std::make_shared<ScanAllByLabelPropertyRange>(
|
||||
scan_a, sym_b, label, prop, "prop", lower_bound, upper_bound);
|
||||
auto ident_b = IDENT("b");
|
||||
symbol_table[*ident_b] = sym_b;
|
||||
auto ident_b = IDENT("b")->MapTo(sym_b);
|
||||
auto as_b = NEXPR("b", ident_b);
|
||||
auto produce = std::make_shared<Produce>(
|
||||
scan_b, std::vector<query::NamedExpression *>{as_b});
|
||||
|
@ -44,7 +44,7 @@ class ExpressionEvaluatorTest : public ::testing::Test {
|
||||
const TypedValue &value) {
|
||||
auto id = storage.Create<Identifier>(name, true);
|
||||
auto symbol = symbol_table.CreateSymbol(name, true);
|
||||
symbol_table[*id] = symbol;
|
||||
id->MapTo(symbol);
|
||||
frame[symbol] = value;
|
||||
return id;
|
||||
}
|
||||
@ -630,7 +630,7 @@ TEST_F(ExpressionEvaluatorTest, LabelsTest) {
|
||||
v1.add_label(dba->Label("NICE_DOG"));
|
||||
auto *identifier = storage.Create<Identifier>("n");
|
||||
auto node_symbol = symbol_table.CreateSymbol("n", true);
|
||||
symbol_table[*identifier] = node_symbol;
|
||||
identifier->MapTo(node_symbol);
|
||||
frame[node_symbol] = v1;
|
||||
{
|
||||
auto *op = storage.Create<LabelsTest>(
|
||||
@ -662,7 +662,7 @@ TEST_F(ExpressionEvaluatorTest, Aggregation) {
|
||||
auto aggr = storage.Create<Aggregation>(storage.Create<PrimitiveLiteral>(42),
|
||||
nullptr, Aggregation::Op::COUNT);
|
||||
auto aggr_sym = symbol_table.CreateSymbol("aggr", true);
|
||||
symbol_table[*aggr] = aggr_sym;
|
||||
aggr->MapTo(aggr_sym);
|
||||
frame[aggr_sym] = TypedValue(1);
|
||||
auto value = Eval(aggr);
|
||||
EXPECT_EQ(value.ValueInt(), 1);
|
||||
@ -699,8 +699,8 @@ TEST_F(ExpressionEvaluatorTest, All) {
|
||||
auto *all =
|
||||
ALL("x", LIST(LITERAL(1), LITERAL(2)), WHERE(EQ(ident_x, LITERAL(1))));
|
||||
const auto x_sym = symbol_table.CreateSymbol("x", true);
|
||||
symbol_table[*all->identifier_] = x_sym;
|
||||
symbol_table[*ident_x] = x_sym;
|
||||
all->identifier_->MapTo(x_sym);
|
||||
ident_x->MapTo(x_sym);
|
||||
auto value = Eval(all);
|
||||
ASSERT_TRUE(value.IsBool());
|
||||
EXPECT_FALSE(value.ValueBool());
|
||||
@ -710,7 +710,7 @@ TEST_F(ExpressionEvaluatorTest, FunctionAllNullList) {
|
||||
AstStorage storage;
|
||||
auto *all = ALL("x", LITERAL(PropertyValue::Null), WHERE(LITERAL(true)));
|
||||
const auto x_sym = symbol_table.CreateSymbol("x", true);
|
||||
symbol_table[*all->identifier_] = x_sym;
|
||||
all->identifier_->MapTo(x_sym);
|
||||
auto value = Eval(all);
|
||||
EXPECT_TRUE(value.IsNull());
|
||||
}
|
||||
@ -719,7 +719,7 @@ TEST_F(ExpressionEvaluatorTest, FunctionAllWhereWrongType) {
|
||||
AstStorage storage;
|
||||
auto *all = ALL("x", LIST(LITERAL(1)), WHERE(LITERAL(2)));
|
||||
const auto x_sym = symbol_table.CreateSymbol("x", true);
|
||||
symbol_table[*all->identifier_] = x_sym;
|
||||
all->identifier_->MapTo(x_sym);
|
||||
EXPECT_THROW(Eval(all), QueryRuntimeException);
|
||||
}
|
||||
|
||||
@ -729,8 +729,8 @@ TEST_F(ExpressionEvaluatorTest, FunctionSingle) {
|
||||
auto *single =
|
||||
SINGLE("x", LIST(LITERAL(1), LITERAL(2)), WHERE(EQ(ident_x, LITERAL(1))));
|
||||
const auto x_sym = symbol_table.CreateSymbol("x", true);
|
||||
symbol_table[*single->identifier_] = x_sym;
|
||||
symbol_table[*ident_x] = x_sym;
|
||||
single->identifier_->MapTo(x_sym);
|
||||
ident_x->MapTo(x_sym);
|
||||
auto value = Eval(single);
|
||||
ASSERT_TRUE(value.IsBool());
|
||||
EXPECT_TRUE(value.ValueBool());
|
||||
@ -742,8 +742,8 @@ TEST_F(ExpressionEvaluatorTest, FunctionSingle2) {
|
||||
auto *single = SINGLE("x", LIST(LITERAL(1), LITERAL(2)),
|
||||
WHERE(GREATER(ident_x, LITERAL(0))));
|
||||
const auto x_sym = symbol_table.CreateSymbol("x", true);
|
||||
symbol_table[*single->identifier_] = x_sym;
|
||||
symbol_table[*ident_x] = x_sym;
|
||||
single->identifier_->MapTo(x_sym);
|
||||
ident_x->MapTo(x_sym);
|
||||
auto value = Eval(single);
|
||||
ASSERT_TRUE(value.IsBool());
|
||||
EXPECT_FALSE(value.ValueBool());
|
||||
@ -754,7 +754,7 @@ TEST_F(ExpressionEvaluatorTest, FunctionSingleNullList) {
|
||||
auto *single =
|
||||
SINGLE("x", LITERAL(PropertyValue::Null), WHERE(LITERAL(true)));
|
||||
const auto x_sym = symbol_table.CreateSymbol("x", true);
|
||||
symbol_table[*single->identifier_] = x_sym;
|
||||
single->identifier_->MapTo(x_sym);
|
||||
auto value = Eval(single);
|
||||
EXPECT_TRUE(value.IsNull());
|
||||
}
|
||||
@ -766,11 +766,11 @@ TEST_F(ExpressionEvaluatorTest, FunctionReduce) {
|
||||
auto *reduce = REDUCE("sum", LITERAL(0), "x", LIST(LITERAL(1), LITERAL(2)),
|
||||
ADD(ident_sum, ident_x));
|
||||
const auto sum_sym = symbol_table.CreateSymbol("sum", true);
|
||||
symbol_table[*reduce->accumulator_] = sum_sym;
|
||||
symbol_table[*ident_sum] = sum_sym;
|
||||
reduce->accumulator_->MapTo(sum_sym);
|
||||
ident_sum->MapTo(sum_sym);
|
||||
const auto x_sym = symbol_table.CreateSymbol("x", true);
|
||||
symbol_table[*reduce->identifier_] = x_sym;
|
||||
symbol_table[*ident_x] = x_sym;
|
||||
reduce->identifier_->MapTo(x_sym);
|
||||
ident_x->MapTo(x_sym);
|
||||
auto value = Eval(reduce);
|
||||
ASSERT_TRUE(value.IsInt());
|
||||
EXPECT_EQ(value.ValueInt(), 3);
|
||||
@ -783,8 +783,8 @@ TEST_F(ExpressionEvaluatorTest, FunctionExtract) {
|
||||
EXTRACT("x", LIST(LITERAL(1), LITERAL(2), LITERAL(PropertyValue::Null)),
|
||||
ADD(ident_x, LITERAL(1)));
|
||||
const auto x_sym = symbol_table.CreateSymbol("x", true);
|
||||
symbol_table[*extract->identifier_] = x_sym;
|
||||
symbol_table[*ident_x] = x_sym;
|
||||
extract->identifier_->MapTo(x_sym);
|
||||
ident_x->MapTo(x_sym);
|
||||
auto value = Eval(extract);
|
||||
EXPECT_TRUE(value.IsList());
|
||||
;
|
||||
@ -800,8 +800,8 @@ TEST_F(ExpressionEvaluatorTest, FunctionExtractNull) {
|
||||
auto *extract =
|
||||
EXTRACT("x", LITERAL(PropertyValue::Null), ADD(ident_x, LITERAL(1)));
|
||||
const auto x_sym = symbol_table.CreateSymbol("x", true);
|
||||
symbol_table[*extract->identifier_] = x_sym;
|
||||
symbol_table[*ident_x] = x_sym;
|
||||
extract->identifier_->MapTo(x_sym);
|
||||
ident_x->MapTo(x_sym);
|
||||
auto value = Eval(extract);
|
||||
EXPECT_TRUE(value.IsNull());
|
||||
}
|
||||
@ -811,8 +811,8 @@ TEST_F(ExpressionEvaluatorTest, FunctionExtractExceptions) {
|
||||
auto *ident_x = IDENT("x");
|
||||
auto *extract = EXTRACT("x", LITERAL("bla"), ADD(ident_x, LITERAL(1)));
|
||||
const auto x_sym = symbol_table.CreateSymbol("x", true);
|
||||
symbol_table[*extract->identifier_] = x_sym;
|
||||
symbol_table[*ident_x] = x_sym;
|
||||
extract->identifier_->MapTo(x_sym);
|
||||
ident_x->MapTo(x_sym);
|
||||
EXPECT_THROW(Eval(extract), QueryRuntimeException);
|
||||
}
|
||||
|
||||
@ -853,10 +853,10 @@ class ExpressionEvaluatorPropertyLookup : public ExpressionEvaluatorTest {
|
||||
std::make_pair("age", dba->Property("age"));
|
||||
std::pair<std::string, storage::Property> prop_height =
|
||||
std::make_pair("height", dba->Property("height"));
|
||||
Expression *identifier = storage.Create<Identifier>("element");
|
||||
Identifier *identifier = storage.Create<Identifier>("element");
|
||||
Symbol symbol = symbol_table.CreateSymbol("element", true);
|
||||
|
||||
void SetUp() { symbol_table[*identifier] = symbol; }
|
||||
void SetUp() { identifier->MapTo(symbol); }
|
||||
|
||||
auto Value(std::pair<std::string, storage::Property> property) {
|
||||
auto *op = storage.Create<PropertyLookup>(
|
||||
@ -905,7 +905,7 @@ class FunctionTest : public ExpressionEvaluatorTest {
|
||||
auto *ident =
|
||||
storage.Create<Identifier>("arg_" + std::to_string(i), true);
|
||||
auto sym = symbol_table.CreateSymbol("arg_" + std::to_string(i), true);
|
||||
symbol_table[*ident] = sym;
|
||||
ident->MapTo(sym);
|
||||
frame[sym] = tvs[i];
|
||||
expressions.push_back(ident);
|
||||
}
|
||||
|
@ -330,9 +330,9 @@ TYPED_TEST(TestPlanner, MatchMultiPatternSameExpandStart) {
|
||||
// We expect the second pattern to generate only an Expand. Another
|
||||
// ScanAll would be redundant, as it would generate the nodes obtained from
|
||||
// expansion. Additionally, a uniqueness filter is expected.
|
||||
CheckPlan<TypeParam>(
|
||||
query, storage, ExpectScanAll(), ExpectExpand(), ExpectExpand(),
|
||||
ExpectEdgeUniquenessFilter(), ExpectProduce());
|
||||
CheckPlan<TypeParam>(query, storage, ExpectScanAll(), ExpectExpand(),
|
||||
ExpectExpand(), ExpectEdgeUniquenessFilter(),
|
||||
ExpectProduce());
|
||||
}
|
||||
|
||||
TYPED_TEST(TestPlanner, MultiMatch) {
|
||||
@ -456,12 +456,13 @@ TYPED_TEST(TestPlanner, CreateWithSum) {
|
||||
FakeDbAccessor dba;
|
||||
auto prop = dba.Property("prop");
|
||||
AstStorage storage;
|
||||
auto n_prop = PROPERTY_LOOKUP("n", prop);
|
||||
auto ident_n = IDENT("n");
|
||||
auto n_prop = PROPERTY_LOOKUP(ident_n, prop);
|
||||
auto sum = SUM(n_prop);
|
||||
auto query =
|
||||
QUERY(SINGLE_QUERY(CREATE(PATTERN(NODE("n"))), WITH(sum, AS("sum"))));
|
||||
auto symbol_table = query::MakeSymbolTable(query);
|
||||
auto acc = ExpectAccumulate({symbol_table.at(*n_prop->expression_)});
|
||||
auto acc = ExpectAccumulate({symbol_table.at(*ident_n)});
|
||||
auto aggr = ExpectAggregate({sum}, {});
|
||||
auto planner = MakePlanner<TypeParam>(&dba, storage, symbol_table, query);
|
||||
// We expect both the accumulation and aggregation because the part before
|
||||
@ -522,13 +523,14 @@ TYPED_TEST(TestPlanner, CreateReturnSumSkipLimit) {
|
||||
FakeDbAccessor dba;
|
||||
auto prop = dba.Property("prop");
|
||||
AstStorage storage;
|
||||
auto n_prop = PROPERTY_LOOKUP("n", prop);
|
||||
auto ident_n = IDENT("n");
|
||||
auto n_prop = PROPERTY_LOOKUP(ident_n, prop);
|
||||
auto sum = SUM(n_prop);
|
||||
auto query = QUERY(
|
||||
SINGLE_QUERY(CREATE(PATTERN(NODE("n"))),
|
||||
RETURN(sum, AS("s"), SKIP(LITERAL(2)), LIMIT(LITERAL(1)))));
|
||||
auto symbol_table = query::MakeSymbolTable(query);
|
||||
auto acc = ExpectAccumulate({symbol_table.at(*n_prop->expression_)});
|
||||
auto acc = ExpectAccumulate({symbol_table.at(*ident_n)});
|
||||
auto aggr = ExpectAggregate({sum}, {});
|
||||
auto planner = MakePlanner<TypeParam>(&dba, storage, symbol_table, query);
|
||||
CheckPlan(planner.plan(), symbol_table, ExpectCreateNode(), acc, aggr,
|
||||
@ -558,9 +560,11 @@ TYPED_TEST(TestPlanner, CreateWithOrderByWhere) {
|
||||
auto r_type = "r";
|
||||
AstStorage storage;
|
||||
auto ident_n = IDENT("n");
|
||||
auto ident_r = IDENT("r");
|
||||
auto ident_m = IDENT("m");
|
||||
auto new_prop = PROPERTY_LOOKUP("new", prop);
|
||||
auto r_prop = PROPERTY_LOOKUP("r", prop);
|
||||
auto m_prop = PROPERTY_LOOKUP("m", prop);
|
||||
auto r_prop = PROPERTY_LOOKUP(ident_r, prop);
|
||||
auto m_prop = PROPERTY_LOOKUP(ident_m, prop);
|
||||
auto query = QUERY(SINGLE_QUERY(
|
||||
CREATE(
|
||||
PATTERN(NODE("n"), EDGE("r", Direction::OUT, {r_type}), NODE("m"))),
|
||||
@ -569,9 +573,9 @@ TYPED_TEST(TestPlanner, CreateWithOrderByWhere) {
|
||||
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
|
||||
symbol_table.at(*r_prop->expression_), // `r` in ORDER BY
|
||||
symbol_table.at(*m_prop->expression_), // `m` in WHERE
|
||||
symbol_table.at(*ident_n), // `n` in WITH
|
||||
symbol_table.at(*ident_r), // `r` in ORDER BY
|
||||
symbol_table.at(*ident_m), // `m` in WHERE
|
||||
});
|
||||
auto planner = MakePlanner<TypeParam>(&dba, storage, symbol_table, query);
|
||||
CheckPlan(planner.plan(), symbol_table, ExpectCreateNode(),
|
||||
|
@ -48,12 +48,10 @@ TEST(QueryPlan, Accumulate) {
|
||||
EdgeAtom::Direction::BOTH, {}, "m", false, GraphView::OLD);
|
||||
|
||||
auto one = LITERAL(1);
|
||||
auto n_p = PROPERTY_LOOKUP("n", prop);
|
||||
symbol_table[*n_p->expression_] = n.sym_;
|
||||
auto n_p = PROPERTY_LOOKUP(IDENT("n")->MapTo(n.sym_), prop);
|
||||
auto set_n_p =
|
||||
std::make_shared<plan::SetProperty>(r_m.op_, prop, n_p, ADD(n_p, one));
|
||||
auto m_p = PROPERTY_LOOKUP("m", prop);
|
||||
symbol_table[*m_p->expression_] = r_m.node_sym_;
|
||||
auto m_p = PROPERTY_LOOKUP(IDENT("m")->MapTo(r_m.node_sym_), prop);
|
||||
auto set_m_p =
|
||||
std::make_shared<plan::SetProperty>(set_n_p, prop, m_p, ADD(m_p, one));
|
||||
|
||||
@ -63,10 +61,10 @@ TEST(QueryPlan, Accumulate) {
|
||||
last_op, std::vector<Symbol>{n.sym_, r_m.node_sym_});
|
||||
}
|
||||
|
||||
auto n_p_ne = NEXPR("n.p", n_p);
|
||||
symbol_table[*n_p_ne] = symbol_table.CreateSymbol("n_p_ne", true);
|
||||
auto m_p_ne = NEXPR("m.p", m_p);
|
||||
symbol_table[*m_p_ne] = symbol_table.CreateSymbol("m_p_ne", true);
|
||||
auto n_p_ne =
|
||||
NEXPR("n.p", n_p)->MapTo(symbol_table.CreateSymbol("n_p_ne", true));
|
||||
auto m_p_ne =
|
||||
NEXPR("m.p", m_p)->MapTo(symbol_table.CreateSymbol("m_p_ne", true));
|
||||
auto produce = MakeProduce(last_op, n_p_ne, m_p_ne);
|
||||
auto context = MakeContext(storage, symbol_table, &dba);
|
||||
auto results = CollectProduce(*produce, &context);
|
||||
@ -119,27 +117,25 @@ std::shared_ptr<Produce> MakeAggregationProduce(
|
||||
for (auto aggr_op : aggr_ops) {
|
||||
// TODO change this from using IDENT to using AGGREGATION
|
||||
// once AGGREGATION is handled properly in ExpressionEvaluation
|
||||
auto named_expr = NEXPR("", IDENT("aggregation"));
|
||||
auto aggr_sym = symbol_table.CreateSymbol("aggregation", true);
|
||||
auto named_expr =
|
||||
NEXPR("", IDENT("aggregation")->MapTo(aggr_sym))
|
||||
->MapTo(symbol_table.CreateSymbol("named_expression", true));
|
||||
named_expressions.push_back(named_expr);
|
||||
symbol_table[*named_expr->expression_] =
|
||||
symbol_table.CreateSymbol("aggregation", true);
|
||||
symbol_table[*named_expr] =
|
||||
symbol_table.CreateSymbol("named_expression", true);
|
||||
// the key expression is only used in COLLECT_MAP
|
||||
Expression *key_expr_ptr =
|
||||
aggr_op == Aggregation::Op::COLLECT_MAP ? LITERAL("key") : nullptr;
|
||||
aggregates.emplace_back(
|
||||
Aggregate::Element{*aggr_inputs_it++, key_expr_ptr, aggr_op,
|
||||
symbol_table[*named_expr->expression_]});
|
||||
Aggregate::Element{*aggr_inputs_it++, key_expr_ptr, aggr_op, aggr_sym});
|
||||
}
|
||||
|
||||
// Produce will also evaluate group_by expressions and return them after the
|
||||
// aggregations.
|
||||
for (auto group_by_expr : group_by_exprs) {
|
||||
auto named_expr = NEXPR("", group_by_expr);
|
||||
auto named_expr =
|
||||
NEXPR("", group_by_expr)
|
||||
->MapTo(symbol_table.CreateSymbol("named_expression", true));
|
||||
named_expressions.push_back(named_expr);
|
||||
symbol_table[*named_expr] =
|
||||
symbol_table.CreateSymbol("named_expression", true);
|
||||
}
|
||||
auto aggregation =
|
||||
std::make_shared<Aggregate>(input, aggregates, group_by_exprs, remember);
|
||||
@ -179,8 +175,7 @@ class QueryPlanAggregateOps : public ::testing::Test {
|
||||
Aggregation::Op::COLLECT_MAP}) {
|
||||
// match all nodes and perform aggregations
|
||||
auto n = MakeScanAll(storage, symbol_table, "n");
|
||||
auto n_p = PROPERTY_LOOKUP("n", prop);
|
||||
symbol_table[*n_p->expression_] = n.sym_;
|
||||
auto n_p = PROPERTY_LOOKUP(IDENT("n")->MapTo(n.sym_), prop);
|
||||
|
||||
std::vector<Expression *> aggregation_expressions(ops.size(), n_p);
|
||||
std::vector<Expression *> group_bys;
|
||||
@ -326,8 +321,7 @@ TEST(QueryPlan, AggregateGroupByValues) {
|
||||
|
||||
// match all nodes and perform aggregations
|
||||
auto n = MakeScanAll(storage, symbol_table, "n");
|
||||
auto n_p = PROPERTY_LOOKUP("n", prop);
|
||||
symbol_table[*n_p->expression_] = n.sym_;
|
||||
auto n_p = PROPERTY_LOOKUP(IDENT("n")->MapTo(n.sym_), prop);
|
||||
|
||||
auto produce =
|
||||
MakeAggregationProduce(n.op_, symbol_table, storage, {n_p},
|
||||
@ -371,12 +365,9 @@ TEST(QueryPlan, AggregateMultipleGroupBy) {
|
||||
|
||||
// match all nodes and perform aggregations
|
||||
auto n = MakeScanAll(storage, symbol_table, "n");
|
||||
auto n_p1 = PROPERTY_LOOKUP("n", prop1);
|
||||
auto n_p2 = PROPERTY_LOOKUP("n", prop2);
|
||||
auto n_p3 = PROPERTY_LOOKUP("n", prop3);
|
||||
symbol_table[*n_p1->expression_] = n.sym_;
|
||||
symbol_table[*n_p2->expression_] = n.sym_;
|
||||
symbol_table[*n_p3->expression_] = n.sym_;
|
||||
auto n_p1 = PROPERTY_LOOKUP(IDENT("n")->MapTo(n.sym_), prop1);
|
||||
auto n_p2 = PROPERTY_LOOKUP(IDENT("n")->MapTo(n.sym_), prop2);
|
||||
auto n_p3 = PROPERTY_LOOKUP(IDENT("n")->MapTo(n.sym_), prop3);
|
||||
|
||||
auto produce = MakeAggregationProduce(n.op_, symbol_table, storage, {n_p1},
|
||||
{Aggregation::Op::COUNT},
|
||||
@ -394,9 +385,6 @@ TEST(QueryPlan, AggregateNoInput) {
|
||||
SymbolTable symbol_table;
|
||||
|
||||
auto two = LITERAL(2);
|
||||
auto output = NEXPR("two", IDENT("two"));
|
||||
symbol_table[*output->expression_] = symbol_table.CreateSymbol("two", true);
|
||||
|
||||
auto produce = MakeAggregationProduce(nullptr, symbol_table, storage, {two},
|
||||
{Aggregation::Op::COUNT}, {}, {});
|
||||
auto context = MakeContext(storage, symbol_table, dba.get());
|
||||
@ -425,8 +413,7 @@ TEST(QueryPlan, AggregateCountEdgeCases) {
|
||||
SymbolTable symbol_table;
|
||||
|
||||
auto n = MakeScanAll(storage, symbol_table, "n");
|
||||
auto n_p = PROPERTY_LOOKUP("n", prop);
|
||||
symbol_table[*n_p->expression_] = n.sym_;
|
||||
auto n_p = PROPERTY_LOOKUP(IDENT("n")->MapTo(n.sym_), prop);
|
||||
|
||||
// returns -1 when there are no results
|
||||
// otherwise returns MATCH (n) RETURN count(n.prop)
|
||||
@ -485,10 +472,8 @@ TEST(QueryPlan, AggregateFirstValueTypes) {
|
||||
SymbolTable symbol_table;
|
||||
|
||||
auto n = MakeScanAll(storage, symbol_table, "n");
|
||||
auto n_prop_string = PROPERTY_LOOKUP("n", prop_string);
|
||||
symbol_table[*n_prop_string->expression_] = n.sym_;
|
||||
auto n_prop_int = PROPERTY_LOOKUP("n", prop_int);
|
||||
symbol_table[*n_prop_int->expression_] = n.sym_;
|
||||
auto n_prop_string = PROPERTY_LOOKUP(IDENT("n")->MapTo(n.sym_), prop_string);
|
||||
auto n_prop_int = PROPERTY_LOOKUP(IDENT("n")->MapTo(n.sym_), prop_int);
|
||||
auto n_id = n_prop_string->expression_;
|
||||
|
||||
auto aggregate = [&](Expression *expression, Aggregation::Op aggr_op) {
|
||||
@ -545,10 +530,8 @@ TEST(QueryPlan, AggregateTypes) {
|
||||
SymbolTable symbol_table;
|
||||
|
||||
auto n = MakeScanAll(storage, symbol_table, "n");
|
||||
auto n_p1 = PROPERTY_LOOKUP("n", p1);
|
||||
symbol_table[*n_p1->expression_] = n.sym_;
|
||||
auto n_p2 = PROPERTY_LOOKUP("n", p2);
|
||||
symbol_table[*n_p2->expression_] = n.sym_;
|
||||
auto n_p1 = PROPERTY_LOOKUP(IDENT("n")->MapTo(n.sym_), p1);
|
||||
auto n_p2 = PROPERTY_LOOKUP(IDENT("n")->MapTo(n.sym_), p2);
|
||||
|
||||
auto aggregate = [&](Expression *expression, Aggregation::Op aggr_op) {
|
||||
auto produce = MakeAggregationProduce(n.op_, symbol_table, storage,
|
||||
@ -599,16 +582,14 @@ TEST(QueryPlan, Unwind) {
|
||||
|
||||
auto x = symbol_table.CreateSymbol("x", true);
|
||||
auto unwind_0 = std::make_shared<plan::Unwind>(nullptr, input_expr, x);
|
||||
auto x_expr = IDENT("x");
|
||||
symbol_table[*x_expr] = x;
|
||||
auto x_expr = IDENT("x")->MapTo(x);
|
||||
auto y = symbol_table.CreateSymbol("y", true);
|
||||
auto unwind_1 = std::make_shared<plan::Unwind>(unwind_0, x_expr, y);
|
||||
|
||||
auto x_ne = NEXPR("x", x_expr);
|
||||
symbol_table[*x_ne] = symbol_table.CreateSymbol("x_ne", true);
|
||||
auto y_ne = NEXPR("y", IDENT("y"));
|
||||
symbol_table[*y_ne->expression_] = y;
|
||||
symbol_table[*y_ne] = symbol_table.CreateSymbol("y_ne", true);
|
||||
auto x_ne =
|
||||
NEXPR("x", x_expr)->MapTo(symbol_table.CreateSymbol("x_ne", true));
|
||||
auto y_ne = NEXPR("y", IDENT("y")->MapTo(y))
|
||||
->MapTo(symbol_table.CreateSymbol("y_ne", true));
|
||||
auto produce = MakeProduce(unwind_1, x_ne, y_ne);
|
||||
|
||||
auto context = MakeContext(storage, symbol_table, dba.get());
|
||||
|
@ -151,13 +151,12 @@ TEST(QueryPlan, OrderBy) {
|
||||
|
||||
// order by and collect results
|
||||
auto n = MakeScanAll(storage, symbol_table, "n");
|
||||
auto n_p = PROPERTY_LOOKUP("n", prop);
|
||||
symbol_table[*n_p->expression_] = n.sym_;
|
||||
auto n_p = PROPERTY_LOOKUP(IDENT("n")->MapTo(n.sym_), prop);
|
||||
auto order_by = std::make_shared<plan::OrderBy>(
|
||||
n.op_, std::vector<SortItem>{{order_value_pair.first, n_p}},
|
||||
std::vector<Symbol>{n.sym_});
|
||||
auto n_p_ne = NEXPR("n.p", n_p);
|
||||
symbol_table[*n_p_ne] = symbol_table.CreateSymbol("n.p", true);
|
||||
auto n_p_ne =
|
||||
NEXPR("n.p", n_p)->MapTo(symbol_table.CreateSymbol("n.p", true));
|
||||
auto produce = MakeProduce(order_by, n_p_ne);
|
||||
auto context = MakeContext(storage, symbol_table, &dba);
|
||||
auto results = CollectProduce(*produce, &context);
|
||||
@ -194,10 +193,8 @@ TEST(QueryPlan, OrderByMultiple) {
|
||||
|
||||
// order by and collect results
|
||||
auto n = MakeScanAll(storage, symbol_table, "n");
|
||||
auto n_p1 = PROPERTY_LOOKUP("n", p1);
|
||||
symbol_table[*n_p1->expression_] = n.sym_;
|
||||
auto n_p2 = PROPERTY_LOOKUP("n", p2);
|
||||
symbol_table[*n_p2->expression_] = n.sym_;
|
||||
auto n_p1 = PROPERTY_LOOKUP(IDENT("n")->MapTo(n.sym_), p1);
|
||||
auto n_p2 = PROPERTY_LOOKUP(IDENT("n")->MapTo(n.sym_), p2);
|
||||
// order the results so we get
|
||||
// (p1: 0, p2: N-1)
|
||||
// (p1: 0, p2: N-2)
|
||||
@ -209,10 +206,10 @@ TEST(QueryPlan, OrderByMultiple) {
|
||||
{Ordering::DESC, n_p2},
|
||||
},
|
||||
std::vector<Symbol>{n.sym_});
|
||||
auto n_p1_ne = NEXPR("n.p1", n_p1);
|
||||
symbol_table[*n_p1_ne] = symbol_table.CreateSymbol("n.p1", true);
|
||||
auto n_p2_ne = NEXPR("n.p2", n_p2);
|
||||
symbol_table[*n_p2_ne] = symbol_table.CreateSymbol("n.p2", true);
|
||||
auto n_p1_ne =
|
||||
NEXPR("n.p1", n_p1)->MapTo(symbol_table.CreateSymbol("n.p1", true));
|
||||
auto n_p2_ne =
|
||||
NEXPR("n.p2", n_p2)->MapTo(symbol_table.CreateSymbol("n.p2", true));
|
||||
auto produce = MakeProduce(order_by, n_p1_ne, n_p2_ne);
|
||||
auto context = MakeContext(storage, symbol_table, &dba);
|
||||
auto results = CollectProduce(*produce, &context);
|
||||
@ -261,8 +258,7 @@ TEST(QueryPlan, OrderByExceptions) {
|
||||
|
||||
// order by and expect an exception
|
||||
auto n = MakeScanAll(storage, symbol_table, "n");
|
||||
auto n_p = PROPERTY_LOOKUP("n", prop);
|
||||
symbol_table[*n_p->expression_] = n.sym_;
|
||||
auto n_p = PROPERTY_LOOKUP(IDENT("n")->MapTo(n.sym_), prop);
|
||||
auto order_by = std::make_shared<plan::OrderBy>(
|
||||
n.op_, std::vector<SortItem>{{Ordering::ASC, n_p}},
|
||||
std::vector<Symbol>{});
|
||||
|
@ -39,7 +39,7 @@ std::vector<std::vector<TypedValue>> CollectProduce(const Produce &produce,
|
||||
// collect the symbols from the return clause
|
||||
std::vector<Symbol> symbols;
|
||||
for (auto named_expression : produce.named_expressions_)
|
||||
symbols.emplace_back(context->symbol_table[*named_expression]);
|
||||
symbols.emplace_back(context->symbol_table.at(*named_expression));
|
||||
|
||||
// stream out results
|
||||
auto cursor = produce.MakeCursor(*context->db_accessor);
|
||||
@ -86,7 +86,7 @@ ScanAllTuple MakeScanAll(AstStorage &storage, SymbolTable &symbol_table,
|
||||
GraphView graph_view = GraphView::OLD) {
|
||||
auto node = NODE(identifier);
|
||||
auto symbol = symbol_table.CreateSymbol(identifier, true);
|
||||
symbol_table[*node->identifier_] = symbol;
|
||||
node->identifier_->MapTo(symbol);
|
||||
auto logical_op = std::make_shared<ScanAll>(input, symbol, graph_view);
|
||||
return ScanAllTuple{node, logical_op, symbol};
|
||||
}
|
||||
@ -104,7 +104,7 @@ ScanAllTuple MakeScanAllByLabel(
|
||||
GraphView graph_view = GraphView::OLD) {
|
||||
auto node = NODE(identifier);
|
||||
auto symbol = symbol_table.CreateSymbol(identifier, true);
|
||||
symbol_table[*node->identifier_] = symbol;
|
||||
node->identifier_->MapTo(symbol);
|
||||
auto logical_op =
|
||||
std::make_shared<ScanAllByLabel>(input, symbol, label, graph_view);
|
||||
return ScanAllTuple{node, logical_op, symbol};
|
||||
@ -126,7 +126,7 @@ ScanAllTuple MakeScanAllByLabelPropertyRange(
|
||||
GraphView graph_view = GraphView::OLD) {
|
||||
auto node = NODE(identifier);
|
||||
auto symbol = symbol_table.CreateSymbol(identifier, true);
|
||||
symbol_table[*node->identifier_] = symbol;
|
||||
node->identifier_->MapTo(symbol);
|
||||
auto logical_op = std::make_shared<ScanAllByLabelPropertyRange>(
|
||||
input, symbol, label, property, property_name, lower_bound, upper_bound,
|
||||
graph_view);
|
||||
@ -147,7 +147,7 @@ ScanAllTuple MakeScanAllByLabelPropertyValue(
|
||||
GraphView graph_view = GraphView::OLD) {
|
||||
auto node = NODE(identifier);
|
||||
auto symbol = symbol_table.CreateSymbol(identifier, true);
|
||||
symbol_table[*node->identifier_] = symbol;
|
||||
node->identifier_->MapTo(symbol);
|
||||
auto logical_op = std::make_shared<ScanAllByLabelPropertyValue>(
|
||||
input, symbol, label, property, property_name, value, graph_view);
|
||||
return ScanAllTuple{node, logical_op, symbol};
|
||||
@ -170,11 +170,11 @@ ExpandTuple MakeExpand(AstStorage &storage, SymbolTable &symbol_table,
|
||||
GraphView graph_view) {
|
||||
auto edge = EDGE(edge_identifier, direction);
|
||||
auto edge_sym = symbol_table.CreateSymbol(edge_identifier, true);
|
||||
symbol_table[*edge->identifier_] = edge_sym;
|
||||
edge->identifier_->MapTo(edge_sym);
|
||||
|
||||
auto node = NODE(node_identifier);
|
||||
auto node_sym = symbol_table.CreateSymbol(node_identifier, true);
|
||||
symbol_table[*node->identifier_] = node_sym;
|
||||
node->identifier_->MapTo(node_sym);
|
||||
|
||||
auto op = std::make_shared<Expand>(input, input_symbol, node_sym, edge_sym,
|
||||
direction, edge_types, existing_node,
|
||||
|
@ -69,15 +69,13 @@ TEST(QueryPlan, CreateReturn) {
|
||||
node.properties.emplace_back(property.second, LITERAL(42));
|
||||
|
||||
auto create = std::make_shared<CreateNode>(nullptr, node);
|
||||
auto named_expr_n = NEXPR("n", IDENT("n"));
|
||||
symbol_table[*named_expr_n] = symbol_table.CreateSymbol("named_expr_n", true);
|
||||
symbol_table[*named_expr_n->expression_] = node.symbol;
|
||||
auto prop_lookup = PROPERTY_LOOKUP("n", property);
|
||||
symbol_table[*prop_lookup->expression_] = node.symbol;
|
||||
auto named_expr_n_p = NEXPR("n", prop_lookup);
|
||||
symbol_table[*named_expr_n_p] =
|
||||
symbol_table.CreateSymbol("named_expr_n_p", true);
|
||||
symbol_table[*named_expr_n->expression_] = node.symbol;
|
||||
auto named_expr_n =
|
||||
NEXPR("n", IDENT("n")->MapTo(node.symbol))
|
||||
->MapTo(symbol_table.CreateSymbol("named_expr_n", true));
|
||||
auto prop_lookup = PROPERTY_LOOKUP(IDENT("n")->MapTo(node.symbol), property);
|
||||
auto named_expr_n_p =
|
||||
NEXPR("n", prop_lookup)
|
||||
->MapTo(symbol_table.CreateSymbol("named_expr_n_p", true));
|
||||
|
||||
auto produce = MakeProduce(create, named_expr_n, named_expr_n_p);
|
||||
auto context = MakeContext(storage, symbol_table, &dba);
|
||||
@ -267,8 +265,7 @@ TEST(QueryPlan, Delete) {
|
||||
// attempt to delete a vertex, and fail
|
||||
{
|
||||
auto n = MakeScanAll(storage, symbol_table, "n");
|
||||
auto n_get = storage.Create<Identifier>("n");
|
||||
symbol_table[*n_get] = n.sym_;
|
||||
auto n_get = storage.Create<Identifier>("n")->MapTo(n.sym_);
|
||||
auto delete_op = std::make_shared<plan::Delete>(
|
||||
n.op_, std::vector<Expression *>{n_get}, false);
|
||||
auto context = MakeContext(storage, symbol_table, dba.get());
|
||||
@ -281,8 +278,7 @@ TEST(QueryPlan, Delete) {
|
||||
// detach delete a single vertex
|
||||
{
|
||||
auto n = MakeScanAll(storage, symbol_table, "n");
|
||||
auto n_get = storage.Create<Identifier>("n");
|
||||
symbol_table[*n_get] = n.sym_;
|
||||
auto n_get = storage.Create<Identifier>("n")->MapTo(n.sym_);
|
||||
auto delete_op = std::make_shared<plan::Delete>(
|
||||
n.op_, std::vector<Expression *>{n_get}, true);
|
||||
Frame frame(symbol_table.max_position());
|
||||
@ -299,8 +295,7 @@ TEST(QueryPlan, Delete) {
|
||||
auto r_m =
|
||||
MakeExpand(storage, symbol_table, n.op_, n.sym_, "r",
|
||||
EdgeAtom::Direction::OUT, {}, "m", false, GraphView::NEW);
|
||||
auto r_get = storage.Create<Identifier>("r");
|
||||
symbol_table[*r_get] = r_m.edge_sym_;
|
||||
auto r_get = storage.Create<Identifier>("r")->MapTo(r_m.edge_sym_);
|
||||
auto delete_op = std::make_shared<plan::Delete>(
|
||||
r_m.op_, std::vector<Expression *>{r_get}, false);
|
||||
auto context = MakeContext(storage, symbol_table, dba.get());
|
||||
@ -313,8 +308,7 @@ TEST(QueryPlan, Delete) {
|
||||
// delete all remaining vertices
|
||||
{
|
||||
auto n = MakeScanAll(storage, symbol_table, "n");
|
||||
auto n_get = storage.Create<Identifier>("n");
|
||||
symbol_table[*n_get] = n.sym_;
|
||||
auto n_get = storage.Create<Identifier>("n")->MapTo(n.sym_);
|
||||
auto delete_op = std::make_shared<plan::Delete>(
|
||||
n.op_, std::vector<Expression *>{n_get}, false);
|
||||
auto context = MakeContext(storage, symbol_table, dba.get());
|
||||
@ -357,12 +351,9 @@ TEST(QueryPlan, DeleteTwiceDeleteBlockingEdge) {
|
||||
EdgeAtom::Direction::BOTH, {}, "m", false, GraphView::OLD);
|
||||
|
||||
// getter expressions for deletion
|
||||
auto n_get = storage.Create<Identifier>("n");
|
||||
symbol_table[*n_get] = n.sym_;
|
||||
auto r_get = storage.Create<Identifier>("r");
|
||||
symbol_table[*r_get] = r_m.edge_sym_;
|
||||
auto m_get = storage.Create<Identifier>("m");
|
||||
symbol_table[*m_get] = r_m.node_sym_;
|
||||
auto n_get = storage.Create<Identifier>("n")->MapTo(n.sym_);
|
||||
auto r_get = storage.Create<Identifier>("r")->MapTo(r_m.edge_sym_);
|
||||
auto m_get = storage.Create<Identifier>("m")->MapTo(r_m.node_sym_);
|
||||
|
||||
auto delete_op = std::make_shared<plan::Delete>(
|
||||
r_m.op_, std::vector<Expression *>{n_get, r_get, m_get}, detach);
|
||||
@ -398,15 +389,13 @@ TEST(QueryPlan, DeleteReturn) {
|
||||
|
||||
auto n = MakeScanAll(storage, symbol_table, "n");
|
||||
|
||||
auto n_get = storage.Create<Identifier>("n");
|
||||
symbol_table[*n_get] = n.sym_;
|
||||
auto n_get = storage.Create<Identifier>("n")->MapTo(n.sym_);
|
||||
auto delete_op = std::make_shared<plan::Delete>(
|
||||
n.op_, std::vector<Expression *>{n_get}, true);
|
||||
|
||||
auto prop_lookup = PROPERTY_LOOKUP("n", prop);
|
||||
symbol_table[*prop_lookup->expression_] = n.sym_;
|
||||
auto n_p = storage.Create<NamedExpression>("n", prop_lookup);
|
||||
symbol_table[*n_p] = symbol_table.CreateSymbol("bla", true);
|
||||
auto prop_lookup = PROPERTY_LOOKUP(IDENT("n")->MapTo(n.sym_), prop);
|
||||
auto n_p = storage.Create<NamedExpression>("n", prop_lookup)
|
||||
->MapTo(symbol_table.CreateSymbol("bla", true));
|
||||
auto produce = MakeProduce(delete_op, n_p);
|
||||
|
||||
auto context = MakeContext(storage, symbol_table, &dba);
|
||||
@ -449,8 +438,7 @@ TEST(QueryPlan, DeleteAdvance) {
|
||||
SymbolTable symbol_table;
|
||||
|
||||
auto n = MakeScanAll(storage, symbol_table, "n");
|
||||
auto n_get = storage.Create<Identifier>("n");
|
||||
symbol_table[*n_get] = n.sym_;
|
||||
auto n_get = storage.Create<Identifier>("n")->MapTo(n.sym_);
|
||||
auto delete_op = std::make_shared<plan::Delete>(
|
||||
n.op_, std::vector<Expression *>{n_get}, false);
|
||||
auto advance = std::make_shared<Accumulate>(
|
||||
@ -489,13 +477,11 @@ TEST(QueryPlan, SetProperty) {
|
||||
auto prop1 = dba.Property("prop1");
|
||||
auto literal = LITERAL(42);
|
||||
|
||||
auto n_p = PROPERTY_LOOKUP("n", prop1);
|
||||
symbol_table[*n_p->expression_] = n.sym_;
|
||||
auto n_p = PROPERTY_LOOKUP(IDENT("n")->MapTo(n.sym_), prop1);
|
||||
auto set_n_p =
|
||||
std::make_shared<plan::SetProperty>(r_m.op_, prop1, n_p, literal);
|
||||
|
||||
auto r_p = PROPERTY_LOOKUP("r", prop1);
|
||||
symbol_table[*r_p->expression_] = r_m.edge_sym_;
|
||||
auto r_p = PROPERTY_LOOKUP(IDENT("r")->MapTo(r_m.edge_sym_), prop1);
|
||||
auto set_r_p =
|
||||
std::make_shared<plan::SetProperty>(set_n_p, prop1, r_p, literal);
|
||||
auto context = MakeContext(storage, symbol_table, &dba);
|
||||
@ -544,10 +530,8 @@ TEST(QueryPlan, SetProperties) {
|
||||
: plan::SetProperties::Op::REPLACE;
|
||||
|
||||
// set properties on r to n, and on r to m
|
||||
auto r_ident = IDENT("r");
|
||||
symbol_table[*r_ident] = r_m.edge_sym_;
|
||||
auto m_ident = IDENT("m");
|
||||
symbol_table[*m_ident] = r_m.node_sym_;
|
||||
auto r_ident = IDENT("r")->MapTo(r_m.edge_sym_);
|
||||
auto m_ident = IDENT("m")->MapTo(r_m.node_sym_);
|
||||
auto set_r_to_n =
|
||||
std::make_shared<plan::SetProperties>(r_m.op_, n.sym_, r_ident, op);
|
||||
auto set_m_to_r = std::make_shared<plan::SetProperties>(
|
||||
@ -647,12 +631,10 @@ TEST(QueryPlan, RemoveProperty) {
|
||||
MakeExpand(storage, symbol_table, n.op_, n.sym_, "r",
|
||||
EdgeAtom::Direction::OUT, {}, "m", false, GraphView::OLD);
|
||||
|
||||
auto n_p = PROPERTY_LOOKUP("n", prop1);
|
||||
symbol_table[*n_p->expression_] = n.sym_;
|
||||
auto n_p = PROPERTY_LOOKUP(IDENT("n")->MapTo(n.sym_), prop1);
|
||||
auto set_n_p = std::make_shared<plan::RemoveProperty>(r_m.op_, prop1, n_p);
|
||||
|
||||
auto r_p = PROPERTY_LOOKUP("r", prop1);
|
||||
symbol_table[*r_p->expression_] = r_m.edge_sym_;
|
||||
auto r_p = PROPERTY_LOOKUP(IDENT("r")->MapTo(r_m.edge_sym_), prop1);
|
||||
auto set_r_p = std::make_shared<plan::RemoveProperty>(set_n_p, prop1, r_p);
|
||||
auto context = MakeContext(storage, symbol_table, &dba);
|
||||
EXPECT_EQ(2, PullAll(*set_r_p, &context));
|
||||
@ -733,8 +715,7 @@ TEST(QueryPlan, NodeFilterSet) {
|
||||
LITERAL(42));
|
||||
auto node_filter = std::make_shared<Filter>(expand.op_, filter_expr);
|
||||
// SET n.prop = n.prop + 1
|
||||
auto set_prop = PROPERTY_LOOKUP("n", prop);
|
||||
symbol_table[*set_prop->expression_] = scan_all.sym_;
|
||||
auto set_prop = PROPERTY_LOOKUP(IDENT("n")->MapTo(scan_all.sym_), prop);
|
||||
auto add = ADD(set_prop, LITERAL(1));
|
||||
auto set = std::make_shared<plan::SetProperty>(node_filter, prop.second,
|
||||
set_prop, add);
|
||||
@ -771,13 +752,11 @@ TEST(QueryPlan, FilterRemove) {
|
||||
auto expand =
|
||||
MakeExpand(storage, symbol_table, scan_all.op_, scan_all.sym_, "r",
|
||||
EdgeAtom::Direction::BOTH, {}, "m", false, GraphView::OLD);
|
||||
auto filter_prop = PROPERTY_LOOKUP("n", prop);
|
||||
symbol_table[*filter_prop->expression_] = scan_all.sym_;
|
||||
auto filter_prop = PROPERTY_LOOKUP(IDENT("n")->MapTo(scan_all.sym_), prop);
|
||||
auto filter =
|
||||
std::make_shared<Filter>(expand.op_, LESS(filter_prop, LITERAL(43)));
|
||||
// REMOVE n.prop
|
||||
auto rem_prop = PROPERTY_LOOKUP("n", prop);
|
||||
symbol_table[*rem_prop->expression_] = scan_all.sym_;
|
||||
auto rem_prop = PROPERTY_LOOKUP(IDENT("n")->MapTo(scan_all.sym_), prop);
|
||||
auto rem =
|
||||
std::make_shared<plan::RemoveProperty>(filter, prop.second, rem_prop);
|
||||
auto context = MakeContext(storage, symbol_table, &dba);
|
||||
@ -838,14 +817,12 @@ TEST(QueryPlan, Merge) {
|
||||
auto r_m =
|
||||
MakeExpand(storage, symbol_table, std::make_shared<Once>(), n.sym_, "r",
|
||||
EdgeAtom::Direction::BOTH, {}, "m", false, GraphView::OLD);
|
||||
auto m_p = PROPERTY_LOOKUP("m", prop);
|
||||
symbol_table[*m_p->expression_] = r_m.node_sym_;
|
||||
auto m_p = PROPERTY_LOOKUP(IDENT("m")->MapTo(r_m.node_sym_), prop);
|
||||
auto m_set = std::make_shared<plan::SetProperty>(r_m.op_, prop.second, m_p,
|
||||
LITERAL(1));
|
||||
|
||||
// merge_create branch
|
||||
auto n_p = PROPERTY_LOOKUP("n", prop);
|
||||
symbol_table[*n_p->expression_] = n.sym_;
|
||||
auto n_p = PROPERTY_LOOKUP(IDENT("n")->MapTo(n.sym_), prop);
|
||||
auto n_set = std::make_shared<plan::SetProperty>(
|
||||
std::make_shared<Once>(), prop.second, n_p, LITERAL(2));
|
||||
|
||||
@ -910,8 +887,7 @@ TEST(QueryPlan, SetPropertiesOnNull) {
|
||||
AstStorage storage;
|
||||
SymbolTable symbol_table;
|
||||
auto n = MakeScanAll(storage, symbol_table, "n");
|
||||
auto n_ident = IDENT("n");
|
||||
symbol_table[*n_ident] = n.sym_;
|
||||
auto n_ident = IDENT("n")->MapTo(n.sym_);
|
||||
auto optional = std::make_shared<plan::Optional>(nullptr, n.op_,
|
||||
std::vector<Symbol>{n.sym_});
|
||||
auto set_op = std::make_shared<plan::SetProperties>(
|
||||
@ -929,8 +905,6 @@ TEST(QueryPlan, SetLabelsOnNull) {
|
||||
AstStorage storage;
|
||||
SymbolTable symbol_table;
|
||||
auto n = MakeScanAll(storage, symbol_table, "n");
|
||||
auto n_ident = IDENT("n");
|
||||
symbol_table[*n_ident] = n.sym_;
|
||||
auto optional = std::make_shared<plan::Optional>(nullptr, n.op_,
|
||||
std::vector<Symbol>{n.sym_});
|
||||
auto set_op = std::make_shared<plan::SetLabels>(
|
||||
@ -965,8 +939,6 @@ TEST(QueryPlan, RemoveLabelsOnNull) {
|
||||
AstStorage storage;
|
||||
SymbolTable symbol_table;
|
||||
auto n = MakeScanAll(storage, symbol_table, "n");
|
||||
auto n_ident = IDENT("n");
|
||||
symbol_table[*n_ident] = n.sym_;
|
||||
auto optional = std::make_shared<plan::Optional>(nullptr, n.op_,
|
||||
std::vector<Symbol>{n.sym_});
|
||||
auto remove_op = std::make_shared<plan::RemoveLabels>(
|
||||
@ -988,13 +960,11 @@ TEST(QueryPlan, DeleteSetProperty) {
|
||||
SymbolTable symbol_table;
|
||||
// MATCH (n) DELETE n SET n.property = 42
|
||||
auto n = MakeScanAll(storage, symbol_table, "n");
|
||||
auto n_get = storage.Create<Identifier>("n");
|
||||
symbol_table[*n_get] = n.sym_;
|
||||
auto n_get = storage.Create<Identifier>("n")->MapTo(n.sym_);
|
||||
auto delete_op = std::make_shared<plan::Delete>(
|
||||
n.op_, std::vector<Expression *>{n_get}, false);
|
||||
auto prop = PROPERTY_PAIR("property");
|
||||
auto n_prop = PROPERTY_LOOKUP("n", prop);
|
||||
symbol_table[*n_prop->expression_] = n.sym_;
|
||||
auto n_prop = PROPERTY_LOOKUP(IDENT("n")->MapTo(n.sym_), prop);
|
||||
auto set_op = std::make_shared<plan::SetProperty>(delete_op, prop.second,
|
||||
n_prop, LITERAL(42));
|
||||
auto context = MakeContext(storage, symbol_table, &dba);
|
||||
@ -1013,17 +983,13 @@ TEST(QueryPlan, DeleteSetPropertiesFromMap) {
|
||||
SymbolTable symbol_table;
|
||||
// MATCH (n) DELETE n SET n = {property: 42}
|
||||
auto n = MakeScanAll(storage, symbol_table, "n");
|
||||
auto n_get = storage.Create<Identifier>("n");
|
||||
symbol_table[*n_get] = n.sym_;
|
||||
auto n_get = storage.Create<Identifier>("n")->MapTo(n.sym_);
|
||||
auto delete_op = std::make_shared<plan::Delete>(
|
||||
n.op_, std::vector<Expression *>{n_get}, false);
|
||||
auto prop = PROPERTY_PAIR("property");
|
||||
auto n_prop = PROPERTY_LOOKUP("n", prop);
|
||||
symbol_table[*n_prop->expression_] = n.sym_;
|
||||
std::unordered_map<PropertyIx, Expression *> prop_map;
|
||||
prop_map.emplace(storage.GetPropertyIx(prop.first), LITERAL(42));
|
||||
auto *rhs = storage.Create<MapLiteral>(prop_map);
|
||||
symbol_table[*rhs] = n.sym_;
|
||||
for (auto op_type :
|
||||
{plan::SetProperties::Op::REPLACE, plan::SetProperties::Op::UPDATE}) {
|
||||
auto set_op =
|
||||
@ -1048,15 +1014,10 @@ TEST(QueryPlan, DeleteSetPropertiesFromVertex) {
|
||||
SymbolTable symbol_table;
|
||||
// MATCH (n) DELETE n SET n = n
|
||||
auto n = MakeScanAll(storage, symbol_table, "n");
|
||||
auto n_get = storage.Create<Identifier>("n");
|
||||
symbol_table[*n_get] = n.sym_;
|
||||
auto n_get = storage.Create<Identifier>("n")->MapTo(n.sym_);
|
||||
auto delete_op = std::make_shared<plan::Delete>(
|
||||
n.op_, std::vector<Expression *>{n_get}, false);
|
||||
auto prop = PROPERTY_PAIR("property");
|
||||
auto n_prop = PROPERTY_LOOKUP("n", prop);
|
||||
symbol_table[*n_prop->expression_] = n.sym_;
|
||||
auto *rhs = IDENT("n");
|
||||
symbol_table[*rhs] = n.sym_;
|
||||
auto *rhs = IDENT("n")->MapTo(n.sym_);
|
||||
for (auto op_type :
|
||||
{plan::SetProperties::Op::REPLACE, plan::SetProperties::Op::UPDATE}) {
|
||||
auto set_op =
|
||||
@ -1077,8 +1038,7 @@ TEST(QueryPlan, DeleteRemoveLabels) {
|
||||
SymbolTable symbol_table;
|
||||
// MATCH (n) DELETE n REMOVE n :label
|
||||
auto n = MakeScanAll(storage, symbol_table, "n");
|
||||
auto n_get = storage.Create<Identifier>("n");
|
||||
symbol_table[*n_get] = n.sym_;
|
||||
auto n_get = storage.Create<Identifier>("n")->MapTo(n.sym_);
|
||||
auto delete_op = std::make_shared<plan::Delete>(
|
||||
n.op_, std::vector<Expression *>{n_get}, false);
|
||||
std::vector<storage::Label> labels{dba->Label("label")};
|
||||
@ -1099,13 +1059,11 @@ TEST(QueryPlan, DeleteRemoveProperty) {
|
||||
SymbolTable symbol_table;
|
||||
// MATCH (n) DELETE n REMOVE n.property
|
||||
auto n = MakeScanAll(storage, symbol_table, "n");
|
||||
auto n_get = storage.Create<Identifier>("n");
|
||||
symbol_table[*n_get] = n.sym_;
|
||||
auto n_get = storage.Create<Identifier>("n")->MapTo(n.sym_);
|
||||
auto delete_op = std::make_shared<plan::Delete>(
|
||||
n.op_, std::vector<Expression *>{n_get}, false);
|
||||
auto prop = PROPERTY_PAIR("property");
|
||||
auto n_prop = PROPERTY_LOOKUP("n", prop);
|
||||
symbol_table[*n_prop->expression_] = n.sym_;
|
||||
auto n_prop = PROPERTY_LOOKUP(IDENT("n")->MapTo(n.sym_), prop);
|
||||
auto rem_op =
|
||||
std::make_shared<plan::RemoveProperty>(delete_op, prop.second, n_prop);
|
||||
auto context = MakeContext(storage, symbol_table, &dba);
|
||||
|
@ -52,11 +52,10 @@ TEST_F(MatchReturnFixture, MatchReturn) {
|
||||
auto test_pull_count = [&](GraphView graph_view) {
|
||||
auto scan_all =
|
||||
MakeScanAll(storage, symbol_table, "n", nullptr, graph_view);
|
||||
auto output = NEXPR("n", IDENT("n"));
|
||||
auto output =
|
||||
NEXPR("n", IDENT("n")->MapTo(scan_all.sym_))
|
||||
->MapTo(symbol_table.CreateSymbol("named_expression_1", true));
|
||||
auto produce = MakeProduce(scan_all.op_, output);
|
||||
symbol_table[*output->expression_] = scan_all.sym_;
|
||||
symbol_table[*output] =
|
||||
symbol_table.CreateSymbol("named_expression_1", true);
|
||||
auto context = MakeContext(storage, symbol_table, dba_.get());
|
||||
return PullAll(*produce, &context);
|
||||
};
|
||||
@ -78,9 +77,9 @@ TEST_F(MatchReturnFixture, MatchReturnPath) {
|
||||
Symbol path_sym = symbol_table.CreateSymbol("path", true);
|
||||
auto make_path = std::make_shared<ConstructNamedPath>(
|
||||
scan_all.op_, path_sym, std::vector<Symbol>{scan_all.sym_});
|
||||
auto output = NEXPR("path", IDENT("path"));
|
||||
symbol_table[*output->expression_] = path_sym;
|
||||
symbol_table[*output] = symbol_table.CreateSymbol("named_expression_1", true);
|
||||
auto output =
|
||||
NEXPR("path", IDENT("path")->MapTo(path_sym))
|
||||
->MapTo(symbol_table.CreateSymbol("named_expression_1", true));
|
||||
auto produce = MakeProduce(make_path, output);
|
||||
auto results = Results<query::Path>(produce);
|
||||
ASSERT_EQ(results.size(), 2);
|
||||
@ -104,14 +103,12 @@ TEST(QueryPlan, MatchReturnCartesian) {
|
||||
|
||||
auto n = MakeScanAll(storage, symbol_table, "n");
|
||||
auto m = MakeScanAll(storage, symbol_table, "m", n.op_);
|
||||
auto return_n = NEXPR("n", IDENT("n"));
|
||||
symbol_table[*return_n->expression_] = n.sym_;
|
||||
symbol_table[*return_n] =
|
||||
symbol_table.CreateSymbol("named_expression_1", true);
|
||||
auto return_m = NEXPR("m", IDENT("m"));
|
||||
symbol_table[*return_m->expression_] = m.sym_;
|
||||
symbol_table[*return_m] =
|
||||
symbol_table.CreateSymbol("named_expression_2", true);
|
||||
auto return_n =
|
||||
NEXPR("n", IDENT("n")->MapTo(n.sym_))
|
||||
->MapTo(symbol_table.CreateSymbol("named_expression_1", true));
|
||||
auto return_m =
|
||||
NEXPR("m", IDENT("m")->MapTo(m.sym_))
|
||||
->MapTo(symbol_table.CreateSymbol("named_expression_2", true));
|
||||
auto produce = MakeProduce(m.op_, return_n, return_m);
|
||||
auto context = MakeContext(storage, symbol_table, dba.get());
|
||||
auto results = CollectProduce(*produce, &context);
|
||||
@ -138,7 +135,7 @@ TEST(QueryPlan, StandaloneReturn) {
|
||||
|
||||
auto output = NEXPR("n", LITERAL(42));
|
||||
auto produce = MakeProduce(std::shared_ptr<LogicalOperator>(nullptr), output);
|
||||
symbol_table[*output] = symbol_table.CreateSymbol("named_expression_1", true);
|
||||
output->MapTo(symbol_table.CreateSymbol("named_expression_1", true));
|
||||
|
||||
auto context = MakeContext(storage, symbol_table, dba.get());
|
||||
auto results = CollectProduce(*produce, &context);
|
||||
@ -189,9 +186,9 @@ TEST(QueryPlan, NodeFilterLabelsAndProperties) {
|
||||
auto node_filter = std::make_shared<Filter>(n.op_, filter_expr);
|
||||
|
||||
// make a named expression and a produce
|
||||
auto output = NEXPR("x", IDENT("n"));
|
||||
symbol_table[*output->expression_] = n.sym_;
|
||||
symbol_table[*output] = symbol_table.CreateSymbol("named_expression_1", true);
|
||||
auto output =
|
||||
NEXPR("x", IDENT("n")->MapTo(n.sym_))
|
||||
->MapTo(symbol_table.CreateSymbol("named_expression_1", true));
|
||||
auto produce = MakeProduce(node_filter, output);
|
||||
|
||||
auto context = MakeContext(storage, symbol_table, &dba);
|
||||
@ -244,13 +241,11 @@ TEST(QueryPlan, NodeFilterMultipleLabels) {
|
||||
auto node_filter = std::make_shared<Filter>(n.op_, filter_expr);
|
||||
|
||||
// make a named expression and a produce
|
||||
auto output = NEXPR("n", IDENT("n"));
|
||||
auto output =
|
||||
NEXPR("n", IDENT("n")->MapTo(n.sym_))
|
||||
->MapTo(symbol_table.CreateSymbol("named_expression_1", true));
|
||||
auto produce = MakeProduce(node_filter, output);
|
||||
|
||||
// fill up the symbol table
|
||||
symbol_table[*output] = symbol_table.CreateSymbol("named_expression_1", true);
|
||||
symbol_table[*output->expression_] = n.sym_;
|
||||
|
||||
auto context = MakeContext(storage, symbol_table, dba.get());
|
||||
auto results = CollectProduce(*produce, &context);
|
||||
EXPECT_EQ(results.size(), 2);
|
||||
@ -275,14 +270,12 @@ TEST(QueryPlan, Cartesian) {
|
||||
|
||||
auto n = MakeScanAll(storage, symbol_table, "n");
|
||||
auto m = MakeScanAll(storage, symbol_table, "m");
|
||||
auto return_n = NEXPR("n", IDENT("n"));
|
||||
symbol_table[*return_n->expression_] = n.sym_;
|
||||
symbol_table[*return_n] =
|
||||
symbol_table.CreateSymbol("named_expression_1", true);
|
||||
auto return_m = NEXPR("m", IDENT("m"));
|
||||
symbol_table[*return_m->expression_] = m.sym_;
|
||||
symbol_table[*return_m] =
|
||||
symbol_table.CreateSymbol("named_expression_2", true);
|
||||
auto return_n =
|
||||
NEXPR("n", IDENT("n")->MapTo(n.sym_))
|
||||
->MapTo(symbol_table.CreateSymbol("named_expression_1", true));
|
||||
auto return_m =
|
||||
NEXPR("m", IDENT("m")->MapTo(m.sym_))
|
||||
->MapTo(symbol_table.CreateSymbol("named_expression_2", true));
|
||||
|
||||
std::vector<Symbol> left_symbols{n.sym_};
|
||||
std::vector<Symbol> right_symbols{m.sym_};
|
||||
@ -311,14 +304,12 @@ TEST(QueryPlan, CartesianEmptySet) {
|
||||
|
||||
auto n = MakeScanAll(storage, symbol_table, "n");
|
||||
auto m = MakeScanAll(storage, symbol_table, "m");
|
||||
auto return_n = NEXPR("n", IDENT("n"));
|
||||
symbol_table[*return_n->expression_] = n.sym_;
|
||||
symbol_table[*return_n] =
|
||||
symbol_table.CreateSymbol("named_expression_1", true);
|
||||
auto return_m = NEXPR("m", IDENT("m"));
|
||||
symbol_table[*return_m->expression_] = m.sym_;
|
||||
symbol_table[*return_m] =
|
||||
symbol_table.CreateSymbol("named_expression_2", true);
|
||||
auto return_n =
|
||||
NEXPR("n", IDENT("n")->MapTo(n.sym_))
|
||||
->MapTo(symbol_table.CreateSymbol("named_expression_1", true));
|
||||
auto return_m =
|
||||
NEXPR("m", IDENT("m")->MapTo(m.sym_))
|
||||
->MapTo(symbol_table.CreateSymbol("named_expression_2", true));
|
||||
|
||||
std::vector<Symbol> left_symbols{n.sym_};
|
||||
std::vector<Symbol> right_symbols{m.sym_};
|
||||
@ -350,18 +341,15 @@ TEST(QueryPlan, CartesianThreeWay) {
|
||||
auto n = MakeScanAll(storage, symbol_table, "n");
|
||||
auto m = MakeScanAll(storage, symbol_table, "m");
|
||||
auto l = MakeScanAll(storage, symbol_table, "l");
|
||||
auto return_n = NEXPR("n", IDENT("n"));
|
||||
symbol_table[*return_n->expression_] = n.sym_;
|
||||
symbol_table[*return_n] =
|
||||
symbol_table.CreateSymbol("named_expression_1", true);
|
||||
auto return_m = NEXPR("m", IDENT("m"));
|
||||
symbol_table[*return_m->expression_] = m.sym_;
|
||||
symbol_table[*return_m] =
|
||||
symbol_table.CreateSymbol("named_expression_2", true);
|
||||
auto return_l = NEXPR("l", IDENT("l"));
|
||||
symbol_table[*return_l->expression_] = l.sym_;
|
||||
symbol_table[*return_l] =
|
||||
symbol_table.CreateSymbol("named_expression_3", true);
|
||||
auto return_n =
|
||||
NEXPR("n", IDENT("n")->MapTo(n.sym_))
|
||||
->MapTo(symbol_table.CreateSymbol("named_expression_1", true));
|
||||
auto return_m =
|
||||
NEXPR("m", IDENT("m")->MapTo(m.sym_))
|
||||
->MapTo(symbol_table.CreateSymbol("named_expression_2", true));
|
||||
auto return_l =
|
||||
NEXPR("l", IDENT("l")->MapTo(l.sym_))
|
||||
->MapTo(symbol_table.CreateSymbol("named_expression_3", true));
|
||||
|
||||
std::vector<Symbol> n_symbols{n.sym_};
|
||||
std::vector<Symbol> m_symbols{m.sym_};
|
||||
@ -420,10 +408,9 @@ TEST_F(ExpandFixture, Expand) {
|
||||
{}, "m", false, graph_view);
|
||||
|
||||
// make a named expression and a produce
|
||||
auto output = NEXPR("m", IDENT("m"));
|
||||
symbol_table[*output->expression_] = r_m.node_sym_;
|
||||
symbol_table[*output] =
|
||||
symbol_table.CreateSymbol("named_expression_1", true);
|
||||
auto output =
|
||||
NEXPR("m", IDENT("m")->MapTo(r_m.node_sym_))
|
||||
->MapTo(symbol_table.CreateSymbol("named_expression_1", true));
|
||||
auto produce = MakeProduce(r_m.op_, output);
|
||||
auto context = MakeContext(storage, symbol_table, dba_.get());
|
||||
return PullAll(*produce, &context);
|
||||
@ -456,9 +443,9 @@ TEST_F(ExpandFixture, ExpandPath) {
|
||||
auto path = std::make_shared<ConstructNamedPath>(
|
||||
r_m.op_, path_sym,
|
||||
std::vector<Symbol>{n.sym_, r_m.edge_sym_, r_m.node_sym_});
|
||||
auto output = NEXPR("m", IDENT("m"));
|
||||
symbol_table[*output->expression_] = path_sym;
|
||||
symbol_table[*output] = symbol_table.CreateSymbol("named_expression_1", true);
|
||||
auto output =
|
||||
NEXPR("path", IDENT("path")->MapTo(path_sym))
|
||||
->MapTo(symbol_table.CreateSymbol("named_expression_1", true));
|
||||
auto produce = MakeProduce(path, output);
|
||||
|
||||
std::vector<query::Path> expected_paths{{v1, r2, v3}, {v1, r1, v2}};
|
||||
@ -560,7 +547,7 @@ class QueryPlanExpandVariable : public testing::Test {
|
||||
|
||||
auto n_to = NODE(node_to);
|
||||
auto n_to_sym = symbol_table.CreateSymbol(node_to, true);
|
||||
symbol_table[*n_to->identifier_] = n_to_sym;
|
||||
n_to->identifier_->MapTo(n_to_sym);
|
||||
|
||||
if (std::is_same<TExpansionOperator, ExpandVariable>::value) {
|
||||
// convert optional ints to optional expressions
|
||||
@ -588,7 +575,7 @@ class QueryPlanExpandVariable : public testing::Test {
|
||||
auto Edge(const std::string &identifier, EdgeAtom::Direction direction) {
|
||||
auto edge = EDGE(identifier, direction);
|
||||
auto edge_sym = symbol_table.CreateSymbol(identifier, true);
|
||||
symbol_table[*edge->identifier_] = edge_sym;
|
||||
edge->identifier_->MapTo(edge_sym);
|
||||
return edge_sym;
|
||||
}
|
||||
|
||||
@ -769,8 +756,8 @@ TEST_F(QueryPlanExpandVariable, NamedPath) {
|
||||
AddMatch<ExpandVariable>(nullptr, "n", 0, EdgeAtom::Direction::OUT, {}, 2,
|
||||
2, e, "m", GraphView::OLD);
|
||||
auto find_symbol = [this](const std::string &name) {
|
||||
for (const auto &pos_sym : symbol_table.table())
|
||||
if (pos_sym.second.name() == name) return pos_sym.second;
|
||||
for (const auto &sym : symbol_table.table())
|
||||
if (sym.name() == name) return sym;
|
||||
throw std::runtime_error("Symbol not found");
|
||||
};
|
||||
|
||||
@ -884,7 +871,7 @@ class QueryPlanExpandWeightedShortestPath : public testing::Test {
|
||||
}
|
||||
|
||||
auto ident_e = IDENT("e");
|
||||
symbol_table[*ident_e] = weight_edge;
|
||||
ident_e->MapTo(weight_edge);
|
||||
|
||||
// expand wshortest
|
||||
auto node_sym = existing_node_input
|
||||
@ -929,7 +916,7 @@ class QueryPlanExpandWeightedShortestPath : public testing::Test {
|
||||
|
||||
Expression *PropNe(Symbol symbol, int value) {
|
||||
auto ident = IDENT("inner_element");
|
||||
symbol_table[*ident] = symbol;
|
||||
ident->MapTo(symbol);
|
||||
return NEQ(PROPERTY_LOOKUP(ident, prop), LITERAL(value));
|
||||
}
|
||||
};
|
||||
@ -1173,15 +1160,12 @@ TEST(QueryPlan, ExpandOptional) {
|
||||
n.op_, r_m.op_, std::vector<Symbol>{r_m.edge_sym_, r_m.node_sym_});
|
||||
|
||||
// RETURN n, r, m
|
||||
auto n_ne = NEXPR("n", IDENT("n"));
|
||||
symbol_table[*n_ne->expression_] = n.sym_;
|
||||
symbol_table[*n_ne] = symbol_table.CreateSymbol("n", true);
|
||||
auto r_ne = NEXPR("r", IDENT("r"));
|
||||
symbol_table[*r_ne->expression_] = r_m.edge_sym_;
|
||||
symbol_table[*r_ne] = symbol_table.CreateSymbol("r", true);
|
||||
auto m_ne = NEXPR("m", IDENT("m"));
|
||||
symbol_table[*m_ne->expression_] = r_m.node_sym_;
|
||||
symbol_table[*m_ne] = symbol_table.CreateSymbol("m", true);
|
||||
auto n_ne = NEXPR("n", IDENT("n")->MapTo(n.sym_))
|
||||
->MapTo(symbol_table.CreateSymbol("n", true));
|
||||
auto r_ne = NEXPR("r", IDENT("r")->MapTo(r_m.edge_sym_))
|
||||
->MapTo(symbol_table.CreateSymbol("r", true));
|
||||
auto m_ne = NEXPR("m", IDENT("m")->MapTo(r_m.node_sym_))
|
||||
->MapTo(symbol_table.CreateSymbol("m", true));
|
||||
auto produce = MakeProduce(optional, n_ne, r_ne, m_ne);
|
||||
auto context = MakeContext(storage, symbol_table, dba.get());
|
||||
auto results = CollectProduce(*produce, &context);
|
||||
@ -1214,9 +1198,8 @@ TEST(QueryPlan, OptionalMatchEmptyDB) {
|
||||
// OPTIONAL MATCH (n)
|
||||
auto n = MakeScanAll(storage, symbol_table, "n");
|
||||
// RETURN n
|
||||
auto n_ne = NEXPR("n", IDENT("n"));
|
||||
symbol_table[*n_ne->expression_] = n.sym_;
|
||||
symbol_table[*n_ne] = symbol_table.CreateSymbol("n", true);
|
||||
auto n_ne = NEXPR("n", IDENT("n")->MapTo(n.sym_))
|
||||
->MapTo(symbol_table.CreateSymbol("n", true));
|
||||
auto optional = std::make_shared<plan::Optional>(nullptr, n.op_,
|
||||
std::vector<Symbol>{n.sym_});
|
||||
auto produce = MakeProduce(optional, n_ne);
|
||||
@ -1236,19 +1219,17 @@ TEST(QueryPlan, OptionalMatchEmptyDBExpandFromNode) {
|
||||
auto optional = std::make_shared<plan::Optional>(nullptr, n.op_,
|
||||
std::vector<Symbol>{n.sym_});
|
||||
// WITH n
|
||||
auto n_ne = NEXPR("n", IDENT("n"));
|
||||
symbol_table[*n_ne->expression_] = n.sym_;
|
||||
auto n_ne = NEXPR("n", IDENT("n")->MapTo(n.sym_));
|
||||
auto with_n_sym = symbol_table.CreateSymbol("n", true);
|
||||
symbol_table[*n_ne] = with_n_sym;
|
||||
n_ne->MapTo(with_n_sym);
|
||||
auto with = MakeProduce(optional, n_ne);
|
||||
// MATCH (n) -[r]-> (m)
|
||||
auto r_m =
|
||||
MakeExpand(storage, symbol_table, with, with_n_sym, "r",
|
||||
EdgeAtom::Direction::OUT, {}, "m", false, GraphView::OLD);
|
||||
// RETURN m
|
||||
auto m_ne = NEXPR("m", IDENT("m"));
|
||||
symbol_table[*m_ne->expression_] = r_m.node_sym_;
|
||||
symbol_table[*m_ne] = symbol_table.CreateSymbol("m", true);
|
||||
auto m_ne = NEXPR("m", IDENT("m")->MapTo(r_m.node_sym_))
|
||||
->MapTo(symbol_table.CreateSymbol("m", true));
|
||||
auto produce = MakeProduce(r_m.op_, m_ne);
|
||||
auto context = MakeContext(storage, symbol_table, dba.get());
|
||||
auto results = CollectProduce(*produce, &context);
|
||||
@ -1279,26 +1260,24 @@ TEST(QueryPlan, OptionalMatchThenExpandToMissingNode) {
|
||||
auto optional = std::make_shared<plan::Optional>(nullptr, node_filter,
|
||||
std::vector<Symbol>{n.sym_});
|
||||
// WITH n
|
||||
auto n_ne = NEXPR("n", IDENT("n"));
|
||||
symbol_table[*n_ne->expression_] = n.sym_;
|
||||
auto n_ne = NEXPR("n", IDENT("n")->MapTo(n.sym_));
|
||||
auto with_n_sym = symbol_table.CreateSymbol("n", true);
|
||||
symbol_table[*n_ne] = with_n_sym;
|
||||
n_ne->MapTo(with_n_sym);
|
||||
auto with = MakeProduce(optional, n_ne);
|
||||
// MATCH (m) -[r]-> (n)
|
||||
auto m = MakeScanAll(storage, symbol_table, "m", with);
|
||||
auto edge_direction = EdgeAtom::Direction::OUT;
|
||||
auto edge = EDGE("r", edge_direction);
|
||||
auto edge_sym = symbol_table.CreateSymbol("r", true);
|
||||
symbol_table[*edge->identifier_] = edge_sym;
|
||||
edge->identifier_->MapTo(edge_sym);
|
||||
auto node = NODE("n");
|
||||
symbol_table[*node->identifier_] = with_n_sym;
|
||||
node->identifier_->MapTo(with_n_sym);
|
||||
auto expand = std::make_shared<plan::Expand>(
|
||||
m.op_, m.sym_, with_n_sym, edge_sym, edge_direction,
|
||||
std::vector<storage::EdgeType>{}, true, GraphView::OLD);
|
||||
// RETURN m
|
||||
auto m_ne = NEXPR("m", IDENT("m"));
|
||||
symbol_table[*m_ne->expression_] = m.sym_;
|
||||
symbol_table[*m_ne] = symbol_table.CreateSymbol("m", true);
|
||||
auto m_ne = NEXPR("m", IDENT("m")->MapTo(m.sym_))
|
||||
->MapTo(symbol_table.CreateSymbol("m", true));
|
||||
auto produce = MakeProduce(expand, m_ne);
|
||||
auto context = MakeContext(storage, symbol_table, dba.get());
|
||||
auto results = CollectProduce(*produce, &context);
|
||||
@ -1332,10 +1311,9 @@ TEST(QueryPlan, ExpandExistingNode) {
|
||||
std::vector<storage::EdgeType>{}, with_existing, GraphView::OLD);
|
||||
|
||||
// make a named expression and a produce
|
||||
auto output = NEXPR("n", IDENT("n"));
|
||||
symbol_table[*output->expression_] = n.sym_;
|
||||
symbol_table[*output] =
|
||||
symbol_table.CreateSymbol("named_expression_1", true);
|
||||
auto output =
|
||||
NEXPR("n", IDENT("n")->MapTo(n.sym_))
|
||||
->MapTo(symbol_table.CreateSymbol("named_expression_1", true));
|
||||
auto produce = MakeProduce(r_n.op_, output);
|
||||
auto context = MakeContext(storage, symbol_table, dba.get());
|
||||
auto results = CollectProduce(*produce, &context);
|
||||
@ -1421,10 +1399,9 @@ TEST(QueryPlan, EdgeFilter) {
|
||||
auto edge_filter = std::make_shared<Filter>(r_m.op_, filter_expr);
|
||||
|
||||
// make a named expression and a produce
|
||||
auto output = NEXPR("m", IDENT("m"));
|
||||
symbol_table[*output->expression_] = r_m.node_sym_;
|
||||
symbol_table[*output] =
|
||||
symbol_table.CreateSymbol("named_expression_1", true);
|
||||
auto output =
|
||||
NEXPR("m", IDENT("m")->MapTo(r_m.node_sym_))
|
||||
->MapTo(symbol_table.CreateSymbol("named_expression_1", true));
|
||||
auto produce = MakeProduce(edge_filter, output);
|
||||
auto context = MakeContext(storage, symbol_table, &dba);
|
||||
return PullAll(*produce, &context);
|
||||
@ -1462,12 +1439,10 @@ TEST(QueryPlan, EdgeFilterMultipleTypes) {
|
||||
GraphView::OLD);
|
||||
|
||||
// make a named expression and a produce
|
||||
auto output = NEXPR("m", IDENT("m"));
|
||||
auto output =
|
||||
NEXPR("m", IDENT("m")->MapTo(r_m.node_sym_))
|
||||
->MapTo(symbol_table.CreateSymbol("named_expression_1", true));
|
||||
auto produce = MakeProduce(r_m.op_, output);
|
||||
|
||||
// fill up the symbol table
|
||||
symbol_table[*output] = symbol_table.CreateSymbol("named_expression_1", true);
|
||||
symbol_table[*output->expression_] = r_m.node_sym_;
|
||||
auto context = MakeContext(storage, symbol_table, dba.get());
|
||||
auto results = CollectProduce(*produce, &context);
|
||||
EXPECT_EQ(results.size(), 2);
|
||||
@ -1489,14 +1464,12 @@ TEST(QueryPlan, Filter) {
|
||||
SymbolTable symbol_table;
|
||||
|
||||
auto n = MakeScanAll(storage, symbol_table, "n");
|
||||
auto e = PROPERTY_LOOKUP("n", property);
|
||||
symbol_table[*e->expression_] = n.sym_;
|
||||
auto e = PROPERTY_LOOKUP(IDENT("n")->MapTo(n.sym_), property);
|
||||
auto f = std::make_shared<Filter>(n.op_, e);
|
||||
|
||||
auto output =
|
||||
storage.Create<NamedExpression>("x", storage.Create<Identifier>("n"));
|
||||
symbol_table[*output->expression_] = n.sym_;
|
||||
symbol_table[*output] = symbol_table.CreateSymbol("named_expression_1", true);
|
||||
NEXPR("x", IDENT("n")->MapTo(n.sym_))
|
||||
->MapTo(symbol_table.CreateSymbol("named_expression_1", true));
|
||||
auto produce = MakeProduce(f, output);
|
||||
auto context = MakeContext(storage, symbol_table, &dba);
|
||||
EXPECT_EQ(CollectProduce(*produce, &context).size(), 2);
|
||||
@ -1555,13 +1528,13 @@ TEST(QueryPlan, Distinct) {
|
||||
auto x = symbol_table.CreateSymbol("x", true);
|
||||
auto unwind = std::make_shared<plan::Unwind>(nullptr, input_expr, x);
|
||||
auto x_expr = IDENT("x");
|
||||
symbol_table[*x_expr] = x;
|
||||
x_expr->MapTo(x);
|
||||
|
||||
auto distinct =
|
||||
std::make_shared<plan::Distinct>(unwind, std::vector<Symbol>{x});
|
||||
|
||||
auto x_ne = NEXPR("x", x_expr);
|
||||
symbol_table[*x_ne] = symbol_table.CreateSymbol("x_ne", true);
|
||||
x_ne->MapTo(symbol_table.CreateSymbol("x_ne", true));
|
||||
auto produce = MakeProduce(distinct, x_ne);
|
||||
auto context = MakeContext(storage, symbol_table, dba.get());
|
||||
auto results = CollectProduce(*produce, &context);
|
||||
@ -1599,10 +1572,9 @@ TEST(QueryPlan, ScanAllByLabel) {
|
||||
auto scan_all_by_label =
|
||||
MakeScanAllByLabel(storage, symbol_table, "n", label);
|
||||
// RETURN n
|
||||
auto output = NEXPR("n", IDENT("n"));
|
||||
auto output = NEXPR("n", IDENT("n")->MapTo(scan_all_by_label.sym_))
|
||||
->MapTo(symbol_table.CreateSymbol("n", true));
|
||||
auto produce = MakeProduce(scan_all_by_label.op_, output);
|
||||
symbol_table[*output->expression_] = scan_all_by_label.sym_;
|
||||
symbol_table[*output] = symbol_table.CreateSymbol("n", true);
|
||||
auto context = MakeContext(storage, symbol_table, dba.get());
|
||||
auto results = CollectProduce(*produce, &context);
|
||||
ASSERT_EQ(results.size(), 1);
|
||||
@ -1645,10 +1617,9 @@ TEST(QueryPlan, ScanAllByLabelProperty) {
|
||||
storage, symbol_table, "n", label, prop, "prop",
|
||||
Bound{LITERAL(lower), lower_type}, Bound{LITERAL(upper), upper_type});
|
||||
// RETURN n
|
||||
auto output = NEXPR("n", IDENT("n"));
|
||||
auto output = NEXPR("n", IDENT("n")->MapTo(scan_all.sym_))
|
||||
->MapTo(symbol_table.CreateSymbol("n", true));
|
||||
auto produce = MakeProduce(scan_all.op_, output);
|
||||
symbol_table[*output->expression_] = scan_all.sym_;
|
||||
symbol_table[*output] = symbol_table.CreateSymbol("n", true);
|
||||
auto context = MakeContext(storage, symbol_table, dba.get());
|
||||
auto results = CollectProduce(*produce, &context);
|
||||
ASSERT_EQ(results.size(), expected.size());
|
||||
@ -1707,10 +1678,9 @@ TEST(QueryPlan, ScanAllByLabelPropertyEqualityNoError) {
|
||||
auto scan_all = MakeScanAllByLabelPropertyValue(
|
||||
storage, symbol_table, "n", label, prop, "prop", LITERAL(42));
|
||||
// RETURN n
|
||||
auto output = NEXPR("n", IDENT("n"));
|
||||
auto output = NEXPR("n", IDENT("n")->MapTo(scan_all.sym_))
|
||||
->MapTo(symbol_table.CreateSymbol("n", true));
|
||||
auto produce = MakeProduce(scan_all.op_, output);
|
||||
symbol_table[*output->expression_] = scan_all.sym_;
|
||||
symbol_table[*output] = symbol_table.CreateSymbol("n", true);
|
||||
auto context = MakeContext(storage, symbol_table, dba.get());
|
||||
auto results = CollectProduce(*produce, &context);
|
||||
ASSERT_EQ(results.size(), 1);
|
||||
@ -1743,7 +1713,7 @@ TEST(QueryPlan, ScanAllByLabelPropertyValueError) {
|
||||
SymbolTable symbol_table;
|
||||
auto scan_all = MakeScanAll(storage, symbol_table, "m");
|
||||
auto *ident_m = IDENT("m");
|
||||
symbol_table[*ident_m] = scan_all.sym_;
|
||||
ident_m->MapTo(scan_all.sym_);
|
||||
auto scan_index = MakeScanAllByLabelPropertyValue(
|
||||
storage, symbol_table, "n", label, prop, "prop", ident_m, scan_all.op_);
|
||||
auto context = MakeContext(storage, symbol_table, dba.get());
|
||||
@ -1771,7 +1741,7 @@ TEST(QueryPlan, ScanAllByLabelPropertyRangeError) {
|
||||
SymbolTable symbol_table;
|
||||
auto scan_all = MakeScanAll(storage, symbol_table, "m");
|
||||
auto *ident_m = IDENT("m");
|
||||
symbol_table[*ident_m] = scan_all.sym_;
|
||||
ident_m->MapTo(scan_all.sym_);
|
||||
{
|
||||
// Lower bound isn't property value
|
||||
auto scan_index = MakeScanAllByLabelPropertyRange(
|
||||
@ -1827,10 +1797,9 @@ TEST(QueryPlan, ScanAllByLabelPropertyEqualNull) {
|
||||
MakeScanAllByLabelPropertyValue(storage, symbol_table, "n", label, prop,
|
||||
"prop", LITERAL(TypedValue::Null));
|
||||
// RETURN n
|
||||
auto output = NEXPR("n", IDENT("n"));
|
||||
auto output = NEXPR("n", IDENT("n")->MapTo(scan_all.sym_))
|
||||
->MapTo(symbol_table.CreateSymbol("n", true));
|
||||
auto produce = MakeProduce(scan_all.op_, output);
|
||||
symbol_table[*output->expression_] = scan_all.sym_;
|
||||
symbol_table[*output] = symbol_table.CreateSymbol("n", true);
|
||||
auto context = MakeContext(storage, symbol_table, dba.get());
|
||||
auto results = CollectProduce(*produce, &context);
|
||||
EXPECT_EQ(results.size(), 0);
|
||||
@ -1863,10 +1832,9 @@ TEST(QueryPlan, ScanAllByLabelPropertyRangeNull) {
|
||||
Bound{LITERAL(TypedValue::Null), Bound::Type::INCLUSIVE},
|
||||
Bound{LITERAL(TypedValue::Null), Bound::Type::EXCLUSIVE});
|
||||
// RETURN n
|
||||
auto output = NEXPR("n", IDENT("n"));
|
||||
auto output = NEXPR("n", IDENT("n")->MapTo(scan_all.sym_))
|
||||
->MapTo(symbol_table.CreateSymbol("n", true));
|
||||
auto produce = MakeProduce(scan_all.op_, output);
|
||||
symbol_table[*output->expression_] = scan_all.sym_;
|
||||
symbol_table[*output] = symbol_table.CreateSymbol("n", true);
|
||||
auto context = MakeContext(storage, symbol_table, dba.get());
|
||||
auto results = CollectProduce(*produce, &context);
|
||||
EXPECT_EQ(results.size(), 0);
|
||||
@ -1895,7 +1863,7 @@ TEST(QueryPlan, ScanAllByLabelPropertyNoValueInIndexContinuation) {
|
||||
auto x = symbol_table.CreateSymbol("x", true);
|
||||
auto unwind = std::make_shared<plan::Unwind>(nullptr, input_expr, x);
|
||||
auto x_expr = IDENT("x");
|
||||
symbol_table[*x_expr] = x;
|
||||
x_expr->MapTo(x);
|
||||
|
||||
// MATCH (n :label {prop: x})
|
||||
auto scan_all = MakeScanAllByLabelPropertyValue(
|
||||
@ -1937,11 +1905,10 @@ TEST(QueryPlan, ScanAllEqualsScanAllByLabelProperty) {
|
||||
auto dba = db.Access();
|
||||
auto scan_all_by_label_property_value = MakeScanAllByLabelPropertyValue(
|
||||
storage, symbol_table, "n", label, prop, "prop", LITERAL(prop_value));
|
||||
auto output = NEXPR("n", IDENT("n"));
|
||||
auto output =
|
||||
NEXPR("n", IDENT("n")->MapTo(scan_all_by_label_property_value.sym_))
|
||||
->MapTo(symbol_table.CreateSymbol("named_expression_1", true));
|
||||
auto produce = MakeProduce(scan_all_by_label_property_value.op_, output);
|
||||
symbol_table[*output->expression_] = scan_all_by_label_property_value.sym_;
|
||||
symbol_table[*output] =
|
||||
symbol_table.CreateSymbol("named_expression_1", true);
|
||||
auto context = MakeContext(storage, symbol_table, dba.get());
|
||||
EXPECT_EQ(PullAll(*produce, &context), prop_count);
|
||||
};
|
||||
@ -1953,15 +1920,14 @@ TEST(QueryPlan, ScanAllEqualsScanAllByLabelProperty) {
|
||||
auto dba_ptr = db.Access();
|
||||
auto &dba = *dba_ptr;
|
||||
auto scan_all = MakeScanAll(storage, symbol_table, "n");
|
||||
auto e = PROPERTY_LOOKUP("n", std::make_pair("prop", prop));
|
||||
symbol_table[*e->expression_] = scan_all.sym_;
|
||||
auto e = PROPERTY_LOOKUP(IDENT("n")->MapTo(scan_all.sym_),
|
||||
std::make_pair("prop", prop));
|
||||
auto filter =
|
||||
std::make_shared<Filter>(scan_all.op_, EQ(e, LITERAL(prop_value)));
|
||||
auto output = NEXPR("n", IDENT("n"));
|
||||
auto output =
|
||||
NEXPR("n", IDENT("n")->MapTo(scan_all.sym_))
|
||||
->MapTo(symbol_table.CreateSymbol("named_expression_1", true));
|
||||
auto produce = MakeProduce(filter, output);
|
||||
symbol_table[*output->expression_] = scan_all.sym_;
|
||||
symbol_table[*output] =
|
||||
symbol_table.CreateSymbol("named_expression_1", true);
|
||||
auto context = MakeContext(storage, symbol_table, &dba);
|
||||
EXPECT_EQ(PullAll(*produce, &context), prop_count);
|
||||
};
|
||||
|
@ -30,19 +30,20 @@ TEST_F(TestSymbolGenerator, MatchNodeReturn) {
|
||||
EXPECT_EQ(symbol_table.max_position(), 3);
|
||||
auto match = dynamic_cast<Match *>(query_ast->single_query_->clauses_[0]);
|
||||
auto pattern = match->patterns_[0];
|
||||
auto pattern_sym = symbol_table[*pattern->identifier_];
|
||||
auto pattern_sym = symbol_table.at(*pattern->identifier_);
|
||||
EXPECT_EQ(pattern_sym.type(), Symbol::Type::PATH);
|
||||
EXPECT_FALSE(pattern_sym.user_declared());
|
||||
auto node_atom = dynamic_cast<NodeAtom *>(pattern->atoms_[0]);
|
||||
auto node_sym = symbol_table[*node_atom->identifier_];
|
||||
auto node_sym = symbol_table.at(*node_atom->identifier_);
|
||||
EXPECT_EQ(node_sym.name(), "node_atom_1");
|
||||
EXPECT_EQ(node_sym.type(), Symbol::Type::VERTEX);
|
||||
auto ret = dynamic_cast<Return *>(query_ast->single_query_->clauses_[1]);
|
||||
auto named_expr = ret->body_.named_expressions[0];
|
||||
auto column_sym = symbol_table[*named_expr];
|
||||
auto column_sym = symbol_table.at(*named_expr);
|
||||
EXPECT_EQ(node_sym.name(), column_sym.name());
|
||||
EXPECT_NE(node_sym, column_sym);
|
||||
auto ret_sym = symbol_table[*named_expr->expression_];
|
||||
auto ret_sym =
|
||||
symbol_table.at(*dynamic_cast<Identifier *>(named_expr->expression_));
|
||||
EXPECT_EQ(node_sym, ret_sym);
|
||||
}
|
||||
|
||||
@ -55,7 +56,7 @@ TEST_F(TestSymbolGenerator, MatchNamedPattern) {
|
||||
EXPECT_EQ(symbol_table.max_position(), 3);
|
||||
auto match = dynamic_cast<Match *>(query_ast->single_query_->clauses_[0]);
|
||||
auto pattern = match->patterns_[0];
|
||||
auto pattern_sym = symbol_table[*pattern->identifier_];
|
||||
auto pattern_sym = symbol_table.at(*pattern->identifier_);
|
||||
EXPECT_EQ(pattern_sym.type(), Symbol::Type::PATH);
|
||||
EXPECT_EQ(pattern_sym.name(), "p");
|
||||
EXPECT_TRUE(pattern_sym.user_declared());
|
||||
@ -93,15 +94,16 @@ TEST_F(TestSymbolGenerator, CreateNodeReturn) {
|
||||
auto create = dynamic_cast<Create *>(query_ast->single_query_->clauses_[0]);
|
||||
auto pattern = create->patterns_[0];
|
||||
auto node_atom = dynamic_cast<NodeAtom *>(pattern->atoms_[0]);
|
||||
auto node_sym = symbol_table[*node_atom->identifier_];
|
||||
auto node_sym = symbol_table.at(*node_atom->identifier_);
|
||||
EXPECT_EQ(node_sym.name(), "n");
|
||||
EXPECT_EQ(node_sym.type(), Symbol::Type::VERTEX);
|
||||
auto ret = dynamic_cast<Return *>(query_ast->single_query_->clauses_[1]);
|
||||
auto named_expr = ret->body_.named_expressions[0];
|
||||
auto column_sym = symbol_table[*named_expr];
|
||||
auto column_sym = symbol_table.at(*named_expr);
|
||||
EXPECT_EQ(node_sym.name(), column_sym.name());
|
||||
EXPECT_NE(node_sym, column_sym);
|
||||
auto ret_sym = symbol_table[*named_expr->expression_];
|
||||
auto ret_sym =
|
||||
symbol_table.at(*dynamic_cast<Identifier *>(named_expr->expression_));
|
||||
EXPECT_EQ(node_sym, ret_sym);
|
||||
}
|
||||
|
||||
@ -255,7 +257,7 @@ TEST_F(TestSymbolGenerator, MatchWithWhere) {
|
||||
EXPECT_EQ(node_symbol, old);
|
||||
auto with_n = symbol_table.at(*with_as_n);
|
||||
EXPECT_NE(old, with_n);
|
||||
auto n = symbol_table.at(*n_prop->expression_);
|
||||
auto n = symbol_table.at(*dynamic_cast<Identifier *>(n_prop->expression_));
|
||||
EXPECT_EQ(n, with_n);
|
||||
}
|
||||
|
||||
@ -372,7 +374,8 @@ TEST_F(TestSymbolGenerator, MatchPropCreateNodeProp) {
|
||||
// symbols: pattern * 2, `node_n`, `node_m`
|
||||
EXPECT_EQ(symbol_table.max_position(), 4);
|
||||
auto n = symbol_table.at(*node_n->identifier_);
|
||||
EXPECT_EQ(n, symbol_table.at(*n_prop->expression_));
|
||||
EXPECT_EQ(n,
|
||||
symbol_table.at(*dynamic_cast<Identifier *>(n_prop->expression_)));
|
||||
auto m = symbol_table.at(*node_m->identifier_);
|
||||
EXPECT_NE(n, m);
|
||||
}
|
||||
@ -551,7 +554,8 @@ TEST_F(TestSymbolGenerator, MergeOnMatchOnCreate) {
|
||||
EXPECT_EQ(symbol_table.max_position(), 6);
|
||||
auto n = symbol_table.at(*match_n->identifier_);
|
||||
EXPECT_EQ(n, symbol_table.at(*merge_n->identifier_));
|
||||
EXPECT_EQ(n, symbol_table.at(*n_prop->expression_));
|
||||
EXPECT_EQ(n,
|
||||
symbol_table.at(*dynamic_cast<Identifier *>(n_prop->expression_)));
|
||||
auto r = symbol_table.at(*edge_r->identifier_);
|
||||
EXPECT_NE(r, n);
|
||||
EXPECT_EQ(r, symbol_table.at(*ident_r));
|
||||
@ -560,7 +564,8 @@ TEST_F(TestSymbolGenerator, MergeOnMatchOnCreate) {
|
||||
EXPECT_NE(m, n);
|
||||
EXPECT_NE(m, r);
|
||||
EXPECT_NE(m, symbol_table.at(*as_r));
|
||||
EXPECT_EQ(m, symbol_table.at(*m_prop->expression_));
|
||||
EXPECT_EQ(m,
|
||||
symbol_table.at(*dynamic_cast<Identifier *>(m_prop->expression_)));
|
||||
}
|
||||
|
||||
TEST_F(TestSymbolGenerator, WithUnwindRedeclareReturn) {
|
||||
@ -586,7 +591,8 @@ TEST_F(TestSymbolGenerator, WithUnwindReturn) {
|
||||
// Symbols for: `list`, `elem`, `AS list`, `AS elem`
|
||||
EXPECT_EQ(symbol_table.max_position(), 4);
|
||||
const auto &list = symbol_table.at(*with_as_list);
|
||||
EXPECT_EQ(list, symbol_table.at(*unwind->named_expression_->expression_));
|
||||
EXPECT_EQ(list, symbol_table.at(*dynamic_cast<Identifier *>(
|
||||
unwind->named_expression_->expression_)));
|
||||
const auto &elem = symbol_table.at(*unwind->named_expression_);
|
||||
EXPECT_NE(list, elem);
|
||||
EXPECT_EQ(list, symbol_table.at(*ret_list));
|
||||
@ -612,11 +618,13 @@ TEST_F(TestSymbolGenerator, MatchCrossReferenceVariable) {
|
||||
// Symbols for pattern * 2, `n`, `m` and `AS n`
|
||||
EXPECT_EQ(symbol_table.max_position(), 5);
|
||||
auto n = symbol_table.at(*node_n->identifier_);
|
||||
EXPECT_EQ(n, symbol_table.at(*n_prop->expression_));
|
||||
EXPECT_EQ(n,
|
||||
symbol_table.at(*dynamic_cast<Identifier *>(n_prop->expression_)));
|
||||
EXPECT_EQ(n, symbol_table.at(*ident_n));
|
||||
EXPECT_NE(n, symbol_table.at(*as_n));
|
||||
auto m = symbol_table.at(*node_m->identifier_);
|
||||
EXPECT_EQ(m, symbol_table.at(*m_prop->expression_));
|
||||
EXPECT_EQ(m,
|
||||
symbol_table.at(*dynamic_cast<Identifier *>(m_prop->expression_)));
|
||||
EXPECT_NE(n, m);
|
||||
EXPECT_NE(m, symbol_table.at(*as_n));
|
||||
}
|
||||
@ -638,7 +646,8 @@ TEST_F(TestSymbolGenerator, MatchWithAsteriskReturnAsterisk) {
|
||||
// Symbols for pattern, `n`, `e`, `m`, `AS n.prop`.
|
||||
EXPECT_EQ(symbol_table.max_position(), 5);
|
||||
auto n = symbol_table.at(*node_n->identifier_);
|
||||
EXPECT_EQ(n, symbol_table.at(*n_prop->expression_));
|
||||
EXPECT_EQ(n,
|
||||
symbol_table.at(*dynamic_cast<Identifier *>(n_prop->expression_)));
|
||||
}
|
||||
|
||||
TEST_F(TestSymbolGenerator, MatchReturnAsteriskSameResult) {
|
||||
@ -683,7 +692,8 @@ TEST_F(TestSymbolGenerator, MatchEdgeWithIdentifierInProperty) {
|
||||
// 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_);
|
||||
EXPECT_EQ(n, symbol_table.at(*n_prop->expression_));
|
||||
EXPECT_EQ(n,
|
||||
symbol_table.at(*dynamic_cast<Identifier *>(n_prop->expression_)));
|
||||
}
|
||||
|
||||
TEST_F(TestSymbolGenerator, MatchVariablePathUsingIdentifier) {
|
||||
@ -701,7 +711,8 @@ TEST_F(TestSymbolGenerator, MatchVariablePathUsingIdentifier) {
|
||||
// implicit in RETURN `r AS r`
|
||||
EXPECT_EQ(symbol_table.max_position(), 9);
|
||||
auto l = symbol_table.at(*node_l->identifier_);
|
||||
EXPECT_EQ(l, symbol_table.at(*l_prop->expression_));
|
||||
EXPECT_EQ(l,
|
||||
symbol_table.at(*dynamic_cast<Identifier *>(l_prop->expression_)));
|
||||
auto r = symbol_table.at(*edge->identifier_);
|
||||
EXPECT_EQ(r.type(), Symbol::Type::EDGE_LIST);
|
||||
}
|
||||
@ -772,7 +783,8 @@ TEST_F(TestSymbolGenerator, MatchPropertySameIdentifier) {
|
||||
auto query = QUERY(SINGLE_QUERY(MATCH(PATTERN(node_n)), RETURN("n")));
|
||||
auto symbol_table = query::MakeSymbolTable(query);
|
||||
auto n = symbol_table.at(*node_n->identifier_);
|
||||
EXPECT_EQ(n, symbol_table.at(*n_prop->expression_));
|
||||
EXPECT_EQ(n,
|
||||
symbol_table.at(*dynamic_cast<Identifier *>(n_prop->expression_)));
|
||||
}
|
||||
|
||||
TEST_F(TestSymbolGenerator, WithReturnAll) {
|
||||
@ -901,12 +913,12 @@ TEST_F(TestSymbolGenerator, MatchBfsReturn) {
|
||||
symbol_table.at(*bfs->filter_lambda_.inner_edge));
|
||||
EXPECT_TRUE(symbol_table.at(*bfs->filter_lambda_.inner_edge).user_declared());
|
||||
EXPECT_EQ(symbol_table.at(*bfs->filter_lambda_.inner_edge),
|
||||
symbol_table.at(*r_prop->expression_));
|
||||
symbol_table.at(*dynamic_cast<Identifier *>(r_prop->expression_)));
|
||||
EXPECT_NE(symbol_table.at(*node_n->identifier_),
|
||||
symbol_table.at(*bfs->filter_lambda_.inner_node));
|
||||
EXPECT_TRUE(symbol_table.at(*bfs->filter_lambda_.inner_node).user_declared());
|
||||
EXPECT_EQ(symbol_table.at(*node_n->identifier_),
|
||||
symbol_table.at(*n_prop->expression_));
|
||||
symbol_table.at(*dynamic_cast<Identifier *>(n_prop->expression_)));
|
||||
}
|
||||
|
||||
TEST_F(TestSymbolGenerator, MatchBfsUsesEdgeSymbolError) {
|
||||
@ -935,7 +947,8 @@ TEST_F(TestSymbolGenerator, MatchBfsUsesPreviousOuterSymbol) {
|
||||
QUERY(SINGLE_QUERY(MATCH(PATTERN(node_a, bfs, NODE("m"))), RETURN("r")));
|
||||
auto symbol_table = query::MakeSymbolTable(query);
|
||||
EXPECT_EQ(symbol_table.at(*node_a->identifier_),
|
||||
symbol_table.at(*bfs->filter_lambda_.expression));
|
||||
symbol_table.at(
|
||||
*dynamic_cast<Identifier *>(bfs->filter_lambda_.expression)));
|
||||
}
|
||||
|
||||
TEST_F(TestSymbolGenerator, MatchBfsUsesLaterSymbolError) {
|
||||
@ -971,12 +984,11 @@ TEST_F(TestSymbolGenerator, MatchVariableLambdaSymbols) {
|
||||
// `AS res` and the auto-generated path name symbol.
|
||||
EXPECT_EQ(symbol_table.max_position(), 7);
|
||||
// All symbols except `AS res` are anonymously generated.
|
||||
for (const auto &id_and_symbol : symbol_table.table()) {
|
||||
const auto &symbol = id_and_symbol.second;
|
||||
for (const auto &symbol : symbol_table.table()) {
|
||||
if (symbol.name() == "res") {
|
||||
EXPECT_TRUE(symbol.user_declared());
|
||||
} else {
|
||||
EXPECT_FALSE(id_and_symbol.second.user_declared());
|
||||
EXPECT_FALSE(symbol.user_declared());
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1017,14 +1029,16 @@ TEST_F(TestSymbolGenerator, MatchWShortestReturn) {
|
||||
symbol_table.at(*shortest->filter_lambda_.inner_edge));
|
||||
EXPECT_TRUE(
|
||||
symbol_table.at(*shortest->filter_lambda_.inner_edge).user_declared());
|
||||
EXPECT_EQ(symbol_table.at(*shortest->weight_lambda_.inner_edge),
|
||||
symbol_table.at(*r_weight->expression_));
|
||||
EXPECT_EQ(
|
||||
symbol_table.at(*shortest->weight_lambda_.inner_edge),
|
||||
symbol_table.at(*dynamic_cast<Identifier *>(r_weight->expression_)));
|
||||
EXPECT_NE(symbol_table.at(*shortest->weight_lambda_.inner_edge),
|
||||
symbol_table.at(*shortest->filter_lambda_.inner_edge));
|
||||
EXPECT_NE(symbol_table.at(*shortest->weight_lambda_.inner_node),
|
||||
symbol_table.at(*shortest->filter_lambda_.inner_node));
|
||||
EXPECT_EQ(symbol_table.at(*shortest->filter_lambda_.inner_edge),
|
||||
symbol_table.at(*r_filter->expression_));
|
||||
EXPECT_EQ(
|
||||
symbol_table.at(*shortest->filter_lambda_.inner_edge),
|
||||
symbol_table.at(*dynamic_cast<Identifier *>(r_filter->expression_)));
|
||||
EXPECT_TRUE(
|
||||
symbol_table.at(*shortest->filter_lambda_.inner_node).user_declared());
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user