Convert AST to LCP

Reviewers: teon.banek, llugovic

Reviewed By: teon.banek

Subscribers: pullbot

Differential Revision: https://phabricator.memgraph.io/D1628
This commit is contained in:
Marin Tomic 2018-10-04 11:57:23 +02:00
parent ed335e38ff
commit db52b35ab6
24 changed files with 2717 additions and 6050 deletions

2
.gitignore vendored
View File

@ -66,6 +66,8 @@ src/distributed/token_sharing_rpc_messages.capnp
src/distributed/token_sharing_rpc_messages.hpp
src/distributed/updates_rpc_messages.capnp
src/distributed/updates_rpc_messages.hpp
src/query/frontend/ast/ast.capnp
src/query/frontend/ast/ast.hpp
src/query/plan/distributed_ops.capnp
src/query/plan/distributed_ops.hpp
src/query/plan/operator.hpp

View File

@ -117,6 +117,8 @@ add_capnp(distributed/dynamic_worker_rpc_messages.capnp)
# distributed_ops.lcp is leading the capnp code generation, so we don't need
# to generate any capnp for operator.lcp
add_lcp(query/frontend/ast/ast.lcp CAPNP_SCHEMA @0xb107d3d6b4b1600b)
add_capnp(query/frontend/ast/ast.capnp)
add_lcp(query/plan/operator.lcp)
add_lcp(query/plan/distributed_ops.lcp CAPNP_SCHEMA @0xe5cae8d045d30c42
DEPENDS query/plan/operator.lcp)
@ -134,7 +136,6 @@ add_custom_target(generate_lcp DEPENDS ${generated_lcp_files})
add_capnp(communication/rpc/messages.capnp)
add_capnp(durability/recovery.capnp)
add_capnp(query/frontend/ast/ast.capnp)
add_capnp(query/frontend/semantic/symbol.capnp)
add_capnp(query/serialization.capnp)
add_capnp(storage/serialization.capnp)

View File

