2018-04-23 22:23:42 +08:00
|
|
|
#>cpp
|
|
|
|
/** @file */
|
|
|
|
|
|
|
|
#pragma once
|
|
|
|
|
|
|
|
#include <experimental/optional>
|
|
|
|
#include <memory>
|
|
|
|
#include <unordered_map>
|
|
|
|
#include <unordered_set>
|
|
|
|
#include <utility>
|
|
|
|
#include <vector>
|
|
|
|
|
|
|
|
#include "query/common.hpp"
|
|
|
|
#include "query/frontend/ast/ast.hpp"
|
|
|
|
#include "query/frontend/semantic/symbol.hpp"
|
|
|
|
#include "query/typed_value.hpp"
|
|
|
|
#include "storage/types.hpp"
|
|
|
|
#include "utils/bound.hpp"
|
|
|
|
#include "utils/future.hpp"
|
|
|
|
#include "utils/hashing/fnv.hpp"
|
|
|
|
#include "utils/visitor.hpp"
|
|
|
|
|
2018-08-27 22:43:34 +08:00
|
|
|
// TODO: It makes no sense for this file to include distributed_ops Cap'n
|
|
|
|
// Proto schema. Unfortunately, forward declares of nested capnp types do not
|
|
|
|
// work, so we cannot use that mechanism. Perhaps we want to generate
|
|
|
|
// serialization code based only on type info, similarly to RPCs. This
|
|
|
|
// requires rework of LCP and we will need to have a sort of 'register'
|
|
|
|
// mechanism to fill the table of (type info -> operator constructor).
|
|
|
|
#include "query/plan/distributed_ops.capnp.h"
|
2018-05-16 19:48:56 +08:00
|
|
|
|
2018-04-23 22:23:42 +08:00
|
|
|
namespace database {
|
|
|
|
class GraphDbAccessor;
|
|
|
|
}
|
2018-05-16 19:48:56 +08:00
|
|
|
cpp<#
|
2018-04-23 22:23:42 +08:00
|
|
|
|
2018-05-16 19:48:56 +08:00
|
|
|
(lcp:namespace query)
|
2018-04-23 22:23:42 +08:00
|
|
|
|
2018-05-16 19:48:56 +08:00
|
|
|
#>cpp
|
2018-04-23 22:23:42 +08:00
|
|
|
class Context;
|
|
|
|
class ExpressionEvaluator;
|
|
|
|
class Frame;
|
|
|
|
class SymbolTable;
|
2018-05-16 19:48:56 +08:00
|
|
|
cpp<#
|
2018-04-23 22:23:42 +08:00
|
|
|
|
2018-05-16 19:48:56 +08:00
|
|
|
(lcp:namespace plan)
|
2018-04-23 22:23:42 +08:00
|
|
|
|
2018-05-16 19:48:56 +08:00
|
|
|
#>cpp
|
2018-04-23 22:23:42 +08:00
|
|
|
/** @brief Base class for iteration cursors of @c LogicalOperator classes.
|
|
|
|
*
|
|
|
|
* Each @c LogicalOperator must produce a concrete @c Cursor, which provides
|
|
|
|
* the iteration mechanism.
|
|
|
|
*/
|
|
|
|
class Cursor {
|
|
|
|
public:
|
|
|
|
/** @brief Run an iteration of a @c LogicalOperator.
|
|
|
|
*
|
|
|
|
* Since operators may be chained, the iteration may pull results from
|
|
|
|
* multiple operators.
|
|
|
|
*
|
|
|
|
* @param Frame May be read from or written to while performing the
|
|
|
|
* iteration.
|
|
|
|
* @param Context Used to get the position of symbols in frame and other
|
|
|
|
* information.
|
|
|
|
*/
|
|
|
|
virtual bool Pull(Frame &, Context &) = 0;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Resets the Cursor to it's initial state.
|
|
|
|
*/
|
|
|
|
virtual void Reset() = 0;
|
|
|
|
|
|
|
|
virtual ~Cursor() {}
|
|
|
|
};
|
|
|
|
|
|
|
|
class Once;
|
|
|
|
class CreateNode;
|
|
|
|
class CreateExpand;
|
|
|
|
class ScanAll;
|
|
|
|
class ScanAllByLabel;
|
|
|
|
class ScanAllByLabelPropertyRange;
|
|
|
|
class ScanAllByLabelPropertyValue;
|
|
|
|
class Expand;
|
|
|
|
class ExpandVariable;
|
|
|
|
class ConstructNamedPath;
|
|
|
|
class Filter;
|
|
|
|
class Produce;
|
|
|
|
class Delete;
|
|
|
|
class SetProperty;
|
|
|
|
class SetProperties;
|
|
|
|
class SetLabels;
|
|
|
|
class RemoveProperty;
|
|
|
|
class RemoveLabels;
|
|
|
|
template <typename TAccessor>
|
|
|
|
class ExpandUniquenessFilter;
|
|
|
|
class Accumulate;
|
|
|
|
class Aggregate;
|
|
|
|
class Skip;
|
|
|
|
class Limit;
|
|
|
|
class OrderBy;
|
|
|
|
class Merge;
|
|
|
|
class Optional;
|
|
|
|
class Unwind;
|
|
|
|
class Distinct;
|
|
|
|
class CreateIndex;
|
|
|
|
class Union;
|
|
|
|
class Cartesian;
|
2018-08-06 21:16:39 +08:00
|
|
|
class AuthHandler;
|
2018-06-15 22:12:44 +08:00
|
|
|
class CreateStream;
|
|
|
|
class DropStream;
|
|
|
|
class ShowStreams;
|
|
|
|
class StartStopStream;
|
|
|
|
class StartStopAllStreams;
|
2018-07-03 19:57:53 +08:00
|
|
|
class TestStream;
|
2018-08-23 19:15:15 +08:00
|
|
|
class Explain;
|
2018-04-23 22:23:42 +08:00
|
|
|
|
|
|
|
using LogicalOperatorCompositeVisitor = ::utils::CompositeVisitor<
|
|
|
|
Once, CreateNode, CreateExpand, ScanAll, ScanAllByLabel,
|
|
|
|
ScanAllByLabelPropertyRange, ScanAllByLabelPropertyValue, Expand,
|
|
|
|
ExpandVariable, ConstructNamedPath, Filter, Produce, Delete, SetProperty,
|
|
|
|
SetProperties, SetLabels, RemoveProperty, RemoveLabels,
|
|
|
|
ExpandUniquenessFilter<VertexAccessor>,
|
|
|
|
ExpandUniquenessFilter<EdgeAccessor>, Accumulate, Aggregate, Skip, Limit,
|
2018-08-28 17:07:56 +08:00
|
|
|
OrderBy, Merge, Optional, Unwind, Distinct, Union, Cartesian, Explain>;
|
2018-04-23 22:23:42 +08:00
|
|
|
|
2018-06-14 22:02:27 +08:00
|
|
|
using LogicalOperatorLeafVisitor =
|
2018-08-06 21:16:39 +08:00
|
|
|
::utils::LeafVisitor<Once, CreateIndex, AuthHandler, CreateStream,
|
|
|
|
DropStream, ShowStreams, StartStopStream,
|
|
|
|
StartStopAllStreams, TestStream>;
|
2018-04-23 22:23:42 +08:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Base class for hierarhical visitors of @c LogicalOperator class
|
|
|
|
* hierarchy.
|
|
|
|
*/
|
|
|
|
class HierarchicalLogicalOperatorVisitor
|
|
|
|
: public LogicalOperatorCompositeVisitor,
|
|
|
|
public LogicalOperatorLeafVisitor {
|
|
|
|
public:
|
|
|
|
using LogicalOperatorCompositeVisitor::PostVisit;
|
|
|
|
using LogicalOperatorCompositeVisitor::PreVisit;
|
|
|
|
using LogicalOperatorLeafVisitor::Visit;
|
|
|
|
using typename LogicalOperatorLeafVisitor::ReturnType;
|
|
|
|
};
|
2018-05-16 19:48:56 +08:00
|
|
|
cpp<#
|
2018-04-23 22:23:42 +08:00
|
|
|
|
2018-05-16 19:48:56 +08:00
|
|
|
(lcp:capnp-namespace "query::plan")
|
2018-04-23 22:23:42 +08:00
|
|
|
|
2018-05-16 19:48:56 +08:00
|
|
|
(lcp:capnp-import 'utils "/utils/serialization.capnp")
|
Replace boost with capnp in RPC
Summary:
Converts the RPC stack to use Cap'n Proto for serialization instead of
boost. There are still some traces of boost in other places in the code,
but most of it is removed. A future diff should cleanup boost for good.
The RPC API is now changed to be more flexible with regards to how
serialize data. This makes the simplest cases a bit more verbose, but
allows complex serialization code to be correctly written instead of
relying on hacks. (For reference, look for the old serialization of
`PullRpc` which had a nasty pointer hacks to inject accessors in
`TypedValue`.)
Since RPC messages were uselessly modeled via inheritance of Message
base class, that class is now removed. Furthermore, that approach
doesn't really work with Cap'n Proto. Instead, each message type is
required to have some type information. This can be automated, so
`define-rpc` has been added to LCP, which hopefully simplifies defining
new RPC request and response messages.
Specify Cap'n Proto schema ID in cmake
This preserves Cap'n Proto generated typeIds across multiple generations
of capnp schemas through LCP. It is imperative that typeId stays the
same to ensure that different compilations of Memgraph may communicate
via RPC in a distributed cluster.
Use CLOS for meta information on C++ types in LCP
Since some structure slots and functions have started to repeat
themselves, it makes sense to model C++ meta information via Common Lisp
Object System.
Depends on D1391
Reviewers: buda, dgleich, mferencevic, mtomic, mculinovic, msantl
Reviewed By: msantl
Subscribers: pullbot
Differential Revision: https://phabricator.memgraph.io/D1407
2018-06-04 15:48:48 +08:00
|
|
|
(lcp:capnp-import 'storage "/storage/serialization.capnp")
|
2018-05-16 19:48:56 +08:00
|
|
|
(lcp:capnp-import 'ast "/query/frontend/ast/ast.capnp")
|
|
|
|
(lcp:capnp-import 'semantic "/query/frontend/semantic/symbol.capnp")
|
|
|
|
(lcp:capnp-import 'common "/query/common.capnp")
|
2018-04-23 22:23:42 +08:00
|
|
|
|
2018-05-16 19:48:56 +08:00
|
|
|
(lcp:capnp-type-conversion "Symbol" "Semantic.Symbol")
|
|
|
|
(lcp:capnp-type-conversion "storage::Label" "Storage.Common")
|
|
|
|
(lcp:capnp-type-conversion "storage::Property" "Storage.Common")
|
|
|
|
(lcp:capnp-type-conversion "storage::EdgeType" "Storage.Common")
|
|
|
|
(lcp:capnp-type-conversion "GraphView" "Common.GraphView")
|
2018-04-23 22:23:42 +08:00
|
|
|
|
2018-05-16 19:48:56 +08:00
|
|
|
(lcp:define-class logical-operator ("::utils::Visitable<HierarchicalLogicalOperatorVisitor>")
|
|
|
|
()
|
|
|
|
(:documentation
|
|
|
|
"Base class for logical operators.
|
2018-04-23 22:23:42 +08:00
|
|
|
|
2018-05-16 19:48:56 +08:00
|
|
|
Each operator describes an operation, which is to be performed on the
|
|
|
|
database. Operators are iterated over using a @c Cursor. Various operators
|
|
|
|
can serve as inputs to others and thus a sequence of operations is formed.")
|
|
|
|
(:public
|
|
|
|
#>cpp
|
|
|
|
virtual ~LogicalOperator() {}
|
2018-04-23 22:23:42 +08:00
|
|
|
|
2018-05-16 19:48:56 +08:00
|
|
|
/** Constructs a @c Cursor which is used to run this operator.
|
|
|
|
*
|
|
|
|
* @param database::GraphDbAccessor Used to perform operations on the
|
|
|
|
* database.
|
|
|
|
*/
|
|
|
|
virtual std::unique_ptr<Cursor> MakeCursor(
|
|
|
|
database::GraphDbAccessor &) const = 0;
|
2018-04-23 22:23:42 +08:00
|
|
|
|
2018-05-16 19:48:56 +08:00
|
|
|
/** Return @c Symbol vector where the query results will be stored.
|
|
|
|
*
|
|
|
|
* Currently, outputs symbols are generated in @c Produce and @c Union
|
|
|
|
* operators. @c Skip, @c Limit, @c OrderBy and @c Distinct propagate the
|
|
|
|
* symbols from @c Produce (if it exists as input operator).
|
|
|
|
*
|
|
|
|
* @param SymbolTable used to find symbols for expressions.
|
|
|
|
* @return std::vector<Symbol> used for results.
|
|
|
|
*/
|
|
|
|
virtual std::vector<Symbol> OutputSymbols(const SymbolTable &) const {
|
|
|
|
return std::vector<Symbol>();
|
|
|
|
}
|
2018-04-23 22:23:42 +08:00
|
|
|
|
2018-05-16 19:48:56 +08:00
|
|
|
/**
|
|
|
|
* Symbol vector whose values are modified by this operator sub-tree.
|
|
|
|
*
|
|
|
|
* This is different than @c OutputSymbols, because it returns all of the
|
|
|
|
* modified symbols, including those that may not be returned as the
|
|
|
|
* result of the query. Note that the modified symbols will not contain
|
|
|
|
* those that should not be read after the operator is processed.
|
|
|
|
*
|
|
|
|
* For example, `MATCH (n)-[e]-(m) RETURN n AS l` will generate `ScanAll (n) >
|
|
|
|
* Expand (e, m) > Produce (l)`. The modified symbols on Produce sub-tree will
|
|
|
|
* be `l`, the same as output symbols, because it isn't valid to read `n`, `e`
|
|
|
|
* nor `m` after Produce. On the other hand, modified symbols from Expand
|
|
|
|
* contain `e` and `m`, as well as `n`, while output symbols are empty.
|
|
|
|
* Modified symbols from ScanAll contain only `n`, while output symbols are
|
|
|
|
* also empty.
|
|
|
|
*/
|
|
|
|
virtual std::vector<Symbol> ModifiedSymbols(const SymbolTable &) const = 0;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Returns true if the operator takes only one input operator.
|
|
|
|
* NOTE: When this method returns true, you may use `input` and `set_input`
|
|
|
|
* methods.
|
|
|
|
*/
|
|
|
|
virtual bool HasSingleInput() const = 0;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Returns the input operator if it has any.
|
|
|
|
* NOTE: This should only be called if `HasSingleInput() == true`.
|
|
|
|
*/
|
|
|
|
virtual std::shared_ptr<LogicalOperator> input() const = 0;
|
|
|
|
/**
|
|
|
|
* Set a different input on this operator.
|
|
|
|
* NOTE: This should only be called if `HasSingleInput() == true`.
|
|
|
|
*/
|
|
|
|
virtual void set_input(std::shared_ptr<LogicalOperator>) = 0;
|
|
|
|
|
|
|
|
struct SaveHelper {
|
|
|
|
std::vector<int> saved_ast_uids;
|
|
|
|
std::vector<LogicalOperator *> saved_ops;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct LoadHelper {
|
2018-05-22 22:45:52 +08:00
|
|
|
AstStorage ast_storage;
|
2018-05-16 19:48:56 +08:00
|
|
|
std::vector<int> loaded_ast_uids;
|
|
|
|
std::vector<std::pair<uint64_t, std::shared_ptr<LogicalOperator>>>
|
|
|
|
loaded_ops;
|
|
|
|
};
|
|
|
|
cpp<#)
|
|
|
|
(:serialize :capnp :base t
|
|
|
|
:save-args '((helper "SaveHelper *"))
|
|
|
|
:load-args '((helper "LoadHelper *"))))
|
2018-04-23 22:23:42 +08:00
|
|
|
|
2018-05-16 19:48:56 +08:00
|
|
|
(defun save-ast-pointer (builder member)
|
|
|
|
(let ((member-getter (remove #\_ (string-capitalize member))))
|
|
|
|
#>cpp
|
|
|
|
if (${member}) {
|
|
|
|
auto ${member}_builder = ${builder}->init${member-getter}();
|
|
|
|
${member}->Save(&${member}_builder, &helper->saved_ast_uids);
|
|
|
|
}
|
|
|
|
cpp<#))
|
|
|
|
|
|
|
|
(defun load-ast-pointer (ast-type)
|
|
|
|
(lambda (reader member)
|
|
|
|
(let ((member-getter (remove #\_ (string-capitalize member))))
|
|
|
|
#>cpp
|
|
|
|
if (${reader}.has${member-getter}())
|
|
|
|
${member} = static_cast<${ast-type}>(helper->ast_storage.Load(${reader}.get${member-getter}(), &helper->loaded_ast_uids));
|
|
|
|
else
|
|
|
|
${member} = nullptr;
|
|
|
|
cpp<#)))
|
|
|
|
|
|
|
|
(defun save-ast-vector (ast-type)
|
Replace boost with capnp in RPC
Summary:
Converts the RPC stack to use Cap'n Proto for serialization instead of
boost. There are still some traces of boost in other places in the code,
but most of it is removed. A future diff should cleanup boost for good.
The RPC API is now changed to be more flexible with regards to how
serialize data. This makes the simplest cases a bit more verbose, but
allows complex serialization code to be correctly written instead of
relying on hacks. (For reference, look for the old serialization of
`PullRpc` which had a nasty pointer hacks to inject accessors in
`TypedValue`.)
Since RPC messages were uselessly modeled via inheritance of Message
base class, that class is now removed. Furthermore, that approach
doesn't really work with Cap'n Proto. Instead, each message type is
required to have some type information. This can be automated, so
`define-rpc` has been added to LCP, which hopefully simplifies defining
new RPC request and response messages.
Specify Cap'n Proto schema ID in cmake
This preserves Cap'n Proto generated typeIds across multiple generations
of capnp schemas through LCP. It is imperative that typeId stays the
same to ensure that different compilations of Memgraph may communicate
via RPC in a distributed cluster.
Use CLOS for meta information on C++ types in LCP
Since some structure slots and functions have started to repeat
themselves, it makes sense to model C++ meta information via Common Lisp
Object System.
Depends on D1391
Reviewers: buda, dgleich, mferencevic, mtomic, mculinovic, msantl
Reviewed By: msantl
Subscribers: pullbot
Differential Revision: https://phabricator.memgraph.io/D1407
2018-06-04 15:48:48 +08:00
|
|
|
(lcp:capnp-save-vector "::query::capnp::Tree" ast-type
|
|
|
|
"[helper](auto *builder, const auto &val) {
|
|
|
|
val->Save(builder, &helper->saved_ast_uids);
|
|
|
|
}"))
|
2018-05-16 19:48:56 +08:00
|
|
|
|
|
|
|
(defun load-ast-vector (ast-type)
|
Replace boost with capnp in RPC
Summary:
Converts the RPC stack to use Cap'n Proto for serialization instead of
boost. There are still some traces of boost in other places in the code,
but most of it is removed. A future diff should cleanup boost for good.
The RPC API is now changed to be more flexible with regards to how
serialize data. This makes the simplest cases a bit more verbose, but
allows complex serialization code to be correctly written instead of
relying on hacks. (For reference, look for the old serialization of
`PullRpc` which had a nasty pointer hacks to inject accessors in
`TypedValue`.)
Since RPC messages were uselessly modeled via inheritance of Message
base class, that class is now removed. Furthermore, that approach
doesn't really work with Cap'n Proto. Instead, each message type is
required to have some type information. This can be automated, so
`define-rpc` has been added to LCP, which hopefully simplifies defining
new RPC request and response messages.
Specify Cap'n Proto schema ID in cmake
This preserves Cap'n Proto generated typeIds across multiple generations
of capnp schemas through LCP. It is imperative that typeId stays the
same to ensure that different compilations of Memgraph may communicate
via RPC in a distributed cluster.
Use CLOS for meta information on C++ types in LCP
Since some structure slots and functions have started to repeat
themselves, it makes sense to model C++ meta information via Common Lisp
Object System.
Depends on D1391
Reviewers: buda, dgleich, mferencevic, mtomic, mculinovic, msantl
Reviewed By: msantl
Subscribers: pullbot
Differential Revision: https://phabricator.memgraph.io/D1407
2018-06-04 15:48:48 +08:00
|
|
|
(lcp:capnp-load-vector "::query::capnp::Tree" ast-type
|
|
|
|
(format
|
|
|
|
nil
|
|
|
|
"[helper](const auto &reader) {
|
|
|
|
// We expect the unsafe downcast via static_cast to work.
|
|
|
|
return static_cast<~A>(helper->ast_storage.Load(reader, &helper->loaded_ast_uids));
|
|
|
|
}" ast-type)))
|
2018-05-16 19:48:56 +08:00
|
|
|
|
|
|
|
(defun save-operator-pointer (builder member-name)
|
|
|
|
#>cpp
|
|
|
|
utils::SaveSharedPtr<capnp::LogicalOperator, LogicalOperator>(${member-name}, &${builder},
|
|
|
|
[helper](auto *builder, const auto &val) {
|
|
|
|
val.Save(builder, helper);
|
|
|
|
}, &helper->saved_ops);
|
|
|
|
cpp<#)
|
|
|
|
|
|
|
|
(defun load-operator-pointer (reader member-name)
|
|
|
|
#>cpp
|
|
|
|
${member-name} = utils::LoadSharedPtr<capnp::LogicalOperator, LogicalOperator>(${reader},
|
|
|
|
[helper](const auto &reader) {
|
|
|
|
auto op = LogicalOperator::Construct(reader);
|
|
|
|
op->Load(reader, helper);
|
|
|
|
return op.release();
|
|
|
|
}, &helper->loaded_ops);
|
|
|
|
cpp<#)
|
|
|
|
|
2018-04-23 22:23:42 +08:00
|
|
|
(lcp:define-class once (logical-operator)
|
|
|
|
()
|
|
|
|
(:documentation
|
|
|
|
"A logical operator whose Cursor returns true on the first Pull
|
|
|
|
and false on every following Pull.")
|
|
|
|
(:public
|
|
|
|
#>cpp
|
|
|
|
DEFVISITABLE(HierarchicalLogicalOperatorVisitor);
|
|
|
|
std::unique_ptr<Cursor> MakeCursor(
|
|
|
|
database::GraphDbAccessor &db) const override;
|
|
|
|
std::vector<Symbol> ModifiedSymbols(const SymbolTable &) const override {
|
|
|
|
return {};
|
|
|
|
}
|
|
|
|
|
|
|
|
bool HasSingleInput() const override;
|
|
|
|
std::shared_ptr<LogicalOperator> input() const override;
|
|
|
|
void set_input(std::shared_ptr<LogicalOperator>) override;
|
|
|
|
cpp<#)
|
|
|
|
(:private
|
|
|
|
#>cpp
|
|
|
|
class OnceCursor : public Cursor {
|
|
|
|
public:
|
|
|
|
OnceCursor() {}
|
|
|
|
bool Pull(Frame &, Context &) override;
|
|
|
|
void Reset() override;
|
|
|
|
|
|
|
|
private:
|
|
|
|
bool did_pull_{false};
|
|
|
|
};
|
|
|
|
cpp<#)
|
2018-07-30 19:48:22 +08:00
|
|
|
(:serialize :capnp))
|
2018-04-23 22:23:42 +08:00
|
|
|
|
|
|
|
(lcp:define-class create-node (logical-operator)
|
2018-05-16 19:48:56 +08:00
|
|
|
((input "std::shared_ptr<LogicalOperator>"
|
|
|
|
:capnp-save #'save-operator-pointer
|
|
|
|
:capnp-load #'load-operator-pointer)
|
2018-06-19 19:52:11 +08:00
|
|
|
(node-atom "NodeAtom *" :initval "nullptr" :reader t
|
2018-05-16 19:48:56 +08:00
|
|
|
:capnp-type "Ast.Tree" :capnp-init nil
|
2018-07-30 19:48:22 +08:00
|
|
|
:capnp-save #'save-ast-pointer :capnp-load (load-ast-pointer "NodeAtom *"))
|
2018-04-23 22:23:42 +08:00
|
|
|
(on-random-worker :bool :initval "false"))
|
|
|
|
(:documentation
|
|
|
|
"Operator for creating a node.
|
|
|
|
|
|
|
|
This op is used both for creating a single node (`CREATE` statement without
|
|
|
|
a preceeding `MATCH`), or multiple nodes (`MATCH ... CREATE` or
|
|
|
|
`CREATE (), () ...`).
|
|
|
|
|
|
|
|
@sa CreateExpand")
|
|
|
|
(:public
|
|
|
|
#>cpp
|
|
|
|
/**
|
|
|
|
* @param input Optional. If @c nullptr, then a single node will be
|
|
|
|
* created (a single successful @c Cursor::Pull from this op's @c Cursor).
|
|
|
|
* If a valid input, then a node will be created for each
|
|
|
|
* successful pull from the given input.
|
|
|
|
* @param node_atom @c NodeAtom with information on how to create a node.
|
|
|
|
* @param on_random_worker If the node should be created locally or on random
|
|
|
|
* worker.
|
|
|
|
*/
|
|
|
|
CreateNode(const std::shared_ptr<LogicalOperator> &input, NodeAtom *node_atom,
|
|
|
|
bool on_random_worker);
|
|
|
|
bool Accept(HierarchicalLogicalOperatorVisitor &visitor) override;
|
|
|
|
std::unique_ptr<Cursor> MakeCursor(
|
|
|
|
database::GraphDbAccessor &db) const override;
|
|
|
|
std::vector<Symbol> ModifiedSymbols(const SymbolTable &) const override;
|
|
|
|
|
|
|
|
bool HasSingleInput() const override { return true; }
|
|
|
|
std::shared_ptr<LogicalOperator> input() const override { return input_; }
|
|
|
|
void set_input(std::shared_ptr<LogicalOperator> input) override {
|
|
|
|
input_ = input;
|
|
|
|
}
|
|
|
|
|
|
|
|
auto on_random_worker() const { return on_random_worker_; }
|
|
|
|
void set_on_random_worker(bool v) { on_random_worker_ = v; }
|
|
|
|
cpp<#)
|
|
|
|
(:private
|
|
|
|
#>cpp
|
|
|
|
CreateNode() {}
|
|
|
|
|
|
|
|
class CreateNodeCursor : public Cursor {
|
|
|
|
public:
|
|
|
|
CreateNodeCursor(const CreateNode &self, database::GraphDbAccessor &db);
|
|
|
|
bool Pull(Frame &, Context &) override;
|
|
|
|
void Reset() override;
|
|
|
|
|
|
|
|
private:
|
|
|
|
const CreateNode &self_;
|
|
|
|
database::GraphDbAccessor &db_;
|
|
|
|
const std::unique_ptr<Cursor> input_cursor_;
|
|
|
|
};
|
|
|
|
cpp<#)
|
2018-07-30 19:48:22 +08:00
|
|
|
(:serialize :capnp))
|
2018-04-23 22:23:42 +08:00
|
|
|
|
|
|
|
(lcp:define-class create-expand (logical-operator)
|
|
|
|
(
|
|
|
|
;; info on what's getting expanded
|
2018-06-19 19:52:11 +08:00
|
|
|
(node-atom "NodeAtom *" :reader t
|
2018-05-16 19:48:56 +08:00
|
|
|
:capnp-type "Ast.Tree" :capnp-init nil
|
|
|
|
:capnp-save #'save-ast-pointer :capnp-load (load-ast-pointer "NodeAtom *"))
|
2018-06-19 19:52:11 +08:00
|
|
|
(edge-atom "EdgeAtom *" :reader t
|
2018-05-16 19:48:56 +08:00
|
|
|
:capnp-type "Ast.Tree" :capnp-init nil
|
|
|
|
:capnp-save #'save-ast-pointer :capnp-load (load-ast-pointer "EdgeAtom *"))
|
2018-04-23 22:23:42 +08:00
|
|
|
;; the input op and the symbol under which the op's result
|
|
|
|
;; can be found in the frame
|
2018-05-16 19:48:56 +08:00
|
|
|
(input "std::shared_ptr<LogicalOperator>"
|
|
|
|
:capnp-save #'save-operator-pointer
|
|
|
|
:capnp-load #'load-operator-pointer)
|
2018-06-19 19:52:11 +08:00
|
|
|
(input-symbol "Symbol" :reader t)
|
2018-04-23 22:23:42 +08:00
|
|
|
(existing-node :bool :documentation
|
|
|
|
"if the given node atom refers to an existing node (either matched or created)"))
|
|
|
|
(:documentation
|
|
|
|
"Operator for creating edges and destination nodes.
|
|
|
|
|
|
|
|
This operator extends already created nodes with an edge. If the other node
|
|
|
|
on the edge does not exist, it will be created. For example, in `MATCH (n)
|
|
|
|
CREATE (n) -[r:r]-> (n)` query, this operator will create just the edge `r`.
|
|
|
|
In `MATCH (n) CREATE (n) -[r:r]-> (m)` query, the operator will create both
|
|
|
|
the edge `r` and the node `m`. In case of `CREATE (n) -[r:r]-> (m)` the
|
|
|
|
first node `n` is created by @c CreateNode operator, while @c CreateExpand
|
|
|
|
will create the edge `r` and `m`. Similarly, multiple @c CreateExpand are
|
|
|
|
chained in cases when longer paths need creating.
|
|
|
|
|
|
|
|
@sa CreateNode")
|
|
|
|
(:public
|
|
|
|
#>cpp
|
|
|
|
/** @brief Construct @c CreateExpand.
|
|
|
|
*
|
|
|
|
* @param node_atom @c NodeAtom at the end of the edge. Used to create a node,
|
|
|
|
* unless it refers to an existing one.
|
|
|
|
* @param edge_atom @c EdgeAtom with information for the edge to be created.
|
|
|
|
* @param input Optional. Previous @c LogicalOperator which will be pulled.
|
|
|
|
* For each successful @c Cursor::Pull, this operator will create an
|
|
|
|
* expansion.
|
|
|
|
* @param input_symbol @c Symbol for the node at the start of the edge.
|
|
|
|
* @param existing_node @c bool indicating whether the @c node_atom refers to
|
|
|
|
* an existing node. If @c false, the operator will also create the node.
|
|
|
|
*/
|
|
|
|
CreateExpand(NodeAtom *node_atom, EdgeAtom *edge_atom,
|
|
|
|
const std::shared_ptr<LogicalOperator> &input,
|
|
|
|
Symbol input_symbol, bool existing_node);
|
|
|
|
bool Accept(HierarchicalLogicalOperatorVisitor &visitor) override;
|
|
|
|
std::unique_ptr<Cursor> MakeCursor(
|
|
|
|
database::GraphDbAccessor &db) const override;
|
|
|
|
std::vector<Symbol> ModifiedSymbols(const SymbolTable &) const override;
|
|
|
|
|
|
|
|
bool HasSingleInput() const override { return true; }
|
|
|
|
std::shared_ptr<LogicalOperator> input() const override { return input_; }
|
|
|
|
void set_input(std::shared_ptr<LogicalOperator> input) override {
|
|
|
|
input_ = input;
|
|
|
|
}
|
|
|
|
cpp<#)
|
|
|
|
(:private
|
|
|
|
#>cpp
|
|
|
|
CreateExpand() {}
|
|
|
|
|
|
|
|
class CreateExpandCursor : public Cursor {
|
|
|
|
public:
|
|
|
|
CreateExpandCursor(const CreateExpand &self, database::GraphDbAccessor &db);
|
|
|
|
bool Pull(Frame &, Context &) override;
|
|
|
|
void Reset() override;
|
|
|
|
|
|
|
|
private:
|
|
|
|
const CreateExpand &self_;
|
|
|
|
database::GraphDbAccessor &db_;
|
|
|
|
const std::unique_ptr<Cursor> input_cursor_;
|
|
|
|
|
|
|
|
/** Gets the existing node (if existing_node_ == true), or creates a new
|
|
|
|
* node (on the given worker) and returns it. */
|
|
|
|
VertexAccessor &OtherVertex(int worker_id, Frame &frame, Context &context);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Helper function for creating an edge and adding it
|
|
|
|
* to the frame.
|
|
|
|
*
|
|
|
|
* @param from Origin vertex of the edge.
|
|
|
|
* @param to Destination vertex of the edge.
|
|
|
|
* @param evaluator Expression evaluator for property value eval.
|
|
|
|
*/
|
|
|
|
void CreateEdge(VertexAccessor &from, VertexAccessor &to, Frame &frame,
|
|
|
|
const SymbolTable &symbol_table,
|
|
|
|
ExpressionEvaluator &evaluator);
|
|
|
|
};
|
|
|
|
cpp<#)
|
2018-07-30 19:48:22 +08:00
|
|
|
(:serialize :capnp))
|
2018-04-23 22:23:42 +08:00
|
|
|
|
|
|
|
(lcp:define-class scan-all (logical-operator)
|
2018-05-16 19:48:56 +08:00
|
|
|
((input "std::shared_ptr<LogicalOperator>" :scope :protected
|
|
|
|
:capnp-save #'save-operator-pointer
|
|
|
|
:capnp-load #'load-operator-pointer)
|
2018-04-23 22:23:42 +08:00
|
|
|
(output-symbol "Symbol" :reader t :scope :protected)
|
|
|
|
(graph-view "GraphView" :reader t :scope :protected
|
2018-05-16 19:48:56 +08:00
|
|
|
:capnp-init nil
|
Replace boost with capnp in RPC
Summary:
Converts the RPC stack to use Cap'n Proto for serialization instead of
boost. There are still some traces of boost in other places in the code,
but most of it is removed. A future diff should cleanup boost for good.
The RPC API is now changed to be more flexible with regards to how
serialize data. This makes the simplest cases a bit more verbose, but
allows complex serialization code to be correctly written instead of
relying on hacks. (For reference, look for the old serialization of
`PullRpc` which had a nasty pointer hacks to inject accessors in
`TypedValue`.)
Since RPC messages were uselessly modeled via inheritance of Message
base class, that class is now removed. Furthermore, that approach
doesn't really work with Cap'n Proto. Instead, each message type is
required to have some type information. This can be automated, so
`define-rpc` has been added to LCP, which hopefully simplifies defining
new RPC request and response messages.
Specify Cap'n Proto schema ID in cmake
This preserves Cap'n Proto generated typeIds across multiple generations
of capnp schemas through LCP. It is imperative that typeId stays the
same to ensure that different compilations of Memgraph may communicate
via RPC in a distributed cluster.
Use CLOS for meta information on C++ types in LCP
Since some structure slots and functions have started to repeat
themselves, it makes sense to model C++ meta information via Common Lisp
Object System.
Depends on D1391
Reviewers: buda, dgleich, mferencevic, mtomic, mculinovic, msantl
Reviewed By: msantl
Subscribers: pullbot
Differential Revision: https://phabricator.memgraph.io/D1407
2018-06-04 15:48:48 +08:00
|
|
|
:capnp-save (lcp:capnp-save-enum "::query::capnp::GraphView" "GraphView"
|
|
|
|
'(old new))
|
|
|
|
:capnp-load (lcp:capnp-load-enum "::query::capnp::GraphView" "GraphView"
|
|
|
|
'(old new))
|
2018-04-23 22:23:42 +08:00
|
|
|
:documentation
|
|
|
|
"Controls which graph state is used to produce vertices.
|
|
|
|
|
|
|
|
If @c GraphView::OLD, @c ScanAll will produce vertices visible in the previous
|
|
|
|
graph state, before modifications done by current transaction & command. With
|
|
|
|
@c GraphView::NEW, all vertices will be produced the current transaction sees
|
|
|
|
along with their modifications."))
|
|
|
|
|
|
|
|
(:documentation
|
|
|
|
"Operator which iterates over all the nodes currently in the database.
|
|
|
|
When given an input (optional), does a cartesian product.
|
|
|
|
|
|
|
|
It accepts an optional input. If provided then this op scans all the nodes
|
|
|
|
currently in the database for each successful Pull from it's input, thereby
|
|
|
|
producing a cartesian product of input Pulls and database elements.
|
|
|
|
|
|
|
|
ScanAll can either iterate over the previous graph state (state before
|
|
|
|
the current transacton+command) or over current state. This is controlled
|
|
|
|
with a constructor argument.
|
|
|
|
|
|
|
|
@sa ScanAllByLabel
|
|
|
|
@sa ScanAllByLabelPropertyRange
|
|
|
|
@sa ScanAllByLabelPropertyValue")
|
|
|
|
(:public
|
|
|
|
#>cpp
|
|
|
|
ScanAll(const std::shared_ptr<LogicalOperator> &input, Symbol output_symbol,
|
|
|
|
GraphView graph_view = GraphView::OLD);
|
|
|
|
bool Accept(HierarchicalLogicalOperatorVisitor &visitor) override;
|
|
|
|
std::unique_ptr<Cursor> MakeCursor(
|
|
|
|
database::GraphDbAccessor &db) const override;
|
|
|
|
std::vector<Symbol> ModifiedSymbols(const SymbolTable &) const override;
|
|
|
|
|
|
|
|
bool HasSingleInput() const override { return true; }
|
|
|
|
std::shared_ptr<LogicalOperator> input() const override { return input_; }
|
|
|
|
void set_input(std::shared_ptr<LogicalOperator> input) override {
|
|
|
|
input_ = input;
|
|
|
|
}
|
|
|
|
cpp<#)
|
|
|
|
(:protected #>cpp ScanAll() {} cpp<#)
|
2018-07-30 19:48:22 +08:00
|
|
|
(:serialize :capnp))
|
2018-04-23 22:23:42 +08:00
|
|
|
|
|
|
|
(lcp:define-class scan-all-by-label (scan-all)
|
|
|
|
((label "storage::Label" :reader t))
|
|
|
|
(:documentation
|
|
|
|
"Behaves like @c ScanAll, but this operator produces only vertices with
|
|
|
|
given label.
|
|
|
|
|
|
|
|
@sa ScanAll
|
|
|
|
@sa ScanAllByLabelPropertyRange
|
|
|
|
@sa ScanAllByLabelPropertyValue")
|
|
|
|
(:public
|
|
|
|
#>cpp
|
|
|
|
ScanAllByLabel(const std::shared_ptr<LogicalOperator> &input,
|
|
|
|
Symbol output_symbol, storage::Label label,
|
|
|
|
GraphView graph_view = GraphView::OLD);
|
|
|
|
bool Accept(HierarchicalLogicalOperatorVisitor &visitor) override;
|
|
|
|
std::unique_ptr<Cursor> MakeCursor(
|
|
|
|
database::GraphDbAccessor &db) const override;
|
|
|
|
cpp<#)
|
|
|
|
(:private #>cpp ScanAllByLabel() {} cpp<#)
|
2018-07-30 19:48:22 +08:00
|
|
|
(:serialize :capnp))
|
2018-05-16 19:48:56 +08:00
|
|
|
|
|
|
|
(defun save-optional-bound (builder member)
|
|
|
|
(let ((save-bound
|
|
|
|
"[helper](auto *builder, const auto &bound) {
|
|
|
|
builder->setType(bound.type() == Bound::Type::INCLUSIVE ?
|
|
|
|
::utils::capnp::Bound<::query::capnp::Tree>::Type::INCLUSIVE :
|
|
|
|
::utils::capnp::Bound<::query::capnp::Tree>::Type::EXCLUSIVE);
|
|
|
|
auto value_builder = builder->initValue();
|
|
|
|
bound.value()->Save(&value_builder, &helper->saved_ast_uids);
|
|
|
|
}"))
|
Replace boost with capnp in RPC
Summary:
Converts the RPC stack to use Cap'n Proto for serialization instead of
boost. There are still some traces of boost in other places in the code,
but most of it is removed. A future diff should cleanup boost for good.
The RPC API is now changed to be more flexible with regards to how
serialize data. This makes the simplest cases a bit more verbose, but
allows complex serialization code to be correctly written instead of
relying on hacks. (For reference, look for the old serialization of
`PullRpc` which had a nasty pointer hacks to inject accessors in
`TypedValue`.)
Since RPC messages were uselessly modeled via inheritance of Message
base class, that class is now removed. Furthermore, that approach
doesn't really work with Cap'n Proto. Instead, each message type is
required to have some type information. This can be automated, so
`define-rpc` has been added to LCP, which hopefully simplifies defining
new RPC request and response messages.
Specify Cap'n Proto schema ID in cmake
This preserves Cap'n Proto generated typeIds across multiple generations
of capnp schemas through LCP. It is imperative that typeId stays the
same to ensure that different compilations of Memgraph may communicate
via RPC in a distributed cluster.
Use CLOS for meta information on C++ types in LCP
Since some structure slots and functions have started to repeat
themselves, it makes sense to model C++ meta information via Common Lisp
Object System.
Depends on D1391
Reviewers: buda, dgleich, mferencevic, mtomic, mculinovic, msantl
Reviewed By: msantl
Subscribers: pullbot
Differential Revision: https://phabricator.memgraph.io/D1407
2018-06-04 15:48:48 +08:00
|
|
|
(funcall (lcp:capnp-save-optional "::utils::capnp::Bound<::query::capnp::Tree>" "Bound"
|
|
|
|
save-bound)
|
2018-05-16 19:48:56 +08:00
|
|
|
builder member)))
|
|
|
|
|
|
|
|
(defun load-optional-bound (reader member)
|
|
|
|
(let ((load-bound
|
|
|
|
"[helper](const auto &reader) {
|
|
|
|
auto type = reader.getType() == ::utils::capnp::Bound<::query::capnp::Tree>::Type::INCLUSIVE
|
|
|
|
? Bound::Type::INCLUSIVE : Bound::Type::EXCLUSIVE;
|
|
|
|
auto *value = static_cast<Expression*>(helper->ast_storage.Load(reader.getValue(), &helper->loaded_ast_uids));
|
|
|
|
return Bound(value, type);
|
|
|
|
}"))
|
Replace boost with capnp in RPC
Summary:
Converts the RPC stack to use Cap'n Proto for serialization instead of
boost. There are still some traces of boost in other places in the code,
but most of it is removed. A future diff should cleanup boost for good.
The RPC API is now changed to be more flexible with regards to how
serialize data. This makes the simplest cases a bit more verbose, but
allows complex serialization code to be correctly written instead of
relying on hacks. (For reference, look for the old serialization of
`PullRpc` which had a nasty pointer hacks to inject accessors in
`TypedValue`.)
Since RPC messages were uselessly modeled via inheritance of Message
base class, that class is now removed. Furthermore, that approach
doesn't really work with Cap'n Proto. Instead, each message type is
required to have some type information. This can be automated, so
`define-rpc` has been added to LCP, which hopefully simplifies defining
new RPC request and response messages.
Specify Cap'n Proto schema ID in cmake
This preserves Cap'n Proto generated typeIds across multiple generations
of capnp schemas through LCP. It is imperative that typeId stays the
same to ensure that different compilations of Memgraph may communicate
via RPC in a distributed cluster.
Use CLOS for meta information on C++ types in LCP
Since some structure slots and functions have started to repeat
themselves, it makes sense to model C++ meta information via Common Lisp
Object System.
Depends on D1391
Reviewers: buda, dgleich, mferencevic, mtomic, mculinovic, msantl
Reviewed By: msantl
Subscribers: pullbot
Differential Revision: https://phabricator.memgraph.io/D1407
2018-06-04 15:48:48 +08:00
|
|
|
(funcall (lcp:capnp-load-optional "::utils::capnp::Bound<::query::capnp::Tree>" "Bound"
|
|
|
|
load-bound)
|
2018-05-16 19:48:56 +08:00
|
|
|
reader member)))
|
2018-04-23 22:23:42 +08:00
|
|
|
|
|
|
|
(lcp:define-class scan-all-by-label-property-range (scan-all)
|
|
|
|
((label "storage::Label" :reader t)
|
|
|
|
(property "storage::Property" :reader t)
|
|
|
|
(lower-bound "std::experimental::optional<Bound>" :reader t
|
2018-05-16 19:48:56 +08:00
|
|
|
:capnp-type "Utils.Optional(Utils.Bound(Ast.Tree))"
|
2018-07-30 19:48:22 +08:00
|
|
|
:capnp-save #'save-optional-bound :capnp-load #'load-optional-bound)
|
2018-04-23 22:23:42 +08:00
|
|
|
(upper-bound "std::experimental::optional<Bound>" :reader t
|
2018-05-16 19:48:56 +08:00
|
|
|
:capnp-save #'save-optional-bound :capnp-load #'load-optional-bound
|
2018-07-30 19:48:22 +08:00
|
|
|
:capnp-type "Utils.Optional(Utils.Bound(Ast.Tree))"))
|
2018-04-23 22:23:42 +08:00
|
|
|
(:documentation
|
|
|
|
"Behaves like @c ScanAll, but produces only vertices with given label and
|
|
|
|
property value which is inside a range (inclusive or exlusive).
|
|
|
|
|
|
|
|
@sa ScanAll
|
|
|
|
@sa ScanAllByLabel
|
|
|
|
@sa ScanAllByLabelPropertyValue")
|
|
|
|
(:public
|
|
|
|
#>cpp
|
|
|
|
/** Bound with expression which when evaluated produces the bound value. */
|
|
|
|
using Bound = utils::Bound<Expression *>;
|
|
|
|
/**
|
|
|
|
* Constructs the operator for given label and property value in range
|
|
|
|
* (inclusive).
|
|
|
|
*
|
|
|
|
* Range bounds are optional, but only one bound can be left out.
|
|
|
|
*
|
|
|
|
* @param input Preceding operator which will serve as the input.
|
|
|
|
* @param output_symbol Symbol where the vertices will be stored.
|
|
|
|
* @param label Label which the vertex must have.
|
|
|
|
* @param property Property from which the value will be looked up from.
|
|
|
|
* @param lower_bound Optional lower @c Bound.
|
|
|
|
* @param upper_bound Optional upper @c Bound.
|
|
|
|
* @param graph_view GraphView used when obtaining vertices.
|
|
|
|
*/
|
|
|
|
ScanAllByLabelPropertyRange(const std::shared_ptr<LogicalOperator> &input,
|
|
|
|
Symbol output_symbol, storage::Label label,
|
|
|
|
storage::Property property,
|
|
|
|
std::experimental::optional<Bound> lower_bound,
|
|
|
|
std::experimental::optional<Bound> upper_bound,
|
|
|
|
GraphView graph_view = GraphView::OLD);
|
|
|
|
|
|
|
|
bool Accept(HierarchicalLogicalOperatorVisitor &visitor) override;
|
|
|
|
std::unique_ptr<Cursor> MakeCursor(
|
|
|
|
database::GraphDbAccessor &db) const override;
|
|
|
|
cpp<#)
|
|
|
|
(:private #>cpp ScanAllByLabelPropertyRange() {} cpp<#)
|
2018-07-30 19:48:22 +08:00
|
|
|
(:serialize :capnp))
|
2018-04-23 22:23:42 +08:00
|
|
|
|
|
|
|
(lcp:define-class scan-all-by-label-property-value (scan-all)
|
|
|
|
((label "storage::Label" :reader t)
|
|
|
|
(property "storage::Property" :reader t)
|
|
|
|
(expression "Expression *" :reader t
|
2018-05-16 19:48:56 +08:00
|
|
|
:capnp-type "Ast.Tree" :capnp-init nil
|
2018-07-30 19:48:22 +08:00
|
|
|
:capnp-save #'save-ast-pointer :capnp-load (load-ast-pointer "Expression *")))
|
2018-04-23 22:23:42 +08:00
|
|
|
(:documentation
|
|
|
|
"Behaves like @c ScanAll, but produces only vertices with given label and
|
|
|
|
property value.
|
|
|
|
|
|
|
|
@sa ScanAll
|
|
|
|
@sa ScanAllByLabel
|
|
|
|
@sa ScanAllByLabelPropertyRange")
|
|
|
|
(:public
|
|
|
|
#>cpp
|
|
|
|
/**
|
|
|
|
* Constructs the operator for given label and property value.
|
|
|
|
*
|
|
|
|
* @param input Preceding operator which will serve as the input.
|
|
|
|
* @param output_symbol Symbol where the vertices will be stored.
|
|
|
|
* @param label Label which the vertex must have.
|
|
|
|
* @param property Property from which the value will be looked up from.
|
|
|
|
* @param expression Expression producing the value of the vertex property.
|
|
|
|
* @param graph_view GraphView used when obtaining vertices.
|
|
|
|
*/
|
|
|
|
ScanAllByLabelPropertyValue(const std::shared_ptr<LogicalOperator> &input,
|
|
|
|
Symbol output_symbol, storage::Label label,
|
|
|
|
storage::Property property,
|
|
|
|
Expression *expression,
|
|
|
|
GraphView graph_view = GraphView::OLD);
|
|
|
|
|
|
|
|
bool Accept(HierarchicalLogicalOperatorVisitor &visitor) override;
|
|
|
|
std::unique_ptr<Cursor> MakeCursor(
|
|
|
|
database::GraphDbAccessor &db) const override;
|
|
|
|
cpp<#)
|
|
|
|
(:private #>cpp ScanAllByLabelPropertyValue() {} cpp<#)
|
2018-07-30 19:48:22 +08:00
|
|
|
(:serialize :capnp))
|
2018-04-23 22:23:42 +08:00
|
|
|
|
|
|
|
(lcp:define-class expand-common ()
|
|
|
|
(
|
|
|
|
;; info on what's getting expanded
|
|
|
|
(node-symbol "Symbol" :reader t :scope :protected)
|
|
|
|
(edge-symbol "Symbol" :reader t :scope :protected)
|
2018-05-16 19:48:56 +08:00
|
|
|
(direction "EdgeAtom::Direction" :reader t :scope :protected
|
|
|
|
:capnp-type "Ast.EdgeAtom.Direction" :capnp-init nil
|
Replace boost with capnp in RPC
Summary:
Converts the RPC stack to use Cap'n Proto for serialization instead of
boost. There are still some traces of boost in other places in the code,
but most of it is removed. A future diff should cleanup boost for good.
The RPC API is now changed to be more flexible with regards to how
serialize data. This makes the simplest cases a bit more verbose, but
allows complex serialization code to be correctly written instead of
relying on hacks. (For reference, look for the old serialization of
`PullRpc` which had a nasty pointer hacks to inject accessors in
`TypedValue`.)
Since RPC messages were uselessly modeled via inheritance of Message
base class, that class is now removed. Furthermore, that approach
doesn't really work with Cap'n Proto. Instead, each message type is
required to have some type information. This can be automated, so
`define-rpc` has been added to LCP, which hopefully simplifies defining
new RPC request and response messages.
Specify Cap'n Proto schema ID in cmake
This preserves Cap'n Proto generated typeIds across multiple generations
of capnp schemas through LCP. It is imperative that typeId stays the
same to ensure that different compilations of Memgraph may communicate
via RPC in a distributed cluster.
Use CLOS for meta information on C++ types in LCP
Since some structure slots and functions have started to repeat
themselves, it makes sense to model C++ meta information via Common Lisp
Object System.
Depends on D1391
Reviewers: buda, dgleich, mferencevic, mtomic, mculinovic, msantl
Reviewed By: msantl
Subscribers: pullbot
Differential Revision: https://phabricator.memgraph.io/D1407
2018-06-04 15:48:48 +08:00
|
|
|
:capnp-save (lcp:capnp-save-enum "::query::capnp::EdgeAtom::Direction" "EdgeAtom::Direction"
|
|
|
|
'(in out both))
|
|
|
|
:capnp-load (lcp:capnp-load-enum "::query::capnp::EdgeAtom::Direction" "EdgeAtom::Direction"
|
|
|
|
'(in out both)))
|
2018-05-16 19:48:56 +08:00
|
|
|
(edge-types "std::vector<storage::EdgeType>" :reader t :scope :protected
|
Replace boost with capnp in RPC
Summary:
Converts the RPC stack to use Cap'n Proto for serialization instead of
boost. There are still some traces of boost in other places in the code,
but most of it is removed. A future diff should cleanup boost for good.
The RPC API is now changed to be more flexible with regards to how
serialize data. This makes the simplest cases a bit more verbose, but
allows complex serialization code to be correctly written instead of
relying on hacks. (For reference, look for the old serialization of
`PullRpc` which had a nasty pointer hacks to inject accessors in
`TypedValue`.)
Since RPC messages were uselessly modeled via inheritance of Message
base class, that class is now removed. Furthermore, that approach
doesn't really work with Cap'n Proto. Instead, each message type is
required to have some type information. This can be automated, so
`define-rpc` has been added to LCP, which hopefully simplifies defining
new RPC request and response messages.
Specify Cap'n Proto schema ID in cmake
This preserves Cap'n Proto generated typeIds across multiple generations
of capnp schemas through LCP. It is imperative that typeId stays the
same to ensure that different compilations of Memgraph may communicate
via RPC in a distributed cluster.
Use CLOS for meta information on C++ types in LCP
Since some structure slots and functions have started to repeat
themselves, it makes sense to model C++ meta information via Common Lisp
Object System.
Depends on D1391
Reviewers: buda, dgleich, mferencevic, mtomic, mculinovic, msantl
Reviewed By: msantl
Subscribers: pullbot
Differential Revision: https://phabricator.memgraph.io/D1407
2018-06-04 15:48:48 +08:00
|
|
|
:capnp-save (lcp:capnp-save-vector "::storage::capnp::Common" "storage::EdgeType")
|
|
|
|
:capnp-load (lcp:capnp-load-vector "::storage::capnp::Common" "storage::EdgeType"))
|
2018-04-23 22:23:42 +08:00
|
|
|
;; the input op and the symbol under which the op's result
|
|
|
|
;; can be found in the frame
|
2018-05-16 19:48:56 +08:00
|
|
|
(input "std::shared_ptr<LogicalOperator>" :scope :protected
|
|
|
|
:capnp-save #'save-operator-pointer
|
|
|
|
:capnp-load #'load-operator-pointer)
|
2018-04-23 22:23:42 +08:00
|
|
|
(input-symbol "Symbol" :reader t :scope :protected)
|
2018-06-05 21:51:28 +08:00
|
|
|
(existing-node :bool :reader t :scope :protected :documentation
|
2018-04-23 22:23:42 +08:00
|
|
|
"If the given node atom refer to a symbol that has already
|
|
|
|
been expanded and should be just validated in the frame.")
|
2018-05-16 19:48:56 +08:00
|
|
|
(graph-view "GraphView" :reader t :scope :protected
|
|
|
|
:capnp-init nil
|
Replace boost with capnp in RPC
Summary:
Converts the RPC stack to use Cap'n Proto for serialization instead of
boost. There are still some traces of boost in other places in the code,
but most of it is removed. A future diff should cleanup boost for good.
The RPC API is now changed to be more flexible with regards to how
serialize data. This makes the simplest cases a bit more verbose, but
allows complex serialization code to be correctly written instead of
relying on hacks. (For reference, look for the old serialization of
`PullRpc` which had a nasty pointer hacks to inject accessors in
`TypedValue`.)
Since RPC messages were uselessly modeled via inheritance of Message
base class, that class is now removed. Furthermore, that approach
doesn't really work with Cap'n Proto. Instead, each message type is
required to have some type information. This can be automated, so
`define-rpc` has been added to LCP, which hopefully simplifies defining
new RPC request and response messages.
Specify Cap'n Proto schema ID in cmake
This preserves Cap'n Proto generated typeIds across multiple generations
of capnp schemas through LCP. It is imperative that typeId stays the
same to ensure that different compilations of Memgraph may communicate
via RPC in a distributed cluster.
Use CLOS for meta information on C++ types in LCP
Since some structure slots and functions have started to repeat
themselves, it makes sense to model C++ meta information via Common Lisp
Object System.
Depends on D1391
Reviewers: buda, dgleich, mferencevic, mtomic, mculinovic, msantl
Reviewed By: msantl
Subscribers: pullbot
Differential Revision: https://phabricator.memgraph.io/D1407
2018-06-04 15:48:48 +08:00
|
|
|
:capnp-save (lcp:capnp-save-enum "::query::capnp::GraphView" "GraphView"
|
|
|
|
'(old new))
|
|
|
|
:capnp-load (lcp:capnp-load-enum "::query::capnp::GraphView" "GraphView"
|
|
|
|
'(old new))
|
2018-05-16 19:48:56 +08:00
|
|
|
:documentation
|
2018-04-23 22:23:42 +08:00
|
|
|
"from which state the input node should get expanded"))
|
|
|
|
(:documentation
|
|
|
|
"Common functionality and data members of single-edge and variable-length
|
|
|
|
expansion")
|
|
|
|
(:public
|
|
|
|
#>cpp
|
|
|
|
/**
|
|
|
|
* Initializes common expansion parameters.
|
|
|
|
*
|
|
|
|
* Edge/Node existence are controlled with booleans. 'true'
|
|
|
|
* denotes that this expansion references an already
|
|
|
|
* Pulled node/edge, and should only be checked for equality
|
|
|
|
* during expansion.
|
|
|
|
*
|
|
|
|
* Expansion can be done from old or new state of the vertex
|
|
|
|
* the expansion originates from. This is controlled with a
|
|
|
|
* constructor argument.
|
|
|
|
*
|
|
|
|
* @param node_symbol Symbol pointing to the node to be expanded. This is
|
|
|
|
* where the new node will be stored.
|
|
|
|
* @param edge_symbol Symbol for the edges to be expanded. This is where
|
|
|
|
* a TypedValue containing a list of expanded edges will be stored.
|
|
|
|
* @param direction EdgeAtom::Direction determining the direction of edge
|
|
|
|
* expansion. The direction is relative to the starting vertex for each
|
|
|
|
* expansion.
|
|
|
|
* @param edge_types storage::EdgeType specifying which edges we
|
|
|
|
* want to expand. If empty, all edges are valid. If not empty, only edges
|
|
|
|
* with one of the given types are valid.
|
|
|
|
* @param input Optional LogicalOperator that preceeds this one.
|
|
|
|
* @param input_symbol Symbol that points to a VertexAccessor in the Frame
|
|
|
|
* that expansion should emanate from.
|
|
|
|
* @param existing_node If or not the node to be expanded is already present
|
|
|
|
* in the Frame and should just be checked for equality.
|
|
|
|
*/
|
|
|
|
ExpandCommon(Symbol node_symbol, Symbol edge_symbol,
|
|
|
|
EdgeAtom::Direction direction,
|
|
|
|
const std::vector<storage::EdgeType> &edge_types,
|
|
|
|
const std::shared_ptr<LogicalOperator> &input,
|
|
|
|
Symbol input_symbol, bool existing_node,
|
2018-05-15 19:10:15 +08:00
|
|
|
GraphView graph_view);
|
2018-04-23 22:23:42 +08:00
|
|
|
cpp<#)
|
|
|
|
(:protected
|
|
|
|
#>cpp
|
2018-05-16 19:48:56 +08:00
|
|
|
virtual ~ExpandCommon() {}
|
|
|
|
|
2018-04-23 22:23:42 +08:00
|
|
|
// types that we'll use for members in both subclasses
|
|
|
|
using InEdgeT = decltype(std::declval<VertexAccessor>().in());
|
|
|
|
using InEdgeIteratorT = decltype(std::declval<VertexAccessor>().in().begin());
|
|
|
|
using OutEdgeT = decltype(std::declval<VertexAccessor>().out());
|
|
|
|
using OutEdgeIteratorT =
|
|
|
|
decltype(std::declval<VertexAccessor>().out().begin());
|
|
|
|
|
|
|
|
/**
|
|
|
|
* For a newly expanded node handles existence checking and
|
|
|
|
* frame placement.
|
|
|
|
*
|
|
|
|
* @return If or not the given new_node is a valid expansion. It is not
|
|
|
|
* valid only when matching and existing node and new_node does not match
|
|
|
|
* the old.
|
|
|
|
*/
|
|
|
|
bool HandleExistingNode(const VertexAccessor &new_node, Frame &frame) const;
|
|
|
|
|
|
|
|
ExpandCommon() {}
|
|
|
|
cpp<#)
|
2018-07-30 19:48:22 +08:00
|
|
|
(:serialize :capnp
|
2018-05-16 19:48:56 +08:00
|
|
|
:save-args '((helper "LogicalOperator::SaveHelper *"))
|
|
|
|
:load-args '((helper "LogicalOperator::LoadHelper *"))))
|
2018-04-23 22:23:42 +08:00
|
|
|
|
|
|
|
(lcp:define-class expand (logical-operator expand-common)
|
|
|
|
()
|
|
|
|
(:documentation
|
|
|
|
"Expansion operator. For a node existing in the frame it
|
|
|
|
expands one edge and one node and places them on the frame.
|
|
|
|
|
|
|
|
This class does not handle node/edge filtering based on
|
|
|
|
properties, labels and edge types. However, it does handle
|
|
|
|
filtering on existing node / edge.
|
|
|
|
|
|
|
|
Filtering on existing means that for a pattern that references
|
|
|
|
an already declared node or edge (for example in
|
|
|
|
MATCH (a) MATCH (a)--(b)),
|
|
|
|
only expansions that match defined equalities are successfully
|
|
|
|
pulled.")
|
|
|
|
(:public
|
|
|
|
#>cpp
|
|
|
|
/**
|
|
|
|
* Creates an expansion. All parameters are forwarded to @c ExpandCommon and
|
|
|
|
* are documented there.
|
|
|
|
*/
|
|
|
|
using ExpandCommon::ExpandCommon;
|
|
|
|
|
|
|
|
bool Accept(HierarchicalLogicalOperatorVisitor &visitor) override;
|
|
|
|
std::unique_ptr<Cursor> MakeCursor(
|
|
|
|
database::GraphDbAccessor &db) const override;
|
|
|
|
std::vector<Symbol> ModifiedSymbols(const SymbolTable &) const override;
|
|
|
|
|
|
|
|
bool HasSingleInput() const override { return true; }
|
|
|
|
std::shared_ptr<LogicalOperator> input() const override { return input_; }
|
|
|
|
void set_input(std::shared_ptr<LogicalOperator> input) override {
|
|
|
|
input_ = input;
|
|
|
|
}
|
|
|
|
|
|
|
|
class ExpandCursor : public Cursor {
|
|
|
|
public:
|
|
|
|
ExpandCursor(const Expand &self, database::GraphDbAccessor &db);
|
|
|
|
bool Pull(Frame &, Context &) override;
|
|
|
|
void Reset() override;
|
|
|
|
|
|
|
|
private:
|
|
|
|
struct FutureExpand {
|
|
|
|
utils::Future<std::pair<EdgeAccessor, VertexAccessor>> edge_to;
|
|
|
|
std::vector<TypedValue> frame_elems;
|
|
|
|
};
|
|
|
|
|
|
|
|
const Expand &self_;
|
|
|
|
const std::unique_ptr<Cursor> input_cursor_;
|
|
|
|
database::GraphDbAccessor &db_;
|
|
|
|
|
|
|
|
// The iterable over edges and the current edge iterator are referenced via
|
|
|
|
// optional because they can not be initialized in the constructor of
|
|
|
|
// this class. They are initialized once for each pull from the input.
|
|
|
|
std::experimental::optional<InEdgeT> in_edges_;
|
|
|
|
std::experimental::optional<InEdgeIteratorT> in_edges_it_;
|
|
|
|
std::experimental::optional<OutEdgeT> out_edges_;
|
|
|
|
std::experimental::optional<OutEdgeIteratorT> out_edges_it_;
|
|
|
|
// Stores the last frame before we yield the frame for future edge. It needs
|
|
|
|
// to be restored afterward.
|
|
|
|
std::vector<TypedValue> last_frame_;
|
|
|
|
// Edges which are being asynchronously fetched from a remote worker.
|
|
|
|
// NOTE: This should be destructed first to ensure that no invalid
|
|
|
|
// references or pointers exists to other objects of this class.
|
|
|
|
std::vector<FutureExpand> future_expands_;
|
|
|
|
|
|
|
|
bool InitEdges(Frame &, Context &);
|
|
|
|
};
|
|
|
|
cpp<#)
|
2018-07-30 19:48:22 +08:00
|
|
|
(:serialize :capnp :inherit-compose '(expand-common)))
|
2018-04-23 22:23:42 +08:00
|
|
|
|
|
|
|
(lcp:define-class expand-variable (logical-operator expand-common)
|
2018-05-16 19:48:56 +08:00
|
|
|
((type "EdgeAtom::Type" :reader t :capnp-type "Ast.EdgeAtom.Type"
|
|
|
|
:capnp-init nil
|
Replace boost with capnp in RPC
Summary:
Converts the RPC stack to use Cap'n Proto for serialization instead of
boost. There are still some traces of boost in other places in the code,
but most of it is removed. A future diff should cleanup boost for good.
The RPC API is now changed to be more flexible with regards to how
serialize data. This makes the simplest cases a bit more verbose, but
allows complex serialization code to be correctly written instead of
relying on hacks. (For reference, look for the old serialization of
`PullRpc` which had a nasty pointer hacks to inject accessors in
`TypedValue`.)
Since RPC messages were uselessly modeled via inheritance of Message
base class, that class is now removed. Furthermore, that approach
doesn't really work with Cap'n Proto. Instead, each message type is
required to have some type information. This can be automated, so
`define-rpc` has been added to LCP, which hopefully simplifies defining
new RPC request and response messages.
Specify Cap'n Proto schema ID in cmake
This preserves Cap'n Proto generated typeIds across multiple generations
of capnp schemas through LCP. It is imperative that typeId stays the
same to ensure that different compilations of Memgraph may communicate
via RPC in a distributed cluster.
Use CLOS for meta information on C++ types in LCP
Since some structure slots and functions have started to repeat
themselves, it makes sense to model C++ meta information via Common Lisp
Object System.
Depends on D1391
Reviewers: buda, dgleich, mferencevic, mtomic, mculinovic, msantl
Reviewed By: msantl
Subscribers: pullbot
Differential Revision: https://phabricator.memgraph.io/D1407
2018-06-04 15:48:48 +08:00
|
|
|
:capnp-save (lcp:capnp-save-enum "::query::capnp::EdgeAtom::Type" "EdgeAtom::Type"
|
|
|
|
'(single depth-first breadth-first weighted-shortest-path))
|
|
|
|
:capnp-load (lcp:capnp-load-enum "::query::capnp::EdgeAtom::Type" "EdgeAtom::Type"
|
|
|
|
'(single depth-first breadth-first weighted-shortest-path)))
|
2018-08-29 16:28:05 +08:00
|
|
|
(is-reverse :bool :reader t :documentation
|
2018-04-23 22:23:42 +08:00
|
|
|
"True if the path should be written as expanding from node_symbol to input_symbol.")
|
2018-06-19 15:46:21 +08:00
|
|
|
(lower-bound "Expression *" :reader t
|
2018-05-16 19:48:56 +08:00
|
|
|
:capnp-type "Ast.Tree" :capnp-init nil
|
|
|
|
:capnp-save #'save-ast-pointer :capnp-load (load-ast-pointer "Expression *")
|
2018-04-23 22:23:42 +08:00
|
|
|
:documentation "Optional lower bound of the variable length expansion, defaults are (1, inf)")
|
2018-06-19 15:46:21 +08:00
|
|
|
(upper-bound "Expression *" :reader t
|
2018-05-16 19:48:56 +08:00
|
|
|
:capnp-type "Ast.Tree" :capnp-init nil
|
|
|
|
:capnp-save #'save-ast-pointer :capnp-load (load-ast-pointer "Expression *")
|
2018-04-23 22:23:42 +08:00
|
|
|
:documentation "Optional upper bound of the variable length expansion, defaults are (1, inf)")
|
2018-06-19 15:46:21 +08:00
|
|
|
(filter-lambda "Lambda" :reader t)
|
|
|
|
(weight-lambda "std::experimental::optional<Lambda>" :reader t
|
Replace boost with capnp in RPC
Summary:
Converts the RPC stack to use Cap'n Proto for serialization instead of
boost. There are still some traces of boost in other places in the code,
but most of it is removed. A future diff should cleanup boost for good.
The RPC API is now changed to be more flexible with regards to how
serialize data. This makes the simplest cases a bit more verbose, but
allows complex serialization code to be correctly written instead of
relying on hacks. (For reference, look for the old serialization of
`PullRpc` which had a nasty pointer hacks to inject accessors in
`TypedValue`.)
Since RPC messages were uselessly modeled via inheritance of Message
base class, that class is now removed. Furthermore, that approach
doesn't really work with Cap'n Proto. Instead, each message type is
required to have some type information. This can be automated, so
`define-rpc` has been added to LCP, which hopefully simplifies defining
new RPC request and response messages.
Specify Cap'n Proto schema ID in cmake
This preserves Cap'n Proto generated typeIds across multiple generations
of capnp schemas through LCP. It is imperative that typeId stays the
same to ensure that different compilations of Memgraph may communicate
via RPC in a distributed cluster.
Use CLOS for meta information on C++ types in LCP
Since some structure slots and functions have started to repeat
themselves, it makes sense to model C++ meta information via Common Lisp
Object System.
Depends on D1391
Reviewers: buda, dgleich, mferencevic, mtomic, mculinovic, msantl
Reviewed By: msantl
Subscribers: pullbot
Differential Revision: https://phabricator.memgraph.io/D1407
2018-06-04 15:48:48 +08:00
|
|
|
:capnp-save (lcp:capnp-save-optional
|
2018-05-16 19:48:56 +08:00
|
|
|
"capnp::ExpandVariable::Lambda" "Lambda"
|
|
|
|
"[helper](auto *builder, const auto &val) { val.Save(builder, helper); }")
|
Replace boost with capnp in RPC
Summary:
Converts the RPC stack to use Cap'n Proto for serialization instead of
boost. There are still some traces of boost in other places in the code,
but most of it is removed. A future diff should cleanup boost for good.
The RPC API is now changed to be more flexible with regards to how
serialize data. This makes the simplest cases a bit more verbose, but
allows complex serialization code to be correctly written instead of
relying on hacks. (For reference, look for the old serialization of
`PullRpc` which had a nasty pointer hacks to inject accessors in
`TypedValue`.)
Since RPC messages were uselessly modeled via inheritance of Message
base class, that class is now removed. Furthermore, that approach
doesn't really work with Cap'n Proto. Instead, each message type is
required to have some type information. This can be automated, so
`define-rpc` has been added to LCP, which hopefully simplifies defining
new RPC request and response messages.
Specify Cap'n Proto schema ID in cmake
This preserves Cap'n Proto generated typeIds across multiple generations
of capnp schemas through LCP. It is imperative that typeId stays the
same to ensure that different compilations of Memgraph may communicate
via RPC in a distributed cluster.
Use CLOS for meta information on C++ types in LCP
Since some structure slots and functions have started to repeat
themselves, it makes sense to model C++ meta information via Common Lisp
Object System.
Depends on D1391
Reviewers: buda, dgleich, mferencevic, mtomic, mculinovic, msantl
Reviewed By: msantl
Subscribers: pullbot
Differential Revision: https://phabricator.memgraph.io/D1407
2018-06-04 15:48:48 +08:00
|
|
|
:capnp-load (lcp:capnp-load-optional
|
2018-05-16 19:48:56 +08:00
|
|
|
"capnp::ExpandVariable::Lambda" "Lambda"
|
|
|
|
"[helper](const auto &reader) { Lambda val; val.Load(reader, helper); return val; }"))
|
2018-08-29 16:28:05 +08:00
|
|
|
(total-weight "std::experimental::optional<Symbol>" :reader t
|
Replace boost with capnp in RPC
Summary:
Converts the RPC stack to use Cap'n Proto for serialization instead of
boost. There are still some traces of boost in other places in the code,
but most of it is removed. A future diff should cleanup boost for good.
The RPC API is now changed to be more flexible with regards to how
serialize data. This makes the simplest cases a bit more verbose, but
allows complex serialization code to be correctly written instead of
relying on hacks. (For reference, look for the old serialization of
`PullRpc` which had a nasty pointer hacks to inject accessors in
`TypedValue`.)
Since RPC messages were uselessly modeled via inheritance of Message
base class, that class is now removed. Furthermore, that approach
doesn't really work with Cap'n Proto. Instead, each message type is
required to have some type information. This can be automated, so
`define-rpc` has been added to LCP, which hopefully simplifies defining
new RPC request and response messages.
Specify Cap'n Proto schema ID in cmake
This preserves Cap'n Proto generated typeIds across multiple generations
of capnp schemas through LCP. It is imperative that typeId stays the
same to ensure that different compilations of Memgraph may communicate
via RPC in a distributed cluster.
Use CLOS for meta information on C++ types in LCP
Since some structure slots and functions have started to repeat
themselves, it makes sense to model C++ meta information via Common Lisp
Object System.
Depends on D1391
Reviewers: buda, dgleich, mferencevic, mtomic, mculinovic, msantl
Reviewed By: msantl
Subscribers: pullbot
Differential Revision: https://phabricator.memgraph.io/D1407
2018-06-04 15:48:48 +08:00
|
|
|
:capnp-save (lcp:capnp-save-optional "::query::capnp::Symbol" "Symbol")
|
|
|
|
:capnp-load (lcp:capnp-load-optional "::query::capnp::Symbol" "Symbol")))
|
2018-04-23 22:23:42 +08:00
|
|
|
(:documentation
|
|
|
|
"Variable-length expansion operator. For a node existing in
|
|
|
|
the frame it expands a variable number of edges and places them
|
|
|
|
(in a list-type TypedValue), as well as the final destination node,
|
|
|
|
on the frame.
|
|
|
|
|
|
|
|
This class does not handle node/edge filtering based on
|
|
|
|
properties, labels and edge types. However, it does handle
|
|
|
|
filtering on existing node / edge. Additionally it handles's
|
|
|
|
edge-uniquess (cyphermorphism) because it's not feasable to do
|
|
|
|
later.
|
|
|
|
|
|
|
|
Filtering on existing means that for a pattern that references
|
|
|
|
an already declared node or edge (for example in
|
|
|
|
MATCH (a) MATCH (a)--(b)),
|
|
|
|
only expansions that match defined equalities are succesfully
|
|
|
|
pulled.")
|
|
|
|
(:public
|
|
|
|
(lcp:define-struct lambda ()
|
|
|
|
((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."
|
2018-05-16 19:48:56 +08:00
|
|
|
:capnp-type "Ast.Tree" :capnp-init nil
|
2018-07-30 19:48:22 +08:00
|
|
|
:capnp-save #'save-ast-pointer :capnp-load (load-ast-pointer "Expression *")))
|
|
|
|
(:serialize :capnp
|
|
|
|
:save-args '((helper "LogicalOperator::SaveHelper *"))
|
|
|
|
:load-args '((helper "LogicalOperator::LoadHelper *"))))
|
2018-04-23 22:23:42 +08:00
|
|
|
#>cpp
|
|
|
|
/**
|
|
|
|
* Creates a variable-length expansion. Most params are forwarded
|
|
|
|
* to the @c ExpandCommon constructor, and are documented there.
|
|
|
|
*
|
|
|
|
* Expansion length bounds are both inclusive (as in Neo's Cypher
|
|
|
|
* implementation).
|
|
|
|
*
|
|
|
|
* @param type - Either Type::DEPTH_FIRST (default variable-length expansion),
|
|
|
|
* or Type::BREADTH_FIRST.
|
|
|
|
* @param is_reverse Set to `true` if the edges written on frame should expand
|
|
|
|
* from `node_symbol` to `input_symbol`. Opposed to the usual expanding
|
|
|
|
* from `input_symbol` to `node_symbol`.
|
|
|
|
* @param lower_bound An optional indicator of the minimum number of edges
|
|
|
|
* that get expanded (inclusive).
|
|
|
|
* @param upper_bound An optional indicator of the maximum number of edges
|
|
|
|
* that get expanded (inclusive).
|
|
|
|
* @param inner_edge_symbol Like `inner_node_symbol`
|
|
|
|
* @param inner_node_symbol For each expansion the node expanded into is
|
|
|
|
* assigned to this symbol so it can be evaulated by the 'where'
|
|
|
|
* expression.
|
|
|
|
* @param filter_ The filter that must be satisfied for an expansion to
|
2018-05-16 19:48:56 +08:00
|
|
|
* succeed. Can use inner(node/edge) symbols. If nullptr, it is ignored.
|
2018-04-23 22:23:42 +08:00
|
|
|
*/
|
|
|
|
ExpandVariable(Symbol node_symbol, Symbol edge_symbol, EdgeAtom::Type type,
|
|
|
|
EdgeAtom::Direction direction,
|
|
|
|
const std::vector<storage::EdgeType> &edge_types,
|
|
|
|
bool is_reverse, Expression *lower_bound,
|
|
|
|
Expression *upper_bound,
|
|
|
|
const std::shared_ptr<LogicalOperator> &input,
|
|
|
|
Symbol input_symbol, bool existing_node, Lambda filter_lambda,
|
|
|
|
std::experimental::optional<Lambda> weight_lambda,
|
|
|
|
std::experimental::optional<Symbol> total_weight,
|
2018-05-15 19:10:15 +08:00
|
|
|
GraphView graph_view);
|
2018-04-23 22:23:42 +08:00
|
|
|
|
|
|
|
bool Accept(HierarchicalLogicalOperatorVisitor &visitor) override;
|
|
|
|
std::unique_ptr<Cursor> MakeCursor(
|
|
|
|
database::GraphDbAccessor &db) const override;
|
|
|
|
std::vector<Symbol> ModifiedSymbols(const SymbolTable &) const override;
|
|
|
|
|
|
|
|
bool HasSingleInput() const override { return true; }
|
|
|
|
std::shared_ptr<LogicalOperator> input() const override { return input_; }
|
|
|
|
void set_input(std::shared_ptr<LogicalOperator> input) override {
|
|
|
|
input_ = input;
|
|
|
|
}
|
|
|
|
cpp<#)
|
|
|
|
(:private
|
|
|
|
#>cpp
|
|
|
|
// the Cursors are not declared in the header because
|
|
|
|
// it's edges_ and edges_it_ are decltyped using a helper function
|
|
|
|
// that should be inaccessible (private class function won't compile)
|
|
|
|
friend class ExpandVariableCursor;
|
|
|
|
friend class ExpandWeightedShortestPathCursor;
|
|
|
|
|
|
|
|
ExpandVariable() {}
|
|
|
|
cpp<#)
|
2018-08-29 16:28:05 +08:00
|
|
|
(:serialize :capnp :inherit-compose '(expand-common)))
|
2018-04-23 22:23:42 +08:00
|
|
|
|
|
|
|
(lcp:define-class construct-named-path (logical-operator)
|
2018-05-16 19:48:56 +08:00
|
|
|
((input "std::shared_ptr<LogicalOperator>"
|
|
|
|
:capnp-save #'save-operator-pointer
|
|
|
|
:capnp-load #'load-operator-pointer)
|
2018-04-23 22:23:42 +08:00
|
|
|
(path-symbol "Symbol" :reader t)
|
2018-05-16 19:48:56 +08:00
|
|
|
(path-elements "std::vector<Symbol>" :reader t
|
Replace boost with capnp in RPC
Summary:
Converts the RPC stack to use Cap'n Proto for serialization instead of
boost. There are still some traces of boost in other places in the code,
but most of it is removed. A future diff should cleanup boost for good.
The RPC API is now changed to be more flexible with regards to how
serialize data. This makes the simplest cases a bit more verbose, but
allows complex serialization code to be correctly written instead of
relying on hacks. (For reference, look for the old serialization of
`PullRpc` which had a nasty pointer hacks to inject accessors in
`TypedValue`.)
Since RPC messages were uselessly modeled via inheritance of Message
base class, that class is now removed. Furthermore, that approach
doesn't really work with Cap'n Proto. Instead, each message type is
required to have some type information. This can be automated, so
`define-rpc` has been added to LCP, which hopefully simplifies defining
new RPC request and response messages.
Specify Cap'n Proto schema ID in cmake
This preserves Cap'n Proto generated typeIds across multiple generations
of capnp schemas through LCP. It is imperative that typeId stays the
same to ensure that different compilations of Memgraph may communicate
via RPC in a distributed cluster.
Use CLOS for meta information on C++ types in LCP
Since some structure slots and functions have started to repeat
themselves, it makes sense to model C++ meta information via Common Lisp
Object System.
Depends on D1391
Reviewers: buda, dgleich, mferencevic, mtomic, mculinovic, msantl
Reviewed By: msantl
Subscribers: pullbot
Differential Revision: https://phabricator.memgraph.io/D1407
2018-06-04 15:48:48 +08:00
|
|
|
:capnp-save (lcp:capnp-save-vector "::query::capnp::Symbol" "Symbol")
|
|
|
|
:capnp-load (lcp:capnp-load-vector "::query::capnp::Symbol" "Symbol")))
|
2018-04-23 22:23:42 +08:00
|
|
|
(:documentation
|
|
|
|
"Constructs a named path from it's elements and places it on the frame.")
|
|
|
|
(:public
|
|
|
|
#>cpp
|
|
|
|
ConstructNamedPath(const std::shared_ptr<LogicalOperator> &input,
|
|
|
|
Symbol path_symbol,
|
|
|
|
const std::vector<Symbol> &path_elements)
|
|
|
|
: input_(input),
|
|
|
|
path_symbol_(path_symbol),
|
|
|
|
path_elements_(path_elements) {}
|
|
|
|
bool Accept(HierarchicalLogicalOperatorVisitor &visitor) override;
|
|
|
|
std::unique_ptr<Cursor> MakeCursor(
|
|
|
|
database::GraphDbAccessor &db) const override;
|
|
|
|
std::vector<Symbol> ModifiedSymbols(const SymbolTable &) const override;
|
|
|
|
|
|
|
|
bool HasSingleInput() const override { return true; }
|
|
|
|
std::shared_ptr<LogicalOperator> input() const override { return input_; }
|
|
|
|
void set_input(std::shared_ptr<LogicalOperator> input) override {
|
|
|
|
input_ = input;
|
|
|
|
}
|
|
|
|
cpp<#)
|
|
|
|
(:private
|
|
|
|
#>cpp ConstructNamedPath() {} cpp<#)
|
2018-07-30 19:48:22 +08:00
|
|
|
(:serialize :capnp))
|
2018-04-23 22:23:42 +08:00
|
|
|
|
|
|
|
(lcp:define-class filter (logical-operator)
|
2018-05-16 19:48:56 +08:00
|
|
|
((input "std::shared_ptr<LogicalOperator>"
|
|
|
|
:capnp-save #'save-operator-pointer
|
|
|
|
:capnp-load #'load-operator-pointer)
|
2018-06-05 21:51:28 +08:00
|
|
|
(expression "Expression *" :reader t
|
2018-05-16 19:48:56 +08:00
|
|
|
:capnp-type "Ast.Tree" :capnp-init nil
|
2018-07-30 19:48:22 +08:00
|
|
|
:capnp-save #'save-ast-pointer :capnp-load (load-ast-pointer "Expression *")))
|
2018-04-23 22:23:42 +08:00
|
|
|
(:documentation
|
|
|
|
"Filter whose Pull returns true only when the given expression
|
|
|
|
evaluates into true.
|
|
|
|
|
|
|
|
The given expression is assumed to return either NULL (treated as false) or
|
|
|
|
a boolean value.")
|
|
|
|
(:public
|
|
|
|
#>cpp
|
|
|
|
Filter(const std::shared_ptr<LogicalOperator> &input_,
|
|
|
|
Expression *expression_);
|
|
|
|
bool Accept(HierarchicalLogicalOperatorVisitor &visitor) override;
|
|
|
|
std::unique_ptr<Cursor> MakeCursor(
|
|
|
|
database::GraphDbAccessor &db) const override;
|
|
|
|
std::vector<Symbol> ModifiedSymbols(const SymbolTable &) const override;
|
|
|
|
|
|
|
|
bool HasSingleInput() const override { return true; }
|
|
|
|
std::shared_ptr<LogicalOperator> input() const override { return input_; }
|
|
|
|
void set_input(std::shared_ptr<LogicalOperator> input) override {
|
|
|
|
input_ = input;
|
|
|
|
}
|
|
|
|
cpp<#)
|
|
|
|
(:private
|
|
|
|
#>cpp
|
|
|
|
Filter() {}
|
|
|
|
|
|
|
|
class FilterCursor : public Cursor {
|
|
|
|
public:
|
|
|
|
FilterCursor(const Filter &self, database::GraphDbAccessor &db);
|
|
|
|
bool Pull(Frame &, Context &) override;
|
|
|
|
void Reset() override;
|
|
|
|
|
|
|
|
private:
|
|
|
|
const Filter &self_;
|
|
|
|
const std::unique_ptr<Cursor> input_cursor_;
|
|
|
|
};
|
|
|
|
cpp<#)
|
2018-07-30 19:48:22 +08:00
|
|
|
(:serialize :capnp))
|
2018-04-23 22:23:42 +08:00
|
|
|
|
|
|
|
(lcp:define-class produce (logical-operator)
|
2018-05-16 19:48:56 +08:00
|
|
|
((input "std::shared_ptr<LogicalOperator>"
|
|
|
|
:capnp-save #'save-operator-pointer
|
|
|
|
:capnp-load #'load-operator-pointer)
|
2018-04-23 22:23:42 +08:00
|
|
|
(named-expressions "std::vector<NamedExpression *>" :reader t
|
2018-05-16 19:48:56 +08:00
|
|
|
:capnp-type "List(Ast.Tree)"
|
|
|
|
:capnp-save (save-ast-vector "NamedExpression *")
|
2018-07-30 19:48:22 +08:00
|
|
|
:capnp-load (load-ast-vector "NamedExpression *")))
|
2018-04-23 22:23:42 +08:00
|
|
|
(:documentation
|
|
|
|
"A logical operator that places an arbitrary number
|
|
|
|
if named expressions on the frame (the logical operator
|
|
|
|
for the RETURN clause).
|
|
|
|
|
|
|
|
Supports optional input. When the input is provided,
|
|
|
|
it is Pulled from and the Produce succeeds once for
|
|
|
|
every input Pull (typically a MATCH/RETURN query).
|
|
|
|
When the input is not provided (typically a standalone
|
|
|
|
RETURN clause) the Produce's pull succeeds exactly once.")
|
|
|
|
(:public
|
|
|
|
#>cpp
|
|
|
|
Produce(const std::shared_ptr<LogicalOperator> &input,
|
|
|
|
const std::vector<NamedExpression *> &named_expressions);
|
|
|
|
bool Accept(HierarchicalLogicalOperatorVisitor &visitor) override;
|
|
|
|
std::unique_ptr<Cursor> MakeCursor(
|
|
|
|
database::GraphDbAccessor &db) const override;
|
|
|
|
std::vector<Symbol> OutputSymbols(const SymbolTable &) const override;
|
|
|
|
std::vector<Symbol> ModifiedSymbols(const SymbolTable &) const override;
|
|
|
|
|
|
|
|
bool HasSingleInput() const override { return true; }
|
|
|
|
std::shared_ptr<LogicalOperator> input() const override { return input_; }
|
|
|
|
void set_input(std::shared_ptr<LogicalOperator> input) override {
|
|
|
|
input_ = input;
|
|
|
|
}
|
|
|
|
cpp<#)
|
|
|
|
(:private
|
|
|
|
#>cpp
|
|
|
|
class ProduceCursor : public Cursor {
|
|
|
|
public:
|
|
|
|
ProduceCursor(const Produce &self, database::GraphDbAccessor &db);
|
|
|
|
bool Pull(Frame &, Context &) override;
|
|
|
|
void Reset() override;
|
|
|
|
|
|
|
|
private:
|
|
|
|
const Produce &self_;
|
|
|
|
const std::unique_ptr<Cursor> input_cursor_;
|
|
|
|
};
|
|
|
|
|
|
|
|
Produce() {}
|
|
|
|
cpp<#)
|
2018-07-30 19:48:22 +08:00
|
|
|
(:serialize :capnp))
|
2018-04-23 22:23:42 +08:00
|
|
|
|
|
|
|
(lcp:define-class delete (logical-operator)
|
2018-05-16 19:48:56 +08:00
|
|
|
((input "std::shared_ptr<LogicalOperator>"
|
|
|
|
:capnp-save #'save-operator-pointer
|
|
|
|
:capnp-load #'load-operator-pointer)
|
2018-06-19 19:52:11 +08:00
|
|
|
(expressions "std::vector<Expression *>" :reader t
|
2018-05-16 19:48:56 +08:00
|
|
|
:capnp-type "List(Ast.Tree)"
|
|
|
|
:capnp-save (save-ast-vector "Expression *")
|
2018-07-30 19:48:22 +08:00
|
|
|
:capnp-load (load-ast-vector "Expression *"))
|
2018-04-23 22:23:42 +08:00
|
|
|
(detach :bool :documentation
|
|
|
|
"if the vertex should be detached before deletion if not detached,
|
|
|
|
and has connections, an error is raised ignored when deleting edges"))
|
|
|
|
(:documentation
|
|
|
|
"Operator for deleting vertices and edges.
|
|
|
|
|
|
|
|
Has a flag for using DETACH DELETE when deleting vertices.")
|
|
|
|
(:public
|
|
|
|
#>cpp
|
|
|
|
Delete(const std::shared_ptr<LogicalOperator> &input_,
|
|
|
|
const std::vector<Expression *> &expressions, bool detach_);
|
|
|
|
bool Accept(HierarchicalLogicalOperatorVisitor &visitor) override;
|
|
|
|
std::unique_ptr<Cursor> MakeCursor(
|
|
|
|
database::GraphDbAccessor &db) const override;
|
|
|
|
std::vector<Symbol> ModifiedSymbols(const SymbolTable &) const override;
|
|
|
|
|
|
|
|
bool HasSingleInput() const override { return true; }
|
|
|
|
std::shared_ptr<LogicalOperator> input() const override { return input_; }
|
|
|
|
void set_input(std::shared_ptr<LogicalOperator> input) override {
|
|
|
|
input_ = input;
|
|
|
|
}
|
|
|
|
cpp<#)
|
|
|
|
(:private
|
|
|
|
#>cpp
|
|
|
|
Delete() {}
|
|
|
|
|
|
|
|
class DeleteCursor : public Cursor {
|
|
|
|
public:
|
|
|
|
DeleteCursor(const Delete &self, database::GraphDbAccessor &db);
|
|
|
|
bool Pull(Frame &, Context &) override;
|
|
|
|
void Reset() override;
|
|
|
|
|
|
|
|
private:
|
|
|
|
const Delete &self_;
|
|
|
|
database::GraphDbAccessor &db_;
|
|
|
|
const std::unique_ptr<Cursor> input_cursor_;
|
|
|
|
};
|
|
|
|
cpp<#)
|
2018-07-30 19:48:22 +08:00
|
|
|
(:serialize :capnp))
|
2018-04-23 22:23:42 +08:00
|
|
|
|
|
|
|
(lcp:define-class set-property (logical-operator)
|
2018-05-16 19:48:56 +08:00
|
|
|
((input "std::shared_ptr<LogicalOperator>"
|
|
|
|
:capnp-save #'save-operator-pointer
|
|
|
|
:capnp-load #'load-operator-pointer)
|
2018-06-19 19:52:11 +08:00
|
|
|
(lhs "PropertyLookup *" :reader t
|
2018-05-16 19:48:56 +08:00
|
|
|
:capnp-type "Ast.Tree" :capnp-init nil
|
2018-07-30 19:48:22 +08:00
|
|
|
:capnp-save #'save-ast-pointer :capnp-load (load-ast-pointer "PropertyLookup *"))
|
2018-06-19 19:52:11 +08:00
|
|
|
(rhs "Expression *" :reader t
|
2018-05-16 19:48:56 +08:00
|
|
|
:capnp-type "Ast.Tree" :capnp-init nil
|
2018-07-30 19:48:22 +08:00
|
|
|
:capnp-save #'save-ast-pointer :capnp-load (load-ast-pointer "Expression *")))
|
2018-04-23 22:23:42 +08:00
|
|
|
(:documentation
|
|
|
|
"Logical Op for setting a single property on a single vertex or edge.
|
|
|
|
|
|
|
|
The property value is an expression that must evaluate to some type that
|
|
|
|
can be stored (a TypedValue that can be converted to PropertyValue).")
|
|
|
|
(:public
|
|
|
|
#>cpp
|
|
|
|
SetProperty(const std::shared_ptr<LogicalOperator> &input,
|
|
|
|
PropertyLookup *lhs, Expression *rhs);
|
|
|
|
bool Accept(HierarchicalLogicalOperatorVisitor &visitor) override;
|
|
|
|
std::unique_ptr<Cursor> MakeCursor(
|
|
|
|
database::GraphDbAccessor &db) const override;
|
|
|
|
std::vector<Symbol> ModifiedSymbols(const SymbolTable &) const override;
|
|
|
|
|
|
|
|
bool HasSingleInput() const override { return true; }
|
|
|
|
std::shared_ptr<LogicalOperator> input() const override { return input_; }
|
|
|
|
void set_input(std::shared_ptr<LogicalOperator> input) override {
|
|
|
|
input_ = input;
|
|
|
|
}
|
|
|
|
cpp<#)
|
|
|
|
(:private
|
|
|
|
#>cpp
|
|
|
|
SetProperty() {}
|
|
|
|
|
|
|
|
class SetPropertyCursor : public Cursor {
|
|
|
|
public:
|
|
|
|
SetPropertyCursor(const SetProperty &self, database::GraphDbAccessor &db);
|
|
|
|
bool Pull(Frame &, Context &) override;
|
|
|
|
void Reset() override;
|
|
|
|
|
|
|
|
private:
|
|
|
|
const SetProperty &self_;
|
|
|
|
const std::unique_ptr<Cursor> input_cursor_;
|
|
|
|
};
|
|
|
|
cpp<#)
|
2018-07-30 19:48:22 +08:00
|
|
|
(:serialize :capnp))
|
2018-04-23 22:23:42 +08:00
|
|
|
|
|
|
|
(lcp:define-class set-properties (logical-operator)
|
2018-05-16 19:48:56 +08:00
|
|
|
((input "std::shared_ptr<LogicalOperator>"
|
|
|
|
:capnp-save #'save-operator-pointer
|
|
|
|
:capnp-load #'load-operator-pointer)
|
2018-06-19 19:52:11 +08:00
|
|
|
(input-symbol "Symbol" :reader t)
|
|
|
|
(rhs "Expression *" :reader t
|
2018-05-16 19:48:56 +08:00
|
|
|
:capnp-type "Ast.Tree" :capnp-init nil
|
2018-07-30 19:48:22 +08:00
|
|
|
:capnp-save #'save-ast-pointer :capnp-load (load-ast-pointer "Expression *"))
|
2018-08-03 17:09:11 +08:00
|
|
|
(op "Op"))
|
2018-04-23 22:23:42 +08:00
|
|
|
(:documentation
|
2018-05-16 19:48:56 +08:00
|
|
|
"Logical op for setting the whole properties set on a vertex or an edge.
|
2018-04-23 22:23:42 +08:00
|
|
|
|
|
|
|
The value being set is an expression that must evaluate to a vertex, edge
|
2018-05-16 19:48:56 +08:00
|
|
|
or map (literal or parameter).
|
2018-04-23 22:23:42 +08:00
|
|
|
|
|
|
|
Supports setting (replacing the whole properties set with another) and
|
|
|
|
updating.")
|
|
|
|
(:public
|
2018-05-16 19:48:56 +08:00
|
|
|
(lcp:define-enum op
|
Replace boost with capnp in RPC
Summary:
Converts the RPC stack to use Cap'n Proto for serialization instead of
boost. There are still some traces of boost in other places in the code,
but most of it is removed. A future diff should cleanup boost for good.
The RPC API is now changed to be more flexible with regards to how
serialize data. This makes the simplest cases a bit more verbose, but
allows complex serialization code to be correctly written instead of
relying on hacks. (For reference, look for the old serialization of
`PullRpc` which had a nasty pointer hacks to inject accessors in
`TypedValue`.)
Since RPC messages were uselessly modeled via inheritance of Message
base class, that class is now removed. Furthermore, that approach
doesn't really work with Cap'n Proto. Instead, each message type is
required to have some type information. This can be automated, so
`define-rpc` has been added to LCP, which hopefully simplifies defining
new RPC request and response messages.
Specify Cap'n Proto schema ID in cmake
This preserves Cap'n Proto generated typeIds across multiple generations
of capnp schemas through LCP. It is imperative that typeId stays the
same to ensure that different compilations of Memgraph may communicate
via RPC in a distributed cluster.
Use CLOS for meta information on C++ types in LCP
Since some structure slots and functions have started to repeat
themselves, it makes sense to model C++ meta information via Common Lisp
Object System.
Depends on D1391
Reviewers: buda, dgleich, mferencevic, mtomic, mculinovic, msantl
Reviewed By: msantl
Subscribers: pullbot
Differential Revision: https://phabricator.memgraph.io/D1407
2018-06-04 15:48:48 +08:00
|
|
|
(update replace)
|
|
|
|
(:documentation "Defines how setting the properties works.
|
2018-05-16 19:48:56 +08:00
|
|
|
|
|
|
|
@c UPDATE means that the current property set is augmented with additional
|
|
|
|
ones (existing props of the same name are replaced), while @c REPLACE means
|
Replace boost with capnp in RPC
Summary:
Converts the RPC stack to use Cap'n Proto for serialization instead of
boost. There are still some traces of boost in other places in the code,
but most of it is removed. A future diff should cleanup boost for good.
The RPC API is now changed to be more flexible with regards to how
serialize data. This makes the simplest cases a bit more verbose, but
allows complex serialization code to be correctly written instead of
relying on hacks. (For reference, look for the old serialization of
`PullRpc` which had a nasty pointer hacks to inject accessors in
`TypedValue`.)
Since RPC messages were uselessly modeled via inheritance of Message
base class, that class is now removed. Furthermore, that approach
doesn't really work with Cap'n Proto. Instead, each message type is
required to have some type information. This can be automated, so
`define-rpc` has been added to LCP, which hopefully simplifies defining
new RPC request and response messages.
Specify Cap'n Proto schema ID in cmake
This preserves Cap'n Proto generated typeIds across multiple generations
of capnp schemas through LCP. It is imperative that typeId stays the
same to ensure that different compilations of Memgraph may communicate
via RPC in a distributed cluster.
Use CLOS for meta information on C++ types in LCP
Since some structure slots and functions have started to repeat
themselves, it makes sense to model C++ meta information via Common Lisp
Object System.
Depends on D1391
Reviewers: buda, dgleich, mferencevic, mtomic, mculinovic, msantl
Reviewed By: msantl
Subscribers: pullbot
Differential Revision: https://phabricator.memgraph.io/D1407
2018-06-04 15:48:48 +08:00
|
|
|
that the old props are discarded and replaced with new ones.")
|
|
|
|
(:serialize :capnp))
|
2018-04-23 22:23:42 +08:00
|
|
|
|
2018-05-16 19:48:56 +08:00
|
|
|
#>cpp
|
2018-04-23 22:23:42 +08:00
|
|
|
SetProperties(const std::shared_ptr<LogicalOperator> &input,
|
|
|
|
Symbol input_symbol, Expression *rhs, Op op);
|
|
|
|
bool Accept(HierarchicalLogicalOperatorVisitor &visitor) override;
|
|
|
|
std::unique_ptr<Cursor> MakeCursor(
|
|
|
|
database::GraphDbAccessor &db) const override;
|
|
|
|
std::vector<Symbol> ModifiedSymbols(const SymbolTable &) const override;
|
|
|
|
|
|
|
|
bool HasSingleInput() const override { return true; }
|
|
|
|
std::shared_ptr<LogicalOperator> input() const override { return input_; }
|
|
|
|
void set_input(std::shared_ptr<LogicalOperator> input) override {
|
|
|
|
input_ = input;
|
|
|
|
}
|
|
|
|
cpp<#)
|
|
|
|
(:private
|
|
|
|
#>cpp
|
|
|
|
SetProperties() {}
|
|
|
|
|
|
|
|
class SetPropertiesCursor : public Cursor {
|
|
|
|
public:
|
|
|
|
SetPropertiesCursor(const SetProperties &self,
|
|
|
|
database::GraphDbAccessor &db);
|
|
|
|
bool Pull(Frame &, Context &) override;
|
|
|
|
void Reset() override;
|
|
|
|
|
|
|
|
private:
|
|
|
|
const SetProperties &self_;
|
|
|
|
database::GraphDbAccessor &db_;
|
|
|
|
const std::unique_ptr<Cursor> input_cursor_;
|
|
|
|
|
|
|
|
/** Helper function that sets the given values on either
|
|
|
|
* a VertexRecord or an EdgeRecord.
|
|
|
|
* @tparam TRecordAccessor Either RecordAccessor<Vertex> or
|
|
|
|
* RecordAccessor<Edge>
|
|
|
|
*/
|
|
|
|
template <typename TRecordAccessor>
|
|
|
|
void Set(TRecordAccessor &record, const TypedValue &rhs) const;
|
|
|
|
};
|
|
|
|
cpp<#)
|
2018-07-30 19:48:22 +08:00
|
|
|
(:serialize :capnp))
|
2018-04-23 22:23:42 +08:00
|
|
|
|
|
|
|
(lcp:define-class set-labels (logical-operator)
|
2018-05-16 19:48:56 +08:00
|
|
|
((input "std::shared_ptr<LogicalOperator>"
|
|
|
|
:capnp-save #'save-operator-pointer
|
|
|
|
:capnp-load #'load-operator-pointer)
|
2018-06-19 19:52:11 +08:00
|
|
|
(input-symbol "Symbol" :reader t)
|
2018-05-16 19:48:56 +08:00
|
|
|
(labels "std::vector<storage::Label>"
|
Replace boost with capnp in RPC
Summary:
Converts the RPC stack to use Cap'n Proto for serialization instead of
boost. There are still some traces of boost in other places in the code,
but most of it is removed. A future diff should cleanup boost for good.
The RPC API is now changed to be more flexible with regards to how
serialize data. This makes the simplest cases a bit more verbose, but
allows complex serialization code to be correctly written instead of
relying on hacks. (For reference, look for the old serialization of
`PullRpc` which had a nasty pointer hacks to inject accessors in
`TypedValue`.)
Since RPC messages were uselessly modeled via inheritance of Message
base class, that class is now removed. Furthermore, that approach
doesn't really work with Cap'n Proto. Instead, each message type is
required to have some type information. This can be automated, so
`define-rpc` has been added to LCP, which hopefully simplifies defining
new RPC request and response messages.
Specify Cap'n Proto schema ID in cmake
This preserves Cap'n Proto generated typeIds across multiple generations
of capnp schemas through LCP. It is imperative that typeId stays the
same to ensure that different compilations of Memgraph may communicate
via RPC in a distributed cluster.
Use CLOS for meta information on C++ types in LCP
Since some structure slots and functions have started to repeat
themselves, it makes sense to model C++ meta information via Common Lisp
Object System.
Depends on D1391
Reviewers: buda, dgleich, mferencevic, mtomic, mculinovic, msantl
Reviewed By: msantl
Subscribers: pullbot
Differential Revision: https://phabricator.memgraph.io/D1407
2018-06-04 15:48:48 +08:00
|
|
|
:capnp-save (lcp:capnp-save-vector "::storage::capnp::Common" "storage::Label")
|
|
|
|
:capnp-load (lcp:capnp-load-vector "::storage::capnp::Common" "storage::Label")))
|
2018-04-23 22:23:42 +08:00
|
|
|
(:documentation
|
|
|
|
"Logical operator for setting an arbitrary number of labels on a Vertex.
|
|
|
|
|
|
|
|
It does NOT remove labels that are already set on that Vertex.")
|
|
|
|
(:public
|
|
|
|
#>cpp
|
|
|
|
SetLabels(const std::shared_ptr<LogicalOperator> &input, Symbol input_symbol,
|
|
|
|
const std::vector<storage::Label> &labels);
|
|
|
|
bool Accept(HierarchicalLogicalOperatorVisitor &visitor) override;
|
|
|
|
std::unique_ptr<Cursor> MakeCursor(
|
|
|
|
database::GraphDbAccessor &db) const override;
|
|
|
|
std::vector<Symbol> ModifiedSymbols(const SymbolTable &) const override;
|
|
|
|
|
|
|
|
bool HasSingleInput() const override { return true; }
|
|
|
|
std::shared_ptr<LogicalOperator> input() const override { return input_; }
|
|
|
|
void set_input(std::shared_ptr<LogicalOperator> input) override {
|
|
|
|
input_ = input;
|
|
|
|
}
|
|
|
|
cpp<#)
|
|
|
|
(:private
|
|
|
|
#>cpp
|
|
|
|
SetLabels() {}
|
|
|
|
|
|
|
|
class SetLabelsCursor : public Cursor {
|
|
|
|
public:
|
|
|
|
SetLabelsCursor(const SetLabels &self, database::GraphDbAccessor &db);
|
|
|
|
bool Pull(Frame &, Context &) override;
|
|
|
|
void Reset() override;
|
|
|
|
|
|
|
|
private:
|
|
|
|
const SetLabels &self_;
|
|
|
|
const std::unique_ptr<Cursor> input_cursor_;
|
|
|
|
};
|
|
|
|
cpp<#)
|
2018-07-30 19:48:22 +08:00
|
|
|
(:serialize :capnp))
|
2018-04-23 22:23:42 +08:00
|
|
|
|
|
|
|
(lcp:define-class remove-property (logical-operator)
|
2018-05-16 19:48:56 +08:00
|
|
|
((input "std::shared_ptr<LogicalOperator>"
|
|
|
|
:capnp-save #'save-operator-pointer
|
|
|
|
:capnp-load #'load-operator-pointer)
|
2018-06-19 19:52:11 +08:00
|
|
|
(lhs "PropertyLookup *" :reader t
|
2018-05-16 19:48:56 +08:00
|
|
|
:capnp-type "Ast.Tree" :capnp-init nil
|
2018-07-30 19:48:22 +08:00
|
|
|
:capnp-save #'save-ast-pointer :capnp-load (load-ast-pointer "PropertyLookup *")))
|
2018-04-23 22:23:42 +08:00
|
|
|
(:documentation
|
|
|
|
"Logical op for removing a property from an edge or a vertex.")
|
|
|
|
(:public
|
|
|
|
#>cpp
|
|
|
|
RemoveProperty(const std::shared_ptr<LogicalOperator> &input,
|
|
|
|
PropertyLookup *lhs);
|
|
|
|
bool Accept(HierarchicalLogicalOperatorVisitor &visitor) override;
|
|
|
|
std::unique_ptr<Cursor> MakeCursor(
|
|
|
|
database::GraphDbAccessor &db) const override;
|
|
|
|
std::vector<Symbol> ModifiedSymbols(const SymbolTable &) const override;
|
|
|
|
|
|
|
|
bool HasSingleInput() const override { return true; }
|
|
|
|
std::shared_ptr<LogicalOperator> input() const override { return input_; }
|
|
|
|
void set_input(std::shared_ptr<LogicalOperator> input) override {
|
|
|
|
input_ = input;
|
|
|
|
}
|
|
|
|
cpp<#)
|
|
|
|
(:private
|
|
|
|
#>cpp
|
|
|
|
RemoveProperty() {}
|
|
|
|
|
|
|
|
class RemovePropertyCursor : public Cursor {
|
|
|
|
public:
|
|
|
|
RemovePropertyCursor(const RemoveProperty &self,
|
|
|
|
database::GraphDbAccessor &db);
|
|
|
|
bool Pull(Frame &, Context &) override;
|
|
|
|
void Reset() override;
|
|
|
|
|
|
|
|
private:
|
|
|
|
const RemoveProperty &self_;
|
|
|
|
const std::unique_ptr<Cursor> input_cursor_;
|
|
|
|
};
|
|
|
|
cpp<#)
|
2018-07-30 19:48:22 +08:00
|
|
|
(:serialize :capnp))
|
2018-04-23 22:23:42 +08:00
|
|
|
|
|
|
|
(lcp:define-class remove-labels (logical-operator)
|
2018-05-16 19:48:56 +08:00
|
|
|
((input "std::shared_ptr<LogicalOperator>"
|
|
|
|
:capnp-save #'save-operator-pointer
|
|
|
|
:capnp-load #'load-operator-pointer)
|
2018-06-19 19:52:11 +08:00
|
|
|
(input-symbol "Symbol" :reader t)
|
2018-05-16 19:48:56 +08:00
|
|
|
(labels "std::vector<storage::Label>"
|
Replace boost with capnp in RPC
Summary:
Converts the RPC stack to use Cap'n Proto for serialization instead of
boost. There are still some traces of boost in other places in the code,
but most of it is removed. A future diff should cleanup boost for good.
The RPC API is now changed to be more flexible with regards to how
serialize data. This makes the simplest cases a bit more verbose, but
allows complex serialization code to be correctly written instead of
relying on hacks. (For reference, look for the old serialization of
`PullRpc` which had a nasty pointer hacks to inject accessors in
`TypedValue`.)
Since RPC messages were uselessly modeled via inheritance of Message
base class, that class is now removed. Furthermore, that approach
doesn't really work with Cap'n Proto. Instead, each message type is
required to have some type information. This can be automated, so
`define-rpc` has been added to LCP, which hopefully simplifies defining
new RPC request and response messages.
Specify Cap'n Proto schema ID in cmake
This preserves Cap'n Proto generated typeIds across multiple generations
of capnp schemas through LCP. It is imperative that typeId stays the
same to ensure that different compilations of Memgraph may communicate
via RPC in a distributed cluster.
Use CLOS for meta information on C++ types in LCP
Since some structure slots and functions have started to repeat
themselves, it makes sense to model C++ meta information via Common Lisp
Object System.
Depends on D1391
Reviewers: buda, dgleich, mferencevic, mtomic, mculinovic, msantl
Reviewed By: msantl
Subscribers: pullbot
Differential Revision: https://phabricator.memgraph.io/D1407
2018-06-04 15:48:48 +08:00
|
|
|
:capnp-save (lcp:capnp-save-vector "::storage::capnp::Common" "storage::Label")
|
|
|
|
:capnp-load (lcp:capnp-load-vector "::storage::capnp::Common" "storage::Label")))
|
2018-04-23 22:23:42 +08:00
|
|
|
(:documentation
|
|
|
|
"Logical operator for removing an arbitrary number of labels on a Vertex.
|
|
|
|
|
|
|
|
If a label does not exist on a Vertex, nothing happens.")
|
|
|
|
(:public
|
|
|
|
#>cpp
|
|
|
|
RemoveLabels(const std::shared_ptr<LogicalOperator> &input,
|
|
|
|
Symbol input_symbol, const std::vector<storage::Label> &labels);
|
|
|
|
bool Accept(HierarchicalLogicalOperatorVisitor &visitor) override;
|
|
|
|
std::unique_ptr<Cursor> MakeCursor(
|
|
|
|
database::GraphDbAccessor &db) const override;
|
|
|
|
std::vector<Symbol> ModifiedSymbols(const SymbolTable &) const override;
|
|
|
|
|
|
|
|
bool HasSingleInput() const override { return true; }
|
|
|
|
std::shared_ptr<LogicalOperator> input() const override { return input_; }
|
|
|
|
void set_input(std::shared_ptr<LogicalOperator> input) override {
|
|
|
|
input_ = input;
|
|
|
|
}
|
|
|
|
cpp<#)
|
|
|
|
(:private
|
|
|
|
#>cpp
|
|
|
|
RemoveLabels() {}
|
|
|
|
|
|
|
|
class RemoveLabelsCursor : public Cursor {
|
|
|
|
public:
|
|
|
|
RemoveLabelsCursor(const RemoveLabels &self, database::GraphDbAccessor &db);
|
|
|
|
bool Pull(Frame &, Context &) override;
|
|
|
|
void Reset() override;
|
|
|
|
|
|
|
|
private:
|
|
|
|
const RemoveLabels &self_;
|
|
|
|
const std::unique_ptr<Cursor> input_cursor_;
|
|
|
|
};
|
|
|
|
cpp<#)
|
2018-07-30 19:48:22 +08:00
|
|
|
(:serialize :capnp))
|
2018-04-23 22:23:42 +08:00
|
|
|
|
|
|
|
(lcp:define-class (expand-uniqueness-filter t-accessor) (logical-operator)
|
2018-05-16 19:48:56 +08:00
|
|
|
((input "std::shared_ptr<LogicalOperator>"
|
|
|
|
:capnp-save #'save-operator-pointer
|
|
|
|
:capnp-load #'load-operator-pointer)
|
2018-06-05 21:51:28 +08:00
|
|
|
(expand-symbol "Symbol" :reader t)
|
|
|
|
(previous-symbols "std::vector<Symbol>" :reader t
|
Replace boost with capnp in RPC
Summary:
Converts the RPC stack to use Cap'n Proto for serialization instead of
boost. There are still some traces of boost in other places in the code,
but most of it is removed. A future diff should cleanup boost for good.
The RPC API is now changed to be more flexible with regards to how
serialize data. This makes the simplest cases a bit more verbose, but
allows complex serialization code to be correctly written instead of
relying on hacks. (For reference, look for the old serialization of
`PullRpc` which had a nasty pointer hacks to inject accessors in
`TypedValue`.)
Since RPC messages were uselessly modeled via inheritance of Message
base class, that class is now removed. Furthermore, that approach
doesn't really work with Cap'n Proto. Instead, each message type is
required to have some type information. This can be automated, so
`define-rpc` has been added to LCP, which hopefully simplifies defining
new RPC request and response messages.
Specify Cap'n Proto schema ID in cmake
This preserves Cap'n Proto generated typeIds across multiple generations
of capnp schemas through LCP. It is imperative that typeId stays the
same to ensure that different compilations of Memgraph may communicate
via RPC in a distributed cluster.
Use CLOS for meta information on C++ types in LCP
Since some structure slots and functions have started to repeat
themselves, it makes sense to model C++ meta information via Common Lisp
Object System.
Depends on D1391
Reviewers: buda, dgleich, mferencevic, mtomic, mculinovic, msantl
Reviewed By: msantl
Subscribers: pullbot
Differential Revision: https://phabricator.memgraph.io/D1407
2018-06-04 15:48:48 +08:00
|
|
|
:capnp-save (lcp:capnp-save-vector "::query::capnp::Symbol" "Symbol")
|
|
|
|
:capnp-load (lcp:capnp-load-vector "::query::capnp::Symbol" "Symbol")))
|
2018-04-23 22:23:42 +08:00
|
|
|
(:documentation
|
|
|
|
"Filter whose Pull returns true only when the given
|
|
|
|
expand_symbol frame value (the latest expansion) is not
|
|
|
|
equal to any of the previous_symbols frame values.
|
|
|
|
|
2018-05-16 19:48:56 +08:00
|
|
|
Used for implementing [iso/cypher]morphism.
|
2018-04-23 22:23:42 +08:00
|
|
|
Isomorphism is vertex-uniqueness. It means that
|
|
|
|
two different vertices in a pattern can not map to the
|
|
|
|
same data vertex. For example, if the database
|
|
|
|
contains one vertex with a recursive relationship,
|
|
|
|
then the query
|
|
|
|
MATCH ()-[]->() combined with vertex uniqueness
|
|
|
|
yields no results (no uniqueness yields one).
|
|
|
|
Cyphermorphism is edge-uniqueness (the above
|
|
|
|
explanation applies). By default Neo4j uses
|
|
|
|
Cyphermorphism (that's where the name stems from,
|
|
|
|
it is not a valid graph-theory term).
|
|
|
|
|
|
|
|
Works for both Edge and Vertex uniqueness checks
|
|
|
|
(provide the accessor type as a template argument).
|
|
|
|
Supports variable-length-edges (uniqueness comparisons
|
|
|
|
between edges and an edge lists).")
|
|
|
|
(:public
|
|
|
|
#>cpp
|
|
|
|
ExpandUniquenessFilter(const std::shared_ptr<LogicalOperator> &input,
|
|
|
|
Symbol expand_symbol,
|
|
|
|
const std::vector<Symbol> &previous_symbols);
|
|
|
|
bool Accept(HierarchicalLogicalOperatorVisitor &visitor) override;
|
|
|
|
std::unique_ptr<Cursor> MakeCursor(
|
|
|
|
database::GraphDbAccessor &db) const override;
|
|
|
|
std::vector<Symbol> ModifiedSymbols(const SymbolTable &) const override;
|
|
|
|
|
|
|
|
bool HasSingleInput() const override { return true; }
|
|
|
|
std::shared_ptr<LogicalOperator> input() const override { return input_; }
|
|
|
|
void set_input(std::shared_ptr<LogicalOperator> input) override {
|
|
|
|
input_ = input;
|
|
|
|
}
|
|
|
|
cpp<#)
|
|
|
|
(:private
|
|
|
|
#>cpp
|
|
|
|
ExpandUniquenessFilter() {}
|
|
|
|
|
|
|
|
class ExpandUniquenessFilterCursor : public Cursor {
|
|
|
|
public:
|
|
|
|
ExpandUniquenessFilterCursor(const ExpandUniquenessFilter &self,
|
|
|
|
database::GraphDbAccessor &db);
|
|
|
|
bool Pull(Frame &, Context &) override;
|
|
|
|
void Reset() override;
|
|
|
|
|
|
|
|
private:
|
|
|
|
const ExpandUniquenessFilter &self_;
|
|
|
|
const std::unique_ptr<Cursor> input_cursor_;
|
|
|
|
};
|
|
|
|
cpp<#)
|
2018-07-30 19:48:22 +08:00
|
|
|
(:serialize :capnp :type-args '(vertex-accessor edge-accessor)))
|
2018-04-23 22:23:42 +08:00
|
|
|
|
|
|
|
(lcp:define-class accumulate (logical-operator)
|
2018-05-16 19:48:56 +08:00
|
|
|
((input "std::shared_ptr<LogicalOperator>"
|
|
|
|
:capnp-save #'save-operator-pointer
|
|
|
|
:capnp-load #'load-operator-pointer)
|
|
|
|
(symbols "std::vector<Symbol>" :reader t
|
Replace boost with capnp in RPC
Summary:
Converts the RPC stack to use Cap'n Proto for serialization instead of
boost. There are still some traces of boost in other places in the code,
but most of it is removed. A future diff should cleanup boost for good.
The RPC API is now changed to be more flexible with regards to how
serialize data. This makes the simplest cases a bit more verbose, but
allows complex serialization code to be correctly written instead of
relying on hacks. (For reference, look for the old serialization of
`PullRpc` which had a nasty pointer hacks to inject accessors in
`TypedValue`.)
Since RPC messages were uselessly modeled via inheritance of Message
base class, that class is now removed. Furthermore, that approach
doesn't really work with Cap'n Proto. Instead, each message type is
required to have some type information. This can be automated, so
`define-rpc` has been added to LCP, which hopefully simplifies defining
new RPC request and response messages.
Specify Cap'n Proto schema ID in cmake
This preserves Cap'n Proto generated typeIds across multiple generations
of capnp schemas through LCP. It is imperative that typeId stays the
same to ensure that different compilations of Memgraph may communicate
via RPC in a distributed cluster.
Use CLOS for meta information on C++ types in LCP
Since some structure slots and functions have started to repeat
themselves, it makes sense to model C++ meta information via Common Lisp
Object System.
Depends on D1391
Reviewers: buda, dgleich, mferencevic, mtomic, mculinovic, msantl
Reviewed By: msantl
Subscribers: pullbot
Differential Revision: https://phabricator.memgraph.io/D1407
2018-06-04 15:48:48 +08:00
|
|
|
:capnp-save (lcp:capnp-save-vector "::query::capnp::Symbol" "Symbol")
|
|
|
|
:capnp-load (lcp:capnp-load-vector "::query::capnp::Symbol" "Symbol"))
|
2018-04-23 22:23:42 +08:00
|
|
|
(advance-command :bool :reader t))
|
|
|
|
(:documentation
|
|
|
|
"Pulls everything from the input before passing it through.
|
|
|
|
Optionally advances the command after accumulation and before emitting.
|
|
|
|
|
|
|
|
On the first Pull from this Op's Cursor the input Cursor will be
|
|
|
|
Pulled until it is empty. The results will be accumulated in the
|
|
|
|
temporary cache. Once the input Cursor is empty, this Op's Cursor
|
|
|
|
will start returning cached stuff from it's Pull.
|
|
|
|
|
|
|
|
This technique is used for ensuring all the operations from the
|
|
|
|
previous LogicalOp have been performed before exposing data
|
|
|
|
to the next. A typical use-case is the `MATCH - SET - RETURN`
|
|
|
|
query in which every SET iteration must be performed before
|
|
|
|
RETURN starts iterating (see Memgraph Wiki for detailed reasoning).
|
|
|
|
|
|
|
|
IMPORTANT: This Op does not cache all the results but only those
|
|
|
|
elements from the frame whose symbols (frame positions) it was given.
|
|
|
|
All other frame positions will contain undefined junk after this
|
|
|
|
op has executed, and should not be used.
|
|
|
|
|
|
|
|
This op can also advance the command after the accumulation and
|
|
|
|
before emitting. If the command gets advanced, every value that
|
|
|
|
has been cached will be reconstructed before Pull returns.
|
|
|
|
|
|
|
|
@param input Input @c LogicalOperator.
|
|
|
|
@param symbols A vector of Symbols that need to be accumulated
|
|
|
|
and exposed to the next op.")
|
|
|
|
(:public
|
|
|
|
#>cpp
|
|
|
|
Accumulate(const std::shared_ptr<LogicalOperator> &input,
|
|
|
|
const std::vector<Symbol> &symbols, bool advance_command = false);
|
|
|
|
bool Accept(HierarchicalLogicalOperatorVisitor &visitor) override;
|
|
|
|
std::unique_ptr<Cursor> MakeCursor(
|
|
|
|
database::GraphDbAccessor &db) const override;
|
|
|
|
std::vector<Symbol> ModifiedSymbols(const SymbolTable &) const override;
|
|
|
|
|
|
|
|
bool HasSingleInput() const override { return true; }
|
|
|
|
std::shared_ptr<LogicalOperator> input() const override { return input_; }
|
|
|
|
void set_input(std::shared_ptr<LogicalOperator> input) override {
|
|
|
|
input_ = input;
|
|
|
|
}
|
|
|
|
cpp<#)
|
|
|
|
(:private
|
|
|
|
#>cpp
|
|
|
|
Accumulate() {}
|
|
|
|
|
|
|
|
class AccumulateCursor : public Cursor {
|
|
|
|
public:
|
|
|
|
AccumulateCursor(const Accumulate &self, database::GraphDbAccessor &db);
|
|
|
|
bool Pull(Frame &, Context &) override;
|
|
|
|
void Reset() override;
|
|
|
|
|
|
|
|
private:
|
|
|
|
const Accumulate &self_;
|
|
|
|
database::GraphDbAccessor &db_;
|
|
|
|
const std::unique_ptr<Cursor> input_cursor_;
|
|
|
|
std::vector<std::vector<TypedValue>> cache_;
|
|
|
|
decltype(cache_.begin()) cache_it_ = cache_.begin();
|
|
|
|
bool pulled_all_input_{false};
|
|
|
|
};
|
|
|
|
cpp<#)
|
2018-07-30 19:48:22 +08:00
|
|
|
(:serialize :capnp))
|
2018-04-23 22:23:42 +08:00
|
|
|
|
|
|
|
#>cpp
|
|
|
|
/**
|
|
|
|
* Custom equality function for a vector of typed values.
|
|
|
|
* Used in unordered_maps in Aggregate and Distinct operators.
|
|
|
|
*/
|
|
|
|
struct TypedValueVectorEqual {
|
|
|
|
bool operator()(const std::vector<TypedValue> &left,
|
|
|
|
const std::vector<TypedValue> &right) const;
|
|
|
|
};
|
|
|
|
cpp<#
|
|
|
|
|
|
|
|
(lcp:define-class aggregate (logical-operator)
|
2018-05-16 19:48:56 +08:00
|
|
|
((input "std::shared_ptr<LogicalOperator>"
|
|
|
|
:capnp-save #'save-operator-pointer
|
|
|
|
:capnp-load #'load-operator-pointer)
|
|
|
|
(aggregations "std::vector<Element>" :reader t
|
Replace boost with capnp in RPC
Summary:
Converts the RPC stack to use Cap'n Proto for serialization instead of
boost. There are still some traces of boost in other places in the code,
but most of it is removed. A future diff should cleanup boost for good.
The RPC API is now changed to be more flexible with regards to how
serialize data. This makes the simplest cases a bit more verbose, but
allows complex serialization code to be correctly written instead of
relying on hacks. (For reference, look for the old serialization of
`PullRpc` which had a nasty pointer hacks to inject accessors in
`TypedValue`.)
Since RPC messages were uselessly modeled via inheritance of Message
base class, that class is now removed. Furthermore, that approach
doesn't really work with Cap'n Proto. Instead, each message type is
required to have some type information. This can be automated, so
`define-rpc` has been added to LCP, which hopefully simplifies defining
new RPC request and response messages.
Specify Cap'n Proto schema ID in cmake
This preserves Cap'n Proto generated typeIds across multiple generations
of capnp schemas through LCP. It is imperative that typeId stays the
same to ensure that different compilations of Memgraph may communicate
via RPC in a distributed cluster.
Use CLOS for meta information on C++ types in LCP
Since some structure slots and functions have started to repeat
themselves, it makes sense to model C++ meta information via Common Lisp
Object System.
Depends on D1391
Reviewers: buda, dgleich, mferencevic, mtomic, mculinovic, msantl
Reviewed By: msantl
Subscribers: pullbot
Differential Revision: https://phabricator.memgraph.io/D1407
2018-06-04 15:48:48 +08:00
|
|
|
:capnp-save (lcp:capnp-save-vector
|
2018-05-16 19:48:56 +08:00
|
|
|
"capnp::Aggregate::Element" "Element"
|
|
|
|
"[helper](auto *builder, const auto &val) { val.Save(builder, helper); }")
|
Replace boost with capnp in RPC
Summary:
Converts the RPC stack to use Cap'n Proto for serialization instead of
boost. There are still some traces of boost in other places in the code,
but most of it is removed. A future diff should cleanup boost for good.
The RPC API is now changed to be more flexible with regards to how
serialize data. This makes the simplest cases a bit more verbose, but
allows complex serialization code to be correctly written instead of
relying on hacks. (For reference, look for the old serialization of
`PullRpc` which had a nasty pointer hacks to inject accessors in
`TypedValue`.)
Since RPC messages were uselessly modeled via inheritance of Message
base class, that class is now removed. Furthermore, that approach
doesn't really work with Cap'n Proto. Instead, each message type is
required to have some type information. This can be automated, so
`define-rpc` has been added to LCP, which hopefully simplifies defining
new RPC request and response messages.
Specify Cap'n Proto schema ID in cmake
This preserves Cap'n Proto generated typeIds across multiple generations
of capnp schemas through LCP. It is imperative that typeId stays the
same to ensure that different compilations of Memgraph may communicate
via RPC in a distributed cluster.
Use CLOS for meta information on C++ types in LCP
Since some structure slots and functions have started to repeat
themselves, it makes sense to model C++ meta information via Common Lisp
Object System.
Depends on D1391
Reviewers: buda, dgleich, mferencevic, mtomic, mculinovic, msantl
Reviewed By: msantl
Subscribers: pullbot
Differential Revision: https://phabricator.memgraph.io/D1407
2018-06-04 15:48:48 +08:00
|
|
|
:capnp-load (lcp:capnp-load-vector
|
2018-05-16 19:48:56 +08:00
|
|
|
"capnp::Aggregate::Element" "Element"
|
|
|
|
"[helper](const auto &reader) { Element val; val.Load(reader, helper); return val; }"))
|
2018-04-23 22:23:42 +08:00
|
|
|
(group-by "std::vector<Expression *>" :reader t
|
2018-05-16 19:48:56 +08:00
|
|
|
:capnp-type "List(Ast.Tree)"
|
|
|
|
:capnp-save (save-ast-vector "Expression *")
|
2018-07-30 19:48:22 +08:00
|
|
|
:capnp-load (load-ast-vector "Expression *"))
|
2018-05-16 19:48:56 +08:00
|
|
|
(remember "std::vector<Symbol>" :reader t
|
Replace boost with capnp in RPC
Summary:
Converts the RPC stack to use Cap'n Proto for serialization instead of
boost. There are still some traces of boost in other places in the code,
but most of it is removed. A future diff should cleanup boost for good.
The RPC API is now changed to be more flexible with regards to how
serialize data. This makes the simplest cases a bit more verbose, but
allows complex serialization code to be correctly written instead of
relying on hacks. (For reference, look for the old serialization of
`PullRpc` which had a nasty pointer hacks to inject accessors in
`TypedValue`.)
Since RPC messages were uselessly modeled via inheritance of Message
base class, that class is now removed. Furthermore, that approach
doesn't really work with Cap'n Proto. Instead, each message type is
required to have some type information. This can be automated, so
`define-rpc` has been added to LCP, which hopefully simplifies defining
new RPC request and response messages.
Specify Cap'n Proto schema ID in cmake
This preserves Cap'n Proto generated typeIds across multiple generations
of capnp schemas through LCP. It is imperative that typeId stays the
same to ensure that different compilations of Memgraph may communicate
via RPC in a distributed cluster.
Use CLOS for meta information on C++ types in LCP
Since some structure slots and functions have started to repeat
themselves, it makes sense to model C++ meta information via Common Lisp
Object System.
Depends on D1391
Reviewers: buda, dgleich, mferencevic, mtomic, mculinovic, msantl
Reviewed By: msantl
Subscribers: pullbot
Differential Revision: https://phabricator.memgraph.io/D1407
2018-06-04 15:48:48 +08:00
|
|
|
:capnp-save (lcp:capnp-save-vector "::query::capnp::Symbol" "Symbol")
|
|
|
|
:capnp-load (lcp:capnp-load-vector "::query::capnp::Symbol" "Symbol")))
|
2018-04-23 22:23:42 +08:00
|
|
|
(:documentation
|
|
|
|
"Performs an arbitrary number of aggregations of data
|
|
|
|
from the given input grouped by the given criteria.
|
|
|
|
|
|
|
|
Aggregations are defined by triples that define
|
|
|
|
(input data expression, type of aggregation, output symbol).
|
|
|
|
Input data is grouped based on the given set of named
|
|
|
|
expressions. Grouping is done on unique values.
|
|
|
|
|
|
|
|
IMPORTANT:
|
|
|
|
Ops taking their input from an aggregation are only
|
|
|
|
allowed to use frame values that are either aggregation
|
|
|
|
outputs or group-by named-expressions. All other frame
|
|
|
|
elements are in an undefined state after aggregation.")
|
|
|
|
(:public
|
|
|
|
(lcp:define-struct element ()
|
|
|
|
((value "Expression *"
|
2018-05-16 19:48:56 +08:00
|
|
|
:capnp-type "Ast.Tree" :capnp-init nil
|
2018-07-30 19:48:22 +08:00
|
|
|
:capnp-save #'save-ast-pointer :capnp-load (load-ast-pointer "Expression *"))
|
2018-04-23 22:23:42 +08:00
|
|
|
(key "Expression *"
|
2018-05-16 19:48:56 +08:00
|
|
|
:capnp-type "Ast.Tree" :capnp-init nil
|
2018-07-30 19:48:22 +08:00
|
|
|
:capnp-save #'save-ast-pointer :capnp-load (load-ast-pointer "Expression *"))
|
2018-05-16 19:48:56 +08:00
|
|
|
(op "Aggregation::Op" :capnp-type "Ast.Aggregation.Op"
|
Replace boost with capnp in RPC
Summary:
Converts the RPC stack to use Cap'n Proto for serialization instead of
boost. There are still some traces of boost in other places in the code,
but most of it is removed. A future diff should cleanup boost for good.
The RPC API is now changed to be more flexible with regards to how
serialize data. This makes the simplest cases a bit more verbose, but
allows complex serialization code to be correctly written instead of
relying on hacks. (For reference, look for the old serialization of
`PullRpc` which had a nasty pointer hacks to inject accessors in
`TypedValue`.)
Since RPC messages were uselessly modeled via inheritance of Message
base class, that class is now removed. Furthermore, that approach
doesn't really work with Cap'n Proto. Instead, each message type is
required to have some type information. This can be automated, so
`define-rpc` has been added to LCP, which hopefully simplifies defining
new RPC request and response messages.
Specify Cap'n Proto schema ID in cmake
This preserves Cap'n Proto generated typeIds across multiple generations
of capnp schemas through LCP. It is imperative that typeId stays the
same to ensure that different compilations of Memgraph may communicate
via RPC in a distributed cluster.
Use CLOS for meta information on C++ types in LCP
Since some structure slots and functions have started to repeat
themselves, it makes sense to model C++ meta information via Common Lisp
Object System.
Depends on D1391
Reviewers: buda, dgleich, mferencevic, mtomic, mculinovic, msantl
Reviewed By: msantl
Subscribers: pullbot
Differential Revision: https://phabricator.memgraph.io/D1407
2018-06-04 15:48:48 +08:00
|
|
|
:capnp-init nil :capnp-save (lcp:capnp-save-enum "::query::capnp::Aggregation::Op" "Aggregation::Op"
|
|
|
|
'(count min max sum avg collect-list collect-map))
|
|
|
|
:capnp-load (lcp:capnp-load-enum "::query::capnp::Aggregation::Op" "Aggregation::Op"
|
|
|
|
'(count min max sum avg collect-list collect-map)))
|
2018-05-16 19:48:56 +08:00
|
|
|
(output-sym "Symbol"))
|
2018-04-23 22:23:42 +08:00
|
|
|
(:documentation
|
|
|
|
"An aggregation element, contains:
|
|
|
|
(input data expression, key expression - only used in COLLECT_MAP, type of
|
|
|
|
aggregation, output symbol).")
|
2018-07-30 19:48:22 +08:00
|
|
|
(:serialize :capnp
|
|
|
|
:save-args '((helper "LogicalOperator::SaveHelper *"))
|
|
|
|
:load-args '((helper "LogicalOperator::LoadHelper *"))))
|
2018-04-23 22:23:42 +08:00
|
|
|
#>cpp
|
|
|
|
Aggregate(const std::shared_ptr<LogicalOperator> &input,
|
|
|
|
const std::vector<Element> &aggregations,
|
|
|
|
const std::vector<Expression *> &group_by,
|
|
|
|
const std::vector<Symbol> &remember);
|
|
|
|
bool Accept(HierarchicalLogicalOperatorVisitor &visitor) override;
|
|
|
|
std::unique_ptr<Cursor> MakeCursor(
|
|
|
|
database::GraphDbAccessor &db) const override;
|
|
|
|
std::vector<Symbol> ModifiedSymbols(const SymbolTable &) const override;
|
|
|
|
|
|
|
|
bool HasSingleInput() const override { return true; }
|
|
|
|
std::shared_ptr<LogicalOperator> input() const override { return input_; }
|
|
|
|
void set_input(std::shared_ptr<LogicalOperator> input) override {
|
|
|
|
input_ = input;
|
|
|
|
}
|
|
|
|
cpp<#)
|
|
|
|
(:private
|
|
|
|
#>cpp
|
|
|
|
Aggregate() {}
|
|
|
|
|
|
|
|
class AggregateCursor : public Cursor {
|
|
|
|
public:
|
|
|
|
AggregateCursor(const Aggregate &self, database::GraphDbAccessor &db);
|
|
|
|
bool Pull(Frame &, Context &) override;
|
|
|
|
void Reset() override;
|
|
|
|
|
|
|
|
private:
|
|
|
|
// Data structure for a single aggregation cache.
|
|
|
|
// does NOT include the group-by values since those
|
|
|
|
// are a key in the aggregation map.
|
|
|
|
// The vectors in an AggregationValue contain one element
|
|
|
|
// for each aggregation in this LogicalOp.
|
|
|
|
struct AggregationValue {
|
|
|
|
// how many input rows has been aggregated in respective
|
|
|
|
// values_ element so far
|
|
|
|
std::vector<int> counts_;
|
|
|
|
// aggregated values. Initially Null (until at least one
|
|
|
|
// input row with a valid value gets processed)
|
|
|
|
std::vector<TypedValue> values_;
|
|
|
|
// remember values.
|
|
|
|
std::vector<TypedValue> remember_;
|
|
|
|
};
|
|
|
|
|
|
|
|
const Aggregate &self_;
|
|
|
|
const std::unique_ptr<Cursor> input_cursor_;
|
|
|
|
// storage for aggregated data
|
|
|
|
// map key is the vector of group-by values
|
|
|
|
// map value is an AggregationValue struct
|
|
|
|
std::unordered_map<
|
|
|
|
std::vector<TypedValue>, AggregationValue,
|
|
|
|
// use FNV collection hashing specialized for a vector of TypedValues
|
|
|
|
utils::FnvCollection<std::vector<TypedValue>, TypedValue,
|
|
|
|
TypedValue::Hash>,
|
|
|
|
// custom equality
|
|
|
|
TypedValueVectorEqual>
|
|
|
|
aggregation_;
|
|
|
|
// iterator over the accumulated cache
|
|
|
|
decltype(aggregation_.begin()) aggregation_it_ = aggregation_.begin();
|
|
|
|
// this LogicalOp pulls all from the input on it's first pull
|
|
|
|
// this switch tracks if this has been performed
|
|
|
|
bool pulled_all_input_{false};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Pulls from the input operator until exhausted and aggregates the
|
|
|
|
* results. If the input operator is not provided, a single call
|
|
|
|
* to ProcessOne is issued.
|
|
|
|
*
|
|
|
|
* Accumulation automatically groups the results so that `aggregation_`
|
|
|
|
* cache cardinality depends on number of
|
|
|
|
* aggregation results, and not on the number of inputs.
|
|
|
|
*/
|
|
|
|
void ProcessAll(Frame &, Context &);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Performs a single accumulation.
|
|
|
|
*/
|
|
|
|
void ProcessOne(Frame &frame, const SymbolTable &symbolTable,
|
|
|
|
ExpressionEvaluator &evaluator);
|
|
|
|
|
|
|
|
/** Ensures the new AggregationValue has been initialized. This means
|
|
|
|
* that the value vectors are filled with an appropriate number of Nulls,
|
|
|
|
* counts are set to 0 and remember values are remembered.
|
|
|
|
*/
|
|
|
|
void EnsureInitialized(Frame &frame, AggregationValue &agg_value) const;
|
|
|
|
|
|
|
|
/** Updates the given AggregationValue with new data. Assumes that
|
|
|
|
* the AggregationValue has been initialized */
|
|
|
|
void Update(Frame &frame, const SymbolTable &symbol_table,
|
|
|
|
ExpressionEvaluator &evaluator, AggregationValue &agg_value);
|
|
|
|
|
|
|
|
/** Checks if the given TypedValue is legal in MIN and MAX. If not
|
|
|
|
* an appropriate exception is thrown. */
|
|
|
|
void EnsureOkForMinMax(const TypedValue &value) const;
|
|
|
|
|
|
|
|
/** Checks if the given TypedValue is legal in AVG and SUM. If not
|
|
|
|
* an appropriate exception is thrown. */
|
|
|
|
void EnsureOkForAvgSum(const TypedValue &value) const;
|
|
|
|
};
|
|
|
|
cpp<#)
|
2018-07-30 19:48:22 +08:00
|
|
|
(:serialize :capnp))
|
2018-04-23 22:23:42 +08:00
|
|
|
|
|
|
|
(lcp:define-class skip (logical-operator)
|
2018-05-16 19:48:56 +08:00
|
|
|
((input "std::shared_ptr<LogicalOperator>"
|
|
|
|
:capnp-save #'save-operator-pointer
|
|
|
|
:capnp-load #'load-operator-pointer)
|
2018-06-19 19:52:11 +08:00
|
|
|
(expression "Expression *" :reader t
|
2018-05-16 19:48:56 +08:00
|
|
|
:capnp-type "Ast.Tree" :capnp-init nil
|
2018-07-30 19:48:22 +08:00
|
|
|
:capnp-save #'save-ast-pointer :capnp-load (load-ast-pointer "Expression *")))
|
2018-04-23 22:23:42 +08:00
|
|
|
(:documentation
|
|
|
|
"Skips a number of Pulls from the input op.
|
|
|
|
|
|
|
|
The given expression determines how many Pulls from the input
|
|
|
|
should be skipped (ignored).
|
|
|
|
All other successful Pulls from the
|
|
|
|
input are simply passed through.
|
|
|
|
|
|
|
|
The given expression is evaluated after the first Pull from
|
|
|
|
the input, and only once. Neo does not allow this expression
|
|
|
|
to contain identifiers, and neither does Memgraph, but this
|
|
|
|
operator's implementation does not expect this.")
|
|
|
|
(:public
|
|
|
|
#>cpp
|
|
|
|
Skip(const std::shared_ptr<LogicalOperator> &input, Expression *expression);
|
|
|
|
bool Accept(HierarchicalLogicalOperatorVisitor &visitor) override;
|
|
|
|
std::unique_ptr<Cursor> MakeCursor(
|
|
|
|
database::GraphDbAccessor &db) const override;
|
|
|
|
std::vector<Symbol> OutputSymbols(const SymbolTable &) const override;
|
|
|
|
std::vector<Symbol> ModifiedSymbols(const SymbolTable &) const override;
|
|
|
|
|
|
|
|
bool HasSingleInput() const override { return true; }
|
|
|
|
std::shared_ptr<LogicalOperator> input() const override { return input_; }
|
|
|
|
void set_input(std::shared_ptr<LogicalOperator> input) override {
|
|
|
|
input_ = input;
|
|
|
|
}
|
|
|
|
cpp<#)
|
|
|
|
(:private
|
|
|
|
#>cpp
|
|
|
|
Skip() {}
|
|
|
|
|
|
|
|
class SkipCursor : public Cursor {
|
|
|
|
public:
|
|
|
|
SkipCursor(const Skip &self, database::GraphDbAccessor &db);
|
|
|
|
bool Pull(Frame &, Context &) override;
|
|
|
|
void Reset() override;
|
|
|
|
|
|
|
|
private:
|
|
|
|
const Skip &self_;
|
|
|
|
const std::unique_ptr<Cursor> input_cursor_;
|
|
|
|
// init to_skip_ to -1, indicating
|
|
|
|
// that it's still unknown (input has not been Pulled yet)
|
|
|
|
int to_skip_{-1};
|
|
|
|
int skipped_{0};
|
|
|
|
};
|
|
|
|
cpp<#)
|
2018-07-30 19:48:22 +08:00
|
|
|
(:serialize :capnp))
|
2018-04-23 22:23:42 +08:00
|
|
|
|
|
|
|
(lcp:define-class limit (logical-operator)
|
2018-05-16 19:48:56 +08:00
|
|
|
((input "std::shared_ptr<LogicalOperator>"
|
|
|
|
:capnp-save #'save-operator-pointer
|
|
|
|
:capnp-load #'load-operator-pointer)
|
2018-06-19 19:52:11 +08:00
|
|
|
(expression "Expression *" :reader t
|
2018-05-16 19:48:56 +08:00
|
|
|
:capnp-type "Ast.Tree" :capnp-init nil
|
2018-07-30 19:48:22 +08:00
|
|
|
:capnp-save #'save-ast-pointer :capnp-load (load-ast-pointer "Expression *")))
|
2018-04-23 22:23:42 +08:00
|
|
|
(:documentation
|
|
|
|
"Limits the number of Pulls from the input op.
|
|
|
|
|
|
|
|
The given expression determines how many
|
|
|
|
input Pulls should be passed through. The input is not
|
|
|
|
Pulled once this limit is reached. Note that this has
|
|
|
|
implications: the out-of-bounds input Pulls are never
|
|
|
|
evaluated.
|
|
|
|
|
|
|
|
The limit expression must NOT use anything from the
|
|
|
|
Frame. It is evaluated before the first Pull from the
|
|
|
|
input. This is consistent with Neo (they don't allow
|
|
|
|
identifiers in limit expressions), and it's necessary
|
|
|
|
when limit evaluates to 0 (because 0 Pulls from the
|
|
|
|
input should be performed).")
|
|
|
|
(:public
|
|
|
|
#>cpp
|
|
|
|
Limit(const std::shared_ptr<LogicalOperator> &input, Expression *expression);
|
|
|
|
bool Accept(HierarchicalLogicalOperatorVisitor &visitor) override;
|
|
|
|
std::unique_ptr<Cursor> MakeCursor(
|
|
|
|
database::GraphDbAccessor &db) const override;
|
|
|
|
std::vector<Symbol> OutputSymbols(const SymbolTable &) const override;
|
|
|
|
std::vector<Symbol> ModifiedSymbols(const SymbolTable &) const override;
|
|
|
|
|
|
|
|
bool HasSingleInput() const override { return true; }
|
|
|
|
std::shared_ptr<LogicalOperator> input() const override { return input_; }
|
|
|
|
void set_input(std::shared_ptr<LogicalOperator> input) override {
|
|
|
|
input_ = input;
|
|
|
|
}
|
|
|
|
cpp<#)
|
|
|
|
(:private
|
|
|
|
#>cpp
|
|
|
|
Limit() {}
|
|
|
|
|
|
|
|
class LimitCursor : public Cursor {
|
|
|
|
public:
|
|
|
|
LimitCursor(const Limit &self, database::GraphDbAccessor &db);
|
|
|
|
bool Pull(Frame &, Context &) override;
|
|
|
|
void Reset() override;
|
|
|
|
|
|
|
|
private:
|
|
|
|
const Limit &self_;
|
|
|
|
std::unique_ptr<Cursor> input_cursor_;
|
|
|
|
// init limit_ to -1, indicating
|
|
|
|
// that it's still unknown (Cursor has not been Pulled yet)
|
|
|
|
int limit_{-1};
|
|
|
|
int pulled_{0};
|
|
|
|
};
|
|
|
|
cpp<#)
|
2018-07-30 19:48:22 +08:00
|
|
|
(:serialize :capnp))
|
2018-04-23 22:23:42 +08:00
|
|
|
|
|
|
|
(lcp:define-class order-by (logical-operator)
|
2018-05-16 19:48:56 +08:00
|
|
|
((input "std::shared_ptr<LogicalOperator>"
|
|
|
|
:capnp-save #'save-operator-pointer
|
|
|
|
:capnp-load #'load-operator-pointer)
|
|
|
|
(compare "TypedValueVectorCompare" :reader t
|
|
|
|
:capnp-type "Common.TypedValueVectorCompare")
|
2018-04-23 22:23:42 +08:00
|
|
|
(order-by "std::vector<Expression *>" :reader t
|
2018-05-16 19:48:56 +08:00
|
|
|
:capnp-type "List(Ast.Tree)"
|
|
|
|
:capnp-save (save-ast-vector "Expression *")
|
2018-07-30 19:48:22 +08:00
|
|
|
:capnp-load (load-ast-vector "Expression *"))
|
2018-05-16 19:48:56 +08:00
|
|
|
(output-symbols "std::vector<Symbol>" :reader t
|
Replace boost with capnp in RPC
Summary:
Converts the RPC stack to use Cap'n Proto for serialization instead of
boost. There are still some traces of boost in other places in the code,
but most of it is removed. A future diff should cleanup boost for good.
The RPC API is now changed to be more flexible with regards to how
serialize data. This makes the simplest cases a bit more verbose, but
allows complex serialization code to be correctly written instead of
relying on hacks. (For reference, look for the old serialization of
`PullRpc` which had a nasty pointer hacks to inject accessors in
`TypedValue`.)
Since RPC messages were uselessly modeled via inheritance of Message
base class, that class is now removed. Furthermore, that approach
doesn't really work with Cap'n Proto. Instead, each message type is
required to have some type information. This can be automated, so
`define-rpc` has been added to LCP, which hopefully simplifies defining
new RPC request and response messages.
Specify Cap'n Proto schema ID in cmake
This preserves Cap'n Proto generated typeIds across multiple generations
of capnp schemas through LCP. It is imperative that typeId stays the
same to ensure that different compilations of Memgraph may communicate
via RPC in a distributed cluster.
Use CLOS for meta information on C++ types in LCP
Since some structure slots and functions have started to repeat
themselves, it makes sense to model C++ meta information via Common Lisp
Object System.
Depends on D1391
Reviewers: buda, dgleich, mferencevic, mtomic, mculinovic, msantl
Reviewed By: msantl
Subscribers: pullbot
Differential Revision: https://phabricator.memgraph.io/D1407
2018-06-04 15:48:48 +08:00
|
|
|
:capnp-save (lcp:capnp-save-vector "::query::capnp::Symbol" "Symbol")
|
|
|
|
:capnp-load (lcp:capnp-load-vector "::query::capnp::Symbol" "Symbol")))
|
2018-04-23 22:23:42 +08:00
|
|
|
(:documentation
|
|
|
|
"Logical operator for ordering (sorting) results.
|
|
|
|
|
|
|
|
Sorts the input rows based on an arbitrary number of
|
|
|
|
Expressions. Ascending or descending ordering can be chosen
|
|
|
|
for each independently (not providing enough orderings
|
|
|
|
results in a runtime error).
|
|
|
|
|
|
|
|
For each row an arbitrary number of Frame elements can be
|
|
|
|
remembered. Only these elements (defined by their Symbols)
|
|
|
|
are valid for usage after the OrderBy operator.")
|
|
|
|
(:public
|
|
|
|
#>cpp
|
|
|
|
OrderBy(const std::shared_ptr<LogicalOperator> &input,
|
|
|
|
const std::vector<std::pair<Ordering, Expression *>> &order_by,
|
|
|
|
const std::vector<Symbol> &output_symbols);
|
|
|
|
bool Accept(HierarchicalLogicalOperatorVisitor &visitor) override;
|
|
|
|
std::unique_ptr<Cursor> MakeCursor(
|
|
|
|
database::GraphDbAccessor &db) const override;
|
|
|
|
std::vector<Symbol> OutputSymbols(const SymbolTable &) const override;
|
|
|
|
std::vector<Symbol> ModifiedSymbols(const SymbolTable &) const override;
|
|
|
|
|
|
|
|
bool HasSingleInput() const override { return true; }
|
|
|
|
std::shared_ptr<LogicalOperator> input() const override { return input_; }
|
|
|
|
void set_input(std::shared_ptr<LogicalOperator> input) override {
|
|
|
|
input_ = input;
|
|
|
|
}
|
|
|
|
cpp<#)
|
|
|
|
(:private
|
|
|
|
#>cpp
|
|
|
|
OrderBy() {}
|
|
|
|
|
|
|
|
class OrderByCursor : public Cursor {
|
|
|
|
public:
|
|
|
|
OrderByCursor(const OrderBy &self, database::GraphDbAccessor &db);
|
|
|
|
bool Pull(Frame &, Context &) override;
|
|
|
|
void Reset() override;
|
|
|
|
|
|
|
|
private:
|
|
|
|
const OrderBy &self_;
|
|
|
|
const std::unique_ptr<Cursor> input_cursor_;
|
|
|
|
bool did_pull_all_{false};
|
|
|
|
// a cache of elements pulled from the input
|
|
|
|
// first pair element is the order-by vector
|
|
|
|
// second pair is the remember vector
|
|
|
|
// the cache is filled and sorted (only on first pair elem) on first Pull
|
|
|
|
std::vector<std::pair<std::vector<TypedValue>, std::vector<TypedValue>>>
|
|
|
|
cache_;
|
|
|
|
// iterator over the cache_, maintains state between Pulls
|
|
|
|
decltype(cache_.begin()) cache_it_ = cache_.begin();
|
|
|
|
};
|
|
|
|
cpp<#)
|
2018-07-30 19:48:22 +08:00
|
|
|
(:serialize :capnp))
|
2018-04-23 22:23:42 +08:00
|
|
|
|
|
|
|
(lcp:define-class merge (logical-operator)
|
2018-05-16 19:48:56 +08:00
|
|
|
((input "std::shared_ptr<LogicalOperator>"
|
|
|
|
:capnp-save #'save-operator-pointer
|
|
|
|
:capnp-load #'load-operator-pointer)
|
|
|
|
(merge-match "std::shared_ptr<LogicalOperator>" :reader t
|
|
|
|
:capnp-save #'save-operator-pointer
|
|
|
|
:capnp-load #'load-operator-pointer)
|
|
|
|
(merge-create "std::shared_ptr<LogicalOperator>" :reader t
|
|
|
|
:capnp-save #'save-operator-pointer
|
|
|
|
:capnp-load #'load-operator-pointer))
|
2018-04-23 22:23:42 +08:00
|
|
|
(:documentation
|
|
|
|
"Merge operator. For every sucessful Pull from the
|
|
|
|
input operator a Pull from the merge_match is attempted. All
|
|
|
|
successfull Pulls from the merge_match are passed on as output.
|
|
|
|
If merge_match Pull does not yield any elements, a single Pull
|
|
|
|
from the merge_create op is performed.
|
|
|
|
|
|
|
|
The input logical op is optional. If false (nullptr)
|
|
|
|
it will be replaced by a Once op.
|
|
|
|
|
|
|
|
For an argumentation of this implementation see the wiki
|
|
|
|
documentation.")
|
|
|
|
(:public
|
|
|
|
#>cpp
|
|
|
|
Merge(const std::shared_ptr<LogicalOperator> &input,
|
|
|
|
const std::shared_ptr<LogicalOperator> &merge_match,
|
|
|
|
const std::shared_ptr<LogicalOperator> &merge_create);
|
|
|
|
bool Accept(HierarchicalLogicalOperatorVisitor &visitor) override;
|
|
|
|
std::unique_ptr<Cursor> MakeCursor(
|
|
|
|
database::GraphDbAccessor &db) const override;
|
|
|
|
std::vector<Symbol> ModifiedSymbols(const SymbolTable &) const override;
|
|
|
|
|
|
|
|
// TODO: Consider whether we want to treat Merge as having single input. It
|
|
|
|
// makes sense that we do, because other branches are executed depending on
|
|
|
|
// the input.
|
|
|
|
bool HasSingleInput() const override { return true; }
|
|
|
|
std::shared_ptr<LogicalOperator> input() const override { return input_; }
|
|
|
|
void set_input(std::shared_ptr<LogicalOperator> input) override {
|
|
|
|
input_ = input;
|
|
|
|
}
|
|
|
|
cpp<#)
|
|
|
|
(:private
|
|
|
|
#>cpp
|
|
|
|
Merge() {}
|
|
|
|
|
|
|
|
class MergeCursor : public Cursor {
|
|
|
|
public:
|
|
|
|
MergeCursor(const Merge &self, database::GraphDbAccessor &db);
|
|
|
|
bool Pull(Frame &, Context &) override;
|
|
|
|
void Reset() override;
|
|
|
|
|
|
|
|
private:
|
|
|
|
const std::unique_ptr<Cursor> input_cursor_;
|
|
|
|
const std::unique_ptr<Cursor> merge_match_cursor_;
|
|
|
|
const std::unique_ptr<Cursor> merge_create_cursor_;
|
|
|
|
|
|
|
|
// indicates if the next Pull from this cursor
|
|
|
|
// should perform a pull from input_cursor_
|
|
|
|
// this is true when:
|
|
|
|
// - first Pulling from this cursor
|
|
|
|
// - previous Pull from this cursor exhausted the merge_match_cursor
|
|
|
|
bool pull_input_{true};
|
|
|
|
};
|
|
|
|
cpp<#)
|
2018-07-30 19:48:22 +08:00
|
|
|
(:serialize :capnp))
|
2018-04-23 22:23:42 +08:00
|
|
|
|
|
|
|
(lcp:define-class optional (logical-operator)
|
2018-05-16 19:48:56 +08:00
|
|
|
((input "std::shared_ptr<LogicalOperator>"
|
|
|
|
:capnp-save #'save-operator-pointer
|
|
|
|
:capnp-load #'load-operator-pointer)
|
|
|
|
(optional "std::shared_ptr<LogicalOperator>" :reader t
|
|
|
|
:capnp-save #'save-operator-pointer
|
|
|
|
:capnp-load #'load-operator-pointer)
|
|
|
|
(optional-symbols "std::vector<Symbol>" :reader t
|
Replace boost with capnp in RPC
Summary:
Converts the RPC stack to use Cap'n Proto for serialization instead of
boost. There are still some traces of boost in other places in the code,
but most of it is removed. A future diff should cleanup boost for good.
The RPC API is now changed to be more flexible with regards to how
serialize data. This makes the simplest cases a bit more verbose, but
allows complex serialization code to be correctly written instead of
relying on hacks. (For reference, look for the old serialization of
`PullRpc` which had a nasty pointer hacks to inject accessors in
`TypedValue`.)
Since RPC messages were uselessly modeled via inheritance of Message
base class, that class is now removed. Furthermore, that approach
doesn't really work with Cap'n Proto. Instead, each message type is
required to have some type information. This can be automated, so
`define-rpc` has been added to LCP, which hopefully simplifies defining
new RPC request and response messages.
Specify Cap'n Proto schema ID in cmake
This preserves Cap'n Proto generated typeIds across multiple generations
of capnp schemas through LCP. It is imperative that typeId stays the
same to ensure that different compilations of Memgraph may communicate
via RPC in a distributed cluster.
Use CLOS for meta information on C++ types in LCP
Since some structure slots and functions have started to repeat
themselves, it makes sense to model C++ meta information via Common Lisp
Object System.
Depends on D1391
Reviewers: buda, dgleich, mferencevic, mtomic, mculinovic, msantl
Reviewed By: msantl
Subscribers: pullbot
Differential Revision: https://phabricator.memgraph.io/D1407
2018-06-04 15:48:48 +08:00
|
|
|
:capnp-save (lcp:capnp-save-vector "::query::capnp::Symbol" "Symbol")
|
|
|
|
:capnp-load (lcp:capnp-load-vector "::query::capnp::Symbol" "Symbol")))
|
2018-04-23 22:23:42 +08:00
|
|
|
(:documentation
|
|
|
|
"Optional operator. Used for optional match. For every
|
|
|
|
successful Pull from the input branch a Pull from the optional
|
|
|
|
branch is attempted (and Pulled from till exhausted). If zero
|
|
|
|
Pulls succeed from the optional branch, the Optional operator
|
|
|
|
sets the optional symbols to TypedValue::Null on the Frame
|
|
|
|
and returns true, once.")
|
|
|
|
(:public
|
|
|
|
#>cpp
|
|
|
|
Optional(const std::shared_ptr<LogicalOperator> &input,
|
|
|
|
const std::shared_ptr<LogicalOperator> &optional,
|
|
|
|
const std::vector<Symbol> &optional_symbols);
|
|
|
|
bool Accept(HierarchicalLogicalOperatorVisitor &visitor) override;
|
|
|
|
std::unique_ptr<Cursor> MakeCursor(
|
|
|
|
database::GraphDbAccessor &db) const override;
|
|
|
|
std::vector<Symbol> ModifiedSymbols(const SymbolTable &) const override;
|
|
|
|
|
|
|
|
bool HasSingleInput() const override { return true; }
|
|
|
|
std::shared_ptr<LogicalOperator> input() const override { return input_; }
|
|
|
|
void set_input(std::shared_ptr<LogicalOperator> input) override {
|
|
|
|
input_ = input;
|
|
|
|
}
|
|
|
|
cpp<#)
|
|
|
|
(:private
|
|
|
|
#>cpp
|
|
|
|
Optional() {}
|
|
|
|
|
|
|
|
class OptionalCursor : public Cursor {
|
|
|
|
public:
|
|
|
|
OptionalCursor(const Optional &self, database::GraphDbAccessor &db);
|
|
|
|
bool Pull(Frame &, Context &) override;
|
|
|
|
void Reset() override;
|
|
|
|
|
|
|
|
private:
|
|
|
|
const Optional &self_;
|
|
|
|
const std::unique_ptr<Cursor> input_cursor_;
|
|
|
|
const std::unique_ptr<Cursor> optional_cursor_;
|
|
|
|
// indicates if the next Pull from this cursor should
|
|
|
|
// perform a Pull from the input_cursor_
|
|
|
|
// this is true when:
|
|
|
|
// - first pulling from this Cursor
|
|
|
|
// - previous Pull from this cursor exhausted the optional_cursor_
|
|
|
|
bool pull_input_{true};
|
|
|
|
};
|
|
|
|
cpp<#)
|
2018-07-30 19:48:22 +08:00
|
|
|
(:serialize :capnp))
|
2018-04-23 22:23:42 +08:00
|
|
|
|
2018-08-06 21:16:39 +08:00
|
|
|
(lcp:define-class auth-handler (logical-operator)
|
|
|
|
((action "AuthQuery::Action" :reader t
|
|
|
|
:capnp-init nil
|
|
|
|
:capnp-type "Ast.AuthQuery.Action"
|
|
|
|
:capnp-save (lcp:capnp-save-enum "::query::capnp::AuthQuery::Action"
|
|
|
|
"AuthQuery::Action"
|
|
|
|
'(create-role drop-role show-roles
|
|
|
|
create-user set-password
|
2018-08-29 15:18:51 +08:00
|
|
|
drop-user show-users set-role
|
|
|
|
clear-role grant-privilege
|
2018-08-06 21:16:39 +08:00
|
|
|
deny-privilege revoke-privilege
|
2018-08-29 15:18:51 +08:00
|
|
|
show-privileges show-role-for-user
|
2018-08-06 21:16:39 +08:00
|
|
|
show-users-for-role))
|
2018-08-21 20:12:53 +08:00
|
|
|
:capnp-load (lcp:capnp-load-enum "::query::capnp::AuthQuery::Action"
|
2018-08-06 21:16:39 +08:00
|
|
|
"AuthQuery::Action"
|
|
|
|
'(create-role drop-role show-roles
|
|
|
|
create-user set-password
|
2018-08-29 15:18:51 +08:00
|
|
|
drop-user show-users set-role
|
|
|
|
clear-role grant-privilege
|
2018-08-06 21:16:39 +08:00
|
|
|
deny-privilege revoke-privilege
|
2018-08-29 15:18:51 +08:00
|
|
|
show-privileges show-role-for-user
|
2018-08-06 21:16:39 +08:00
|
|
|
show-users-for-role)))
|
|
|
|
(user "std::string" :reader t)
|
|
|
|
(role "std::string" :reader t)
|
|
|
|
(user-or-role "std::string" :reader t)
|
|
|
|
(password "Expression *" :reader t
|
|
|
|
:capnp-type "Ast.Tree" :capnp-init nil
|
|
|
|
:capnp-save #'save-ast-pointer
|
|
|
|
:capnp-load (load-ast-pointer "Expression *"))
|
|
|
|
(privileges "std::vector<AuthQuery::Privilege>" :reader t
|
|
|
|
:capnp-type "List(Ast.AuthQuery.Privilege)"
|
|
|
|
:capnp-save
|
|
|
|
(lambda (builder member-name)
|
|
|
|
#>cpp
|
|
|
|
for (size_t i = 0; i < ${member-name}.size(); ++i) {
|
|
|
|
switch (privileges_[i]) {
|
|
|
|
case AuthQuery::Privilege::CREATE:
|
|
|
|
${builder}.set(i, query::capnp::AuthQuery::Privilege::CREATE);
|
|
|
|
break;
|
|
|
|
case AuthQuery::Privilege::DELETE:
|
|
|
|
${builder}.set(i, query::capnp::AuthQuery::Privilege::DELETE);
|
|
|
|
break;
|
|
|
|
case AuthQuery::Privilege::MATCH:
|
|
|
|
${builder}.set(i, query::capnp::AuthQuery::Privilege::MATCH);
|
|
|
|
break;
|
|
|
|
case AuthQuery::Privilege::MERGE:
|
|
|
|
${builder}.set(i, query::capnp::AuthQuery::Privilege::MERGE);
|
|
|
|
break;
|
|
|
|
case AuthQuery::Privilege::SET:
|
|
|
|
${builder}.set(i, query::capnp::AuthQuery::Privilege::SET);
|
|
|
|
break;
|
2018-08-14 17:34:00 +08:00
|
|
|
case AuthQuery::Privilege::REMOVE:
|
|
|
|
${builder}.set(i, query::capnp::AuthQuery::Privilege::REMOVE);
|
|
|
|
break;
|
|
|
|
case AuthQuery::Privilege::INDEX:
|
|
|
|
${builder}.set(i, query::capnp::AuthQuery::Privilege::INDEX);
|
|
|
|
break;
|
2018-08-06 21:16:39 +08:00
|
|
|
case AuthQuery::Privilege::AUTH:
|
|
|
|
${builder}.set(i, query::capnp::AuthQuery::Privilege::AUTH);
|
|
|
|
break;
|
|
|
|
case AuthQuery::Privilege::STREAM:
|
|
|
|
${builder}.set(i, query::capnp::AuthQuery::Privilege::STREAM);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
cpp<#)
|
|
|
|
:capnp-load
|
|
|
|
(lambda (reader member-name)
|
|
|
|
#>cpp
|
|
|
|
for (auto privilege : ${reader}) {
|
|
|
|
switch (privilege) {
|
|
|
|
case query::capnp::AuthQuery::Privilege::CREATE:
|
|
|
|
${member-name}.push_back(AuthQuery::Privilege::CREATE);
|
|
|
|
break;
|
|
|
|
case query::capnp::AuthQuery::Privilege::DELETE:
|
|
|
|
${member-name}.push_back(AuthQuery::Privilege::DELETE);
|
|
|
|
break;
|
|
|
|
case query::capnp::AuthQuery::Privilege::MATCH:
|
|
|
|
${member-name}.push_back(AuthQuery::Privilege::MATCH);
|
|
|
|
break;
|
|
|
|
case query::capnp::AuthQuery::Privilege::MERGE:
|
|
|
|
${member-name}.push_back(AuthQuery::Privilege::MERGE);
|
|
|
|
break;
|
|
|
|
case query::capnp::AuthQuery::Privilege::SET:
|
|
|
|
${member-name}.push_back(AuthQuery::Privilege::SET);
|
|
|
|
break;
|
2018-08-14 17:34:00 +08:00
|
|
|
case query::capnp::AuthQuery::Privilege::REMOVE:
|
|
|
|
${member-name}.push_back(AuthQuery::Privilege::REMOVE);
|
|
|
|
break;
|
|
|
|
case query::capnp::AuthQuery::Privilege::INDEX:
|
|
|
|
${member-name}.push_back(AuthQuery::Privilege::INDEX);
|
|
|
|
break;
|
2018-08-06 21:16:39 +08:00
|
|
|
case query::capnp::AuthQuery::Privilege::AUTH:
|
|
|
|
${member-name}.push_back(AuthQuery::Privilege::AUTH);
|
|
|
|
break;
|
|
|
|
case query::capnp::AuthQuery::Privilege::STREAM:
|
|
|
|
${member-name}.push_back(AuthQuery::Privilege::STREAM);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2018-08-14 17:34:00 +08:00
|
|
|
cpp<#))
|
|
|
|
(user-symbol "Symbol" :reader t)
|
|
|
|
(role-symbol "Symbol" :reader t)
|
2018-08-22 16:59:46 +08:00
|
|
|
(privilege-symbol "Symbol" :reader t)
|
|
|
|
(effective-symbol "Symbol" :reader t)
|
|
|
|
(details-symbol "Symbol" :reader t))
|
2018-08-06 21:16:39 +08:00
|
|
|
(:public
|
|
|
|
#>cpp
|
|
|
|
AuthHandler(AuthQuery::Action action, std::string user, std::string role,
|
|
|
|
std::string user_or_role, Expression * password,
|
2018-08-14 17:34:00 +08:00
|
|
|
std::vector<AuthQuery::Privilege> privileges,
|
2018-08-22 16:59:46 +08:00
|
|
|
Symbol user_symbol, Symbol role_symbol,
|
|
|
|
Symbol privilege_symbol, Symbol effective_symbol,
|
|
|
|
Symbol details_symbol);
|
2018-08-06 21:16:39 +08:00
|
|
|
|
|
|
|
bool Accept(HierarchicalLogicalOperatorVisitor &visitor) override;
|
|
|
|
std::unique_ptr<Cursor> MakeCursor(database::GraphDbAccessor & db)
|
|
|
|
const override;
|
2018-08-14 17:34:00 +08:00
|
|
|
std::vector<Symbol> OutputSymbols(const SymbolTable &) const override;
|
2018-08-06 21:16:39 +08:00
|
|
|
virtual std::vector<Symbol> ModifiedSymbols(const SymbolTable &)
|
|
|
|
const override { return {}; }
|
2018-08-21 20:12:53 +08:00
|
|
|
|
2018-08-06 21:16:39 +08:00
|
|
|
bool HasSingleInput() const override;
|
|
|
|
std::shared_ptr<LogicalOperator> input() const override;
|
|
|
|
void set_input(std::shared_ptr<LogicalOperator>) override;
|
|
|
|
cpp<#)
|
|
|
|
(:protected #>cpp AuthHandler() {} cpp<#)
|
|
|
|
(:serialize :capnp))
|
|
|
|
|
2018-04-23 22:23:42 +08:00
|
|
|
(lcp:define-class unwind (logical-operator)
|
2018-05-16 19:48:56 +08:00
|
|
|
((input "std::shared_ptr<LogicalOperator>"
|
|
|
|
:capnp-save #'save-operator-pointer
|
|
|
|
:capnp-load #'load-operator-pointer)
|
2018-04-23 22:23:42 +08:00
|
|
|
(input-expression "Expression *" :reader t
|
2018-05-16 19:48:56 +08:00
|
|
|
:capnp-type "Ast.Tree" :capnp-init nil
|
2018-07-30 19:48:22 +08:00
|
|
|
:capnp-save #'save-ast-pointer :capnp-load (load-ast-pointer "Expression *"))
|
2018-04-23 22:23:42 +08:00
|
|
|
(output-symbol "Symbol"))
|
|
|
|
(:documentation
|
|
|
|
"Takes a list TypedValue as it's input and yields each
|
|
|
|
element as it's output.
|
|
|
|
|
|
|
|
Input is optional (unwind can be the first clause in a query).")
|
|
|
|
(:public
|
|
|
|
#>cpp
|
|
|
|
Unwind(const std::shared_ptr<LogicalOperator> &input,
|
|
|
|
Expression *input_expression_, Symbol output_symbol);
|
|
|
|
bool Accept(HierarchicalLogicalOperatorVisitor &visitor) override;
|
|
|
|
std::unique_ptr<Cursor> MakeCursor(
|
|
|
|
database::GraphDbAccessor &db) const override;
|
|
|
|
std::vector<Symbol> ModifiedSymbols(const SymbolTable &) const override;
|
|
|
|
|
2018-08-06 21:16:39 +08:00
|
|
|
bool HasSingleInput() const override {
|
|
|
|
return true; }
|
|
|
|
std::shared_ptr<LogicalOperator> input() const override {
|
|
|
|
return input_; }
|
2018-04-23 22:23:42 +08:00
|
|
|
void set_input(std::shared_ptr<LogicalOperator> input) override {
|
|
|
|
input_ = input;
|
|
|
|
}
|
|
|
|
cpp<#)
|
|
|
|
(:private
|
|
|
|
#>cpp
|
|
|
|
Unwind() {}
|
|
|
|
|
|
|
|
class UnwindCursor : public Cursor {
|
|
|
|
public:
|
|
|
|
UnwindCursor(const Unwind &self, database::GraphDbAccessor &db);
|
|
|
|
bool Pull(Frame &, Context &) override;
|
|
|
|
void Reset() override;
|
|
|
|
|
|
|
|
private:
|
|
|
|
const Unwind &self_;
|
|
|
|
database::GraphDbAccessor &db_;
|
|
|
|
const std::unique_ptr<Cursor> input_cursor_;
|
|
|
|
// typed values we are unwinding and yielding
|
|
|
|
std::vector<TypedValue> input_value_;
|
|
|
|
// current position in input_value_
|
|
|
|
std::vector<TypedValue>::iterator input_value_it_ = input_value_.end();
|
|
|
|
};
|
|
|
|
cpp<#)
|
2018-07-30 19:48:22 +08:00
|
|
|
(:serialize :capnp))
|
2018-04-23 22:23:42 +08:00
|
|
|
|
|
|
|
(lcp:define-class distinct (logical-operator)
|
2018-05-16 19:48:56 +08:00
|
|
|
((input "std::shared_ptr<LogicalOperator>"
|
|
|
|
:capnp-save #'save-operator-pointer
|
|
|
|
:capnp-load #'load-operator-pointer)
|
2018-06-19 19:52:11 +08:00
|
|
|
(value-symbols "std::vector<Symbol>" :reader t
|
Replace boost with capnp in RPC
Summary:
Converts the RPC stack to use Cap'n Proto for serialization instead of
boost. There are still some traces of boost in other places in the code,
but most of it is removed. A future diff should cleanup boost for good.
The RPC API is now changed to be more flexible with regards to how
serialize data. This makes the simplest cases a bit more verbose, but
allows complex serialization code to be correctly written instead of
relying on hacks. (For reference, look for the old serialization of
`PullRpc` which had a nasty pointer hacks to inject accessors in
`TypedValue`.)
Since RPC messages were uselessly modeled via inheritance of Message
base class, that class is now removed. Furthermore, that approach
doesn't really work with Cap'n Proto. Instead, each message type is
required to have some type information. This can be automated, so
`define-rpc` has been added to LCP, which hopefully simplifies defining
new RPC request and response messages.
Specify Cap'n Proto schema ID in cmake
This preserves Cap'n Proto generated typeIds across multiple generations
of capnp schemas through LCP. It is imperative that typeId stays the
same to ensure that different compilations of Memgraph may communicate
via RPC in a distributed cluster.
Use CLOS for meta information on C++ types in LCP
Since some structure slots and functions have started to repeat
themselves, it makes sense to model C++ meta information via Common Lisp
Object System.
Depends on D1391
Reviewers: buda, dgleich, mferencevic, mtomic, mculinovic, msantl
Reviewed By: msantl
Subscribers: pullbot
Differential Revision: https://phabricator.memgraph.io/D1407
2018-06-04 15:48:48 +08:00
|
|
|
:capnp-save (lcp:capnp-save-vector "::query::capnp::Symbol" "Symbol")
|
|
|
|
:capnp-load (lcp:capnp-load-vector "::query::capnp::Symbol" "Symbol")))
|
2018-04-23 22:23:42 +08:00
|
|
|
(:documentation
|
|
|
|
"Ensures that only distinct rows are yielded.
|
|
|
|
This implementation accepts a vector of Symbols
|
|
|
|
which define a row. Only those Symbols are valid
|
|
|
|
for use in operators following Distinct.
|
|
|
|
|
|
|
|
This implementation maintains input ordering.")
|
|
|
|
(:public
|
|
|
|
#>cpp
|
|
|
|
Distinct(const std::shared_ptr<LogicalOperator> &input,
|
|
|
|
const std::vector<Symbol> &value_symbols);
|
|
|
|
bool Accept(HierarchicalLogicalOperatorVisitor &visitor) override;
|
|
|
|
std::unique_ptr<Cursor> MakeCursor(
|
|
|
|
database::GraphDbAccessor &db) const override;
|
|
|
|
std::vector<Symbol> OutputSymbols(const SymbolTable &) const override;
|
|
|
|
std::vector<Symbol> ModifiedSymbols(const SymbolTable &) const override;
|
|
|
|
|
|
|
|
bool HasSingleInput() const override { return true; }
|
|
|
|
std::shared_ptr<LogicalOperator> input() const override { return input_; }
|
|
|
|
void set_input(std::shared_ptr<LogicalOperator> input) override {
|
|
|
|
input_ = input;
|
|
|
|
}
|
|
|
|
cpp<#)
|
|
|
|
(:private
|
|
|
|
#>cpp
|
|
|
|
Distinct() {}
|
|
|
|
|
|
|
|
class DistinctCursor : public Cursor {
|
|
|
|
public:
|
|
|
|
DistinctCursor(const Distinct &self, database::GraphDbAccessor &db);
|
|
|
|
|
|
|
|
bool Pull(Frame &, Context &) override;
|
|
|
|
void Reset() override;
|
|
|
|
|
|
|
|
private:
|
|
|
|
const Distinct &self_;
|
|
|
|
const std::unique_ptr<Cursor> input_cursor_;
|
|
|
|
// a set of already seen rows
|
|
|
|
std::unordered_set<
|
|
|
|
std::vector<TypedValue>,
|
|
|
|
// use FNV collection hashing specialized for a vector of TypedValues
|
|
|
|
utils::FnvCollection<std::vector<TypedValue>, TypedValue,
|
|
|
|
TypedValue::Hash>,
|
|
|
|
TypedValueVectorEqual>
|
|
|
|
seen_rows_;
|
|
|
|
};
|
|
|
|
cpp<#)
|
2018-07-30 19:48:22 +08:00
|
|
|
(:serialize :capnp))
|
2018-04-23 22:23:42 +08:00
|
|
|
|
|
|
|
(lcp:define-class create-index (logical-operator)
|
|
|
|
((label "storage::Label" :reader t)
|
|
|
|
(property "storage::Property" :reader t))
|
|
|
|
(:documentation
|
|
|
|
"Creates an index for a combination of label and a property.
|
|
|
|
|
|
|
|
This operator takes no input and it shouldn't serve as an input to any
|
|
|
|
operator. Pulling from the cursor of this operator will create an index in
|
|
|
|
the database for the vertices which have the given label and property. In
|
|
|
|
case the index already exists, nothing happens.")
|
|
|
|
(:public
|
|
|
|
#>cpp
|
|
|
|
CreateIndex(storage::Label label, storage::Property property);
|
|
|
|
bool Accept(HierarchicalLogicalOperatorVisitor &visitor) override;
|
|
|
|
std::unique_ptr<Cursor> MakeCursor(
|
|
|
|
database::GraphDbAccessor &db) const override;
|
|
|
|
std::vector<Symbol> ModifiedSymbols(const SymbolTable &) const override {
|
|
|
|
return {};
|
|
|
|
}
|
|
|
|
|
|
|
|
bool HasSingleInput() const override;
|
|
|
|
std::shared_ptr<LogicalOperator> input() const override;
|
|
|
|
void set_input(std::shared_ptr<LogicalOperator>) override;
|
|
|
|
cpp<#)
|
|
|
|
(:private #>cpp CreateIndex() {} cpp<#)
|
2018-07-30 19:48:22 +08:00
|
|
|
(:serialize :capnp))
|
2018-04-23 22:23:42 +08:00
|
|
|
|
|
|
|
(lcp:define-class union (logical-operator)
|
2018-05-16 19:48:56 +08:00
|
|
|
((left-op "std::shared_ptr<LogicalOperator>" :reader t
|
|
|
|
:capnp-save #'save-operator-pointer
|
|
|
|
:capnp-load #'load-operator-pointer)
|
|
|
|
(right-op "std::shared_ptr<LogicalOperator>" :reader t
|
|
|
|
:capnp-save #'save-operator-pointer
|
|
|
|
:capnp-load #'load-operator-pointer)
|
|
|
|
(union-symbols "std::vector<Symbol>" :reader t
|
Replace boost with capnp in RPC
Summary:
Converts the RPC stack to use Cap'n Proto for serialization instead of
boost. There are still some traces of boost in other places in the code,
but most of it is removed. A future diff should cleanup boost for good.
The RPC API is now changed to be more flexible with regards to how
serialize data. This makes the simplest cases a bit more verbose, but
allows complex serialization code to be correctly written instead of
relying on hacks. (For reference, look for the old serialization of
`PullRpc` which had a nasty pointer hacks to inject accessors in
`TypedValue`.)
Since RPC messages were uselessly modeled via inheritance of Message
base class, that class is now removed. Furthermore, that approach
doesn't really work with Cap'n Proto. Instead, each message type is
required to have some type information. This can be automated, so
`define-rpc` has been added to LCP, which hopefully simplifies defining
new RPC request and response messages.
Specify Cap'n Proto schema ID in cmake
This preserves Cap'n Proto generated typeIds across multiple generations
of capnp schemas through LCP. It is imperative that typeId stays the
same to ensure that different compilations of Memgraph may communicate
via RPC in a distributed cluster.
Use CLOS for meta information on C++ types in LCP
Since some structure slots and functions have started to repeat
themselves, it makes sense to model C++ meta information via Common Lisp
Object System.
Depends on D1391
Reviewers: buda, dgleich, mferencevic, mtomic, mculinovic, msantl
Reviewed By: msantl
Subscribers: pullbot
Differential Revision: https://phabricator.memgraph.io/D1407
2018-06-04 15:48:48 +08:00
|
|
|
:capnp-save (lcp:capnp-save-vector "::query::capnp::Symbol" "Symbol")
|
|
|
|
:capnp-load (lcp:capnp-load-vector "::query::capnp::Symbol" "Symbol"))
|
2018-05-16 19:48:56 +08:00
|
|
|
(left-symbols "std::vector<Symbol>" :reader t
|
Replace boost with capnp in RPC
Summary:
Converts the RPC stack to use Cap'n Proto for serialization instead of
boost. There are still some traces of boost in other places in the code,
but most of it is removed. A future diff should cleanup boost for good.
The RPC API is now changed to be more flexible with regards to how
serialize data. This makes the simplest cases a bit more verbose, but
allows complex serialization code to be correctly written instead of
relying on hacks. (For reference, look for the old serialization of
`PullRpc` which had a nasty pointer hacks to inject accessors in
`TypedValue`.)
Since RPC messages were uselessly modeled via inheritance of Message
base class, that class is now removed. Furthermore, that approach
doesn't really work with Cap'n Proto. Instead, each message type is
required to have some type information. This can be automated, so
`define-rpc` has been added to LCP, which hopefully simplifies defining
new RPC request and response messages.
Specify Cap'n Proto schema ID in cmake
This preserves Cap'n Proto generated typeIds across multiple generations
of capnp schemas through LCP. It is imperative that typeId stays the
same to ensure that different compilations of Memgraph may communicate
via RPC in a distributed cluster.
Use CLOS for meta information on C++ types in LCP
Since some structure slots and functions have started to repeat
themselves, it makes sense to model C++ meta information via Common Lisp
Object System.
Depends on D1391
Reviewers: buda, dgleich, mferencevic, mtomic, mculinovic, msantl
Reviewed By: msantl
Subscribers: pullbot
Differential Revision: https://phabricator.memgraph.io/D1407
2018-06-04 15:48:48 +08:00
|
|
|
:capnp-save (lcp:capnp-save-vector "::query::capnp::Symbol" "Symbol")
|
|
|
|
:capnp-load (lcp:capnp-load-vector "::query::capnp::Symbol" "Symbol"))
|
2018-05-16 19:48:56 +08:00
|
|
|
(right-symbols "std::vector<Symbol>" :reader t
|
Replace boost with capnp in RPC
Summary:
Converts the RPC stack to use Cap'n Proto for serialization instead of
boost. There are still some traces of boost in other places in the code,
but most of it is removed. A future diff should cleanup boost for good.
The RPC API is now changed to be more flexible with regards to how
serialize data. This makes the simplest cases a bit more verbose, but
allows complex serialization code to be correctly written instead of
relying on hacks. (For reference, look for the old serialization of
`PullRpc` which had a nasty pointer hacks to inject accessors in
`TypedValue`.)
Since RPC messages were uselessly modeled via inheritance of Message
base class, that class is now removed. Furthermore, that approach
doesn't really work with Cap'n Proto. Instead, each message type is
required to have some type information. This can be automated, so
`define-rpc` has been added to LCP, which hopefully simplifies defining
new RPC request and response messages.
Specify Cap'n Proto schema ID in cmake
This preserves Cap'n Proto generated typeIds across multiple generations
of capnp schemas through LCP. It is imperative that typeId stays the
same to ensure that different compilations of Memgraph may communicate
via RPC in a distributed cluster.
Use CLOS for meta information on C++ types in LCP
Since some structure slots and functions have started to repeat
themselves, it makes sense to model C++ meta information via Common Lisp
Object System.
Depends on D1391
Reviewers: buda, dgleich, mferencevic, mtomic, mculinovic, msantl
Reviewed By: msantl
Subscribers: pullbot
Differential Revision: https://phabricator.memgraph.io/D1407
2018-06-04 15:48:48 +08:00
|
|
|
:capnp-save (lcp:capnp-save-vector "::query::capnp::Symbol" "Symbol")
|
|
|
|
:capnp-load (lcp:capnp-load-vector "::query::capnp::Symbol" "Symbol")))
|
2018-04-23 22:23:42 +08:00
|
|
|
(:documentation
|
|
|
|
"A logical operator that applies UNION operator on inputs and places the
|
|
|
|
result on the frame.
|
|
|
|
|
|
|
|
This operator takes two inputs, a vector of symbols for the result, and
|
|
|
|
vectors of symbols used by each of the inputs.")
|
|
|
|
(:public
|
|
|
|
#>cpp
|
|
|
|
Union(const std::shared_ptr<LogicalOperator> &left_op,
|
|
|
|
const std::shared_ptr<LogicalOperator> &right_op,
|
|
|
|
const std::vector<Symbol> &union_symbols,
|
|
|
|
const std::vector<Symbol> &left_symbols,
|
|
|
|
const std::vector<Symbol> &right_symbols);
|
|
|
|
bool Accept(HierarchicalLogicalOperatorVisitor &visitor) override;
|
|
|
|
std::unique_ptr<Cursor> MakeCursor(
|
|
|
|
database::GraphDbAccessor &db) const override;
|
|
|
|
std::vector<Symbol> OutputSymbols(const SymbolTable &) const override;
|
|
|
|
std::vector<Symbol> ModifiedSymbols(const SymbolTable &) const override;
|
|
|
|
|
|
|
|
bool HasSingleInput() const override;
|
|
|
|
std::shared_ptr<LogicalOperator> input() const override;
|
|
|
|
void set_input(std::shared_ptr<LogicalOperator>) override;
|
|
|
|
cpp<#)
|
|
|
|
(:private
|
|
|
|
#>cpp
|
|
|
|
Union() {}
|
|
|
|
|
|
|
|
class UnionCursor : public Cursor {
|
|
|
|
public:
|
|
|
|
UnionCursor(const Union &self, database::GraphDbAccessor &db);
|
|
|
|
bool Pull(Frame &, Context &) override;
|
|
|
|
void Reset() override;
|
|
|
|
|
|
|
|
private:
|
|
|
|
const Union &self_;
|
|
|
|
const std::unique_ptr<Cursor> left_cursor_, right_cursor_;
|
|
|
|
};
|
|
|
|
cpp<#)
|
2018-07-30 19:48:22 +08:00
|
|
|
(:serialize :capnp))
|
2018-04-23 22:23:42 +08:00
|
|
|
|
2018-08-27 22:43:34 +08:00
|
|
|
;; TODO: We should probably output this operator in regular planner, not just
|
|
|
|
;; distributed planner.
|
2018-04-23 22:23:42 +08:00
|
|
|
(lcp:define-class cartesian (logical-operator)
|
2018-05-16 19:48:56 +08:00
|
|
|
((left-op "std::shared_ptr<LogicalOperator>" :reader t
|
|
|
|
:capnp-save #'save-operator-pointer
|
|
|
|
:capnp-load #'load-operator-pointer)
|
|
|
|
(left-symbols "std::vector<Symbol>" :reader t
|
Replace boost with capnp in RPC
Summary:
Converts the RPC stack to use Cap'n Proto for serialization instead of
boost. There are still some traces of boost in other places in the code,
but most of it is removed. A future diff should cleanup boost for good.
The RPC API is now changed to be more flexible with regards to how
serialize data. This makes the simplest cases a bit more verbose, but
allows complex serialization code to be correctly written instead of
relying on hacks. (For reference, look for the old serialization of
`PullRpc` which had a nasty pointer hacks to inject accessors in
`TypedValue`.)
Since RPC messages were uselessly modeled via inheritance of Message
base class, that class is now removed. Furthermore, that approach
doesn't really work with Cap'n Proto. Instead, each message type is
required to have some type information. This can be automated, so
`define-rpc` has been added to LCP, which hopefully simplifies defining
new RPC request and response messages.
Specify Cap'n Proto schema ID in cmake
This preserves Cap'n Proto generated typeIds across multiple generations
of capnp schemas through LCP. It is imperative that typeId stays the
same to ensure that different compilations of Memgraph may communicate
via RPC in a distributed cluster.
Use CLOS for meta information on C++ types in LCP
Since some structure slots and functions have started to repeat
themselves, it makes sense to model C++ meta information via Common Lisp
Object System.
Depends on D1391
Reviewers: buda, dgleich, mferencevic, mtomic, mculinovic, msantl
Reviewed By: msantl
Subscribers: pullbot
Differential Revision: https://phabricator.memgraph.io/D1407
2018-06-04 15:48:48 +08:00
|
|
|
:capnp-save (lcp:capnp-save-vector "::query::capnp::Symbol" "Symbol")
|
|
|
|
:capnp-load (lcp:capnp-load-vector "::query::capnp::Symbol" "Symbol"))
|
2018-05-16 19:48:56 +08:00
|
|
|
(right-op "std::shared_ptr<LogicalOperator>" :reader t
|
|
|
|
:capnp-save #'save-operator-pointer
|
|
|
|
:capnp-load #'load-operator-pointer)
|
|
|
|
(right-symbols "std::vector<Symbol>" :reader t
|
Replace boost with capnp in RPC
Summary:
Converts the RPC stack to use Cap'n Proto for serialization instead of
boost. There are still some traces of boost in other places in the code,
but most of it is removed. A future diff should cleanup boost for good.
The RPC API is now changed to be more flexible with regards to how
serialize data. This makes the simplest cases a bit more verbose, but
allows complex serialization code to be correctly written instead of
relying on hacks. (For reference, look for the old serialization of
`PullRpc` which had a nasty pointer hacks to inject accessors in
`TypedValue`.)
Since RPC messages were uselessly modeled via inheritance of Message
base class, that class is now removed. Furthermore, that approach
doesn't really work with Cap'n Proto. Instead, each message type is
required to have some type information. This can be automated, so
`define-rpc` has been added to LCP, which hopefully simplifies defining
new RPC request and response messages.
Specify Cap'n Proto schema ID in cmake
This preserves Cap'n Proto generated typeIds across multiple generations
of capnp schemas through LCP. It is imperative that typeId stays the
same to ensure that different compilations of Memgraph may communicate
via RPC in a distributed cluster.
Use CLOS for meta information on C++ types in LCP
Since some structure slots and functions have started to repeat
themselves, it makes sense to model C++ meta information via Common Lisp
Object System.
Depends on D1391
Reviewers: buda, dgleich, mferencevic, mtomic, mculinovic, msantl
Reviewed By: msantl
Subscribers: pullbot
Differential Revision: https://phabricator.memgraph.io/D1407
2018-06-04 15:48:48 +08:00
|
|
|
:capnp-save (lcp:capnp-save-vector "::query::capnp::Symbol" "Symbol")
|
|
|
|
:capnp-load (lcp:capnp-load-vector "::query::capnp::Symbol" "Symbol")))
|
2018-04-23 22:23:42 +08:00
|
|
|
(:documentation
|
|
|
|
"Operator for producing a Cartesian product from 2 input branches")
|
|
|
|
(:public
|
|
|
|
#>cpp
|
|
|
|
/** Construct the operator with left input branch and right input branch. */
|
|
|
|
Cartesian(const std::shared_ptr<LogicalOperator> &left_op,
|
|
|
|
const std::vector<Symbol> &left_symbols,
|
|
|
|
const std::shared_ptr<LogicalOperator> &right_op,
|
|
|
|
const std::vector<Symbol> &right_symbols)
|
|
|
|
: left_op_(left_op),
|
|
|
|
left_symbols_(left_symbols),
|
|
|
|
right_op_(right_op),
|
|
|
|
right_symbols_(right_symbols) {}
|
|
|
|
|
|
|
|
bool Accept(HierarchicalLogicalOperatorVisitor &visitor) override;
|
|
|
|
std::unique_ptr<Cursor> MakeCursor(
|
|
|
|
database::GraphDbAccessor &db) const override;
|
|
|
|
std::vector<Symbol> ModifiedSymbols(const SymbolTable &) const override;
|
|
|
|
|
|
|
|
bool HasSingleInput() const override;
|
|
|
|
std::shared_ptr<LogicalOperator> input() const override;
|
|
|
|
void set_input(std::shared_ptr<LogicalOperator>) override;
|
|
|
|
cpp<#)
|
|
|
|
(:private #>cpp Cartesian() {} cpp<#)
|
2018-07-30 19:48:22 +08:00
|
|
|
(:serialize :capnp))
|
2018-04-23 22:23:42 +08:00
|
|
|
|
2018-08-27 22:43:34 +08:00
|
|
|
;;; KAFKA STREAM OPERATORS
|
2018-06-15 22:12:44 +08:00
|
|
|
(lcp:define-class create-stream (logical-operator)
|
|
|
|
((stream-name "std::string" :reader t)
|
|
|
|
(stream-uri "Expression *"
|
|
|
|
:reader t
|
|
|
|
:capnp-type "Ast.Tree"
|
|
|
|
:capnp-init nil
|
|
|
|
:capnp-save #'save-ast-pointer
|
|
|
|
:capnp-load (load-ast-pointer "Expression *"))
|
2018-06-19 20:37:02 +08:00
|
|
|
(stream-topic "Expression *"
|
|
|
|
:reader t
|
|
|
|
:capnp-type "Ast.Tree"
|
|
|
|
:capnp-init nil
|
|
|
|
:capnp-save #'save-ast-pointer
|
|
|
|
:capnp-load (load-ast-pointer "Expression *"))
|
2018-06-15 22:12:44 +08:00
|
|
|
(transform-uri "Expression *"
|
|
|
|
:reader t
|
|
|
|
:capnp-type "Ast.Tree"
|
|
|
|
:capnp-init nil
|
|
|
|
:capnp-save #'save-ast-pointer
|
|
|
|
:capnp-load (load-ast-pointer "Expression *"))
|
2018-06-19 20:37:02 +08:00
|
|
|
(batch-interval-in-ms "Expression *"
|
|
|
|
:reader t
|
|
|
|
:capnp-type "Ast.Tree"
|
|
|
|
:capnp-init nil
|
|
|
|
:capnp-save #'save-ast-pointer
|
|
|
|
:capnp-load (load-ast-pointer "Expression *"))
|
|
|
|
(batch-size "Expression *"
|
2018-06-15 22:12:44 +08:00
|
|
|
:reader t
|
|
|
|
:capnp-type "Ast.Tree"
|
|
|
|
:capnp-init nil
|
|
|
|
:capnp-save #'save-ast-pointer
|
|
|
|
:capnp-load (load-ast-pointer "Expression *")))
|
|
|
|
(:documentation
|
|
|
|
"Creates a new stream with given parameters that imports data.")
|
|
|
|
(:public
|
|
|
|
#>cpp
|
2018-06-19 20:37:02 +08:00
|
|
|
CreateStream(std::string stream_name, Expression *stream_uri,
|
|
|
|
Expression *stream_topic, Expression *transform_uri,
|
|
|
|
Expression *batch_interval_in_ms, Expression *batch_size);
|
2018-06-15 22:12:44 +08:00
|
|
|
DEFVISITABLE(HierarchicalLogicalOperatorVisitor);
|
|
|
|
std::unique_ptr<Cursor> MakeCursor(
|
|
|
|
database::GraphDbAccessor &db) const override;
|
|
|
|
std::vector<Symbol> ModifiedSymbols(const SymbolTable &) const override {
|
|
|
|
return {};
|
|
|
|
}
|
|
|
|
|
|
|
|
bool HasSingleInput() const override;
|
|
|
|
std::shared_ptr<LogicalOperator> input() const override;
|
|
|
|
void set_input(std::shared_ptr<LogicalOperator>) override;
|
|
|
|
cpp<#)
|
|
|
|
(:private
|
|
|
|
#>cpp CreateStream() {} cpp<#)
|
2018-07-30 19:48:22 +08:00
|
|
|
(:serialize :capnp))
|
2018-06-15 22:12:44 +08:00
|
|
|
|
|
|
|
(lcp:define-class drop-stream (logical-operator)
|
|
|
|
((stream-name "std::string" :reader t))
|
|
|
|
(:documentation
|
|
|
|
"Stops and deletes a stream if it exists.")
|
|
|
|
(:public
|
|
|
|
#>cpp
|
|
|
|
explicit DropStream(std::string stream_name);
|
|
|
|
DEFVISITABLE(HierarchicalLogicalOperatorVisitor);
|
|
|
|
std::unique_ptr<Cursor> MakeCursor(
|
|
|
|
database::GraphDbAccessor &db) const override;
|
|
|
|
std::vector<Symbol> ModifiedSymbols(const SymbolTable &) const override {
|
|
|
|
return {};
|
|
|
|
}
|
|
|
|
|
|
|
|
bool HasSingleInput() const override;
|
|
|
|
std::shared_ptr<LogicalOperator> input() const override;
|
|
|
|
void set_input(std::shared_ptr<LogicalOperator>) override;
|
|
|
|
cpp<#)
|
|
|
|
(:private
|
|
|
|
#>cpp DropStream() {} cpp<#)
|
2018-07-30 19:48:22 +08:00
|
|
|
(:serialize :capnp))
|
2018-06-15 22:12:44 +08:00
|
|
|
|
|
|
|
(lcp:define-class show-streams (logical-operator)
|
2018-06-19 20:37:02 +08:00
|
|
|
((name-symbol "Symbol" :reader t)
|
|
|
|
(uri-symbol "Symbol" :reader t)
|
|
|
|
(topic-symbol "Symbol" :reader t)
|
|
|
|
(transform-symbol "Symbol" :reader t)
|
|
|
|
(status-symbol "Symbol" :reader t))
|
2018-06-15 22:12:44 +08:00
|
|
|
(:documentation
|
|
|
|
"Shows all streams, started and stopped, that were configured.")
|
|
|
|
(:public
|
|
|
|
#>cpp
|
2018-06-19 20:37:02 +08:00
|
|
|
ShowStreams(Symbol name_symbol, Symbol endpoint_symbol, Symbol topic_symbol,
|
|
|
|
Symbol transform_symbol, Symbol status_symbol);
|
2018-06-15 22:12:44 +08:00
|
|
|
DEFVISITABLE(HierarchicalLogicalOperatorVisitor);
|
|
|
|
std::unique_ptr<Cursor> MakeCursor(
|
|
|
|
database::GraphDbAccessor &db) const override;
|
2018-06-19 20:37:02 +08:00
|
|
|
std::vector<Symbol> OutputSymbols(const SymbolTable &) const override;
|
2018-06-15 22:12:44 +08:00
|
|
|
std::vector<Symbol> ModifiedSymbols(const SymbolTable &) const override {
|
|
|
|
return {};
|
|
|
|
}
|
|
|
|
|
|
|
|
bool HasSingleInput() const override;
|
|
|
|
std::shared_ptr<LogicalOperator> input() const override;
|
|
|
|
void set_input(std::shared_ptr<LogicalOperator>) override;
|
|
|
|
cpp<#)
|
2018-06-19 20:37:02 +08:00
|
|
|
(:private
|
|
|
|
#>cpp ShowStreams() {} cpp<#)
|
2018-07-30 19:48:22 +08:00
|
|
|
(:serialize :capnp))
|
2018-06-15 22:12:44 +08:00
|
|
|
|
|
|
|
(lcp:define-class start-stop-stream (logical-operator)
|
|
|
|
((stream-name "std::string" :reader t)
|
|
|
|
(is-start :bool :reader t)
|
|
|
|
(limit-batches "Expression *"
|
|
|
|
:reader t
|
|
|
|
:capnp-type "Ast.Tree"
|
|
|
|
:capnp-init nil
|
|
|
|
:capnp-save #'save-ast-pointer
|
|
|
|
:capnp-load (load-ast-pointer "Expression *")))
|
|
|
|
(:documentation
|
|
|
|
"Starts or stops a stream.
|
|
|
|
When starting a stream import, it can be limited by number of batches
|
|
|
|
If a stream is already running, it wont limit the number of batches that this
|
|
|
|
stream is importing.")
|
|
|
|
(:public
|
|
|
|
#>cpp
|
|
|
|
StartStopStream(std::string stream_name, bool is_start,
|
|
|
|
Expression *limit_batches);
|
|
|
|
DEFVISITABLE(HierarchicalLogicalOperatorVisitor);
|
|
|
|
std::unique_ptr<Cursor> MakeCursor(
|
|
|
|
database::GraphDbAccessor &db) const override;
|
|
|
|
std::vector<Symbol> ModifiedSymbols(const SymbolTable &) const override {
|
|
|
|
return {};
|
|
|
|
}
|
|
|
|
|
|
|
|
bool HasSingleInput() const override;
|
|
|
|
std::shared_ptr<LogicalOperator> input() const override;
|
|
|
|
void set_input(std::shared_ptr<LogicalOperator>) override;
|
|
|
|
cpp<#)
|
|
|
|
(:private
|
|
|
|
#>cpp StartStopStream() {} cpp<#)
|
2018-07-30 19:48:22 +08:00
|
|
|
(:serialize :capnp))
|
2018-06-15 22:12:44 +08:00
|
|
|
|
|
|
|
(lcp:define-class start-stop-all-streams (logical-operator)
|
|
|
|
((stream-name "std::string" :reader t)
|
|
|
|
(is-start :bool :reader t))
|
|
|
|
(:documentation
|
|
|
|
"Starts or stops all stream.")
|
|
|
|
(:public
|
|
|
|
#>cpp
|
|
|
|
explicit StartStopAllStreams(bool is_start);
|
|
|
|
DEFVISITABLE(HierarchicalLogicalOperatorVisitor);
|
|
|
|
std::unique_ptr<Cursor> MakeCursor(
|
|
|
|
database::GraphDbAccessor &db) const override;
|
|
|
|
std::vector<Symbol> ModifiedSymbols(const SymbolTable &) const override {
|
|
|
|
return {};
|
|
|
|
}
|
|
|
|
|
|
|
|
bool HasSingleInput() const override;
|
|
|
|
std::shared_ptr<LogicalOperator> input() const override;
|
|
|
|
void set_input(std::shared_ptr<LogicalOperator>) override;
|
|
|
|
cpp<#)
|
|
|
|
(:private
|
|
|
|
#>cpp StartStopAllStreams() {} cpp<#)
|
2018-07-30 19:48:22 +08:00
|
|
|
(:serialize :capnp))
|
2018-06-15 22:12:44 +08:00
|
|
|
|
2018-07-03 19:57:53 +08:00
|
|
|
(lcp:define-class test-stream (logical-operator)
|
|
|
|
((stream-name "std::string" :reader t)
|
|
|
|
(limit-batches "Expression *"
|
|
|
|
:reader t
|
|
|
|
:capnp-type "Ast.Tree"
|
|
|
|
:capnp-init nil
|
|
|
|
:capnp-save #'save-ast-pointer
|
|
|
|
:capnp-load (load-ast-pointer "Expression *"))
|
2018-08-06 19:05:42 +08:00
|
|
|
(query-symbol "Symbol" :reader t)
|
|
|
|
(params-symbol "Symbol" :reader t))
|
2018-07-03 19:57:53 +08:00
|
|
|
(:documentation
|
|
|
|
"Test a stream. This will start consuming messages but wont insert anything
|
|
|
|
in the db.")
|
|
|
|
(:public
|
|
|
|
#>cpp
|
|
|
|
TestStream(std::string stream_name, Expression *limit_batches,
|
2018-08-06 19:05:42 +08:00
|
|
|
Symbol query_symbol, Symbol params_symbol);
|
2018-07-03 19:57:53 +08:00
|
|
|
DEFVISITABLE(HierarchicalLogicalOperatorVisitor);
|
|
|
|
std::unique_ptr<Cursor> MakeCursor(
|
|
|
|
database::GraphDbAccessor &db) const override;
|
2018-07-06 15:28:05 +08:00
|
|
|
std::vector<Symbol> OutputSymbols(const SymbolTable &) const override;
|
2018-07-03 19:57:53 +08:00
|
|
|
std::vector<Symbol> ModifiedSymbols(const SymbolTable &) const override {
|
|
|
|
return {};
|
|
|
|
}
|
|
|
|
|
|
|
|
bool HasSingleInput() const override;
|
|
|
|
std::shared_ptr<LogicalOperator> input() const override;
|
|
|
|
void set_input(std::shared_ptr<LogicalOperator>) override;
|
|
|
|
cpp<#)
|
|
|
|
(:private
|
|
|
|
#>cpp TestStream() {} cpp<#)
|
2018-07-30 19:48:22 +08:00
|
|
|
(:serialize :capnp))
|
2018-07-03 19:57:53 +08:00
|
|
|
|
2018-08-27 22:43:34 +08:00
|
|
|
;;; END KAFKA STREAM OPERATORS
|
|
|
|
|
2018-08-23 19:15:15 +08:00
|
|
|
(lcp:define-class explain (logical-operator)
|
|
|
|
((input "std::shared_ptr<LogicalOperator>"
|
|
|
|
:capnp-save #'save-operator-pointer
|
|
|
|
:capnp-load #'load-operator-pointer)
|
|
|
|
(output-symbol "Symbol" :reader t))
|
|
|
|
(:documentation "Pretty print a LogicalOperator plan")
|
|
|
|
(:public
|
|
|
|
#>cpp
|
|
|
|
Explain(const std::shared_ptr<LogicalOperator> &input,
|
|
|
|
const Symbol &output_symbol);
|
|
|
|
|
|
|
|
bool Accept(HierarchicalLogicalOperatorVisitor &visitor) override;
|
|
|
|
std::unique_ptr<Cursor> MakeCursor(
|
|
|
|
database::GraphDbAccessor & db) const override;
|
|
|
|
std::vector<Symbol> OutputSymbols(const SymbolTable &) const override;
|
|
|
|
std::vector<Symbol> ModifiedSymbols(const SymbolTable &) const override;
|
|
|
|
|
|
|
|
bool HasSingleInput() const override { return true; }
|
|
|
|
std::shared_ptr<LogicalOperator> input() const override { return input_; }
|
|
|
|
void set_input(std::shared_ptr<LogicalOperator> input) override {
|
|
|
|
input_ = input;
|
|
|
|
}
|
|
|
|
cpp<#)
|
|
|
|
(:private
|
|
|
|
#>cpp Explain () {} cpp<#)
|
|
|
|
(:serialize :capnp))
|
2018-07-03 19:57:53 +08:00
|
|
|
|
2018-05-16 19:48:56 +08:00
|
|
|
(lcp:pop-namespace) ;; plan
|
|
|
|
(lcp:pop-namespace) ;; query
|