Generate SLK serialization from LCP

Summary:
Classes marked with `:serialize (:slk)` will now generate SLK
serialization code. This diff also changes how the `:serialize` option
is parsed, so that multiple different serialization backends are
supported.

Reviewers: mtomic, llugovic, mferencevic

Reviewed By: mtomic

Subscribers: pullbot

Differential Revision: https://phabricator.memgraph.io/D1755
This commit is contained in:
Teon Banek 2018-12-04 14:41:37 +01:00
parent eabd832048
commit 7638b09867
16 changed files with 293 additions and 253 deletions

View File

@ -416,7 +416,7 @@ generation and tuning of its serialization code. Previously, LCP supported
Boost.Serialization, but it was removed.
To specify a class or structure for serialization, you may pass a
`:serialize :capnp` option when defining such type. (Note that
`:serialize (:capnp)` option when defining such type. (Note that
`lcp:define-enum` takes `:serialize` without any arguments).
For example:
@ -424,7 +424,7 @@ For example:
```lisp
(lcp:define-struct my-struct ()
((member :int64_t))
(:serialize :capnp))
(:serialize (:capnp)))
```
`:serialize` option will generate a Cap'n Proto schema of the class and store
@ -454,11 +454,11 @@ For example:
```lisp
(lcp:define-class base ()
((base-member "std::vector<int64_t>" :scope :public))
(:serialize :capnp))
(:serialize (:capnp)))
(lcp:define-class derived (base)
((derived-member :bool :scope :public))
(:serialize :capnp))
(:serialize (:capnp)))
```
Note that all classes need to have the `:serialize` option set. Signatures of
@ -492,7 +492,7 @@ of super classes.
```lisp
(lcp:define-class derived (primary-base some-interface other-interface)
...
(:serialize :capnp :ignore-other-base-classes t))
(:serialize (:capnp :ignore-other-base-classes t)))
```
Another form of multiple inheritance is reusing some common code. In
@ -506,7 +506,7 @@ For example:
```lisp
(lcp:define-class derived (first-base second-base)
...
(:serialize :capnp :inherit-compose '(second-base)))
(:serialize (:capnp :inherit-compose '(second-base))))
```
With `:inherit-compose` you can pass a list of parent classes which should be
@ -523,19 +523,19 @@ will not be able to generate correct serialization code.
The cases so far have been only with classes that are pure interface and need
no serialization code. This is signaled to LCP by passing the option `:base t`
to `:serialize :capnp`. LCP will treat such classes as actually being the base
class of a hierarchy.
to `:capnp`. LCP will treat such classes as actually being the base class of a
hierarchy.
For example:
```lisp
(lcp:define-class my-class ("utils::TotalOrdering")
(...)
(:serialize :capnp :base t))
(:serialize (:capnp :base t)))
(lcp:define-class derived (my-class)
(...)
(:serialize :capnp))
(:serialize (:capnp)))
```
Only the base class for serialization has the `:base t` option set. Derived
@ -555,7 +555,7 @@ To specify template arguments, pass a `:type-args` option. For example:
```lisp
(lcp:define-class (my-container t-value) ()
(...)
(:serialize :capnp :type-args '(my-class)))
(:serialize (:capnp :type-args '(my-class))))
```
The above will support serialization of `MyContainer<MyClass>` type.
@ -646,7 +646,7 @@ Example:
auto data = ${reader}.getData();
${member}.LoadFromData(data);
cpp<#)))
(:serialize :capnp))
(:serialize (:capnp)))
```
With custom serialization code, you may want to get additional details through
@ -683,9 +683,9 @@ For example:
:capnp-save ;; custom save
:capnp-load ;; custom load
))
(:serialize :capnp
:save-args '((save-helper "SaveHelper *"))
:load-args '((load-helper "LoadHelper *"))))
(:serialize (:capnp
:save-args '((save-helper "SaveHelper *"))
:load-args '((load-helper "LoadHelper *")))))
```
The custom serialization code will now have access to `save_helper` and
@ -707,11 +707,11 @@ serialized as expected:
```lisp
(lcp:define-class my-class-with-primitive-optional ()
((primitive-optional "std::experimental::optional<int64_t>"))
(:serialize :capnp))
(:serialize (:capnp)))
(lcp:define-class my-class-with-known-type-optional ()
((known-type-optional "std::experimental::optional<MyClassWithPrimitiveOptional>"))
(:serialize :capnp))
(:serialize (:capnp)))
```
In cases when the value contained in `std::optional` needs custom
@ -780,13 +780,13 @@ Example:
LCP supports generating serialization code for use with our own simple
serialization framework, SaveLoadKit (SLK).
To specify a class or structure for serialization, pass a `:serialize :slk`
To specify a class or structure for serialization, pass a `:serialize (:slk)`
class option. For example:
```lisp
(lcp:define-struct my-struct ()
((member :int64_t))
(:serialize :slk))
(:serialize (:slk)))
```
The above will generate C++ functions for saving and loading all members of
@ -856,11 +856,11 @@ For example:
```lisp
(lcp:define-class base ()
...
(:serialize :slk))
(:serialize (:slk)))
(lcp:define-class derived (base)
...
(:serialize :slk))
(:serialize (:slk)))
```
We get the following declarations generated:
@ -894,7 +894,7 @@ inheritance by specifying `:ignore-other-base-classes` option. For example:
```lisp
(lcp:define-class derived (primary-base some-interface ...)
...
(:serialize :slk (:ignore-other-base-classes t)))
(:serialize (:slk :ignore-other-base-classes t)))
```
The above will produce serialization code as if `derived` is inheriting *only*
@ -938,7 +938,7 @@ be done in LCP.
std::vector<std::shared_ptr<SomeType>> already_loaded;
slk::Load(&self->${member}, reader, &already_loaded);
cpp<#)))
(:serialize :slk))
(:serialize (:slk)))
```
The above use is very artificial, because we usually have multiple shared
@ -976,7 +976,7 @@ type.
#>cpp
slk::Load(&self->${member}, reader, already_loaded);
cpp<#)))
(:serialize :slk (:save-args '((already-saved "std::vector<SomeType *> *"))
(:serialize (:slk :save-args '((already-saved "std::vector<SomeType *> *"))
:load-args '((already-loaded "std::vector<std::shared_ptr<SomeType>> *")))))
```
@ -1011,6 +1011,6 @@ example:
for (size_t i = 0; i < size; ++i)
slk::Load(&self->${member}[i], reader, &already_loaded);
cpp<#)))
(:serialize :slk))
(:serialize (:slk)))
```

View File

@ -67,7 +67,7 @@ cpp<#
#>cpp
query::LoadEvaluationContext(${reader}, &${member});
cpp<#)))
(:serialize :capnp :load-args '((ast-storage "query::AstStorage *"))))
(:serialize (:capnp :load-args '((ast-storage "query::AstStorage *")))))
(:response ((member :int64_t))))
(lcp:define-rpc register-subcursors
@ -110,7 +110,7 @@ cpp<#
(lcp:define-enum expand-result
(success failure lambda-error)
(:serialize :capnp))
(:serialize))
(lcp:define-rpc expand-level
(:request ((member :int64_t)))
@ -133,10 +133,10 @@ cpp<#
"[dba, data_manager](const auto &reader) {
return storage::LoadVertexAccessor(reader, dba, data_manager);
}")))
(:serialize :capnp
:save-args '((worker-id :int))
:load-args '((dba "database::GraphDbAccessor *")
(data-manager "distributed::DataManager *")))))
(:serialize (:capnp
:save-args '((worker-id :int))
:load-args '((dba "database::GraphDbAccessor *")
(data-manager "distributed::DataManager *"))))))
(lcp:define-rpc set-source
(:request
@ -194,10 +194,10 @@ cpp<#
(next-edge "std::experimental::optional<storage::EdgeAddress>"
:capnp-save (lcp:capnp-save-optional "storage::capnp::Address" "storage::EdgeAddress")
:capnp-load (lcp:capnp-load-optional "storage::capnp::Address" "storage::EdgeAddress")))
(:serialize :capnp
:save-args '((worker-id :int))
:load-args '((dba "database::GraphDbAccessor *")
(data-manager "distributed::DataManager *")))
(:serialize (:capnp
:save-args '((worker-id :int))
:load-args '((dba "database::GraphDbAccessor *")
(data-manager "distributed::DataManager *"))))
(:public
#>cpp
using Capnp = capnp::ReconstructPathRes;
@ -236,9 +236,9 @@ cpp<#
return value;
}"))
(worker-id :int :dont-save t))
(:serialize :capnp
:load-args '((dba "database::GraphDbAccessor *")
(data-manager "distributed::DataManager *"))))
(:serialize (:capnp
:load-args '((dba "database::GraphDbAccessor *")
(data-manager "distributed::DataManager *")))))
(:response ()))
(lcp:pop-namespace) ;; distributed

View File

@ -23,7 +23,7 @@ cpp<#
(lcp:define-struct tx-gid-pair ()
((tx-id "tx::TransactionId" :capnp-type "UInt64")
(gid "gid::Gid" :capnp-type "UInt64"))
(:serialize :capnp))
(:serialize (:capnp)))
(lcp:define-rpc vertex
(:request ((member "TxGidPair")))

View File

@ -174,8 +174,8 @@ to the appropriate value. Not used on side that generates the response.")
PullResData(PullResData &&) = default;
PullResData &operator=(PullResData &&) = default;
cpp<#)
(:serialize :capnp :load-args '((dba "database::GraphDbAccessor *")
(data-manager "distributed::DataManager *"))))
(:serialize (:capnp :load-args '((dba "database::GraphDbAccessor *")
(data-manager "distributed::DataManager *")))))
(lcp:define-rpc pull
(:request
@ -211,8 +211,8 @@ to the appropriate value. Not used on side that generates the response.")
'(both only-old only-new)))))
(:response
((data "PullResData" :initarg :move))
(:serialize :capnp :base t :load-args '((dba "database::GraphDbAccessor *")
(data-manager "distributed::DataManager *")))))
(:serialize (:capnp :base t :load-args '((dba "database::GraphDbAccessor *")
(data-manager "distributed::DataManager *"))))))
;; TODO make a separate RPC for the continuation of an existing pull, as an
;; optimization not to have to send the full PullReqData pack every time.

View File

@ -51,7 +51,7 @@ cpp<#
((result "UpdateResult")
(cypher-id :int64_t :documentation "Only valid if creation was successful.")
(gid "gid::Gid" :documentation "Only valid if creation was successful."))
(:serialize :capnp))
(:serialize (:capnp)))
(lcp:define-struct create-vertex-req-data ()
((tx-id "tx::TransactionId")
@ -107,7 +107,7 @@ cpp<#
return reader.getValue();
});
cpp<#)))
(:serialize :capnp))
(:serialize (:capnp)))
(lcp:define-rpc create-vertex
(:request ((member "CreateVertexReqData")))
@ -138,7 +138,7 @@ cpp<#
return reader.getValue();
});
cpp<#)))
(:serialize :capnp))
(:serialize (:capnp)))
(lcp:define-rpc create-edge
(:request ((member "CreateEdgeReqData")))
@ -150,7 +150,7 @@ cpp<#
(to "gid::Gid")
(edge-type "storage::EdgeType")
(tx-id "tx::TransactionId"))
(:serialize :capnp))
(:serialize (:capnp)))
(lcp:define-rpc add-in-edge
(:request ((member "AddInEdgeReqData")))
@ -160,7 +160,7 @@ cpp<#
((gid "gid::Gid")
(tx-id "tx::TransactionId")
(check-empty :bool))
(:serialize :capnp))
(:serialize (:capnp)))
(lcp:define-rpc remove-vertex
(:request ((member "RemoveVertexReqData")))
@ -171,7 +171,7 @@ cpp<#
(edge-id "gid::Gid")
(vertex-from-id "gid::Gid")
(vertex-to-address "storage::VertexAddress"))
(:serialize :capnp))
(:serialize (:capnp)))
(lcp:define-rpc remove-edge
(:request ((member "RemoveEdgeData")))
@ -181,7 +181,7 @@ cpp<#
((tx-id "tx::TransactionId")
(vertex "gid::Gid")
(edge-address "storage::EdgeAddress"))
(:serialize :capnp))
(:serialize (:capnp)))
(lcp:define-rpc remove-in-edge
(:request ((member "RemoveInEdgeData")))

View File

@ -102,7 +102,7 @@ in StateDeltas.")
"Defines StateDelta type. For each type the comment indicates which values
need to be stored. All deltas have the transaction_id member, so that's
omitted in the comment.")
(:serialize :capnp))
(:serialize))
#>cpp
StateDelta() = default;
StateDelta(const enum Type &type, tx::TransactionId tx_id)
@ -171,6 +171,6 @@ omitted in the comment.")
/// Applies CRUD delta to database accessor. Fails on other types of deltas
void Apply(GraphDbAccessor &dba) const;
cpp<#)
(:serialize :capnp))
(:serialize (:capnp)))
(lcp:pop-namespace) ;; database

View File

@ -95,7 +95,7 @@ in StateDeltas.")
"Defines StateDelta type. For each type the comment indicates which values
need to be stored. All deltas have the transaction_id member, so that's
omitted in the comment.")
(:serialize :capnp))
(:serialize))
#>cpp
StateDelta() = default;
StateDelta(const enum Type &type, tx::TransactionId tx_id)
@ -153,6 +153,6 @@ omitted in the comment.")
/// Applies CRUD delta to database accessor. Fails on other types of deltas
void Apply(GraphDbAccessor &dba) const;
cpp<#)
(:serialize :capnp))
(:serialize (:capnp)))
(lcp:pop-namespace) ;; database

View File

@ -177,7 +177,7 @@
(undefine-cpp-types)
(let ((test-struct (lcp:define-struct test-struct ()
()
(:serialize :slk (:save-args '((extra-arg "SaveArgType"))
(:serialize (:slk :save-args '((extra-arg "SaveArgType"))
:load-args '((extra-arg "LoadArgType")))))))
(is-generated (lcp.slk:save-function-declaration-for-class test-struct)
"void Save(const TestStruct &self, slk::Builder *builder, SaveArgType extra_arg)")
@ -186,7 +186,7 @@
(undefine-cpp-types)
(let ((base-class (lcp:define-struct base ()
()
(:serialize :slk (:save-args '((extra-arg "SaveArgType"))
(:serialize (:slk :save-args '((extra-arg "SaveArgType"))
:load-args '((extra-arg "LoadArgType"))))))
(derived-class (lcp:define-struct derived (base)
())))
@ -215,7 +215,7 @@
(is-generated (lcp.slk:save-function-declaration-for-class
(lcp:define-class derived (fst-base snd-base)
()
(:serialize :slk (:ignore-other-base-classes t))))
(:serialize (:slk :ignore-other-base-classes t))))
"void Save(const Derived &self, slk::Builder *builder)")
(undefine-cpp-types)
;; Unsupported template classes
@ -423,7 +423,7 @@
((base-member :bool))))
(derived-class (lcp:define-struct derived (base ignored-base)
((derived-member :int64_t))
(:serialize :slk (:ignore-other-base-classes t)))))
(:serialize (:slk :ignore-other-base-classes t)))))
(is-generated (lcp.slk:save-function-definition-for-class base-class)
base-save-code)
(is-generated (lcp.slk:construct-and-load-function-definition-for-class base-class)
@ -516,7 +516,7 @@
(undefine-cpp-types)
(let ((class (lcp:define-struct derived ("UnknownBase")
((member :bool))
(:serialize :slk (:base t)))))
(:serialize (:slk :base t)))))
(is-generated (lcp.slk:save-function-definition-for-class class)
"void Save(const Derived &self, slk::Builder *builder) { slk::Save(self.member, builder); }")
(is-generated (lcp.slk:load-function-definition-for-class class)
@ -526,7 +526,7 @@
(let ((base-class (lcp:define-struct base ()
()
(:abstractp t)
(:serialize :slk (:save-args '((extra-arg "SaveArg"))
(:serialize (:slk :save-args '((extra-arg "SaveArg"))
:load-args '((extra-arg "LoadArg"))))))
(derived-class (lcp:define-struct derived (base)
())))

View File

@ -304,9 +304,6 @@ encoded as union inheritance in Cap'n Proto."
(list (first (capnp-union-and-compose-parents class)))))))))
(cdr (rec cpp-class))))
(defvar *capnp-serialize-p* nil
"True if we should generate Cap'n Proto serialization code")
(defvar *capnp-type-converters* nil
"Pairs of (cpp-type capnp-type) which map the conversion of C++ types to
Cap'n Proto types.")
@ -453,7 +450,7 @@ encoded as union inheritance in Cap'n Proto."
(incf field-number)))))))
(dolist (inner inner-types)
(when (or (and (typep inner 'cpp-class) (cpp-class-capnp-opts inner))
(and (typep inner 'cpp-enum) (cpp-enum-capnp-schema inner)))
(and (typep inner 'cpp-enum) (cpp-enum-serializep inner)))
(write-line (capnp-schema inner) s)))
(when union-subclasses
(with-cpp-block-output (s :name "union")
@ -1336,13 +1333,13 @@ enums which aren't defined in LCP."
(:public
,(decl-type-info req-name)
,(def-constructor req-name (second request)))
(:serialize :capnp :base t))
(:serialize (:capnp)))
(define-struct ,res-sym ()
,@(cdr response)
(:public
,(decl-type-info res-name)
,(def-constructor res-name (second response)))
(:serialize :capnp :base t))
(:serialize (:capnp)))
,rpc-decl))))
(defun read-lcp (filepath)
@ -1422,8 +1419,8 @@ file."
;; have our own accompanying .cpp files
(cpp-file (concatenate 'string lcp-file ".cpp"))
(capnp-file (concatenate 'string filename ".capnp"))
(serializep capnp-id)
;; Reset globals
(*capnp-serialize-p* capnp-id)
(*capnp-namespace* nil)
(*capnp-imports* nil)
(*capnp-type-converters* nil)
@ -1445,40 +1442,82 @@ file."
(write-line (cpp-code res) out)))
(when *cpp-namespaces*
(error "Unclosed namespaces: ~A" (reverse *cpp-namespaces*)))
;; If we have a capnp-id, generate the schema and serialization code
(let ((types-for-capnp (when capnp-id
;; Collect types for serialization
(let ((types-for-capnp (when (and serializep capnp-id)
(append (remove-if (complement #'cpp-class-capnp-opts) *cpp-classes*)
(remove-if (complement #'cpp-enum-capnp-schema) *cpp-enums*)))))
;; Append top-level declarations for Cap'n Proto serialization
(with-open-file (out hpp-file :direction :output :if-exists :append)
(terpri out)
(write-line "// Cap'n Proto serialization declarations" out)
(with-namespaced-output (out open-namespace)
(dolist (type-for-capnp types-for-capnp)
(open-namespace (cpp-type-namespace type-for-capnp))
(ctypecase type-for-capnp
(cpp-class
(format out "~A;~%" (capnp-save-function-declaration type-for-capnp))
(format out "~A;~%" (capnp-load-function-declaration type-for-capnp)))
(cpp-enum
(format out "~A;~%" (cpp-enum-to-capnp-function-declaration type-for-capnp))
(format out "~A;~%" (cpp-enum-from-capnp-function-declaration type-for-capnp)))))))
;; When we have either capnp or C++ code for the .cpp file, generate
;; the .cpp file. Note, that some code may rely on the fact that .cpp
;; file is generated after .hpp.
(when (or *cpp-impl* types-for-capnp)
(let ((*generating-cpp-impl-p* t))
(with-open-file (out cpp-file :direction :output :if-exists :supersede)
(format out "~@{// ~A~%~}" +emacs-read-only+ +vim-read-only+)
(format out "// DO NOT EDIT! Generated using LCP from '~A'~2%"
(file-namestring lcp-file))
(format out "#include \"~A\"~2%" (file-namestring hpp-file))
;; First output the C++ code from the user
(remove-if (complement #'cpp-enum-serializep) *cpp-enums*))))
(types-for-slk (when serializep
(append (remove-if (complement #'cpp-class-slk-opts) *cpp-classes*)
(remove-if (complement #'cpp-enum-serializep) *cpp-enums*)))))
(when types-for-capnp
;; Append top-level declarations for Cap'n Proto serialization
(with-open-file (out hpp-file :direction :output :if-exists :append)
(terpri out)
(write-line "// Cap'n Proto serialization declarations" out)
(with-namespaced-output (out open-namespace)
(dolist (type-for-capnp types-for-capnp)
(open-namespace (cpp-type-namespace type-for-capnp))
(ctypecase type-for-capnp
(cpp-class
(format out "~A;~%" (capnp-save-function-declaration type-for-capnp))
(format out "~A;~%" (capnp-load-function-declaration type-for-capnp)))
(cpp-enum
(format out "~A;~%" (cpp-enum-to-capnp-function-declaration type-for-capnp))
(format out "~A;~%" (cpp-enum-from-capnp-function-declaration type-for-capnp))))))))
(when types-for-slk
;; Append top-level declarations for SLK serialization
(with-open-file (out hpp-file :direction :output :if-exists :append)
(terpri out)
(write-line "// SLK serialization declarations" out)
(write-line "#include \"communication/rpc/serialization.hpp\"" out)
(with-namespaced-output (out open-namespace)
(open-namespace '("slk"))
(dolist (type-for-slk types-for-slk)
(ctypecase type-for-slk
(cpp-class
(format out "~A;~%" (lcp.slk:save-function-declaration-for-class type-for-slk))
(when (or (cpp-class-super-classes type-for-slk)
(direct-subclasses-of type-for-slk))
(format out "~A;~%" (lcp.slk:construct-and-load-function-declaration-for-class type-for-slk)))
(unless (cpp-class-abstractp type-for-slk)
(format out "~A;~%" (lcp.slk:load-function-declaration-for-class type-for-slk))))
(cpp-enum
(format out "~A;~%" (lcp.slk:save-function-declaration-for-enum type-for-slk))
(format out "~A;~%" (lcp.slk:load-function-declaration-for-enum type-for-slk))))))))
;; Generate the .cpp file. Note, that some code may rely on the fact
;; that .cpp file is generated after .hpp.
(let ((*generating-cpp-impl-p* t))
(with-open-file (out cpp-file :direction :output :if-exists :supersede)
(format out "~@{// ~A~%~}" +emacs-read-only+ +vim-read-only+)
(format out "// DO NOT EDIT! Generated using LCP from '~A'~2%"
(file-namestring lcp-file))
(format out "#include \"~A\"~2%" (file-namestring hpp-file))
;; First output the C++ code from the user
(with-namespaced-output (out open-namespace)
(dolist (cpp *cpp-impl*)
(destructuring-bind (namespaces . code) cpp
(open-namespace namespaces)
(write-line (cpp-code code) out))))
;; Generate Cap'n Proto serialization
(when types-for-capnp
(generate-capnp types-for-capnp :capnp-file capnp-file :capnp-id capnp-id
:cpp-out out :lcp-file lcp-file))
;; Generate SLK serialization
(when types-for-slk
(write-line "// Autogenerated SLK serialization code" out)
(with-namespaced-output (out open-namespace)
(dolist (cpp *cpp-impl*)
(destructuring-bind (namespaces . code) cpp
(open-namespace namespaces)
(write-line (cpp-code code) out))))
(when types-for-capnp
(generate-capnp types-for-capnp :capnp-file capnp-file :capnp-id capnp-id
:cpp-out out :lcp-file lcp-file)))))))))
(open-namespace '("slk"))
(dolist (cpp-type types-for-slk)
(ctypecase cpp-type
(cpp-class
(format out "// Serialize code for ~A~2%" (cpp-type-name cpp-type))
;; Top level functions
(write-line (lcp.slk:save-function-definition-for-class cpp-type) out)
(when (or (cpp-class-super-classes cpp-type)
(direct-subclasses-of cpp-type))
(format out "~A;~%" (lcp.slk:construct-and-load-function-definition-for-class cpp-type)))
(unless (cpp-class-abstractp cpp-type)
(write-line (lcp.slk:load-function-definition-for-class cpp-type) out)))
(cpp-enum
(write-line (lcp.slk:save-function-definition-for-enum cpp-type) out)
(write-line (lcp.slk:load-function-definition-for-enum cpp-type) out))))))))))))

View File

@ -110,9 +110,8 @@
(defclass cpp-enum (cpp-type)
((values :type list :initarg :values :initform nil :reader cpp-enum-values)
;; If true, generate the schema for this enum.
(capnp-schema :type boolean :initarg :capnp-schema :initform nil
:reader cpp-enum-capnp-schema))
;; If true, generate serialization code for this enum.
(serializep :type boolean :initarg :serializep :initform nil :reader cpp-enum-serializep))
(:documentation "Meta information on a C++ enum."))
(defstruct cpp-member
@ -473,7 +472,7 @@ CPP-TYPE has no namespace, return an empty string."
:values ',values
:namespace (reverse *cpp-namespaces*)
:enclosing-class *cpp-enclosing-class*
:capnp-schema (and *capnp-serialize-p* ',(assoc :serialize options)))))
:serializep ,(if (assoc :serialize options) t))))
(prog1 ,enum
(push ,enum *cpp-enums*)
(push ,enum *cpp-inner-types*)))))
@ -522,9 +521,10 @@ Currently supported class-options are:
* :public -- additional C++ code in public scope.
* :protected -- additional C++ code in protected scope.
* :private -- additional C++ code in private scope.
* :serialize -- only :capnp is a valid value. Setting :capnp will generate
* :serialize -- either (:capnp) or (:slk). Setting :capnp will generate
the Cap'n Proto serialization code for the class members. You may
specifiy additional options after :capnp to fill the `CAPNP-OPTS' slots.
Similarly, you may specify `SLK-OPTS' after :slk.
* :abstractp -- if t, marks that this class cannot be instantiated
(currently only useful in serialization code)
@ -533,7 +533,7 @@ Larger example:
;; (lcp:define-class derived (base)
;; ((val :int :reader t :initval 42))
;; (:public #>cpp void set_val(int new_val) { val_ = new_val; } cpp<#)
;; (:serialize :capnp))
;; (:serialize (:capnp)))
Generates C++:
@ -577,11 +577,10 @@ Generates C++:
:public (list ,@(cdr (assoc :public options)))
:protected (list ,@(cdr (assoc :protected options)))
:private (list ,@(cdr (assoc :private options)))
:capnp-opts ,(when (member :capnp serialize)
`(and *capnp-serialize-p*
(make-capnp-opts ,@(cdr (member :capnp serialize)))))
:slk-opts ,(when (member :slk serialize)
`(make-slk-opts ,@(cadr (member :slk serialize))))
:capnp-opts ,(when (assoc :capnp serialize)
`(make-capnp-opts ,@(cdr (assoc :capnp serialize))))
:slk-opts ,(when (assoc :slk serialize)
`(make-slk-opts ,@(cdr (assoc :slk serialize))))
:abstractp ,abstractp
:namespace (reverse *cpp-namespaces*)
;; Set inner types at the end. This works

View File

@ -169,21 +169,22 @@ cpp<#
#>cpp
explicit Tree(int uid) : uid_(uid) {}
cpp<#)
(:serialize :capnp :base t
:save-args '((saved-uids "std::vector<int32_t> *"))
:load-args '((storage "AstStorage *")
(loaded-uids "std::vector<int32_t> *"))
:post-save (lambda (builder)
(declare (ignore builder))
;; This is a bit hacky because it relies on the fact that parent class
;; serialization is inlined so we can short-circuit and avoid serializing
;; the derived class.
#>cpp
if (utils::Contains(*saved_uids, self.uid_)) {
return;
}
saved_uids->push_back(self.uid_);
cpp<#)))
(:serialize
(:capnp :base t
:save-args '((saved-uids "std::vector<int32_t> *"))
:load-args '((storage "AstStorage *")
(loaded-uids "std::vector<int32_t> *"))
:post-save (lambda (builder)
(declare (ignore builder))
;; This is a bit hacky because it relies on the fact that parent class
;; serialization is inlined so we can short-circuit and avoid serializing
;; the derived class.
#>cpp
if (utils::Contains(*saved_uids, self.uid_)) {
return;
}
saved_uids->push_back(self.uid_);
cpp<#))))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; Expressions
@ -212,7 +213,7 @@ cpp<#
#>cpp
friend class AstStorage;
cpp<#)
(:serialize :capnp :ignore-other-base-classes t))
(:serialize (:capnp :ignore-other-base-classes t)))
(lcp:define-class where (tree "::utils::Visitable<HierarchicalTreeVisitor>")
((expression "Expression *" :initval "nullptr" :scope :public
@ -245,7 +246,7 @@ cpp<#
#>cpp
friend class AstStorage;
cpp<#)
(:serialize :capnp :ignore-other-base-classes t))
(:serialize (:capnp :ignore-other-base-classes t)))
(lcp:define-class binary-operator (expression)
((expression1 "Expression *" :initval "nullptr" :scope :public
@ -273,7 +274,7 @@ cpp<#
#>cpp
friend class AstStorage;
cpp<#)
(:serialize :capnp))
(:serialize (:capnp)))
(lcp:define-class unary-operator (expression)
((expression "Expression *" :initval "nullptr" :scope :public
@ -297,7 +298,7 @@ cpp<#
#>cpp
friend class AstStorage;
cpp<#)
(:serialize :capnp))
(:serialize (:capnp)))
(macrolet ((define-binary-operators ()
`(lcp:cpp-list
@ -331,7 +332,7 @@ cpp<#
#>cpp
friend class AstStorage;
cpp<#)
(:serialize :capnp))))))
(:serialize (:capnp)))))))
(define-binary-operators))
(macrolet ((define-unary-operators ()
@ -363,7 +364,7 @@ cpp<#
#>cpp
friend class AstStorage;
cpp<#)
(:serialize :capnp))))))
(:serialize (:capnp)))))))
(define-unary-operators))
(lcp:define-class aggregation (binary-operator)
@ -371,7 +372,7 @@ cpp<#
(:public
(lcp:define-enum op
(count min max sum avg collect-list collect-map)
(:serialize :capnp))
(:serialize))
#>cpp
Aggregation() = default;
@ -425,7 +426,7 @@ cpp<#
#>cpp
friend class AstStorage;
cpp<#)
(:serialize :capnp))
(:serialize (:capnp)))
(lcp:define-class list-slicing-operator (expression)
((list "Expression *" :initval "nullptr" :scope :public
@ -479,7 +480,7 @@ cpp<#
#>cpp
friend class AstStorage;
cpp<#)
(:serialize :capnp))
(:serialize (:capnp)))
(lcp:define-class if-operator (expression)
((condition "Expression *" :scope :public
@ -528,7 +529,7 @@ cpp<#
#>cpp
friend class AstStorage;
cpp<#)
(:serialize :capnp))
(:serialize (:capnp)))
(lcp:define-class base-literal (expression)
()
@ -547,7 +548,7 @@ cpp<#
#>cpp
friend class AstStorage;
cpp<#)
(:serialize :capnp))
(:serialize (:capnp)))
(lcp:define-class primitive-literal (base-literal)
((value "PropertyValue" :scope :public
@ -586,7 +587,7 @@ cpp<#
PrimitiveLiteral(int uid, T value, int token_position)
: BaseLiteral(uid), value_(value), token_position_(token_position) {}
cpp<#)
(:serialize :capnp))
(:serialize (:capnp)))
(lcp:define-class list-literal (base-literal)
((elements "std::vector<Expression *>"
@ -626,7 +627,7 @@ cpp<#
#>cpp
friend class AstStorage;
cpp<#)
(:serialize :capnp))
(:serialize (:capnp)))
(lcp:define-class map-literal (base-literal)
((elements "std::unordered_map<std::pair<std::string, storage::Property>, Expression *>"
@ -667,7 +668,7 @@ cpp<#
#>cpp
friend class AstStorage;
cpp<#)
(:serialize :capnp))
(:serialize (:capnp)))
(lcp:define-class identifier (expression)
((name "std::string" :scope :public)
@ -694,7 +695,7 @@ cpp<#
#>cpp
friend class AstStorage;
cpp<#)
(:serialize :capnp))
(:serialize (:capnp)))
(lcp:define-class property-lookup (expression)
((expression "Expression *" :initval "nullptr" :scope :public
@ -740,7 +741,7 @@ cpp<#
#>cpp
friend class AstStorage;
cpp<#)
(:serialize :capnp))
(:serialize (:capnp)))
(lcp:define-class labels-test (expression)
((expression "Expression *" :initval "nullptr" :scope :public
@ -781,7 +782,7 @@ cpp<#
#>cpp
friend class AstStorage;
cpp<#)
(:serialize :capnp))
(:serialize (:capnp)))
(lcp:define-class function (expression)
((arguments "std::vector<Expression *>"
@ -837,7 +838,7 @@ cpp<#
#>cpp
friend class AstStorage;
cpp<#)
(:serialize :capnp))
(:serialize (:capnp)))
(lcp:define-class reduce (expression)
((accumulator "Identifier *" :initval "nullptr" :scope :public
@ -902,7 +903,7 @@ cpp<#
#>cpp
friend class AstStorage;
cpp<#)
(:serialize :capnp))
(:serialize (:capnp)))
(lcp:define-class coalesce (expression)
((expressions "std::vector<Expression *>"
@ -943,7 +944,7 @@ cpp<#
friend class AstStorage;
cpp<#)
(:serialize :capnp))
(:serialize (:capnp)))
(lcp:define-class extract (expression)
((identifier "Identifier *" :initval "nullptr" :scope :public
@ -994,7 +995,7 @@ cpp<#
#>cpp
friend class AstStorage;
cpp<#)
(:serialize :capnp))
(:serialize (:capnp)))
(lcp:define-class all (expression)
((identifier "Identifier *" :initval "nullptr" :scope :public
@ -1042,7 +1043,7 @@ cpp<#
#>cpp
friend class AstStorage;
cpp<#)
(:serialize :capnp))
(:serialize (:capnp)))
;; TODO: This is pretty much copy pasted from All. Consider merging Reduce,
;; All, Any and Single into something like a higher-order function call which
@ -1093,7 +1094,7 @@ cpp<#
#>cpp
friend class AstStorage;
cpp<#)
(:serialize :capnp))
(:serialize (:capnp)))
(lcp:define-class parameter-lookup (expression)
((token-position :int32_t :initval -1 :scope :public
@ -1120,7 +1121,7 @@ cpp<#
#>cpp
friend class AstStorage;
cpp<#)
(:serialize :capnp))
(:serialize (:capnp)))
(lcp:define-class named-expression (tree "::utils::Visitable<HierarchicalTreeVisitor>"
"::utils::Visitable<ExpressionVisitor<TypedValue>>"
@ -1171,7 +1172,7 @@ cpp<#
#>cpp
friend class AstStorage;
cpp<#)
(:serialize :capnp :ignore-other-base-classes t))
(:serialize (:capnp :ignore-other-base-classes t)))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; END Expressions
@ -1201,7 +1202,7 @@ cpp<#
#>cpp
friend class AstStorage;
cpp<#)
(:serialize :capnp :ignore-other-base-classes t))
(:serialize (:capnp :ignore-other-base-classes t)))
(lcp:define-class node-atom (pattern-atom)
((labels "std::vector<storage::Label>" :scope :public
@ -1247,7 +1248,7 @@ cpp<#
#>cpp
friend class AstStorage;
cpp<#)
(:serialize :capnp))
(:serialize (:capnp)))
(lcp:define-class edge-atom (pattern-atom)
((type "Type" :initval "Type::SINGLE" :scope :public)
@ -1286,10 +1287,10 @@ cpp<#
(:public
(lcp:define-enum type
(single depth-first breadth-first weighted-shortest-path)
(:serialize :capnp))
(:serialize))
(lcp:define-enum direction
(in out both)
(:serialize :capnp))
(:serialize))
(lcp:define-struct lambda ()
((inner-edge "Identifier *" :initval "nullptr"
:capnp-type "Tree" :capnp-init nil
@ -1307,10 +1308,10 @@ cpp<#
:capnp-load (load-ast-pointer "Expression *")
:documentation "Evaluates the result of the lambda."))
(:documentation "Lambda for use in filtering or weight calculation during variable expand.")
(:serialize :capnp
:save-args '((saved-uids "std::vector<int32_t> *"))
:load-args '((storage "AstStorage *")
(loaded-uids "std::vector<int32_t> *"))))
(:serialize (:capnp
:save-args '((saved-uids "std::vector<int32_t> *"))
:load-args '((storage "AstStorage *")
(loaded-uids "std::vector<int32_t> *")))))
#>cpp
bool Accept(HierarchicalTreeVisitor &visitor) override {
if (visitor.PreVisit(*this)) {
@ -1388,7 +1389,7 @@ cpp<#
return ptr ? ptr->Clone(storage) : nullptr;
}
cpp<#)
(:serialize :capnp))
(:serialize (:capnp)))
(lcp:define-class pattern (tree "::utils::Visitable<HierarchicalTreeVisitor>")
((identifier "Identifier *" :initval "nullptr" :scope :public
@ -1435,7 +1436,7 @@ cpp<#
#>cpp
friend class AstStorage;
cpp<#)
(:serialize :capnp :ignore-other-base-classes t))
(:serialize (:capnp :ignore-other-base-classes t)))
(lcp:define-class clause (tree "::utils::Visitable<HierarchicalTreeVisitor>")
()
@ -1456,7 +1457,7 @@ cpp<#
#>cpp
friend class AstStorage;
cpp<#)
(:serialize :capnp :ignore-other-base-classes t))
(:serialize (:capnp :ignore-other-base-classes t)))
(lcp:define-class single-query (tree "::utils::Visitable<HierarchicalTreeVisitor>")
((clauses "std::vector<Clause *>"
@ -1495,7 +1496,7 @@ cpp<#
#>cpp
friend class AstStorage;
cpp<#)
(:serialize :capnp :ignore-other-base-classes t))
(:serialize (:capnp :ignore-other-base-classes t)))
(lcp:define-class cypher-union (tree "::utils::Visitable<HierarchicalTreeVisitor>")
((single-query "SingleQuery *" :initval "nullptr" :scope :public
@ -1540,7 +1541,7 @@ cpp<#
#>cpp
friend class AstStorage;
cpp<#)
(:serialize :capnp :ignore-other-base-classes t))
(:serialize (:capnp :ignore-other-base-classes t)))
(lcp:define-class query (tree "::utils::Visitable<QueryVisitor<void>>")
()
@ -1561,7 +1562,7 @@ cpp<#
#>cpp
friend class AstStorage;
cpp<#)
(:serialize :capnp :ignore-other-base-classes t))
(:serialize (:capnp :ignore-other-base-classes t)))
(lcp:define-class cypher-query (query)
((single-query "SingleQuery *" :initval "nullptr" :scope :public
@ -1598,7 +1599,7 @@ cpp<#
#>cpp
friend class AstStorage;
cpp<#)
(:serialize :capnp))
(:serialize (:capnp)))
(lcp:define-class explain-query (query)
((cypher-query "CypherQuery *" :initval "nullptr" :scope :public
@ -1626,7 +1627,7 @@ cpp<#
#>cpp
friend class AstStorage;
cpp<#)
(:serialize :capnp))
(:serialize (:capnp)))
(lcp:define-class index-query (query)
((action "Action" :scope :public)
@ -1637,7 +1638,7 @@ cpp<#
(:public
(lcp:define-enum action
(create create-unique drop)
(:serialize :capnp))
(:serialize))
#>cpp
IndexQuery() = default;
@ -1659,7 +1660,7 @@ cpp<#
#>cpp
friend class AstStorage;
cpp<#)
(:serialize :capnp))
(:serialize (:capnp)))
(lcp:define-class create (clause)
((patterns "std::vector<Pattern *>"
@ -1698,7 +1699,7 @@ cpp<#
#>cpp
friend class AstStorage;
cpp<#)
(:serialize :capnp))
(:serialize (:capnp)))
(lcp:define-class match (clause)
((patterns "std::vector<Pattern *>"
@ -1751,12 +1752,12 @@ cpp<#
#>cpp
friend class AstStorage;
cpp<#)
(:serialize :capnp))
(:serialize (:capnp)))
(lcp:define-enum ordering
(asc desc)
(:documentation "Defines the order for sorting values (ascending or descending).")
(:serialize :capnp))
(:serialize))
(lcp:define-struct sort-item ()
((ordering "Ordering")
@ -1764,10 +1765,10 @@ cpp<#
:capnp-type "Tree" :capnp-init nil
:capnp-save #'save-ast-pointer
:capnp-load (load-ast-pointer "Expression *")))
(:serialize :capnp
:save-args '((saved-uids "std::vector<int32_t> *"))
:load-args '((storage "AstStorage *")
(loaded-uids "std::vector<int32_t> *"))))
(:serialize (:capnp
:save-args '((saved-uids "std::vector<int32_t> *"))
:load-args '((storage "AstStorage *")
(loaded-uids "std::vector<int32_t> *")))))
(lcp:define-struct return-body ()
((distinct :bool :initval "false"
@ -1806,10 +1807,10 @@ cpp<#
:capnp-load (load-ast-pointer "Expression *")
:documentation "Optional expression on how many results to produce."))
(:documentation "Contents common to @c Return and @c With clauses.")
(:serialize :capnp
:save-args '((saved-uids "std::vector<int32_t> *"))
:load-args '((storage "AstStorage *")
(loaded-uids "std::vector<int32_t> *"))))
(:serialize (:capnp
:save-args '((saved-uids "std::vector<int32_t> *"))
:load-args '((storage "AstStorage *")
(loaded-uids "std::vector<int32_t> *")))))
#>cpp
// Deep copy ReturnBody.
@ -1862,7 +1863,7 @@ cpp<#
#>cpp
friend class AstStorage;
cpp<#)
(:serialize :capnp))
(:serialize (:capnp)))
(lcp:define-class with (clause)
((body "ReturnBody" :scope :public)
@ -1915,7 +1916,7 @@ cpp<#
#>cpp
friend class AstStorage;
cpp<#)
(:serialize :capnp))
(:serialize (:capnp)))
(lcp:define-class delete (clause)
((expressions "std::vector<Expression *>"
@ -1956,7 +1957,7 @@ cpp<#
#>cpp
friend class AstStorage;
cpp<#)
(:serialize :capnp))
(:serialize (:capnp)))
(lcp:define-class set-property (clause)
((property-lookup "PropertyLookup *" :initval "nullptr" :scope :public
@ -1995,7 +1996,7 @@ cpp<#
#>cpp
friend class AstStorage;
cpp<#)
(:serialize :capnp))
(:serialize (:capnp)))
(lcp:define-class set-properties (clause)
((identifier "Identifier *" :initval "nullptr" :scope :public
@ -2037,7 +2038,7 @@ cpp<#
#>cpp
friend class AstStorage;
cpp<#)
(:serialize :capnp))
(:serialize (:capnp)))
(lcp:define-class set-labels (clause)
((identifier "Identifier *" :initval "nullptr" :scope :public
@ -2077,7 +2078,7 @@ cpp<#
#>cpp
friend class AstStorage;
cpp<#)
(:serialize :capnp))
(:serialize (:capnp)))
(lcp:define-class remove-property (clause)
((property-lookup "PropertyLookup *" :initval "nullptr" :scope :public
@ -2109,7 +2110,7 @@ cpp<#
#>cpp
friend class AstStorage;
cpp<#)
(:serialize :capnp))
(:serialize (:capnp)))
(lcp:define-class remove-labels (clause)
((identifier "Identifier *" :initval "nullptr" :scope :public
@ -2149,7 +2150,7 @@ cpp<#
#>cpp
friend class AstStorage;
cpp<#)
(:serialize :capnp))
(:serialize (:capnp)))
(lcp:define-class merge (clause)
((pattern "Pattern *" :initval "nullptr" :scope :public
@ -2219,7 +2220,7 @@ cpp<#
#>cpp
friend class AstStorage;
cpp<#)
(:serialize :capnp))
(:serialize (:capnp)))
(lcp:define-class unwind (clause)
((named-expression "NamedExpression *" :initval "nullptr" :scope :public
@ -2255,7 +2256,7 @@ cpp<#
#>cpp
friend class AstStorage;
cpp<#)
(:serialize :capnp))
(:serialize (:capnp)))
(lcp:define-class auth-query (query)
((action "Action" :scope :public)
@ -2274,10 +2275,10 @@ cpp<#
clear-role grant-privilege deny-privilege
revoke-privilege show-privileges
show-role-for-user show-users-for-role)
(:serialize :capnp))
(:serialize))
(lcp:define-enum privilege
(create delete match merge set remove index auth stream)
(:serialize :capnp))
(:serialize))
#>cpp
AuthQuery() = default;
@ -2308,7 +2309,7 @@ cpp<#
#>cpp
friend class AstStorage;
cpp<#)
(:serialize :capnp))
(:serialize (:capnp)))
#>cpp
// Constant that holds all available privileges.
@ -2350,7 +2351,7 @@ cpp<#
(:public
(lcp:define-enum action (create-stream drop-stream show-streams start-stream
stop-stream start-all-streams stop-all-streams test-stream)
(:serialize :capnp))
(:serialize))
#>cpp
StreamQuery() = default;
@ -2393,7 +2394,7 @@ cpp<#
#>cpp
friend class AstStorage;
cpp<#)
(:serialize :capnp))
(:serialize (:capnp)))
#>cpp
#undef CLONE_BINARY_EXPRESSION

View File

@ -20,7 +20,7 @@ cpp<#
;; This is similar to TypedValue::Type, but this has `Any` type.
;; TODO: Make a better Type structure which can store a generic List.
(lcp:define-enum type (any vertex edge path number edge-list)
(:serialize :capnp))
(:serialize))
#>cpp
// TODO: Generate enum to string conversion from LCP. Note, that this is
// displayed to the end user, so we may want to have a pretty name of each
@ -53,7 +53,7 @@ cpp<#
bool user_declared() const { return user_declared_; }
int token_position() const { return token_position_; }
cpp<#)
(:serialize :capnp))
(:serialize (:capnp)))
(lcp:pop-namespace) ;; query