@ -272,6 +272,7 @@ produces:
;; Extra arguments to the generated save function. List of (name cpp-type).
(save-args nil :read-only t)
(load-args nil :read-only t)
(construct nil :read-only t)
;; Explicit instantiation of template to generate schema with enum.
(type-args nil :read-only t)
;; In case of multiple inheritance, list of classes which should be handled
@ -291,7 +292,8 @@ produces:
(private :initarg :private :initform nil :accessor cpp-class-private)
(capnp-opts :type (or null capnp-opts) :initarg :capnp-opts :initform nil
:reader cpp-class-capnp-opts)
(inner-types :initarg :inner-types :initform nil :reader cpp-class-inner-types))
(inner-types :initarg :inner-types :initform nil :reader cpp-class-inner-types)
(abstractp :initarg :abstractp :initform nil :reader cpp-class-abstractp))
(:documentation "Meta information on a C++ class (or struct)."))
(defvar *cpp-classes* nil "List of defined classes from LCP file")
@ -759,7 +761,7 @@ encoded as union inheritance in Cap'n Proto."
(write-line (capnp-schema inner) s)))
(when union-subclasses
(with-cpp-block-output (s :name "union")
(when union-parents
(when (not (cpp-class-abstractp cpp-class))
;; Allow instantiating classes in the middle of inheritance
;; hierarchy.
(format s " ~A @~A :Void;~%"
@ -935,7 +937,7 @@ Proto schema."
(format nil "Save(~A, &~A~{, ~A~});"
member-name member-builder extra-args))))))
(defun capnp-save-members (cpp-class &key instance-access)
(defun capnp-save-members (cpp-class builder &key instance-access)
"Generate Cap'n Proto saving code for members of CPP-CLASS. INSTANCE-ACCESS
is a C++ string which is prefixed to member access. For example,
INSTANCE-ACCESS could be `my_struct->`"
@ -954,7 +956,7 @@ Proto schema."
(cond
((and (not (cpp-member-capnp-save member))
(capnp-primitive-type-p (capnp-type-of-member member)))
(format s " builder->set~A(~A);~%" capnp-name member-access))
(format s " ~A->set~A(~A);~%" builder capnp-name member-access))
(t
;; Enclose larger save code in new scope
(with-cpp-block-output (s)
@ -965,9 +967,9 @@ Proto schema."
"")))
(if (and (cpp-member-capnp-init member)
(not (find-cpp-enum (cpp-member-type member))))
(format s " auto ~A = builder->init~A(~A);~%"
member-builder capnp-name size)
(setf member-builder "builder")))
(format s " auto ~A = ~A->init~A(~A);~%"
member-builder builder capnp-name size)
(setf member-builder builder)))
(if (cpp-member-capnp-save member)
(format s " ~A~%"
(cpp-code (funcall (cpp-member-capnp-save member)
@ -976,84 +978,60 @@ Proto schema."
member-builder capnp-name)
s))))))))))
(defun capnp-save-parents (cpp-class save-parent)
"Generate Cap'n Proto code for serializing parent classes of CPP-CLASS.
SAVE-PARENT is a function which generates the code for serializing a parent.
It takes a parent class symbol."
(declare (type cpp-class cpp-class))
(declare (type (function (symbol) string) save-parent))
(multiple-value-bind (direct-union-parents compose-parents)
(capnp-union-and-compose-parents cpp-class)
(declare (ignore direct-union-parents))
;; Handle the union inheritance calls first.
(with-output-to-string (s)
(let ((parents (capnp-union-parents-rec cpp-class)))
(when parents
(let ((first-parent (first parents)))
(write-line (funcall save-parent first-parent) s))
(if (or compose-parents (cpp-class-members cpp-class))
(progn
(format s " auto ~A_builder = base_builder->~{get~A().~}init~A();~%"
(cpp-variable-name (cpp-type-base-name cpp-class))
(mapcar #'cpp-type-name (cdr (reverse parents)))
(cpp-type-name cpp-class))
(format s " auto *builder = &~A_builder;~%"
(cpp-variable-name (cpp-type-base-name cpp-class))))
(format s " base_builder->~{get~A().~}init~A();~%"
(mapcar #'cpp-type-name (cdr (reverse parents)))
(cpp-type-name cpp-class)))
(when (capnp-union-subclasses cpp-class)
;; We are in the middle of inheritance hierarchy, so set our
;; union Void field.
(format s " builder->set~A();" (cpp-type-name cpp-class)))))
;; Now handle composite inheritance calls.
(dolist (parent compose-parents)
(with-cpp-block-output (s)
(let* ((builder (format nil "~A_builder" (cpp-variable-name parent))))
(format s " auto ~A = builder->init~A();~%" builder (cpp-type-name parent))
(format s " auto *builder = &~A;~%" builder)
(write-line (funcall save-parent parent) s)))))))
(defun capnp-save-function-code (cpp-class)
"Generate Cap'n Proto save code for CPP-CLASS."
(declare (type cpp-class cpp-class))
(labels ((save-class (cpp-class cpp-out)
"Output the serialization code for members of this and parent class."
(write-line (capnp-save-parents cpp-class #'save-parent) cpp-out)
;; Set the template instantiations
(when (and (capnp-opts-type-args (cpp-class-capnp-opts cpp-class))
(/= 1 (list-length (cpp-type-type-params cpp-class))))
(error "Don't know how to save templated class ~A" (cpp-type-base-name cpp-class)))
(let ((type-param (first (mapcar #'cpp-type-name (cpp-type-type-params cpp-class)))))
(dolist (type-arg (mapcar #'cpp-type-name
(capnp-opts-type-args (cpp-class-capnp-opts cpp-class))))
(write-string
(raw-cpp-string
#>cpp
if (std::is_same<${type-arg}, ${type-param}>::value) {
builder->set${type-arg}();
}
cpp<#)
cpp-out)))
(write-line (capnp-save-members cpp-class :instance-access "self.") cpp-out))
(save-parent (parent)
"Generate serialization code for parent class."
(let ((cpp-class (find-cpp-class parent)))
(with-output-to-string (s)
(with-cpp-block-output (s)
(format s "// Save base class ~A~%" (cpp-type-name parent))
(save-class cpp-class s))))))
(labels ((save-class (cpp-class builder cpp-out &key (force-builder nil))
"Output the serialization code for CPP-CLASS and its parent classes."
(let* ((compose-parents (nth-value 1 (capnp-union-and-compose-parents cpp-class)))
(parents (capnp-union-parents-rec cpp-class))
(first-parent (find-cpp-class (first parents))))
(when first-parent
(with-cpp-block-output (cpp-out)
(format cpp-out "// Save parent class ~A~%" (cpp-type-name first-parent))
(save-class first-parent builder cpp-out)))
;; Initialize CPP-CLASS builder
(when parents
(if (or force-builder compose-parents (cpp-class-members cpp-class))
(progn
(format cpp-out "auto ~A_builder = ~A->~{get~A().~}init~A();~%"
(cpp-variable-name (cpp-type-base-name cpp-class))
builder
(mapcar #'cpp-type-name (cdr (reverse parents)))
(cpp-type-name cpp-class))
(format cpp-out "auto *builder = &~A_builder;~%"
(cpp-variable-name (cpp-type-base-name cpp-class)))
(setf builder "builder"))
(format cpp-out "~A->~{get~A().~}init~A();~%"
builder
(mapcar #'cpp-type-name (cdr (reverse parents)))
(cpp-type-name cpp-class))))
;; Save composed parent classes
(dolist (parent compose-parents)
(with-cpp-block-output (cpp-out)
(let* ((parent-builder (format nil "~A_builder" (cpp-variable-name parent))))
(format cpp-out "// Save composed class ~A~%" (cpp-type-name parent))
(format cpp-out "auto ~A = ~A->init~A();~%"
parent-builder builder (cpp-type-name parent))
(format cpp-out "Save(self, &~A~{, ~A~});"
parent-builder
(mapcar (lambda (name-and-type)
(cpp-variable-name (first name-and-type)))
(capnp-extra-args (find-cpp-class parent) :save))))))
;; Save members
(write-string (capnp-save-members cpp-class builder :instance-access "self.") cpp-out))))
(with-output-to-string (cpp-out)
(let ((subclasses (direct-subclasses-of cpp-class)))
(let ((subclasses (capnp-union-subclasses cpp-class))
(builder (if (capnp-union-parents-rec cpp-class)
"base_builder"
"builder")))
(when subclasses
(write-line "// Forward serialization to most derived type" cpp-out)
(dolist (subclass subclasses)
(let ((derived-name (cpp-type-name subclass))
(save-args
(format nil "~A~{, ~A~}"
(if (capnp-union-parents-rec cpp-class)
"base_builder"
"builder")
builder
(mapcar (lambda (name-and-type)
(cpp-variable-name (first name-and-type)))
(capnp-extra-args cpp-class :save))))
@ -1077,8 +1055,18 @@ It takes a parent class symbol."
return Save(*derived, ${save-args});
}
cpp<#)
cpp-out))))))
(save-class cpp-class cpp-out))))
cpp-out)))))
(cond
((cpp-class-abstractp cpp-class)
(format cpp-out
"LOG(FATAL) << \"Should not get here -- `~A` should be an abstract class!\";"
(cpp-type-name cpp-class)))
((capnp-union-subclasses cpp-class)
;; We are in the middle of inheritance hierarchy, so set our
;; union Void field.
(save-class cpp-class builder cpp-out :force-builder t)
(format cpp-out "builder->set~A();~%" (cpp-type-name cpp-class)))
(t (save-class cpp-class builder cpp-out)))))))
(defun capnp-save-function-definition (cpp-class)
"Generate Cap'n Proto save function."
@ -1124,7 +1112,7 @@ It takes a parent class symbol."
'reader)
(format nil "const capnp::~A::Reader &" top-parent-class)))
(out-arg (list 'self
(if (or parents (direct-subclasses-of cpp-class))
(if (or parents (capnp-union-subclasses cpp-class))
(format nil "std::unique_ptr<~A> *" (cpp-type-decl cpp-class :namespace nil))
(format nil "~A *" (cpp-type-decl cpp-class :namespace nil))))))
(cpp-function-declaration
@ -1178,7 +1166,7 @@ reader variable. CAPNP-NAME is the name of the member in Cap'n Proto schema."
(format nil "Load(&~A, ~A~{, ~A~});"
member-name member-reader extra-args))))))
(defun capnp-load-members (cpp-class &key instance-access)
(defun capnp-load-members (cpp-class reader &key instance-access)
"Generate Cap'n Proto loading code for members of CPP-CLASS.
INSTANCE-ACCESS is a C++ string which will be prefixed to member access. For
example, INSTANCE-ACCESS could be `my_struct->`"
@ -1196,14 +1184,14 @@ example, INSTANCE-ACCESS could be `my_struct->`"
(cond
((and (not (cpp-member-capnp-load member))
(capnp-primitive-type-p (capnp-type-of-member member)))
(format s " ~A = reader.get~A();~%" member-access capnp-name))
(format s " ~A = ~A.get~A();~%" member-access reader capnp-name))
(t
;; Enclose larger load code in new scope
(with-cpp-block-output (s)
(if (and (cpp-member-capnp-init member)
(not (find-cpp-enum (cpp-member-type member))))
(format s " auto ~A = reader.get~A();~%" member-reader capnp-name)
(setf member-reader "reader"))
(format s " auto ~A = ~A.get~A();~%" member-reader reader capnp-name)
(setf member-reader reader))
(if (cpp-member-capnp-load member)
(format s " ~A~%"
(cpp-code (funcall (cpp-member-capnp-load member)
@ -1212,56 +1200,56 @@ example, INSTANCE-ACCESS could be `my_struct->`"
(cpp-member-type member)
member-reader capnp-name) s))))))))))
(defun capnp-load-parents (cpp-class load-parent)
"Generate Cap'n Proto code for loading parent classes of CPP-CLASS.
LOAD-PARENT is a function which generates the code for loading parent members.
It takes a parent class symbol."
(declare (type cpp-class cpp-class))
(declare (type (function (symbol) string) load-parent))
(with-output-to-string (s)
(multiple-value-bind (direct-union-parents compose-parents)
(capnp-union-and-compose-parents cpp-class)
(declare (ignore direct-union-parents))
;; Handle the union inheritance calls first.
(let ((parents (capnp-union-parents-rec cpp-class)))
(when parents
(let ((first-parent (first parents)))
(write-line (funcall load-parent first-parent) s))
(when (or compose-parents (cpp-class-members cpp-class))
(format s " auto reader = base_reader.~{get~A().~}get~A();~%"
(mapcar #'cpp-type-name (cdr (reverse parents)))
(cpp-type-name cpp-class)))
;; Now handle composite inheritance calls.
(dolist (parent compose-parents)
(with-cpp-block-output (s)
(let ((reader (format nil "~A_reader" (cpp-variable-name parent))))
(format s " auto ~A = reader.get~A();~%" reader (cpp-type-name parent))
(format s " const auto &reader = ~A;" reader)
(write-line (funcall load-parent parent) s)))))))))
(defun capnp-load-function-code (cpp-class)
"Generate Cap'n Proto loadd code for CPP-CLASS."
"Generate Cap'n Proto load code for CPP-CLASS."
(declare (type cpp-class cpp-class))
(let ((instance-access (if (or (direct-subclasses-of cpp-class)
(let ((instance-access (if (or (capnp-union-subclasses cpp-class)
(capnp-union-parents-rec cpp-class))
"self->get()->"
"self->")))
(labels ((load-class (cpp-class)
(with-output-to-string (s)
(write-line (capnp-load-parents cpp-class #'load-parent) s)
(write-line (capnp-load-members cpp-class :instance-access instance-access) s)))
(load-parent (parent)
(with-output-to-string (s)
(with-cpp-block-output (s)
(format s "// Load base class ~A~%" (cpp-type-name parent))
(write-line (load-class (find-cpp-class parent)) s)))))
(labels ((load-class (cpp-class reader cpp-out)
(let* ((compose-parents (nth-value 1 (capnp-union-and-compose-parents cpp-class)))
(parents (capnp-union-parents-rec cpp-class))
(first-parent (find-cpp-class (first parents))))
(when first-parent
(with-cpp-block-output (cpp-out)
(format cpp-out "// Load parent class ~A~%" (cpp-type-name first-parent))
(load-class first-parent reader cpp-out)))
;; Initialize CPP-CLASS reader
(when (and parents (or compose-parents (cpp-class-members cpp-class)))
(progn
(format cpp-out "auto reader = ~A.~{get~A().~}get~A();"
reader
(mapcar #'cpp-type-name (cdr (reverse parents)))
(cpp-type-name cpp-class))
(setf reader "reader")))
;; Load composed parent classes
(dolist (parent compose-parents)
(with-cpp-block-output (cpp-out)
(let ((parent-reader (format nil "~A_reader" (cpp-variable-name parent))))
(format cpp-out "// Load composed class ~A~%" (cpp-type-name parent))
(format cpp-out "auto ~A = ~A.get~A();~%"
parent-reader reader (cpp-type-name parent))
(format cpp-out "Load(self->get(), ~A~{, ~A~});~%"
parent-reader
(mapcar (lambda (name-and-type)
(cpp-variable-name (first name-and-type)))
(capnp-extra-args (find-cpp-class parent) :load))))))
;; Load members
(write-string (capnp-load-members cpp-class reader :instance-access instance-access) cpp-out))))
(with-output-to-string (s)
(cond
((and (capnp-union-and-compose-parents cpp-class)
(not (direct-subclasses-of cpp-class)))
;; CPP-CLASS is the most derived class, so construct and load.
(format s "*self = std::make_unique<~A>();~%" (cpp-type-decl cpp-class :namespace nil))
(write-line (load-class cpp-class) s))
(if (and (cpp-class-capnp-opts cpp-class)
(capnp-opts-construct (cpp-class-capnp-opts cpp-class)))
(write-line (funcall
(capnp-opts-construct (cpp-class-capnp-opts cpp-class))
(cpp-type-decl cpp-class :namespace nil))
s)
(format s "*self = std::make_unique<~A>();~%" (cpp-type-decl cpp-class :namespace nil)))
(load-class cpp-class "base_reader" s))
((capnp-union-subclasses cpp-class)
;; Forward the load to most derived class by switching on reader.which()
(let ((parents (capnp-union-parents-rec cpp-class)))
@ -1297,19 +1285,19 @@ It takes a parent class symbol."
;; Regular forward to derived
(load-derived (cpp-type-name subclass))))
(write-line "break;" s))
(when (capnp-union-and-compose-parents cpp-class)
(when (not (cpp-class-abstractp cpp-class))
;; We are in the middle of the hierarchy, so allow constructing and loading us.
(with-cpp-block-output (s :name (format nil "case capnp::~A::~A:"
(cpp-type-name cpp-class)
(cpp-constant-name (cpp-type-base-name cpp-class))))
(format s "*self = std::make_unique<~A>();~%"
(cpp-type-decl cpp-class :namespace nil))
(write-line (load-class cpp-class) s)))))
(load-class cpp-class "base_reader" s)))))
(t
;; Regular load for absolutely no inheritance class
(assert (not (capnp-union-subclasses cpp-class)))
(assert (not (capnp-union-and-compose-parents cpp-class)))
(write-line (load-class cpp-class) s)))))))
(load-class cpp-class "reader" s)))))))
(defun capnp-load-function-definition (cpp-class)
"Generate Cap'n Proto load function."
@ -1382,6 +1370,7 @@ element."
(declare (type string capnp-type cpp-type)
(type (or null string) lambda-code))
;; TODO: Why not use our `capnp-save-default' for this?
;; TODO: namespace doesn't work for enums nested in classes
(let* ((namespace (format nil "~{~A::~}"
(cpp-type-namespace (parse-cpp-type-declaration cpp-type))))
(lambda-code (if lambda-code
@ -1554,6 +1543,8 @@ Currently supported class-options are:
* :serialize -- only :capnp is a valid value. 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.
* :abstractp -- if t, marks that this class cannot be instantiated
(currently only useful in serialization code)
Larger example:
@ -1590,7 +1581,8 @@ Generates C++:
(class-name (if (consp name) (car name) name))
(type-params (when (consp name) (cdr name)))
(class (gensym (format nil "CLASS-~A" name)))
(serialize (cdr (assoc :serialize options))))
(serialize (cdr (assoc :serialize options)))
(abstractp (second (assoc :abstractp options))))
`(let ((,class
(let ((*cpp-inner-types* nil)
(*cpp-enclosing-class* ',class-name))
@ -1606,6 +1598,7 @@ Generates C++:
:capnp-opts ,(when (member :capnp serialize)
`(and *capnp-serialize-p*
(make-capnp-opts ,@(cdr (member :capnp serialize)))))
:abstractp ,abstractp
:namespace (reverse *cpp-namespaces*)
;; Set inner types at the end. This works
;; because CL standard specifies order of

View File

@ -1,466 +0,0 @@
@0xb107d3d6b4b1600b;
using Cxx = import "/capnp/c++.capnp";
$Cxx.namespace("query::capnp");
using Storage = import "/storage/serialization.capnp";
using Symbols = import "/query/frontend/semantic/symbol.capnp";
struct Tree {
uid @0 :Int64;
union {
expression @1 :Expression;
where @2 :Where;
namedExpression @3 :NamedExpression;
patternAtom @4 :PatternAtom;
pattern @5 :Pattern;
clause @6 :Clause;
singleQuery @7 :SingleQuery;
cypherUnion @8 :CypherUnion;
query @9 :Query;
}
}
struct Expression {
union {
binaryOperator @0 :BinaryOperator;
unaryOperator @1 :UnaryOperator;
baseLiteral @2 :BaseLiteral;
listSlicingOperator @3 :ListSlicingOperator;
ifOperator @4 :IfOperator;
identifier @5 :Identifier;
propertyLookup @6 :PropertyLookup;
labelsTest @7 :LabelsTest;
function @8 :Function;
reduce @9 :Reduce;
all @10 :All;
single @11 :Single;
parameterLookup @12 :ParameterLookup;
extract @13 :Extract;
}
}
struct Where {
expression @0 :Tree;
}
struct NamedExpression {
name @0 :Text;
expression @1 :Tree;
tokenPosition @2 :Int32;
}
struct PatternAtom {
union {
nodeAtom @0 :NodeAtom;
edgeAtom @1 :EdgeAtom;
}
identifier @2 :Tree;
}
struct Pair(First, Second) {
first @0 :First;
second @1 :Second;
}
struct NodeAtom {
properties @0 :List(Entry);
struct Entry {
key @0 :Pair(Text, Storage.Common);
value @1 :Tree;
}
labels @1 :List(Storage.Common);
}
struct EdgeAtom {
enum Type {
single @0;
depthFirst @1;
breadthFirst @2;
weightedShortestPath @3;
}
type @0 :Type;
enum Direction {
in @0;
out @1;
both @2;
}
direction @1 :Direction;
properties @2 :List(Entry);
struct Entry {
key @0 :Pair(Text, Storage.Common);
value @1 :Tree;
}
lowerBound @3 :Tree;
upperBound @4 :Tree;
filterLambda @5 :Lambda;
weightLambda @6 :Lambda;
struct Lambda {
innerEdge @0 :Tree;
innerNode @1 :Tree;
expression @2 :Tree;
}
totalWeight @7 :Tree;
edgeTypes @8 :List(Storage.Common);
}
struct Pattern {
identifier @0 :Tree;
atoms @1 :List(Tree);
}
struct Clause {
union {
create @0 :Create;
match @1 :Match;
return @2 :Return;
with @3 :With;
delete @4 :Delete;
setProperty @5 :SetProperty;
setProperties @6 :SetProperties;
setLabels @7 :SetLabels;
removeProperty @8 :RemoveProperty;
removeLabels @9 :RemoveLabels;
merge @10 :Merge;
unwind @11 :Unwind;
createIndex @12 :CreateIndex;
authQuery @13 :AuthQuery;
createStream @14 :CreateStream;
dropStream @15 :DropStream;
showStreams @16 :ShowStreams;
startStopStream @17 :StartStopStream;
startStopAllStreams @18 :StartStopAllStreams;
testStream @19 :TestStream;
}
}
struct SingleQuery {
clauses @0 :List(Tree);
}
struct CypherUnion {
singleQuery @0 :Tree;
distinct @1 :Bool;
unionSymbols @2 :List(Symbols.Symbol);
}
struct Query {
singleQuery @0 :Tree;
cypherUnions @1 :List(Tree);
explain @2 :Bool;
}
struct BinaryOperator {
union {
orOperator @0 :OrOperator;
xorOperator @1 :XorOperator;
andOperator @2 :AndOperator;
additionOperator @3 :AdditionOperator;
subtractionOperator @4 :SubtractionOperator;
multiplicationOperator @5 :MultiplicationOperator;
divisionOperator @6 :DivisionOperator;
modOperator @7 :ModOperator;
notEqualOperator @8 :NotEqualOperator;
equalOperator @9 :EqualOperator;
lessOperator @10 :LessOperator;
greaterOperator @11 :GreaterOperator;
lessEqualOperator @12 :LessEqualOperator;
greaterEqualOperator @13 :GreaterEqualOperator;
inListOperator @14 :InListOperator;
subscriptOperator @15 :SubscriptOperator;
aggregation @16 :Aggregation;
}
expression1 @17 :Tree;
expression2 @18 :Tree;
}
struct OrOperator {}
struct XorOperator {}
struct AndOperator {}
struct AdditionOperator {}
struct SubtractionOperator {}
struct MultiplicationOperator {}
struct DivisionOperator {}
struct ModOperator {}
struct NotEqualOperator {}
struct EqualOperator {}
struct LessOperator {}
struct GreaterOperator {}
struct LessEqualOperator {}
struct GreaterEqualOperator {}
struct InListOperator {}
struct SubscriptOperator {}
struct Aggregation {
enum Op {
count @0;
min @1;
max @2;
sum @3;
avg @4 ;
collectList @5;
collectMap @6;
}
op @0 :Op;
}
struct UnaryOperator {
union {
notOperator @0 :NotOperator;
unaryPlusOperator @1 :UnaryPlusOperator;
unaryMinusOperator @2 :UnaryMinusOperator;
isNullOperator @3 :IsNullOperator;
}
expression @4 :Tree;
}
struct NotOperator {}
struct UnaryPlusOperator {}
struct UnaryMinusOperator {}
struct IsNullOperator {}
struct BaseLiteral {
union {
primitiveLiteral @0 :PrimitiveLiteral;
listLiteral @1 :ListLiteral;
mapLiteral @2 :MapLiteral;
}
}
struct PrimitiveLiteral {
tokenPosition @0 :Int32;
value @1 :Storage.PropertyValue;
}
struct ListLiteral {
elements @0 :List(Tree);
}
struct MapLiteral {
elements @0 :List(Entry);
struct Entry {
key @0 :Pair(Text, Storage.Common);
value @1 :Tree;
}
}
struct ListSlicingOperator {
list @0 :Tree;
lowerBound @1 :Tree;
upperBound @2 :Tree;
}
struct IfOperator {
condition @0 :Tree;
thenExpression @1 :Tree;
elseExpression @2 :Tree;
}
struct Identifier {
name @0 :Text;
userDeclared @1 :Bool;
}
struct PropertyLookup {
expression @0 :Tree;
propertyName @1 :Text;
property @2 :Storage.Common;
}
struct LabelsTest {
expression @0 :Tree;
labels @1 :List(Storage.Common);
}
struct Function {
functionName @0 :Text;
arguments @1 :List(Tree);
}
struct Reduce {
accumulator @0 :Tree;
initializer @1 :Tree;
identifier @2 :Tree;
list @3 :Tree;
expression @4 :Tree;
}
struct Extract {
identifier @0 :Tree;
list @1 :Tree;
expression @2 :Tree;
}
struct All {
identifier @0 :Tree;
listExpression @1 :Tree;
where @2 :Tree;
}
struct Single {
identifier @0 :Tree;
listExpression @1 :Tree;
where @2 :Tree;
}
struct ParameterLookup {
tokenPosition @0 :Int32;
}
struct Create {
patterns @0 :List(Tree);
}
struct Match {
patterns @0 :List(Tree);
where @1 :Tree;
optional @2 :Bool;
}
enum Ordering {
asc @0;
desc @1;
}
struct ReturnBody {
distinct @0 :Bool;
allIdentifiers @1 :Bool;
namedExpressions @2 :List(Tree);
orderBy @3 :List(Pair);
struct Pair {
ordering @0 :Ordering;
expression @1 :Tree;
}
skip @4 :Tree;
limit @5 :Tree;
}
struct Return {
returnBody @0 :ReturnBody;
}
struct With {
returnBody @0 :ReturnBody;
where @1 :Tree;
}
struct Delete {
detach @0 :Bool;
expressions @1 :List(Tree);
}
struct SetProperty {
propertyLookup @0 :Tree;
expression @1 :Tree;
}
struct SetProperties {
identifier @0 :Tree;
expression @1 :Tree;
update @2 :Bool;
}
struct SetLabels {
identifier @0 :Tree;
labels @1 :List(Storage.Common);
}
struct RemoveProperty {
propertyLookup @0 :Tree;
}
struct RemoveLabels {
identifier @0 :Tree;
labels @1 :List(Storage.Common);
}
struct Merge {
pattern @0 :Tree;
onMatch @1 :List(Tree);
onCreate @2 :List(Tree);
}
struct Unwind {
namedExpression @0 :Tree;
}
struct CreateIndex {
label @0 :Storage.Common;
property @1 :Storage.Common;
}
struct AuthQuery {
enum Action {
createRole @0;
dropRole @1;
showRoles @2;
createUser @3;
setPassword @4;
dropUser @5;
showUsers @6;
setRole @7;
clearRole @8;
grantPrivilege @9;
denyPrivilege @10;
revokePrivilege @11;
showPrivileges @12;
showRoleForUser @13;
showUsersForRole @14;
}
enum Privilege {
create @0;
delete @1;
match @2;
merge @3;
set @4;
remove @5;
index @6;
auth @7;
stream @8;
}
action @0 :Action;
user @1 :Text;
role @2 :Text;
userOrRole @3 :Text;
password @4 :Tree;
privileges @5 :List(Privilege);
}
struct CreateStream {
streamName @0 :Text;
streamUri @1 :Tree;
streamTopic @2 :Tree;
transformUri @3 :Tree;
batchIntervalInMs @4 :Tree;
batchSize @5 :Tree;
}
struct DropStream {
streamName @0: Text;
}
struct ShowStreams {}
struct StartStopStream {
streamName @0 :Text;
isStart @1 :Bool;
limitBatches @2: Tree;
}
struct StartStopAllStreams {
isStart @0 :Bool;
}
struct TestStream {
streamName @0 :Text;
limitBatches @1: Tree;
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -638,9 +638,7 @@ antlrcpp::Any CypherMainVisitor::visitReturnBody(
MemgraphCypher::ReturnBodyContext *ctx) {
ReturnBody body;
if (ctx->order()) {
body.order_by = ctx->order()
->accept(this)
.as<std::vector<std::pair<Ordering, Expression *>>>();
body.order_by = ctx->order()->accept(this).as<std::vector<SortItem>>();
}
if (ctx->skip()) {
body.skip = static_cast<Expression *>(ctx->skip()->accept(this));
@ -684,7 +682,7 @@ antlrcpp::Any CypherMainVisitor::visitReturnItem(
}
antlrcpp::Any CypherMainVisitor::visitOrder(MemgraphCypher::OrderContext *ctx) {
std::vector<std::pair<Ordering, Expression *>> order_by;
std::vector<SortItem> order_by;
for (auto *sort_item : ctx->sortItem()) {
order_by.push_back(sort_item->accept(this));
}
@ -693,9 +691,9 @@ antlrcpp::Any CypherMainVisitor::visitOrder(MemgraphCypher::OrderContext *ctx) {
antlrcpp::Any CypherMainVisitor::visitSortItem(
MemgraphCypher::SortItemContext *ctx) {
return std::pair<Ordering, Expression *>(
return SortItem{
ctx->DESC() || ctx->DESCENDING() ? Ordering::DESC : Ordering::ASC,
ctx->expression()->accept(this));
ctx->expression()->accept(this)};
}
antlrcpp::Any CypherMainVisitor::visitNodePattern(

View File

@ -358,12 +358,12 @@ class CypherMainVisitor : public antlropencypher::MemgraphCypherBaseVisitor {
MemgraphCypher::ReturnItemContext *ctx) override;
/**
* @return vector<pair<Ordering, Expression*>>
* @return vector<SortItem>
*/
antlrcpp::Any visitOrder(MemgraphCypher::OrderContext *ctx) override;
/**
* @return pair<Ordering, Expression*>
* @return SortItem
*/
antlrcpp::Any visitSortItem(MemgraphCypher::SortItemContext *ctx) override;

View File

@ -84,7 +84,7 @@ void SymbolGenerator::VisitReturnBody(ReturnBody &body, Where *where) {
}
scope_.in_order_by = true;
for (const auto &order_pair : body.order_by) {
order_pair.second->Accept(*this);
order_pair.expression->Accept(*this);
}
scope_.in_order_by = false;
if (body.skip) {
@ -318,7 +318,7 @@ bool SymbolGenerator::PreVisit(Aggregation &aggr) {
// Create a virtual symbol for aggregation result.
// Currently, we only have aggregation operators which return numbers.
auto aggr_name =
Aggregation::OpToString(aggr.op_) + std::to_string(aggr.uid());
Aggregation::OpToString(aggr.op_) + std::to_string(aggr.uid_);
symbol_table_[aggr] =
symbol_table_.CreateSymbol(aggr_name, false, Symbol::Type::Number);
scope_.in_aggregation = true;

View File

@ -19,10 +19,10 @@ class SymbolTable final {
return Symbol(name, position, user_declared, type, token_position);
}
auto &operator[](const Tree &tree) { return table_[tree.uid()]; }
auto &operator[](const Tree &tree) { return table_[tree.uid_]; }
Symbol &at(const Tree &tree) { return table_.at(tree.uid()); }
const Symbol &at(const Tree &tree) const { return table_.at(tree.uid()); }
Symbol &at(const Tree &tree) { return table_.at(tree.uid_); }
const Symbol &at(const Tree &tree) const { return table_.at(tree.uid_); }
// TODO: Remove these since members are public
int max_position() const { return position_; }

View File

@ -377,16 +377,16 @@ class ExpressionEvaluator : public TreeVisitor<TypedValue> {
for (size_t i = 0; i < function.arguments_.size(); ++i) {
arguments[i] = function.arguments_[i]->Accept(*this);
}
return function.function()(arguments, function.arguments_.size(), *ctx_,
dba_);
return function.function_(arguments, function.arguments_.size(), *ctx_,
dba_);
} else {
std::vector<TypedValue> arguments;
arguments.reserve(function.arguments_.size());
for (const auto &argument : function.arguments_) {
arguments.emplace_back(argument->Accept(*this));
}
return function.function()(arguments.data(), arguments.size(), *ctx_,
dba_);
return function.function_(arguments.data(), arguments.size(), *ctx_,
dba_);
}
}

View File

@ -1214,11 +1214,11 @@ class DistributedPlanner : public HierarchicalLogicalOperatorVisitor {
}
// Create a copy of OrderBy but with added symbols used in expressions, so
// that they can be pulled.
std::vector<std::pair<Ordering, Expression *>> ordering;
std::vector<SortItem> ordering;
ordering.reserve(order_by.order_by_.size());
for (int i = 0; i < order_by.order_by_.size(); ++i) {
ordering.emplace_back(order_by.compare_.ordering()[i],
order_by.order_by_[i]);
ordering.emplace_back(
SortItem{order_by.compare_.ordering()[i], order_by.order_by_[i]});
}
auto worker_plan = std::make_shared<OrderBy>(
order_by.input(), ordering,
@ -1328,7 +1328,7 @@ class DistributedPlanner : public HierarchicalLogicalOperatorVisitor {
auto make_merge_aggregation = [&](auto op, const auto &worker_sym) {
auto *worker_ident = make_ident(worker_sym);
auto merge_name = Aggregation::OpToString(op) +
std::to_string(worker_ident->uid()) + "<-" +
std::to_string(worker_ident->uid_) + "<-" +
worker_sym.name();
auto merge_sym = distributed_plan_.symbol_table.CreateSymbol(
merge_name, false, Symbol::Type::Number);

View File

@ -81,8 +81,7 @@ bool Synchronize::Accept(HierarchicalLogicalOperatorVisitor &visitor) {
PullRemoteOrderBy::PullRemoteOrderBy(
const std::shared_ptr<LogicalOperator> &input, int64_t plan_id,
const std::vector<std::pair<Ordering, Expression *>> &order_by,
const std::vector<Symbol> &symbols)
const std::vector<SortItem> &order_by, const std::vector<Symbol> &symbols)
: input_(input), plan_id_(plan_id), symbols_(symbols) {
CHECK(input_ != nullptr)
<< "PullRemoteOrderBy should always be constructed with input!";
@ -90,8 +89,8 @@ PullRemoteOrderBy::PullRemoteOrderBy(
ordering.reserve(order_by.size());
order_by_.reserve(order_by.size());
for (const auto &ordering_expression_pair : order_by) {
ordering.emplace_back(ordering_expression_pair.first);
order_by_.emplace_back(ordering_expression_pair.second);
ordering.emplace_back(ordering_expression_pair.ordering);
order_by_.emplace_back(ordering_expression_pair.expression);
}
compare_ = TypedValueVectorCompare(ordering);
}

View File

@ -172,8 +172,7 @@ by having only one result from each worker.")
PullRemoteOrderBy() {}
PullRemoteOrderBy(
const std::shared_ptr<LogicalOperator> &input, int64_t plan_id,
const std::vector<std::pair<Ordering, Expression *>> &order_by,
const std::vector<Symbol> &symbols);
const std::vector<SortItem> &order_by, const std::vector<Symbol> &symbols);
bool Accept(HierarchicalLogicalOperatorVisitor &visitor) override;
std::unique_ptr<Cursor> MakeCursor(
database::GraphDbAccessor &db) const override;

View File

@ -2658,7 +2658,7 @@ void Limit::LimitCursor::Reset() {
}
OrderBy::OrderBy(const std::shared_ptr<LogicalOperator> &input,
const std::vector<std::pair<Ordering, Expression *>> &order_by,
const std::vector<SortItem> &order_by,
const std::vector<Symbol> &output_symbols)
: input_(input), output_symbols_(output_symbols) {
// split the order_by vector into two vectors of orderings and expressions
@ -2666,8 +2666,8 @@ OrderBy::OrderBy(const std::shared_ptr<LogicalOperator> &input,
ordering.reserve(order_by.size());
order_by_.reserve(order_by.size());
for (const auto &ordering_expression_pair : order_by) {
ordering.emplace_back(ordering_expression_pair.first);
order_by_.emplace_back(ordering_expression_pair.second);
ordering.emplace_back(ordering_expression_pair.ordering);
order_by_.emplace_back(ordering_expression_pair.expression);
}
compare_ = TypedValueVectorCompare(ordering);
}

View File

@ -151,6 +151,7 @@ cpp<#
(lcp:define-class logical-operator ("::utils::Visitable<HierarchicalLogicalOperatorVisitor>")
()
(:abstractp t)
(:documentation
"Base class for logical operators.
@ -238,23 +239,27 @@ can serve as inputs to others and thus a sequence of operations is formed.")
#>cpp
if (${member}) {
auto ${capnp-name}_builder = ${builder}->init${capnp-name}();
${member}->Save(&${capnp-name}_builder, &helper->saved_ast_uids);
Save(*${member}, &${capnp-name}_builder, &helper->saved_ast_uids);
}
cpp<#)
(defun load-ast-pointer (ast-type)
(lambda (reader member capnp-name)
#>cpp
if (${reader}.has${capnp-name}())
${member} = static_cast<${ast-type}>(helper->ast_storage.Load(${reader}.get${capnp-name}(), &helper->loaded_ast_uids));
else
${member} = nullptr;
cpp<#))
(let ((cpp-type (remove #\* ast-type)))
#>cpp
if (${reader}.has${capnp-name}()) {
std::unique_ptr<${cpp-type}> tmp;
Load(&tmp, ${reader}.get${capnp-name}(), &helper->ast_storage, &helper->loaded_ast_uids);
${member} = helper->ast_storage.Take(std::move(tmp));
} else {
${member} = nullptr;
}
cpp<#)))
(defun save-ast-vector (ast-type)
(lcp:capnp-save-vector "::query::capnp::Tree" ast-type
"[helper](auto *builder, const auto &val) {
val->Save(builder, &helper->saved_ast_uids);
Save(*val, builder, &helper->saved_ast_uids);
}"))
(defun load-ast-vector (ast-type)
@ -262,9 +267,11 @@ can serve as inputs to others and thus a sequence of operations is formed.")
(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)))
std::unique_ptr<~A> tmp;
Load(&tmp, reader, &helper->ast_storage, &helper->loaded_ast_uids);
return helper->ast_storage.Take(std::move(tmp));
}"
(remove #\* ast-type))))
(defun save-operator-pointer (builder member-name capnp-name)
(declare (ignore capnp-name))
@ -547,7 +554,7 @@ given label.
::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);
Save(*bound.value(), &value_builder, &helper->saved_ast_uids);
}"))
(funcall (lcp:capnp-save-optional "::utils::capnp::Bound<::query::capnp::Tree>"
"utils::Bound<Expression *>"
@ -559,7 +566,9 @@ given label.
"[helper](const auto &reader) {
auto type = reader.getType() == ::utils::capnp::Bound<::query::capnp::Tree>::Type::INCLUSIVE
? utils::BoundType::INCLUSIVE : utils::BoundType::EXCLUSIVE;
auto *value = static_cast<Expression*>(helper->ast_storage.Load(reader.getValue(), &helper->loaded_ast_uids));
std::unique_ptr<Tree> tmp;
Load(&tmp, reader.getValue(), &helper->ast_storage, &helper->loaded_ast_uids);
auto *value = static_cast<Expression *>(helper->ast_storage.Take(std::move(tmp)));
return utils::Bound<Expression *>(value, type);
}"))
(funcall (lcp:capnp-load-optional "::utils::capnp::Bound<::query::capnp::Tree>"
@ -818,16 +827,16 @@ pulled.")
:capnp-save (lambda (builder member capnp-name)
#>cpp
if (${member}) {
auto expression_builder = ${builder}->initExpression();
${member}->Save(&expression_builder, saved_ast_uids);
auto ${capnp-name}_builder = ${builder}->init${capnp-name}();
Save(*${member}, &${capnp-name}_builder, saved_ast_uids);
}
cpp<#)
:capnp-load (lambda (reader member capnp-name)
#>cpp
if (${reader}.hasExpression()) {
${member} = static_cast<Expression *>(
ast_storage->Load(${reader}.getExpression(),
loaded_ast_uids));
std::unique_ptr<Expression> tmp;
Load(&tmp, ${reader}.getExpression(), ast_storage, loaded_ast_uids);
${member} = ast_storage->Take(std::move(tmp));
} else {
${member} = nullptr;
}
@ -854,7 +863,7 @@ pulled.")
:capnp-type "Ast.Tree" :capnp-init nil
:capnp-save #'save-ast-pointer :capnp-load (load-ast-pointer "Expression *")
:documentation "Optional upper bound of the variable length expansion, defaults are (1, inf)")
(filter-lambda "ExpansionLambda"
(filter-lambda "ExpansionLambda"
:scope :public
:capnp-save (lambda (builder member capnp-name)
#>cpp
@ -867,12 +876,12 @@ pulled.")
(weight-lambda "std::experimental::optional<ExpansionLambda>" :scope :public
:capnp-save (lcp:capnp-save-optional
"capnp::ExpansionLambda" "ExpansionLambda"
"[helper](auto *builder, const auto &val) {
Save(val, builder, &helper->saved_ast_uids);
"[helper](auto *builder, const auto &val) {
Save(val, builder, &helper->saved_ast_uids);
}")
:capnp-load (lcp:capnp-load-optional
"capnp::ExpansionLambda" "ExpansionLambda"
"[helper](const auto &reader) {
"[helper](const auto &reader) {
ExpansionLambda val;
Load(&val, reader, &helper->ast_storage, &helper->loaded_ast_uids);
return val;
@ -1832,7 +1841,7 @@ are valid for usage after the OrderBy operator.")
OrderBy() {}
OrderBy(const std::shared_ptr<LogicalOperator> &input,
const std::vector<std::pair<Ordering, Expression *>> &order_by,
const std::vector<SortItem> &order_by,
const std::vector<Symbol> &output_symbols);
bool Accept(HierarchicalLogicalOperatorVisitor &visitor) override;
std::unique_ptr<Cursor> MakeCursor(

View File

@ -132,7 +132,7 @@ class ReturnBodyContext : public HierarchicalTreeVisitor {
// about collecting used_symbols. Also, semantic analysis should
// have prevented any aggregations from appearing here.
for (const auto &order_pair : body.order_by) {
order_pair.second->Accept(*this);
order_pair.expression->Accept(*this);
}
if (where) {
where->Accept(*this);

View File

@ -39,7 +39,7 @@ struct PropertyValue {
struct PropertyValueStore {
properties @0 :List(Entry);
struct Entry {
id @0 :Common;
value @1 :PropertyValue;

View File

@ -158,7 +158,7 @@ class CapnpAstGenerator : public Base {
query::capnp::Tree::Builder builder =
message.initRoot<query::capnp::Tree>();
std::vector<int> saved_uids;
visitor.query()->Save(&builder, &saved_uids);
Save(*visitor.query(), &builder, &saved_uids);
}
AstStorage new_ast;
@ -332,8 +332,8 @@ TYPED_TEST(CypherMainVisitorTest, ReturnOrderBy) {
ASSERT_EQ(return_clause->body_.order_by.size(), 3U);
std::vector<std::pair<Ordering, std::string>> ordering;
for (const auto &sort_item : return_clause->body_.order_by) {
auto *identifier = dynamic_cast<Identifier *>(sort_item.second);
ordering.emplace_back(sort_item.first, identifier->name_);
auto *identifier = dynamic_cast<Identifier *>(sort_item.expression);
ordering.emplace_back(sort_item.ordering, identifier->name_);
}
ASSERT_THAT(ordering, UnorderedElementsAre(Pair(Ordering::ASC, "z"),
Pair(Ordering::ASC, "x"),
@ -762,7 +762,7 @@ TYPED_TEST(CypherMainVisitorTest, Function) {
auto *function = dynamic_cast<Function *>(
return_clause->body_.named_expressions[0]->expression_);
ASSERT_TRUE(function);
ASSERT_TRUE(function->function());
ASSERT_TRUE(function->function_);
}
TYPED_TEST(CypherMainVisitorTest, StringLiteralDoubleQuotes) {

View File

@ -329,16 +329,14 @@ TEST_F(DistributedQueryPlan, PullRemoteOrderBy) {
auto n_p = PROPERTY_LOOKUP("n", prop);
ctx.symbol_table_[*n_p->expression_] = n.sym_;
auto order_by = std::make_shared<plan::OrderBy>(
n.op_,
std::vector<std::pair<Ordering, Expression *>>{{Ordering::ASC, n_p}},
n.op_, std::vector<SortItem>{{Ordering::ASC, n_p}},
std::vector<Symbol>{n.sym_});
const int plan_id = 42;
master().plan_dispatcher().DispatchPlan(plan_id, order_by, ctx.symbol_table_);
auto pull_remote_order_by = std::make_shared<plan::PullRemoteOrderBy>(
order_by, plan_id,
std::vector<std::pair<Ordering, Expression *>>{{Ordering::ASC, n_p}},
order_by, plan_id, std::vector<SortItem>{{Ordering::ASC, n_p}},
std::vector<Symbol>{n.sym_});
auto n_p_ne = NEXPR("n.prop", n_p);

View File

@ -57,7 +57,7 @@ auto ToMap(const TypedValue &t) {
// Custom types for ORDER BY, SKIP, LIMIT, ON MATCH and ON CREATE expressions,
// so that they can be used to resolve function calls.
struct OrderBy {
std::vector<std::pair<Ordering, Expression *>> expressions;
std::vector<SortItem> expressions;
};
struct Skip {
Expression *expression = nullptr;
@ -75,7 +75,7 @@ struct OnCreate {
// Helper functions for filling the OrderBy with expressions.
auto FillOrderBy(OrderBy &order_by, Expression *expression,
Ordering ordering = Ordering::ASC) {
order_by.expressions.emplace_back(ordering, expression);
order_by.expressions.push_back({ordering, expression});
}
template <class... T>
auto FillOrderBy(OrderBy &order_by, Expression *expression, Ordering ordering,

View File

@ -151,9 +151,7 @@ TEST(QueryPlan, OrderBy) {
auto n_p = PROPERTY_LOOKUP("n", prop);
symbol_table[*n_p->expression_] = n.sym_;
auto order_by = std::make_shared<plan::OrderBy>(
n.op_,
std::vector<std::pair<Ordering, Expression *>>{
{order_value_pair.first, n_p}},
n.op_, std::vector<SortItem>{{order_value_pair.first, n_p}},
std::vector<Symbol>{n.sym_});
auto n_p_ne = NEXPR("n.p", n_p);
symbol_table[*n_p_ne] = symbol_table.CreateSymbol("n.p", true);
@ -201,13 +199,12 @@ TEST(QueryPlan, OrderByMultiple) {
// (p1: 0, p2: N-2)
// ...
// (p1: N-1, p2:0)
auto order_by = std::make_shared<plan::OrderBy>(
n.op_,
std::vector<std::pair<Ordering, Expression *>>{
{Ordering::ASC, n_p1},
{Ordering::DESC, n_p2},
},
std::vector<Symbol>{n.sym_});
auto order_by = std::make_shared<plan::OrderBy>(n.op_,
std::vector<SortItem>{
{Ordering::ASC, n_p1},
{Ordering::DESC, n_p2},
},
std::vector<Symbol>{n.sym_});
auto n_p1_ne = NEXPR("n.p1", n_p1);
symbol_table[*n_p1_ne] = symbol_table.CreateSymbol("n.p1", true);
auto n_p2_ne = NEXPR("n.p2", n_p2);
@ -262,8 +259,7 @@ TEST(QueryPlan, OrderByExceptions) {
auto n_p = PROPERTY_LOOKUP("n", prop);
symbol_table[*n_p->expression_] = n.sym_;
auto order_by = std::make_shared<plan::OrderBy>(
n.op_,
std::vector<std::pair<Ordering, Expression *>>{{Ordering::ASC, n_p}},
n.op_, std::vector<SortItem>{{Ordering::ASC, n_p}},
std::vector<Symbol>{});
EXPECT_THROW(PullAll(order_by, dba, symbol_table), QueryRuntimeException);
}

View File

@ -3201,7 +3201,7 @@ TEST(CapnpSerial, PullRemoteOrderBy) {
AstStorage storage;
std::vector<Symbol> symbols{
Symbol("my_symbol", 2, true, Symbol::Type::Vertex, 3)};
std::vector<std::pair<query::Ordering, query::Expression *>> order_by{
std::vector<query::SortItem> order_by{
{query::Ordering::ASC, IDENT("my_symbol")}};
auto pull_remote_order_by =
std::make_unique<PullRemoteOrderBy>(once, 42, order_by, symbols);