View File

@ -82,7 +82,7 @@ time on data transfer. It gives no guarantees on result order.")
input_ = input;
}
cpp<#)
(:serialize :capnp))
(:serialize (:capnp)))
(defun load-pull-remote (reader member-name capnp-name)
(declare (ignore capnp-name))
@ -147,7 +147,7 @@ Logic of the synchronize operator is:
input_ = input;
}
cpp<#)
(:serialize :capnp))
(:serialize (:capnp)))
(lcp:define-class pull-remote-order-by (logical-operator)
((input "std::shared_ptr<LogicalOperator>" :scope :public
@ -188,7 +188,7 @@ by having only one result from each worker.")
input_ = input;
}
cpp<#)
(:serialize :capnp))
(:serialize (:capnp)))
(lcp:define-class distributed-expand (logical-operator)
((input "std::shared_ptr<LogicalOperator>" :scope :public
@ -219,7 +219,7 @@ by having only one result from each worker.")
input_ = input;
}
cpp<#)
(:serialize :capnp))
(:serialize (:capnp)))
(lcp:define-class distributed-expand-bfs (logical-operator)
((input "std::shared_ptr<LogicalOperator>" :scope :public
@ -275,7 +275,7 @@ by having only one result from each worker.")
input_ = input;
}
cpp<#)
(:serialize :capnp))
(:serialize (:capnp)))
(lcp:define-class distributed-create-node (logical-operator)
((input "std::shared_ptr<LogicalOperator>" :scope :public
@ -303,7 +303,7 @@ by having only one result from each worker.")
input_ = input;
}
cpp<#)
(:serialize :capnp))
(:serialize (:capnp)))
(lcp:define-class distributed-create-expand (logical-operator)
((node-atom "NodeAtom *" :scope :public
@ -335,7 +335,7 @@ by having only one result from each worker.")
input_ = input;
}
cpp<#)
(:serialize :capnp))
(:serialize (:capnp)))
(lcp:pop-namespace)
(lcp:pop-namespace)

View File

@ -217,9 +217,10 @@ can serve as inputs to others and thus a sequence of operations is formed.")
loaded_ops;
};
cpp<#)
(:serialize :capnp :base t
:save-args '((helper "LogicalOperator::SaveHelper *"))
:load-args '((helper "LogicalOperator::LoadHelper *"))))
(:serialize
(:capnp :base t
:save-args '((helper "LogicalOperator::SaveHelper *"))
:load-args '((helper "LogicalOperator::LoadHelper *")))))
(defun save-ast-pointer (builder member capnp-name)
#>cpp
@ -308,7 +309,7 @@ and false on every following Pull.")
bool did_pull_{false};
};
cpp<#)
(:serialize :capnp))
(:serialize (:capnp)))
(lcp:define-class create-node (logical-operator)
((input "std::shared_ptr<LogicalOperator>" :scope :public
@ -364,7 +365,7 @@ a preceeding `MATCH`), or multiple nodes (`MATCH ... CREATE` or
const std::unique_ptr<Cursor> input_cursor_;
};
cpp<#)
(:serialize :capnp))
(:serialize (:capnp)))
(lcp:define-class create-expand (logical-operator)
(
@ -456,7 +457,7 @@ chained in cases when longer paths need creating.
ExpressionEvaluator &evaluator);
};
cpp<#)
(:serialize :capnp))
(:serialize (:capnp)))
(lcp:define-class scan-all (logical-operator)
((input "std::shared_ptr<LogicalOperator>" :scope :public
@ -508,7 +509,7 @@ with a constructor argument.
input_ = input;
}
cpp<#)
(:serialize :capnp))
(:serialize (:capnp)))
(lcp:define-class scan-all-by-label (scan-all)
((label "storage::Label" :scope :public))
@ -529,7 +530,7 @@ given label.
std::unique_ptr<Cursor> MakeCursor(
database::GraphDbAccessor &db) const override;
cpp<#)
(:serialize :capnp))
(:serialize (:capnp)))
(defun save-optional-bound (builder member capnp-name)
(let ((save-bound
@ -607,7 +608,7 @@ property value which is inside a range (inclusive or exlusive).
std::unique_ptr<Cursor> MakeCursor(
database::GraphDbAccessor &db) const override;
cpp<#)
(:serialize :capnp))
(:serialize (:capnp)))
(lcp:define-class scan-all-by-label-property-value (scan-all)
((label "storage::Label" :scope :public)
@ -645,7 +646,7 @@ property value.
std::unique_ptr<Cursor> MakeCursor(
database::GraphDbAccessor &db) const override;
cpp<#)
(:serialize :capnp))
(:serialize (:capnp)))
(lcp:define-struct expand-common ()
(
@ -686,9 +687,9 @@ that has already been expanded and should be just validated in the frame.")
'(old new))
:documentation
"State from which the input node should get expanded."))
(:serialize :capnp
:save-args '((helper "LogicalOperator::SaveHelper *"))
:load-args '((helper "LogicalOperator::LoadHelper *"))))
(:serialize (:capnp
:save-args '((helper "LogicalOperator::SaveHelper *"))
:load-args '((helper "LogicalOperator::LoadHelper *")))))
(lcp:define-class expand (logical-operator)
((input "std::shared_ptr<LogicalOperator>" :scope :public
@ -766,7 +767,7 @@ pulled.")
bool InitEdges(Frame &, Context &);
};
cpp<#)
(:serialize :capnp))
(:serialize (:capnp)))
(lcp:define-struct expansion-lambda ()
((inner-edge-symbol "Symbol" :documentation "Currently expanded edge symbol.")
@ -789,10 +790,10 @@ pulled.")
${member} = nullptr;
}
cpp<#)))
(:serialize :capnp
:save-args '((saved-ast-uids "std::vector<int> *"))
:load-args '((ast-storage "AstStorage *")
(loaded-ast-uids "std::vector<int> *"))))
(:serialize (:capnp
:save-args '((saved-ast-uids "std::vector<int> *"))
:load-args '((ast-storage "AstStorage *")
(loaded-ast-uids "std::vector<int> *")))))
(lcp:define-class expand-variable (logical-operator)
((input "std::shared_ptr<LogicalOperator>" :scope :public
@ -919,7 +920,7 @@ pulled.")
friend class ExpandVariableCursor;
friend class ExpandWeightedShortestPathCursor;
cpp<#)
(:serialize :capnp))
(:serialize (:capnp)))
(lcp:define-class construct-named-path (logical-operator)
((input "std::shared_ptr<LogicalOperator>" :scope :public
@ -951,7 +952,7 @@ pulled.")
input_ = input;
}
cpp<#)
(:serialize :capnp))
(:serialize (:capnp)))
(lcp:define-class filter (logical-operator)
((input "std::shared_ptr<LogicalOperator>" :scope :public
@ -997,7 +998,7 @@ a boolean value.")
const std::unique_ptr<Cursor> input_cursor_;
};
cpp<#)
(:serialize :capnp))
(:serialize (:capnp)))
(lcp:define-class produce (logical-operator)
((input "std::shared_ptr<LogicalOperator>" :scope :public
@ -1049,7 +1050,7 @@ RETURN clause) the Produce's pull succeeds exactly once.")
const std::unique_ptr<Cursor> input_cursor_;
};
cpp<#)
(:serialize :capnp))
(:serialize (:capnp)))
(lcp:define-class delete (logical-operator)
((input "std::shared_ptr<LogicalOperator>" :scope :public
@ -1098,7 +1099,7 @@ Has a flag for using DETACH DELETE when deleting vertices.")
const std::unique_ptr<Cursor> input_cursor_;
};
cpp<#)
(:serialize :capnp))
(:serialize (:capnp)))
(lcp:define-class set-property (logical-operator)
((input "std::shared_ptr<LogicalOperator>" :scope :public
@ -1146,7 +1147,7 @@ can be stored (a TypedValue that can be converted to PropertyValue).")
const std::unique_ptr<Cursor> input_cursor_;
};
cpp<#)
(:serialize :capnp))
(:serialize (:capnp)))
(lcp:define-class set-properties (logical-operator)
((input "std::shared_ptr<LogicalOperator>" :scope :public
@ -1173,7 +1174,7 @@ updating.")
@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
that the old props are discarded and replaced with new ones.")
(:serialize :capnp))
(:serialize))
#>cpp
SetProperties() {}
@ -1215,7 +1216,7 @@ that the old props are discarded and replaced with new ones.")
void Set(TRecordAccessor &record, const TypedValue &rhs) const;
};
cpp<#)
(:serialize :capnp))
(:serialize (:capnp)))
(lcp:define-class set-labels (logical-operator)
((input "std::shared_ptr<LogicalOperator>" :scope :public
@ -1260,7 +1261,7 @@ It does NOT remove labels that are already set on that Vertex.")
const std::unique_ptr<Cursor> input_cursor_;
};
cpp<#)
(:serialize :capnp))
(:serialize (:capnp)))
(lcp:define-class remove-property (logical-operator)
((input "std::shared_ptr<LogicalOperator>" :scope :public
@ -1303,7 +1304,7 @@ It does NOT remove labels that are already set on that Vertex.")
const std::unique_ptr<Cursor> input_cursor_;
};
cpp<#)
(:serialize :capnp))
(:serialize (:capnp)))
(lcp:define-class remove-labels (logical-operator)
((input "std::shared_ptr<LogicalOperator>" :scope :public
@ -1348,7 +1349,7 @@ If a label does not exist on a Vertex, nothing happens.")
const std::unique_ptr<Cursor> input_cursor_;
};
cpp<#)
(:serialize :capnp))
(:serialize (:capnp)))
(lcp:define-class edge-uniqueness-filter (logical-operator)
((input "std::shared_ptr<LogicalOperator>" :scope :public
@ -1405,7 +1406,7 @@ edge lists).")
const std::unique_ptr<Cursor> input_cursor_;
};
cpp<#)
(:serialize :capnp))
(:serialize (:capnp)))
(lcp:define-class accumulate (logical-operator)
((input "std::shared_ptr<LogicalOperator>" :scope :public
@ -1477,7 +1478,7 @@ has been cached will be reconstructed before Pull returns.
bool pulled_all_input_{false};
};
cpp<#)
(:serialize :capnp))
(:serialize (:capnp)))
#>cpp
/**
@ -1540,9 +1541,9 @@ elements are in an undefined state after aggregation.")
"An aggregation element, contains:
(input data expression, key expression - only used in COLLECT_MAP, type of
aggregation, output symbol).")
(:serialize :capnp
:save-args '((helper "LogicalOperator::SaveHelper *"))
:load-args '((helper "LogicalOperator::LoadHelper *"))))
(:serialize (:capnp
:save-args '((helper "LogicalOperator::SaveHelper *"))
:load-args '((helper "LogicalOperator::LoadHelper *")))))
#>cpp
Aggregate() = default;
Aggregate(const std::shared_ptr<LogicalOperator> &input,
@ -1642,7 +1643,7 @@ elements are in an undefined state after aggregation.")
void EnsureOkForAvgSum(const TypedValue &value) const;
};
cpp<#)
(:serialize :capnp))
(:serialize (:capnp)))
(lcp:define-class skip (logical-operator)
((input "std::shared_ptr<LogicalOperator>" :scope :public
@ -1698,7 +1699,7 @@ operator's implementation does not expect this.")
int skipped_{0};
};
cpp<#)
(:serialize :capnp))
(:serialize (:capnp)))
(lcp:define-class limit (logical-operator)
((input "std::shared_ptr<LogicalOperator>" :scope :public
@ -1757,7 +1758,7 @@ input should be performed).")
int pulled_{0};
};
cpp<#)
(:serialize :capnp))
(:serialize (:capnp)))
(lcp:define-class order-by (logical-operator)
((input "std::shared_ptr<LogicalOperator>" :scope :public
@ -1825,7 +1826,7 @@ are valid for usage after the OrderBy operator.")
decltype(cache_.begin()) cache_it_ = cache_.begin();
};
cpp<#)
(:serialize :capnp))
(:serialize (:capnp)))
(lcp:define-class merge (logical-operator)
((input "std::shared_ptr<LogicalOperator>" :scope :public
@ -1892,7 +1893,7 @@ documentation.")
bool pull_input_{true};
};
cpp<#)
(:serialize :capnp))
(:serialize (:capnp)))
(lcp:define-class optional (logical-operator)
((input "std::shared_ptr<LogicalOperator>" :scope :public
@ -1950,7 +1951,7 @@ and returns true, once.")
bool pull_input_{true};
};
cpp<#)
(:serialize :capnp))
(:serialize (:capnp)))
(lcp:define-class unwind (logical-operator)
((input "std::shared_ptr<LogicalOperator>" :scope :public
@ -2003,7 +2004,7 @@ Input is optional (unwind can be the first clause in a query).")
std::vector<TypedValue>::iterator input_value_it_ = input_value_.end();
};
cpp<#)
(:serialize :capnp))
(:serialize (:capnp)))
(lcp:define-class distinct (logical-operator)
((input "std::shared_ptr<LogicalOperator>" :scope :public
@ -2060,7 +2061,7 @@ This implementation maintains input ordering.")
seen_rows_;
};
cpp<#)
(:serialize :capnp))
(:serialize (:capnp)))
(lcp:define-class union (logical-operator)
((left-op "std::shared_ptr<LogicalOperator>" :scope :public
@ -2117,7 +2118,7 @@ vectors of symbols used by each of the inputs.")
const std::unique_ptr<Cursor> left_cursor_, right_cursor_;
};
cpp<#)
(:serialize :capnp))
(:serialize (:capnp)))
;; TODO: We should probably output this operator in regular planner, not just
;; distributed planner.
@ -2158,7 +2159,7 @@ vectors of symbols used by each of the inputs.")
std::shared_ptr<LogicalOperator> input() const override;
void set_input(std::shared_ptr<LogicalOperator>) override;
cpp<#)
(:serialize :capnp))
(:serialize (:capnp)))
(lcp:define-class output-table (logical-operator)
((output-symbols "std::vector<Symbol>" :scope :public :dont-save t)
@ -2190,7 +2191,7 @@ vectors of symbols used by each of the inputs.")
std::shared_ptr<LogicalOperator> input() const override;
void set_input(std::shared_ptr<LogicalOperator> input) override;
cpp<#)
(:serialize :capnp))
(:serialize (:capnp)))
(lcp:pop-namespace) ;; plan
(lcp:pop-namespace) ;; query

View File

@ -14,6 +14,6 @@ cpp<#
(lcp:define-struct log-entry ()
((deltas "std::vector<database::StateDelta>" :capnp-type "List(Database.StateDelta)"))
(:serialize :capnp))
(:serialize (:capnp)))
(lcp:pop-namespace) ;; raft

View File

@ -24,7 +24,7 @@ cpp<#
:capnp-init nil
:capnp-save #'save-snapshot
:capnp-load #'load-snapshot))
(:serialize :capnp))
(:serialize (:capnp)))
(lcp:define-rpc begin
(:request ())