* Remove timout when registering a sync replica * Simplify jepsen configuration file * Remove timeout from jepsen configuration * Add unit test * Remove TimeoutDispatcher
2670 lines
86 KiB
Plaintext
2670 lines
86 KiB
Plaintext
;; Copyright 2022 Memgraph Ltd.
|
|
;;
|
|
;; Use of this software is governed by the Business Source License
|
|
;; included in the file licenses/BSL.txt; by using this file, you agree to be bound by the terms of the Business Source
|
|
;; License, and you may not use this file except in compliance with the Business Source License.
|
|
;;
|
|
;; As of the Change Date specified in that file, in accordance with
|
|
;; the Business Source License, use of this software will be governed
|
|
;; by the Apache License, Version 2.0, included in the file
|
|
;; licenses/APL.txt.
|
|
|
|
#>cpp
|
|
#pragma once
|
|
|
|
#include <memory>
|
|
#include <unordered_map>
|
|
#include <variant>
|
|
#include <vector>
|
|
|
|
#include "query/frontend/ast/ast_visitor.hpp"
|
|
#include "query/frontend/semantic/symbol.hpp"
|
|
#include "query/interpret/awesome_memgraph_functions.hpp"
|
|
#include "query/typed_value.hpp"
|
|
#include "storage/v2/property_value.hpp"
|
|
#include "utils/typeinfo.hpp"
|
|
|
|
cpp<#
|
|
|
|
(lcp:namespace memgraph)
|
|
(lcp:namespace query)
|
|
|
|
(defun slk-save-ast-pointer (member)
|
|
#>cpp
|
|
query::SaveAstPointer(self.${member}, builder);
|
|
cpp<#)
|
|
|
|
(defun slk-load-ast-pointer (type)
|
|
(lambda (member)
|
|
#>cpp
|
|
self->${member} = query::LoadAstPointer<query::${type}>(storage, reader);
|
|
cpp<#))
|
|
|
|
(defun slk-save-ast-vector (member)
|
|
#>cpp
|
|
size_t size = self.${member}.size();
|
|
slk::Save(size, builder);
|
|
for (const auto *val : self.${member}) {
|
|
query::SaveAstPointer(val, builder);
|
|
}
|
|
cpp<#)
|
|
|
|
(defun slk-load-ast-vector (type)
|
|
(lambda (member)
|
|
#>cpp
|
|
size_t size = 0;
|
|
slk::Load(&size, reader);
|
|
self->${member}.resize(size);
|
|
for (size_t i = 0; i < size; ++i) {
|
|
self->${member}[i] = query::LoadAstPointer<query::${type}>(storage, reader);
|
|
}
|
|
cpp<#))
|
|
|
|
(defun slk-save-property-map (member)
|
|
#>cpp
|
|
size_t size = self.${member}.size();
|
|
slk::Save(size, builder);
|
|
for (const auto &entry : self.${member}) {
|
|
slk::Save(entry.first, builder);
|
|
query::SaveAstPointer(entry.second, builder);
|
|
}
|
|
cpp<#)
|
|
|
|
(defun slk-load-property-map (member)
|
|
#>cpp
|
|
size_t size = 0;
|
|
slk::Load(&size, reader);
|
|
for (size_t i = 0; i < size; ++i) {
|
|
query::PropertyIx key;
|
|
slk::Load(&key, reader, storage);
|
|
auto *value = query::LoadAstPointer<query::Expression>(storage, reader);
|
|
self->${member}.emplace(key, value);
|
|
}
|
|
cpp<#)
|
|
|
|
(defun clone-property-map (source dest)
|
|
#>cpp
|
|
for (const auto &entry : ${source}) {
|
|
PropertyIx key = storage->GetPropertyIx(entry.first.name);
|
|
${dest}[key] = entry.second->Clone(storage);
|
|
}
|
|
cpp<#)
|
|
|
|
(defun slk-save-expression-map (member)
|
|
#>cpp
|
|
size_t size = self.${member}.size();
|
|
slk::Save(size, builder);
|
|
for (const auto &entry : self.${member}) {
|
|
query::SaveAstPointer(entry.first, builder);
|
|
query::SaveAstPointer(entry.second, builder);
|
|
}
|
|
cpp<#)
|
|
|
|
(defun slk-load-expression-map (member)
|
|
#>cpp
|
|
size_t size = 0;
|
|
slk::Load(&size, reader);
|
|
for (size_t i = 0; i < size; ++i) {
|
|
auto *key = query::LoadAstPointer<query::Expression>(storage, reader);
|
|
auto *value = query::LoadAstPointer<query::Expression>(storage, reader);
|
|
self->${member}.emplace(key, value);
|
|
}
|
|
cpp<#)
|
|
|
|
(defun clone-expression-map (source dest)
|
|
#>cpp
|
|
for (const auto &[key, value] : ${source}) {
|
|
${dest}[key->Clone(storage)] = value->Clone(storage);
|
|
}
|
|
cpp<#)
|
|
|
|
(defun slk-load-name-ix (name-type)
|
|
(lambda (member)
|
|
#>cpp
|
|
self->${member} = storage->Get${name-type}Ix(self->name).ix;
|
|
cpp<#))
|
|
|
|
(defun clone-name-ix-vector (name-type)
|
|
(lambda (source dest)
|
|
#>cpp
|
|
${dest}.resize(${source}.size());
|
|
for (auto i = 0; i < ${dest}.size(); ++i) {
|
|
${dest}[i] = storage->Get${name-type}Ix(${source}[i].name);
|
|
}
|
|
cpp<#))
|
|
|
|
;; The following index structs serve as a decoupling point of AST from
|
|
;; concrete database types. All the names are collected in AstStorage, and can
|
|
;; be indexed through these instances. This means that we can create a vector
|
|
;; of concrete database types in the same order as all of the names and use the
|
|
;; same index to get the correct behaviour. Additionally, each index is
|
|
;; accompanied with the duplicated name found at the same index. The primary
|
|
;; reason for this duplication is simplifying the Clone and serialization API.
|
|
;; When an old index is being cloned or deserialized into a new AstStorage, we
|
|
;; request the new `ix` from the new AstStorage for the same `name`. If we
|
|
;; didn't do this, we would have to duplicate the old storage, which would
|
|
;; require having access to that storage. This in turn would complicate the
|
|
;; client code.
|
|
(lcp:define-struct label-ix ()
|
|
((name "std::string")
|
|
(ix :int64_t
|
|
:dont-save t
|
|
:slk-load (slk-load-name-ix "Label")))
|
|
(:serialize (:slk :load-args '((storage "query::AstStorage *")))))
|
|
|
|
(lcp:define-struct property-ix ()
|
|
((name "std::string")
|
|
(ix :int64_t
|
|
:dont-save t
|
|
:slk-load (slk-load-name-ix "Property")))
|
|
(:serialize (:slk :load-args '((storage "query::AstStorage *")))))
|
|
|
|
(lcp:define-struct edge-type-ix ()
|
|
((name "std::string")
|
|
(ix :int64_t
|
|
:dont-save t
|
|
:slk-load (slk-load-name-ix "EdgeType")))
|
|
(:serialize (:slk :load-args '((storage "query::AstStorage *")))))
|
|
|
|
#>cpp
|
|
inline bool operator==(const LabelIx &a, const LabelIx &b) {
|
|
return a.ix == b.ix && a.name == b.name;
|
|
}
|
|
|
|
inline bool operator!=(const LabelIx &a, const LabelIx &b) { return !(a == b); }
|
|
|
|
inline bool operator==(const PropertyIx &a, const PropertyIx &b) {
|
|
return a.ix == b.ix && a.name == b.name;
|
|
}
|
|
|
|
inline bool operator!=(const PropertyIx &a, const PropertyIx &b) {
|
|
return !(a == b);
|
|
}
|
|
|
|
inline bool operator==(const EdgeTypeIx &a, const EdgeTypeIx &b) {
|
|
return a.ix == b.ix && a.name == b.name;
|
|
}
|
|
|
|
inline bool operator!=(const EdgeTypeIx &a, const EdgeTypeIx &b) {
|
|
return !(a == b);
|
|
}
|
|
cpp<#
|
|
|
|
(lcp:pop-namespace) ;; namespace query
|
|
(lcp:pop-namespace) ;; namespace memgraph
|
|
|
|
#>cpp
|
|
namespace std {
|
|
|
|
template <>
|
|
struct hash<memgraph::query::LabelIx> {
|
|
size_t operator()(const memgraph::query::LabelIx &label) const { return label.ix; }
|
|
};
|
|
|
|
template <>
|
|
struct hash<memgraph::query::PropertyIx> {
|
|
size_t operator()(const memgraph::query::PropertyIx &prop) const { return prop.ix; }
|
|
};
|
|
|
|
template <>
|
|
struct hash<memgraph::query::EdgeTypeIx> {
|
|
size_t operator()(const memgraph::query::EdgeTypeIx &edge_type) const {
|
|
return edge_type.ix;
|
|
}
|
|
};
|
|
|
|
} // namespace std
|
|
cpp<#
|
|
|
|
(lcp:namespace memgraph)
|
|
(lcp:namespace query)
|
|
|
|
#>cpp
|
|
|
|
class Tree;
|
|
|
|
// It would be better to call this AstTree, but we already have a class Tree,
|
|
// which could be renamed to Node or AstTreeNode, but we also have a class
|
|
// called NodeAtom...
|
|
class AstStorage {
|
|
public:
|
|
AstStorage() = default;
|
|
AstStorage(const AstStorage &) = delete;
|
|
AstStorage &operator=(const AstStorage &) = delete;
|
|
AstStorage(AstStorage &&) = default;
|
|
AstStorage &operator=(AstStorage &&) = default;
|
|
|
|
template <typename T, typename... Args>
|
|
T *Create(Args &&... args) {
|
|
T *ptr = new T(std::forward<Args>(args)...);
|
|
std::unique_ptr<T> tmp(ptr);
|
|
storage_.emplace_back(std::move(tmp));
|
|
return ptr;
|
|
}
|
|
|
|
LabelIx GetLabelIx(const std::string &name) {
|
|
return LabelIx{name, FindOrAddName(name, &labels_)};
|
|
}
|
|
|
|
PropertyIx GetPropertyIx(const std::string &name) {
|
|
return PropertyIx{name, FindOrAddName(name, &properties_)};
|
|
}
|
|
|
|
EdgeTypeIx GetEdgeTypeIx(const std::string &name) {
|
|
return EdgeTypeIx{name, FindOrAddName(name, &edge_types_)};
|
|
}
|
|
|
|
std::vector<std::string> labels_;
|
|
std::vector<std::string> edge_types_;
|
|
std::vector<std::string> properties_;
|
|
|
|
// Public only for serialization access
|
|
std::vector<std::unique_ptr<Tree>> storage_;
|
|
|
|
private:
|
|
int64_t FindOrAddName(const std::string &name,
|
|
std::vector<std::string> *names) {
|
|
for (int64_t i = 0; i < names->size(); ++i) {
|
|
if ((*names)[i] == name) {
|
|
return i;
|
|
}
|
|
}
|
|
names->push_back(name);
|
|
return names->size() - 1;
|
|
}
|
|
};
|
|
cpp<#
|
|
|
|
(lcp:define-class tree ()
|
|
()
|
|
(:abstractp t)
|
|
(:public
|
|
#>cpp
|
|
Tree() = default;
|
|
virtual ~Tree() {}
|
|
cpp<#)
|
|
(:private
|
|
#>cpp
|
|
friend class AstStorage;
|
|
cpp<#)
|
|
(:serialize (:slk :load-args '((storage "query::AstStorage *"))))
|
|
(:clone :return-type (lambda (typename)
|
|
(format nil "~A*" typename))
|
|
:args '((storage "AstStorage *"))
|
|
:init-object (lambda (var typename)
|
|
(format nil "~A* ~A = storage->Create<~A>();"
|
|
typename var typename))))
|
|
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
;;; Expressions
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
|
|
(lcp:define-class expression (tree "::utils::Visitable<HierarchicalTreeVisitor>"
|
|
"::utils::Visitable<ExpressionVisitor<TypedValue>>"
|
|
"::utils::Visitable<ExpressionVisitor<void>>")
|
|
()
|
|
(:abstractp t)
|
|
(:public
|
|
#>cpp
|
|
using utils::Visitable<HierarchicalTreeVisitor>::Accept;
|
|
using utils::Visitable<ExpressionVisitor<TypedValue>>::Accept;
|
|
using utils::Visitable<ExpressionVisitor<void>>::Accept;
|
|
|
|
Expression() = default;
|
|
cpp<#)
|
|
(:private
|
|
#>cpp
|
|
friend class AstStorage;
|
|
cpp<#)
|
|
(:serialize (:slk :ignore-other-base-classes t))
|
|
(:clone :ignore-other-base-classes t)
|
|
(:type-info :ignore-other-base-classes t))
|
|
|
|
(lcp:define-class where (tree "::utils::Visitable<HierarchicalTreeVisitor>")
|
|
((expression "Expression *" :initval "nullptr" :scope :public
|
|
:slk-save #'slk-save-ast-pointer
|
|
:slk-load (slk-load-ast-pointer "Expression")))
|
|
(:public
|
|
#>cpp
|
|
using utils::Visitable<HierarchicalTreeVisitor>::Accept;
|
|
|
|
Where() = default;
|
|
|
|
bool Accept(HierarchicalTreeVisitor &visitor) override {
|
|
if (visitor.PreVisit(*this)) {
|
|
expression_->Accept(visitor);
|
|
}
|
|
return visitor.PostVisit(*this);
|
|
}
|
|
cpp<#)
|
|
(:protected
|
|
#>cpp
|
|
explicit Where(Expression *expression) : expression_(expression) {}
|
|
cpp<#)
|
|
(:private
|
|
#>cpp
|
|
friend class AstStorage;
|
|
cpp<#)
|
|
(:serialize (:slk :ignore-other-base-classes t))
|
|
(:clone :ignore-other-base-classes t)
|
|
(:type-info :ignore-other-base-classes t))
|
|
|
|
(lcp:define-class binary-operator (expression)
|
|
((expression1 "Expression *" :initval "nullptr" :scope :public
|
|
:slk-save #'slk-save-ast-pointer
|
|
:slk-load (slk-load-ast-pointer "Expression"))
|
|
(expression2 "Expression *" :initval "nullptr" :scope :public
|
|
:slk-save #'slk-save-ast-pointer
|
|
:slk-load (slk-load-ast-pointer "Expression")))
|
|
(:abstractp t)
|
|
(:public
|
|
#>cpp
|
|
BinaryOperator() = default;
|
|
cpp<#)
|
|
(:protected
|
|
#>cpp
|
|
BinaryOperator(Expression *expression1, Expression *expression2)
|
|
: expression1_(expression1), expression2_(expression2) {}
|
|
cpp<#)
|
|
(:private
|
|
#>cpp
|
|
friend class AstStorage;
|
|
cpp<#)
|
|
(:serialize (:slk))
|
|
(:clone))
|
|
|
|
(lcp:define-class unary-operator (expression)
|
|
((expression "Expression *" :initval "nullptr" :scope :public
|
|
:slk-save #'slk-save-ast-pointer
|
|
:slk-load (slk-load-ast-pointer "Expression")))
|
|
(:abstractp t)
|
|
(:public
|
|
#>cpp
|
|
UnaryOperator() = default;
|
|
cpp<#)
|
|
(:protected
|
|
#>cpp
|
|
explicit UnaryOperator(Expression *expression) : expression_(expression) {}
|
|
cpp<#)
|
|
(:private
|
|
#>cpp
|
|
friend class AstStorage;
|
|
cpp<#)
|
|
(:serialize (:slk))
|
|
(:clone))
|
|
|
|
(macrolet ((define-binary-operators ()
|
|
`(lcp:cpp-list
|
|
,@(loop for op in
|
|
'(or-operator xor-operator and-operator addition-operator
|
|
subtraction-operator multiplication-operator division-operator
|
|
mod-operator not-equal-operator equal-operator less-operator
|
|
greater-operator less-equal-operator greater-equal-operator
|
|
in-list-operator subscript-operator)
|
|
collecting
|
|
`(lcp:define-class ,op (binary-operator)
|
|
()
|
|
(:public
|
|
#>cpp
|
|
DEFVISITABLE(ExpressionVisitor<TypedValue>);
|
|
DEFVISITABLE(ExpressionVisitor<void>);
|
|
bool Accept(HierarchicalTreeVisitor &visitor) override {
|
|
if (visitor.PreVisit(*this)) {
|
|
expression1_->Accept(visitor) && expression2_->Accept(visitor);
|
|
}
|
|
return visitor.PostVisit(*this);
|
|
}
|
|
cpp<#)
|
|
(:protected
|
|
#>cpp
|
|
using BinaryOperator::BinaryOperator;
|
|
cpp<#)
|
|
(:private
|
|
#>cpp
|
|
friend class AstStorage;
|
|
cpp<#)
|
|
(:serialize (:slk))
|
|
(:clone))))))
|
|
(define-binary-operators))
|
|
|
|
(macrolet ((define-unary-operators ()
|
|
`(lcp:cpp-list
|
|
,@(loop for op in
|
|
'(not-operator unary-plus-operator
|
|
unary-minus-operator is-null-operator)
|
|
collecting
|
|
`(lcp:define-class ,op (unary-operator)
|
|
()
|
|
(:public
|
|
#>cpp
|
|
DEFVISITABLE(ExpressionVisitor<TypedValue>);
|
|
DEFVISITABLE(ExpressionVisitor<void>);
|
|
bool Accept(HierarchicalTreeVisitor &visitor) override {
|
|
if (visitor.PreVisit(*this)) {
|
|
expression_->Accept(visitor);
|
|
}
|
|
return visitor.PostVisit(*this);
|
|
}
|
|
cpp<#)
|
|
(:protected
|
|
#>cpp
|
|
using UnaryOperator::UnaryOperator;
|
|
cpp<#)
|
|
(:private
|
|
#>cpp
|
|
friend class AstStorage;
|
|
cpp<#)
|
|
(:serialize (:slk))
|
|
(:clone))))))
|
|
(define-unary-operators))
|
|
|
|
(lcp:define-class aggregation (binary-operator)
|
|
((op "Op" :scope :public)
|
|
(symbol-pos :int32_t :initval -1 :scope :public
|
|
:documentation "Symbol table position of the symbol this Aggregation is mapped to."))
|
|
(:public
|
|
(lcp:define-enum op
|
|
(count min max sum avg collect-list collect-map)
|
|
(:serialize))
|
|
#>cpp
|
|
Aggregation() = default;
|
|
|
|
static const constexpr char *const kCount = "COUNT";
|
|
static const constexpr char *const kMin = "MIN";
|
|
static const constexpr char *const kMax = "MAX";
|
|
static const constexpr char *const kSum = "SUM";
|
|
static const constexpr char *const kAvg = "AVG";
|
|
static const constexpr char *const kCollect = "COLLECT";
|
|
|
|
static std::string OpToString(Op op) {
|
|
const char *op_strings[] = {kCount, kMin, kMax, kSum,
|
|
kAvg, kCollect, kCollect};
|
|
return op_strings[static_cast<int>(op)];
|
|
}
|
|
|
|
DEFVISITABLE(ExpressionVisitor<TypedValue>);
|
|
DEFVISITABLE(ExpressionVisitor<void>);
|
|
bool Accept(HierarchicalTreeVisitor &visitor) override {
|
|
if (visitor.PreVisit(*this)) {
|
|
if (expression1_) expression1_->Accept(visitor);
|
|
if (expression2_) expression2_->Accept(visitor);
|
|
}
|
|
return visitor.PostVisit(*this);
|
|
}
|
|
|
|
Aggregation *MapTo(const Symbol &symbol) {
|
|
symbol_pos_ = symbol.position();
|
|
return this;
|
|
}
|
|
cpp<#)
|
|
(:protected
|
|
#>cpp
|
|
// Use only for serialization.
|
|
explicit Aggregation(Op op) : op_(op) {}
|
|
|
|
/// Aggregation's first expression is the value being aggregated. The second
|
|
/// expression is the key used only in COLLECT_MAP.
|
|
Aggregation(Expression *expression1, Expression *expression2, Op op)
|
|
: BinaryOperator(expression1, expression2), op_(op) {
|
|
// COUNT without expression denotes COUNT(*) in cypher.
|
|
DMG_ASSERT(expression1 || op == Aggregation::Op::COUNT,
|
|
"All aggregations, except COUNT require expression");
|
|
DMG_ASSERT((expression2 == nullptr) ^ (op == Aggregation::Op::COLLECT_MAP),
|
|
"The second expression is obligatory in COLLECT_MAP and "
|
|
"invalid otherwise");
|
|
}
|
|
cpp<#)
|
|
(:private
|
|
#>cpp
|
|
friend class AstStorage;
|
|
cpp<#)
|
|
(:serialize (:slk))
|
|
(:clone))
|
|
|
|
(lcp:define-class list-slicing-operator (expression)
|
|
((list "Expression *" :initval "nullptr" :scope :public
|
|
:slk-save #'slk-save-ast-pointer
|
|
:slk-load (slk-load-ast-pointer "Expression"))
|
|
(lower-bound "Expression *" :initval "nullptr" :scope :public
|
|
:slk-save #'slk-save-ast-pointer
|
|
:slk-load (slk-load-ast-pointer "Expression"))
|
|
(upper-bound "Expression *" :initval "nullptr" :scope :public
|
|
:slk-save #'slk-save-ast-pointer
|
|
:slk-load (slk-load-ast-pointer "Expression")))
|
|
(:public
|
|
#>cpp
|
|
ListSlicingOperator() = default;
|
|
|
|
DEFVISITABLE(ExpressionVisitor<TypedValue>);
|
|
DEFVISITABLE(ExpressionVisitor<void>);
|
|
bool Accept(HierarchicalTreeVisitor &visitor) override {
|
|
if (visitor.PreVisit(*this)) {
|
|
bool cont = list_->Accept(visitor);
|
|
if (cont && lower_bound_) {
|
|
cont = lower_bound_->Accept(visitor);
|
|
}
|
|
if (cont && upper_bound_) {
|
|
upper_bound_->Accept(visitor);
|
|
}
|
|
}
|
|
return visitor.PostVisit(*this);
|
|
}
|
|
cpp<#)
|
|
(:protected
|
|
#>cpp
|
|
ListSlicingOperator(Expression *list, Expression *lower_bound,
|
|
Expression *upper_bound)
|
|
: list_(list), lower_bound_(lower_bound), upper_bound_(upper_bound) {}
|
|
cpp<#)
|
|
(:private
|
|
#>cpp
|
|
friend class AstStorage;
|
|
cpp<#)
|
|
(:serialize (:slk))
|
|
(:clone))
|
|
|
|
(lcp:define-class if-operator (expression)
|
|
((condition "Expression *" :scope :public
|
|
:slk-save #'slk-save-ast-pointer
|
|
:slk-load (slk-load-ast-pointer "Expression")
|
|
:documentation "None of the expressions should be nullptr. If there is no else_expression, you should make it null PrimitiveLiteral.")
|
|
(then-expression "Expression *" :scope :public
|
|
:slk-save #'slk-save-ast-pointer
|
|
:slk-load (slk-load-ast-pointer "Expression"))
|
|
(else-expression "Expression *" :scope :public
|
|
:slk-save #'slk-save-ast-pointer
|
|
:slk-load (slk-load-ast-pointer "Expression")))
|
|
(:public
|
|
#>cpp
|
|
IfOperator() = default;
|
|
|
|
DEFVISITABLE(ExpressionVisitor<TypedValue>);
|
|
DEFVISITABLE(ExpressionVisitor<void>);
|
|
bool Accept(HierarchicalTreeVisitor &visitor) override {
|
|
if (visitor.PreVisit(*this)) {
|
|
condition_->Accept(visitor) && then_expression_->Accept(visitor) &&
|
|
else_expression_->Accept(visitor);
|
|
}
|
|
return visitor.PostVisit(*this);
|
|
}
|
|
cpp<#)
|
|
(:protected
|
|
#>cpp
|
|
IfOperator(Expression *condition, Expression *then_expression,
|
|
Expression *else_expression)
|
|
: condition_(condition),
|
|
then_expression_(then_expression),
|
|
else_expression_(else_expression) {}
|
|
cpp<#)
|
|
(:private
|
|
#>cpp
|
|
friend class AstStorage;
|
|
cpp<#)
|
|
(:serialize (:slk))
|
|
(:clone))
|
|
|
|
(lcp:define-class base-literal (expression)
|
|
()
|
|
(:abstractp t)
|
|
(:public
|
|
#>cpp
|
|
BaseLiteral() = default;
|
|
cpp<#)
|
|
(:private
|
|
#>cpp
|
|
friend class AstStorage;
|
|
cpp<#)
|
|
(:serialize (:slk))
|
|
(:clone))
|
|
|
|
(lcp:define-class primitive-literal (base-literal)
|
|
((value "::storage::PropertyValue" :scope :public)
|
|
(token-position :int32_t :scope :public :initval -1
|
|
:documentation "This field contains token position of literal used to create PrimitiveLiteral object. If PrimitiveLiteral object is not created from query, leave its value at -1."))
|
|
(:public
|
|
#>cpp
|
|
PrimitiveLiteral() = default;
|
|
|
|
DEFVISITABLE(ExpressionVisitor<TypedValue>);
|
|
DEFVISITABLE(ExpressionVisitor<void>);
|
|
DEFVISITABLE(HierarchicalTreeVisitor);
|
|
cpp<#)
|
|
(:private
|
|
#>cpp
|
|
friend class AstStorage;
|
|
cpp<#)
|
|
(:protected
|
|
#>cpp
|
|
template <typename T>
|
|
explicit PrimitiveLiteral(T value) : value_(value) {}
|
|
template <typename T>
|
|
PrimitiveLiteral(T value, int token_position)
|
|
: value_(value), token_position_(token_position) {}
|
|
cpp<#)
|
|
(:serialize (:slk))
|
|
(:clone))
|
|
|
|
(lcp:define-class list-literal (base-literal)
|
|
((elements "std::vector<Expression *>"
|
|
:scope :public
|
|
:slk-save #'slk-save-ast-vector
|
|
:slk-load (slk-load-ast-vector "Expression")))
|
|
(:public
|
|
#>cpp
|
|
ListLiteral() = default;
|
|
|
|
DEFVISITABLE(ExpressionVisitor<TypedValue>);
|
|
DEFVISITABLE(ExpressionVisitor<void>);
|
|
bool Accept(HierarchicalTreeVisitor &visitor) override {
|
|
if (visitor.PreVisit(*this)) {
|
|
for (auto expr_ptr : elements_)
|
|
if (!expr_ptr->Accept(visitor)) break;
|
|
}
|
|
return visitor.PostVisit(*this);
|
|
}
|
|
cpp<#)
|
|
(:protected
|
|
#>cpp
|
|
explicit ListLiteral(const std::vector<Expression *> &elements)
|
|
: elements_(elements) {}
|
|
cpp<#)
|
|
(:private
|
|
#>cpp
|
|
friend class AstStorage;
|
|
cpp<#)
|
|
(:serialize (:slk))
|
|
(:clone))
|
|
|
|
(lcp:define-class map-literal (base-literal)
|
|
((elements "std::unordered_map<PropertyIx, Expression *>"
|
|
:slk-save #'slk-save-property-map
|
|
:slk-load #'slk-load-property-map
|
|
:clone #'clone-property-map
|
|
:scope :public))
|
|
(:public
|
|
#>cpp
|
|
MapLiteral() = default;
|
|
|
|
DEFVISITABLE(ExpressionVisitor<TypedValue>);
|
|
DEFVISITABLE(ExpressionVisitor<void>);
|
|
bool Accept(HierarchicalTreeVisitor &visitor) override {
|
|
if (visitor.PreVisit(*this)) {
|
|
for (auto pair : elements_)
|
|
if (!pair.second->Accept(visitor)) break;
|
|
}
|
|
return visitor.PostVisit(*this);
|
|
}
|
|
cpp<#)
|
|
(:protected
|
|
#>cpp
|
|
explicit MapLiteral(
|
|
const std::unordered_map<PropertyIx, Expression *> &elements)
|
|
: elements_(elements) {}
|
|
cpp<#)
|
|
(:private
|
|
#>cpp
|
|
friend class AstStorage;
|
|
cpp<#)
|
|
(:serialize (:slk))
|
|
(:clone))
|
|
|
|
(lcp:define-class identifier (expression)
|
|
((name "std::string" :scope :public)
|
|
(user-declared :bool :initval "true" :scope :public)
|
|
(symbol-pos :int32_t :initval -1 :scope :public
|
|
:documentation "Symbol table position of the symbol this Identifier is mapped to."))
|
|
(:public
|
|
#>cpp
|
|
Identifier() = default;
|
|
|
|
DEFVISITABLE(ExpressionVisitor<TypedValue>);
|
|
DEFVISITABLE(ExpressionVisitor<void>);
|
|
DEFVISITABLE(HierarchicalTreeVisitor);
|
|
|
|
Identifier *MapTo(const Symbol &symbol) {
|
|
symbol_pos_ = symbol.position();
|
|
return this;
|
|
}
|
|
|
|
explicit Identifier(const std::string &name) : name_(name) {}
|
|
Identifier(const std::string &name, bool user_declared)
|
|
: name_(name), user_declared_(user_declared) {}
|
|
cpp<#)
|
|
(:private
|
|
#>cpp
|
|
friend class AstStorage;
|
|
cpp<#)
|
|
(:serialize (:slk))
|
|
(:clone))
|
|
|
|
(lcp:define-class property-lookup (expression)
|
|
((expression "Expression *" :initval "nullptr" :scope :public
|
|
:slk-save #'slk-save-ast-pointer
|
|
:slk-load (slk-load-ast-pointer "Expression"))
|
|
(property "PropertyIx" :scope :public
|
|
:slk-load (lambda (member)
|
|
#>cpp
|
|
slk::Load(&self->${member}, reader, storage);
|
|
cpp<#)
|
|
:clone (lambda (source dest)
|
|
#>cpp
|
|
${dest} = storage->GetPropertyIx(${source}.name);
|
|
cpp<#)))
|
|
(:public
|
|
#>cpp
|
|
PropertyLookup() = default;
|
|
|
|
DEFVISITABLE(ExpressionVisitor<TypedValue>);
|
|
DEFVISITABLE(ExpressionVisitor<void>);
|
|
bool Accept(HierarchicalTreeVisitor &visitor) override {
|
|
if (visitor.PreVisit(*this)) {
|
|
expression_->Accept(visitor);
|
|
}
|
|
return visitor.PostVisit(*this);
|
|
}
|
|
cpp<#)
|
|
(:protected
|
|
#>cpp
|
|
PropertyLookup(Expression *expression, PropertyIx property)
|
|
: expression_(expression), property_(property) {}
|
|
cpp<#)
|
|
(:private
|
|
#>cpp
|
|
friend class AstStorage;
|
|
cpp<#)
|
|
(:serialize (:slk))
|
|
(:clone))
|
|
|
|
(lcp:define-class labels-test (expression)
|
|
((expression "Expression *" :initval "nullptr" :scope :public
|
|
:slk-save #'slk-save-ast-pointer
|
|
:slk-load (slk-load-ast-pointer "Expression"))
|
|
(labels "std::vector<LabelIx>" :scope :public
|
|
:slk-load (lambda (member)
|
|
#>cpp
|
|
size_t size = 0;
|
|
slk::Load(&size, reader);
|
|
self->${member}.resize(size);
|
|
for (size_t i = 0; i < size; ++i) {
|
|
slk::Load(&self->${member}[i], reader, storage);
|
|
}
|
|
cpp<#)
|
|
:clone (clone-name-ix-vector "Label")))
|
|
(:public
|
|
#>cpp
|
|
LabelsTest() = default;
|
|
|
|
DEFVISITABLE(ExpressionVisitor<TypedValue>);
|
|
DEFVISITABLE(ExpressionVisitor<void>);
|
|
bool Accept(HierarchicalTreeVisitor &visitor) override {
|
|
if (visitor.PreVisit(*this)) {
|
|
expression_->Accept(visitor);
|
|
}
|
|
return visitor.PostVisit(*this);
|
|
}
|
|
cpp<#)
|
|
(:protected
|
|
#>cpp
|
|
LabelsTest(Expression *expression, const std::vector<LabelIx> &labels)
|
|
: expression_(expression), labels_(labels) {}
|
|
cpp<#)
|
|
(:private
|
|
#>cpp
|
|
friend class AstStorage;
|
|
cpp<#)
|
|
(:serialize (:slk))
|
|
(:clone))
|
|
|
|
(lcp:define-class function (expression)
|
|
((arguments "std::vector<Expression *>"
|
|
:scope :public
|
|
:slk-save #'slk-save-ast-vector
|
|
:slk-load (slk-load-ast-vector "Expression"))
|
|
(function-name "std::string" :scope :public)
|
|
(function "std::function<TypedValue(const TypedValue *, int64_t,
|
|
const FunctionContext &)>"
|
|
:scope :public
|
|
:dont-save t
|
|
:clone :copy
|
|
:slk-load (lambda (member)
|
|
#>cpp
|
|
self->${member} = query::NameToFunction(self->function_name_);
|
|
cpp<#)))
|
|
(:public
|
|
#>cpp
|
|
Function() = default;
|
|
|
|
DEFVISITABLE(ExpressionVisitor<TypedValue>);
|
|
DEFVISITABLE(ExpressionVisitor<void>);
|
|
bool Accept(HierarchicalTreeVisitor &visitor) override {
|
|
if (visitor.PreVisit(*this)) {
|
|
for (auto *argument : arguments_) {
|
|
if (!argument->Accept(visitor)) break;
|
|
}
|
|
}
|
|
return visitor.PostVisit(*this);
|
|
}
|
|
cpp<#)
|
|
(:protected
|
|
#>cpp
|
|
Function(const std::string &function_name,
|
|
const std::vector<Expression *> &arguments)
|
|
: arguments_(arguments),
|
|
function_name_(function_name),
|
|
function_(NameToFunction(function_name_)) {
|
|
if (!function_) {
|
|
throw SemanticException("Function '{}' doesn't exist.", function_name);
|
|
}
|
|
}
|
|
cpp<#)
|
|
(:private
|
|
#>cpp
|
|
friend class AstStorage;
|
|
cpp<#)
|
|
(:serialize (:slk))
|
|
(:clone))
|
|
|
|
(lcp:define-class reduce (expression)
|
|
((accumulator "Identifier *" :initval "nullptr" :scope :public
|
|
:slk-save #'slk-save-ast-pointer
|
|
:slk-load (slk-load-ast-pointer "Identifier")
|
|
:documentation "Identifier for the accumulating variable")
|
|
(initializer "Expression *" :initval "nullptr" :scope :public
|
|
:slk-save #'slk-save-ast-pointer
|
|
:slk-load (slk-load-ast-pointer "Expression")
|
|
:documentation "Expression which produces the initial accumulator value.")
|
|
(identifier "Identifier *" :initval "nullptr" :scope :public
|
|
:slk-save #'slk-save-ast-pointer
|
|
:slk-load (slk-load-ast-pointer "Identifier")
|
|
:documentation "Identifier for the list element.")
|
|
(list "Expression *" :initval "nullptr" :scope :public
|
|
:slk-save #'slk-save-ast-pointer
|
|
:slk-load (slk-load-ast-pointer "Expression")
|
|
:documentation "Expression which produces a list to be reduced.")
|
|
(expression "Expression *" :initval "nullptr" :scope :public
|
|
:slk-save #'slk-save-ast-pointer
|
|
:slk-load (slk-load-ast-pointer "Expression")
|
|
:documentation "Expression which does the reduction, i.e. produces the new accumulator value."))
|
|
(:public
|
|
#>cpp
|
|
Reduce() = default;
|
|
|
|
DEFVISITABLE(ExpressionVisitor<TypedValue>);
|
|
DEFVISITABLE(ExpressionVisitor<void>);
|
|
bool Accept(HierarchicalTreeVisitor &visitor) override {
|
|
if (visitor.PreVisit(*this)) {
|
|
accumulator_->Accept(visitor) && initializer_->Accept(visitor) &&
|
|
identifier_->Accept(visitor) && list_->Accept(visitor) &&
|
|
expression_->Accept(visitor);
|
|
}
|
|
return visitor.PostVisit(*this);
|
|
}
|
|
cpp<#)
|
|
(:protected
|
|
#>cpp
|
|
Reduce(Identifier *accumulator, Expression *initializer, Identifier *identifier,
|
|
Expression *list, Expression *expression)
|
|
: accumulator_(accumulator),
|
|
initializer_(initializer),
|
|
identifier_(identifier),
|
|
list_(list),
|
|
expression_(expression) {}
|
|
cpp<#)
|
|
(:private
|
|
#>cpp
|
|
friend class AstStorage;
|
|
cpp<#)
|
|
(:serialize (:slk))
|
|
(:clone))
|
|
|
|
(lcp:define-class coalesce (expression)
|
|
((expressions "std::vector<Expression *>"
|
|
:scope :public
|
|
:slk-save #'slk-save-ast-vector
|
|
:slk-load (slk-load-ast-vector "Expression")
|
|
:documentation "A list of expressions to evaluate. None of the expressions should be nullptr."))
|
|
(:public
|
|
#>cpp
|
|
Coalesce() = default;
|
|
|
|
DEFVISITABLE(ExpressionVisitor<TypedValue>);
|
|
DEFVISITABLE(ExpressionVisitor<void>);
|
|
bool Accept(HierarchicalTreeVisitor &visitor) override {
|
|
if (visitor.PreVisit(*this)) {
|
|
for (auto *expr : expressions_) {
|
|
if (!expr->Accept(visitor)) break;
|
|
}
|
|
}
|
|
return visitor.PostVisit(*this);
|
|
}
|
|
cpp<#
|
|
)
|
|
(:private
|
|
#>cpp
|
|
explicit Coalesce(const std::vector<Expression *> &expressions)
|
|
: expressions_(expressions) {}
|
|
|
|
friend class AstStorage;
|
|
cpp<#)
|
|
(:serialize (:slk))
|
|
(:clone))
|
|
|
|
(lcp:define-class extract (expression)
|
|
((identifier "Identifier *" :initval "nullptr" :scope :public
|
|
:slk-save #'slk-save-ast-pointer
|
|
:slk-load (slk-load-ast-pointer "Identifier")
|
|
:documentation "Identifier for the list element.")
|
|
(list "Expression *" :initval "nullptr" :scope :public
|
|
:slk-save #'slk-save-ast-pointer
|
|
:slk-load (slk-load-ast-pointer "Expression")
|
|
:documentation "Expression which produces a list which will be extracted.")
|
|
(expression "Expression *" :initval "nullptr" :scope :public
|
|
:slk-save #'slk-save-ast-pointer
|
|
:slk-load (slk-load-ast-pointer "Expression")
|
|
:documentation "Expression which produces the new value for list element."))
|
|
(:public
|
|
#>cpp
|
|
Extract() = default;
|
|
|
|
DEFVISITABLE(ExpressionVisitor<TypedValue>);
|
|
DEFVISITABLE(ExpressionVisitor<void>);
|
|
bool Accept(HierarchicalTreeVisitor &visitor) override {
|
|
if (visitor.PreVisit(*this)) {
|
|
identifier_->Accept(visitor) && list_->Accept(visitor) &&
|
|
expression_->Accept(visitor);
|
|
}
|
|
return visitor.PostVisit(*this);
|
|
}
|
|
cpp<#)
|
|
(:protected
|
|
#>cpp
|
|
Extract(Identifier *identifier, Expression *list, Expression *expression)
|
|
: identifier_(identifier), list_(list), expression_(expression) {}
|
|
cpp<#)
|
|
(:private
|
|
#>cpp
|
|
friend class AstStorage;
|
|
cpp<#)
|
|
(:serialize (:slk))
|
|
(:clone))
|
|
|
|
(lcp:define-class all (expression)
|
|
((identifier "Identifier *" :initval "nullptr" :scope :public
|
|
:slk-save #'slk-save-ast-pointer
|
|
:slk-load (slk-load-ast-pointer "Identifier"))
|
|
(list-expression "Expression *" :initval "nullptr" :scope :public
|
|
:slk-save #'slk-save-ast-pointer
|
|
:slk-load (slk-load-ast-pointer "Expression"))
|
|
(where "Where *" :initval "nullptr" :scope :public
|
|
:slk-save #'slk-save-ast-pointer
|
|
:slk-load (slk-load-ast-pointer "Where")))
|
|
(:public
|
|
#>cpp
|
|
All() = default;
|
|
|
|
DEFVISITABLE(ExpressionVisitor<TypedValue>);
|
|
DEFVISITABLE(ExpressionVisitor<void>);
|
|
bool Accept(HierarchicalTreeVisitor &visitor) override {
|
|
if (visitor.PreVisit(*this)) {
|
|
identifier_->Accept(visitor) && list_expression_->Accept(visitor) &&
|
|
where_->Accept(visitor);
|
|
}
|
|
return visitor.PostVisit(*this);
|
|
}
|
|
cpp<#)
|
|
(:protected
|
|
#>cpp
|
|
All(Identifier *identifier, Expression *list_expression, Where *where)
|
|
: identifier_(identifier),
|
|
list_expression_(list_expression),
|
|
where_(where) {}
|
|
cpp<#)
|
|
(:private
|
|
#>cpp
|
|
friend class AstStorage;
|
|
cpp<#)
|
|
(:serialize (:slk))
|
|
(:clone))
|
|
|
|
;; TODO: This is pretty much copy pasted from All. Consider merging Reduce,
|
|
;; All, Any, None and Single into something like a higher-order function call
|
|
;; which takes a list argument and a function which is applied on list elements.
|
|
(lcp:define-class single (expression)
|
|
((identifier "Identifier *" :initval "nullptr" :scope :public
|
|
:slk-save #'slk-save-ast-pointer
|
|
:slk-load (slk-load-ast-pointer "Identifier"))
|
|
(list-expression "Expression *" :initval "nullptr" :scope :public
|
|
:slk-save #'slk-save-ast-pointer
|
|
:slk-load (slk-load-ast-pointer "Expression"))
|
|
(where "Where *" :initval "nullptr" :scope :public
|
|
:slk-save #'slk-save-ast-pointer
|
|
:slk-load (slk-load-ast-pointer "Where")))
|
|
(:public
|
|
#>cpp
|
|
Single() = default;
|
|
|
|
DEFVISITABLE(ExpressionVisitor<TypedValue>);
|
|
DEFVISITABLE(ExpressionVisitor<void>);
|
|
bool Accept(HierarchicalTreeVisitor &visitor) override {
|
|
if (visitor.PreVisit(*this)) {
|
|
identifier_->Accept(visitor) && list_expression_->Accept(visitor) &&
|
|
where_->Accept(visitor);
|
|
}
|
|
return visitor.PostVisit(*this);
|
|
}
|
|
cpp<#)
|
|
(:protected
|
|
#>cpp
|
|
Single(Identifier *identifier, Expression *list_expression, Where *where)
|
|
: identifier_(identifier),
|
|
list_expression_(list_expression),
|
|
where_(where) {}
|
|
cpp<#)
|
|
(:private
|
|
#>cpp
|
|
friend class AstStorage;
|
|
cpp<#)
|
|
(:serialize (:slk))
|
|
(:clone))
|
|
|
|
;; TODO: This is pretty much copy pasted from All. Consider merging Reduce,
|
|
;; All, Any, None and Single into something like a higher-order function call
|
|
;; which takes a list argument and a function which is applied on list elements.
|
|
(lcp:define-class any (expression)
|
|
((identifier "Identifier *" :initval "nullptr" :scope :public
|
|
:slk-save #'slk-save-ast-pointer
|
|
:slk-load (slk-load-ast-pointer "Identifier"))
|
|
(list-expression "Expression *" :initval "nullptr" :scope :public
|
|
:slk-save #'slk-save-ast-pointer
|
|
:slk-load (slk-load-ast-pointer "Expression"))
|
|
(where "Where *" :initval "nullptr" :scope :public
|
|
:slk-save #'slk-save-ast-pointer
|
|
:slk-load (slk-load-ast-pointer "Where")))
|
|
(:public
|
|
#>cpp
|
|
Any() = default;
|
|
|
|
DEFVISITABLE(ExpressionVisitor<TypedValue>);
|
|
DEFVISITABLE(ExpressionVisitor<void>);
|
|
bool Accept(HierarchicalTreeVisitor &visitor) override {
|
|
if (visitor.PreVisit(*this)) {
|
|
identifier_->Accept(visitor) && list_expression_->Accept(visitor) &&
|
|
where_->Accept(visitor);
|
|
}
|
|
return visitor.PostVisit(*this);
|
|
}
|
|
cpp<#)
|
|
(:protected
|
|
#>cpp
|
|
Any(Identifier *identifier, Expression *list_expression, Where *where)
|
|
: identifier_(identifier),
|
|
list_expression_(list_expression),
|
|
where_(where) {}
|
|
cpp<#)
|
|
(:private
|
|
#>cpp
|
|
friend class AstStorage;
|
|
cpp<#)
|
|
(:serialize (:slk))
|
|
(:clone))
|
|
|
|
;; TODO: This is pretty much copy pasted from All. Consider merging Reduce,
|
|
;; All, Any, None and Single into something like a higher-order function call
|
|
;; which takes a list argument and a function which is applied on list elements.
|
|
(lcp:define-class none (expression)
|
|
((identifier "Identifier *" :initval "nullptr" :scope :public
|
|
:slk-save #'slk-save-ast-pointer
|
|
:slk-load (slk-load-ast-pointer "Identifier"))
|
|
(list-expression "Expression *" :initval "nullptr" :scope :public
|
|
:slk-save #'slk-save-ast-pointer
|
|
:slk-load (slk-load-ast-pointer "Expression"))
|
|
(where "Where *" :initval "nullptr" :scope :public
|
|
:slk-save #'slk-save-ast-pointer
|
|
:slk-load (slk-load-ast-pointer "Where")))
|
|
(:public
|
|
#>cpp
|
|
None() = default;
|
|
|
|
DEFVISITABLE(ExpressionVisitor<TypedValue>);
|
|
DEFVISITABLE(ExpressionVisitor<void>);
|
|
bool Accept(HierarchicalTreeVisitor &visitor) override {
|
|
if (visitor.PreVisit(*this)) {
|
|
identifier_->Accept(visitor) && list_expression_->Accept(visitor) &&
|
|
where_->Accept(visitor);
|
|
}
|
|
return visitor.PostVisit(*this);
|
|
}
|
|
cpp<#)
|
|
(:protected
|
|
#>cpp
|
|
None(Identifier *identifier, Expression *list_expression, Where *where)
|
|
: identifier_(identifier),
|
|
list_expression_(list_expression),
|
|
where_(where) {}
|
|
cpp<#)
|
|
(:private
|
|
#>cpp
|
|
friend class AstStorage;
|
|
cpp<#)
|
|
(:serialize (:slk))
|
|
(:clone))
|
|
|
|
(lcp:define-class parameter-lookup (expression)
|
|
((token-position :int32_t :initval -1 :scope :public
|
|
:documentation "This field contains token position of *literal* used to create ParameterLookup object. If ParameterLookup object is not created from a literal leave this value at -1."))
|
|
(:public
|
|
#>cpp
|
|
ParameterLookup() = default;
|
|
|
|
DEFVISITABLE(ExpressionVisitor<TypedValue>);
|
|
DEFVISITABLE(ExpressionVisitor<void>);
|
|
DEFVISITABLE(HierarchicalTreeVisitor);
|
|
cpp<#)
|
|
(:protected
|
|
#>cpp
|
|
explicit ParameterLookup(int token_position)
|
|
: token_position_(token_position) {}
|
|
cpp<#)
|
|
(:private
|
|
#>cpp
|
|
friend class AstStorage;
|
|
cpp<#)
|
|
(:serialize (:slk))
|
|
(:clone))
|
|
|
|
(lcp:define-class regex-match (expression)
|
|
((string-expr "Expression *" :scope :public
|
|
:slk-save #'slk-save-ast-pointer
|
|
:slk-load (slk-load-ast-pointer "Expression"))
|
|
(regex "Expression *" :scope :public
|
|
:slk-save #'slk-save-ast-pointer
|
|
:slk-load (slk-load-ast-pointer "Expression")))
|
|
(:public
|
|
#>cpp
|
|
RegexMatch() = default;
|
|
|
|
DEFVISITABLE(ExpressionVisitor<TypedValue>);
|
|
DEFVISITABLE(ExpressionVisitor<void>);
|
|
bool Accept(HierarchicalTreeVisitor &visitor) override {
|
|
if (visitor.PreVisit(*this)) {
|
|
string_expr_->Accept(visitor) && regex_->Accept(visitor);
|
|
}
|
|
return visitor.PostVisit(*this);
|
|
}
|
|
cpp<#)
|
|
(:private
|
|
#>cpp
|
|
friend class AstStorage;
|
|
RegexMatch(Expression *string_expr, Expression *regex)
|
|
: string_expr_(string_expr), regex_(regex) {}
|
|
cpp<#)
|
|
(:serialize (:slk))
|
|
(:clone))
|
|
|
|
(lcp:define-class named-expression (tree "::utils::Visitable<HierarchicalTreeVisitor>"
|
|
"::utils::Visitable<ExpressionVisitor<TypedValue>>"
|
|
"::utils::Visitable<ExpressionVisitor<void>>")
|
|
((name "std::string" :scope :public)
|
|
(expression "Expression *" :initval "nullptr" :scope :public
|
|
:slk-save #'slk-save-ast-pointer
|
|
:slk-load (slk-load-ast-pointer "Expression"))
|
|
(token-position :int32_t :initval -1 :scope :public
|
|
:documentation "This field contains token position of first token in named expression used to create name_. If NamedExpression object is not created from query or it is aliased leave this value at -1.")
|
|
(symbol-pos :int32_t :initval -1 :scope :public
|
|
:documentation "Symbol table position of the symbol this NamedExpression is mapped to."))
|
|
(:public
|
|
#>cpp
|
|
using utils::Visitable<ExpressionVisitor<TypedValue>>::Accept;
|
|
using utils::Visitable<ExpressionVisitor<void>>::Accept;
|
|
using utils::Visitable<HierarchicalTreeVisitor>::Accept;
|
|
|
|
NamedExpression() = default;
|
|
|
|
DEFVISITABLE(ExpressionVisitor<TypedValue>);
|
|
DEFVISITABLE(ExpressionVisitor<void>);
|
|
bool Accept(HierarchicalTreeVisitor &visitor) override {
|
|
if (visitor.PreVisit(*this)) {
|
|
expression_->Accept(visitor);
|
|
}
|
|
return visitor.PostVisit(*this);
|
|
}
|
|
|
|
NamedExpression *MapTo(const Symbol &symbol) {
|
|
symbol_pos_ = symbol.position();
|
|
return this;
|
|
}
|
|
cpp<#)
|
|
(:protected
|
|
#>cpp
|
|
explicit NamedExpression(const std::string &name) : name_(name) {}
|
|
NamedExpression(const std::string &name, Expression *expression)
|
|
: name_(name), expression_(expression) {}
|
|
NamedExpression(const std::string &name, Expression *expression,
|
|
int token_position)
|
|
: name_(name), expression_(expression), token_position_(token_position) {}
|
|
cpp<#)
|
|
(:private
|
|
#>cpp
|
|
friend class AstStorage;
|
|
cpp<#)
|
|
(:serialize (:slk :ignore-other-base-classes t))
|
|
(:clone :ignore-other-base-classes t)
|
|
(:type-info :ignore-other-base-classes t))
|
|
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
;;; END Expressions
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
|
|
(lcp:define-class pattern-atom (tree "::utils::Visitable<HierarchicalTreeVisitor>")
|
|
((identifier "Identifier *" :initval "nullptr" :scope :public
|
|
:slk-save #'slk-save-ast-pointer
|
|
:slk-load (slk-load-ast-pointer "Identifier")))
|
|
(:abstractp t)
|
|
(:public
|
|
#>cpp
|
|
using utils::Visitable<HierarchicalTreeVisitor>::Accept;
|
|
|
|
PatternAtom() = default;
|
|
cpp<#)
|
|
(:protected
|
|
#>cpp
|
|
explicit PatternAtom(Identifier *identifier) : identifier_(identifier) {}
|
|
cpp<#)
|
|
(:private
|
|
#>cpp
|
|
friend class AstStorage;
|
|
cpp<#)
|
|
(:serialize (:slk :ignore-other-base-classes t))
|
|
(:clone :ignore-other-base-classes t)
|
|
(:type-info :ignore-other-base-classes t))
|
|
|
|
(defun clone-variant-properties (source destination)
|
|
#>cpp
|
|
if (const auto *properties = std::get_if<std::unordered_map<PropertyIx, Expression *>>(&${source})) {
|
|
auto &new_obj_properties = std::get<std::unordered_map<PropertyIx, Expression *>>(${destination});
|
|
for (const auto &[property, value_expression] : *properties) {
|
|
PropertyIx key = storage->GetPropertyIx(property.name);
|
|
new_obj_properties[key] = value_expression->Clone(storage);
|
|
}
|
|
} else {
|
|
${destination} = std::get<ParameterLookup *>(${source})->Clone(storage);
|
|
}
|
|
cpp<#)
|
|
|
|
(lcp:define-class node-atom (pattern-atom)
|
|
((labels "std::vector<LabelIx>" :scope :public
|
|
:slk-load (lambda (member)
|
|
#>cpp
|
|
size_t size = 0;
|
|
slk::Load(&size, reader);
|
|
self->${member}.resize(size);
|
|
for (size_t i = 0; i < size; ++i) {
|
|
slk::Load(&self->${member}[i], reader, storage);
|
|
}
|
|
cpp<#)
|
|
:clone (clone-name-ix-vector "Label"))
|
|
(properties "std::variant<std::unordered_map<PropertyIx, Expression *>, ParameterLookup*>"
|
|
:clone #'clone-variant-properties
|
|
:scope :public))
|
|
(:public
|
|
#>cpp
|
|
bool Accept(HierarchicalTreeVisitor &visitor) override {
|
|
if (visitor.PreVisit(*this)) {
|
|
if (auto* properties = std::get_if<std::unordered_map<PropertyIx, Expression *>>(&properties_)) {
|
|
bool cont = identifier_->Accept(visitor);
|
|
for (auto &property : *properties) {
|
|
if (cont) {
|
|
cont = property.second->Accept(visitor);
|
|
}
|
|
}
|
|
} else {
|
|
std::get<ParameterLookup*>(properties_)->Accept(visitor);
|
|
}
|
|
}
|
|
return visitor.PostVisit(*this);
|
|
}
|
|
cpp<#)
|
|
(:protected
|
|
#>cpp
|
|
using PatternAtom::PatternAtom;
|
|
cpp<#)
|
|
(:private
|
|
#>cpp
|
|
friend class AstStorage;
|
|
cpp<#)
|
|
(:serialize (:slk))
|
|
(:clone))
|
|
|
|
(lcp:define-class edge-atom (pattern-atom)
|
|
((type "Type" :initval "Type::SINGLE" :scope :public)
|
|
(direction "Direction" :initval "Direction::BOTH" :scope :public)
|
|
(edge-types "std::vector<EdgeTypeIx>" :scope :public
|
|
:slk-load (lambda (member)
|
|
#>cpp
|
|
size_t size = 0;
|
|
slk::Load(&size, reader);
|
|
self->${member}.resize(size);
|
|
for (size_t i = 0; i < size; ++i) {
|
|
slk::Load(&self->${member}[i], reader, storage);
|
|
}
|
|
cpp<#)
|
|
:clone (clone-name-ix-vector "EdgeType"))
|
|
(properties "std::variant<std::unordered_map<PropertyIx, Expression *>, ParameterLookup*>"
|
|
:scope :public
|
|
:slk-save #'slk-save-property-map
|
|
:slk-load #'slk-load-property-map
|
|
:clone #'clone-variant-properties)
|
|
(lower-bound "Expression *" :initval "nullptr" :scope :public
|
|
:slk-save #'slk-save-ast-pointer
|
|
:slk-load (slk-load-ast-pointer "Expression")
|
|
:documentation "Evaluates to lower bound in variable length expands.")
|
|
(upper-bound "Expression *" :initval "nullptr" :scope :public
|
|
:slk-save #'slk-save-ast-pointer
|
|
:slk-load (slk-load-ast-pointer "Expression")
|
|
:documentation "Evaluated to upper bound in variable length expands.")
|
|
(filter-lambda "Lambda" :scope :public
|
|
:documentation "Filter lambda for variable length expands. Can have an empty expression, but identifiers must be valid, because an optimization pass may inline other expressions into this lambda."
|
|
:slk-load (lambda (member)
|
|
#>cpp
|
|
slk::Load(&self->${member}, reader, storage);
|
|
cpp<#))
|
|
(weight-lambda "Lambda" :scope :public
|
|
:documentation "Used in weighted shortest path. It must have valid expressions and identifiers. In all other expand types, it is empty."
|
|
:slk-load (lambda (member)
|
|
#>cpp
|
|
slk::Load(&self->${member}, reader, storage);
|
|
cpp<#))
|
|
(total-weight "Identifier *" :initval "nullptr" :scope :public
|
|
:slk-save #'slk-save-ast-pointer
|
|
:slk-load (slk-load-ast-pointer "Identifier")
|
|
:documentation "Variable where the total weight for weighted shortest path will be stored."))
|
|
(:public
|
|
(lcp:define-enum type
|
|
(single depth-first breadth-first weighted-shortest-path)
|
|
(:serialize))
|
|
(lcp:define-enum direction
|
|
(in out both)
|
|
(:serialize))
|
|
(lcp:define-struct lambda ()
|
|
((inner-edge "Identifier *" :initval "nullptr"
|
|
:slk-save #'slk-save-ast-pointer
|
|
:slk-load (slk-load-ast-pointer "Identifier")
|
|
:documentation "Argument identifier for the edge currently being traversed.")
|
|
(inner-node "Identifier *" :initval "nullptr"
|
|
:slk-save #'slk-save-ast-pointer
|
|
:slk-load (slk-load-ast-pointer "Identifier")
|
|
:documentation "Argument identifier for the destination node of the edge.")
|
|
(expression "Expression *" :initval "nullptr"
|
|
:slk-save #'slk-save-ast-pointer
|
|
:slk-load (slk-load-ast-pointer "Expression")
|
|
:documentation "Evaluates the result of the lambda."))
|
|
(:documentation "Lambda for use in filtering or weight calculation during variable expand.")
|
|
(:serialize (:slk :load-args '((storage "query::AstStorage *"))))
|
|
(:clone :args '((storage "AstStorage *"))))
|
|
#>cpp
|
|
bool Accept(HierarchicalTreeVisitor &visitor) override {
|
|
if (visitor.PreVisit(*this)) {
|
|
bool cont = identifier_->Accept(visitor);
|
|
if (auto *properties = std::get_if<std::unordered_map<query::PropertyIx, query::Expression *>>(&properties_)) {
|
|
for (auto &property : *properties) {
|
|
if (cont) {
|
|
cont = property.second->Accept(visitor);
|
|
}
|
|
}
|
|
} else {
|
|
std::get<ParameterLookup *>(properties_)->Accept(visitor);
|
|
}
|
|
if (cont && lower_bound_) {
|
|
cont = lower_bound_->Accept(visitor);
|
|
}
|
|
if (cont && upper_bound_) {
|
|
cont = upper_bound_->Accept(visitor);
|
|
}
|
|
if (cont && total_weight_) {
|
|
total_weight_->Accept(visitor);
|
|
}
|
|
}
|
|
return visitor.PostVisit(*this);
|
|
}
|
|
|
|
bool IsVariable() const {
|
|
switch (type_) {
|
|
case Type::DEPTH_FIRST:
|
|
case Type::BREADTH_FIRST:
|
|
case Type::WEIGHTED_SHORTEST_PATH:
|
|
return true;
|
|
case Type::SINGLE:
|
|
return false;
|
|
}
|
|
}
|
|
cpp<#)
|
|
(:protected
|
|
#>cpp
|
|
using PatternAtom::PatternAtom;
|
|
EdgeAtom(Identifier *identifier, Type type, Direction direction)
|
|
: PatternAtom(identifier), type_(type), direction_(direction) {}
|
|
|
|
// Creates an edge atom for a SINGLE expansion with the given .
|
|
EdgeAtom(Identifier *identifier, Type type, Direction direction,
|
|
const std::vector<EdgeTypeIx> &edge_types)
|
|
: PatternAtom(identifier),
|
|
type_(type),
|
|
direction_(direction),
|
|
edge_types_(edge_types) {}
|
|
cpp<#)
|
|
(:private
|
|
#>cpp
|
|
friend class AstStorage;
|
|
cpp<#)
|
|
(:serialize (:slk))
|
|
(:clone))
|
|
|
|
(lcp:define-class pattern (tree "::utils::Visitable<HierarchicalTreeVisitor>")
|
|
((identifier "Identifier *" :initval "nullptr" :scope :public
|
|
:slk-save #'slk-save-ast-pointer
|
|
:slk-load (slk-load-ast-pointer "Identifier"))
|
|
(atoms "std::vector<PatternAtom *>"
|
|
:scope :public
|
|
:slk-save #'slk-save-ast-vector
|
|
:slk-load (slk-load-ast-vector "PatternAtom")))
|
|
(:public
|
|
#>cpp
|
|
using utils::Visitable<HierarchicalTreeVisitor>::Accept;
|
|
|
|
Pattern() = default;
|
|
|
|
bool Accept(HierarchicalTreeVisitor &visitor) override {
|
|
if (visitor.PreVisit(*this)) {
|
|
bool cont = identifier_->Accept(visitor);
|
|
for (auto &part : atoms_) {
|
|
if (cont) {
|
|
cont = part->Accept(visitor);
|
|
}
|
|
}
|
|
}
|
|
return visitor.PostVisit(*this);
|
|
}
|
|
cpp<#)
|
|
(:private
|
|
#>cpp
|
|
friend class AstStorage;
|
|
cpp<#)
|
|
(:serialize (:slk :ignore-other-base-classes t))
|
|
(:clone :ignore-other-base-classes t)
|
|
(:type-info :ignore-other-base-classes t))
|
|
|
|
(lcp:define-class clause (tree "::utils::Visitable<HierarchicalTreeVisitor>")
|
|
()
|
|
(:abstractp t)
|
|
(:public
|
|
#>cpp
|
|
using utils::Visitable<HierarchicalTreeVisitor>::Accept;
|
|
|
|
Clause() = default;
|
|
cpp<#)
|
|
(:private
|
|
#>cpp
|
|
friend class AstStorage;
|
|
cpp<#)
|
|
(:serialize (:slk :ignore-other-base-classes t))
|
|
(:clone :ignore-other-base-classes t)
|
|
(:type-info :ignore-other-base-classes t))
|
|
|
|
(lcp:define-class single-query (tree "::utils::Visitable<HierarchicalTreeVisitor>")
|
|
((clauses "std::vector<Clause *>"
|
|
:scope :public
|
|
:slk-save #'slk-save-ast-vector
|
|
:slk-load (slk-load-ast-vector "Clause")))
|
|
(:public
|
|
#>cpp
|
|
using utils::Visitable<HierarchicalTreeVisitor>::Accept;
|
|
|
|
SingleQuery() = default;
|
|
|
|
bool Accept(HierarchicalTreeVisitor &visitor) override {
|
|
if (visitor.PreVisit(*this)) {
|
|
for (auto &clause : clauses_) {
|
|
if (!clause->Accept(visitor)) break;
|
|
}
|
|
}
|
|
return visitor.PostVisit(*this);
|
|
}
|
|
cpp<#)
|
|
(:private
|
|
#>cpp
|
|
friend class AstStorage;
|
|
cpp<#)
|
|
(:serialize (:slk :ignore-other-base-classes t))
|
|
(:clone :ignore-other-base-classes t)
|
|
(:type-info :ignore-other-base-classes t))
|
|
|
|
(lcp:define-class cypher-union (tree "::utils::Visitable<HierarchicalTreeVisitor>")
|
|
((single-query "SingleQuery *" :initval "nullptr" :scope :public
|
|
:slk-save #'slk-save-ast-pointer
|
|
:slk-load (slk-load-ast-pointer "SingleQuery"))
|
|
(distinct :bool :initval "false" :scope :public)
|
|
(union-symbols "std::vector<Symbol>" :scope :public
|
|
:documentation "Holds symbols that are created during symbol generation phase. These symbols are used when UNION/UNION ALL combines single query results."))
|
|
(:public
|
|
#>cpp
|
|
using utils::Visitable<HierarchicalTreeVisitor>::Accept;
|
|
|
|
CypherUnion() = default;
|
|
|
|
bool Accept(HierarchicalTreeVisitor &visitor) override {
|
|
if (visitor.PreVisit(*this)) {
|
|
single_query_->Accept(visitor);
|
|
}
|
|
return visitor.PostVisit(*this);
|
|
}
|
|
cpp<#)
|
|
(:protected
|
|
#>cpp
|
|
explicit CypherUnion(bool distinct) : distinct_(distinct) {}
|
|
CypherUnion(bool distinct, SingleQuery *single_query,
|
|
std::vector<Symbol> union_symbols)
|
|
: single_query_(single_query),
|
|
distinct_(distinct),
|
|
union_symbols_(union_symbols) {}
|
|
cpp<#)
|
|
(:private
|
|
#>cpp
|
|
friend class AstStorage;
|
|
cpp<#)
|
|
(:serialize (:slk :ignore-other-base-classes t))
|
|
(:clone :ignore-other-base-classes t)
|
|
(:type-info :ignore-other-base-classes t))
|
|
|
|
(lcp:define-class query (tree "::utils::Visitable<QueryVisitor<void>>")
|
|
()
|
|
(:abstractp t)
|
|
(:public
|
|
#>cpp
|
|
using utils::Visitable<QueryVisitor<void>>::Accept;
|
|
|
|
Query() = default;
|
|
cpp<#)
|
|
(:private
|
|
#>cpp
|
|
friend class AstStorage;
|
|
cpp<#)
|
|
(:serialize (:slk :ignore-other-base-classes t))
|
|
(:clone :ignore-other-base-classes t)
|
|
(:type-info :ignore-other-base-classes t))
|
|
|
|
(lcp:define-class cypher-query (query)
|
|
((single-query "SingleQuery *" :initval "nullptr" :scope :public
|
|
:slk-save #'slk-save-ast-pointer
|
|
:slk-load (slk-load-ast-pointer "SingleQuery")
|
|
:documentation "First and potentially only query.")
|
|
(cypher-unions "std::vector<CypherUnion *>"
|
|
:scope :public
|
|
:slk-save #'slk-save-ast-vector
|
|
:slk-load (slk-load-ast-vector "CypherUnion")
|
|
:documentation "Contains remaining queries that should form and union with `single_query_`.")
|
|
(memory-limit "Expression *" :initval "nullptr" :scope :public
|
|
:slk-save #'slk-save-ast-pointer
|
|
:slk-load (slk-load-ast-pointer "Expression"))
|
|
(memory-scale "size_t" :initval "1024U" :scope :public))
|
|
(:public
|
|
#>cpp
|
|
CypherQuery() = default;
|
|
|
|
DEFVISITABLE(QueryVisitor<void>);
|
|
cpp<#)
|
|
(:private
|
|
#>cpp
|
|
friend class AstStorage;
|
|
cpp<#)
|
|
(:serialize (:slk))
|
|
(:clone))
|
|
|
|
(lcp:define-class explain-query (query)
|
|
((cypher-query "CypherQuery *" :initval "nullptr" :scope :public
|
|
:slk-save #'slk-save-ast-pointer
|
|
:slk-load (slk-load-ast-pointer "CypherQuery")
|
|
:documentation "The CypherQuery to explain."))
|
|
(:public
|
|
#>cpp
|
|
ExplainQuery() = default;
|
|
|
|
DEFVISITABLE(QueryVisitor<void>);
|
|
cpp<#)
|
|
(:private
|
|
#>cpp
|
|
friend class AstStorage;
|
|
cpp<#)
|
|
(:serialize (:slk))
|
|
(:clone))
|
|
|
|
(lcp:define-class profile-query (query)
|
|
((cypher-query "CypherQuery *"
|
|
:initval "nullptr"
|
|
:scope :public
|
|
:slk-save #'slk-save-ast-pointer
|
|
:slk-load (slk-load-ast-pointer "CypherQuery")
|
|
:documentation "The CypherQuery to profile."))
|
|
(:public
|
|
#>cpp
|
|
ProfileQuery() = default;
|
|
|
|
DEFVISITABLE(QueryVisitor<void>);
|
|
cpp<#)
|
|
(:private
|
|
#>cpp
|
|
friend class AstStorage;
|
|
cpp<#)
|
|
(:serialize (:slk))
|
|
(:clone))
|
|
|
|
(lcp:define-class index-query (query)
|
|
((action "Action" :scope :public)
|
|
(label "LabelIx" :scope :public
|
|
:slk-load (lambda (member)
|
|
#>cpp
|
|
slk::Load(&self->${member}, reader, storage);
|
|
cpp<#)
|
|
:clone (lambda (source dest)
|
|
#>cpp
|
|
${dest} = storage->GetLabelIx(${source}.name);
|
|
cpp<#))
|
|
(properties "std::vector<PropertyIx>" :scope :public
|
|
:slk-load (lambda (member)
|
|
#>cpp
|
|
size_t size = 0;
|
|
slk::Load(&size, reader);
|
|
self->${member}.resize(size);
|
|
for (size_t i = 0; i < size; ++i) {
|
|
slk::Load(&self->${member}[i], reader, storage);
|
|
}
|
|
cpp<#)
|
|
:clone (clone-name-ix-vector "Property")))
|
|
(:public
|
|
(lcp:define-enum action
|
|
(create drop)
|
|
(:serialize))
|
|
|
|
#>cpp
|
|
IndexQuery() = default;
|
|
|
|
DEFVISITABLE(QueryVisitor<void>);
|
|
cpp<#)
|
|
(:protected
|
|
#>cpp
|
|
IndexQuery(Action action, LabelIx label, std::vector<PropertyIx> properties)
|
|
: action_(action), label_(label), properties_(properties) {}
|
|
cpp<#)
|
|
(:private
|
|
#>cpp
|
|
friend class AstStorage;
|
|
cpp<#)
|
|
(:serialize (:slk))
|
|
(:clone))
|
|
|
|
(lcp:define-class create (clause)
|
|
((patterns "std::vector<Pattern *>"
|
|
:scope :public
|
|
:slk-save #'slk-save-ast-vector
|
|
:slk-load (slk-load-ast-vector "Pattern")))
|
|
(:public
|
|
#>cpp
|
|
Create() = default;
|
|
|
|
bool Accept(HierarchicalTreeVisitor &visitor) override {
|
|
if (visitor.PreVisit(*this)) {
|
|
for (auto &pattern : patterns_) {
|
|
if (!pattern->Accept(visitor)) break;
|
|
}
|
|
}
|
|
return visitor.PostVisit(*this);
|
|
}
|
|
cpp<#)
|
|
(:protected
|
|
#>cpp
|
|
explicit Create(std::vector<Pattern *> patterns) : patterns_(patterns) {}
|
|
cpp<#)
|
|
(:private
|
|
#>cpp
|
|
friend class AstStorage;
|
|
cpp<#)
|
|
(:serialize (:slk))
|
|
(:clone))
|
|
|
|
(lcp:define-class call-procedure (clause)
|
|
((procedure-name "std::string" :scope :public)
|
|
(arguments "std::vector<Expression *>"
|
|
:scope :public
|
|
:slk-save #'slk-save-ast-vector
|
|
:slk-load (slk-load-ast-vector "Expression"))
|
|
(result-fields "std::vector<std::string>" :scope :public)
|
|
(result-identifiers "std::vector<Identifier *>"
|
|
:scope :public
|
|
:slk-save #'slk-save-ast-vector
|
|
:slk-load (slk-load-ast-vector "Identifier"))
|
|
(memory-limit "Expression *" :initval "nullptr" :scope :public
|
|
:slk-save #'slk-save-ast-pointer
|
|
:slk-load (slk-load-ast-pointer "Expression"))
|
|
(memory-scale "size_t" :initval "1024U" :scope :public)
|
|
(is_write :bool :scope :public))
|
|
(:public
|
|
#>cpp
|
|
CallProcedure() = default;
|
|
|
|
bool Accept(HierarchicalTreeVisitor &visitor) override {
|
|
if (visitor.PreVisit(*this)) {
|
|
bool cont = true;
|
|
for (auto &arg : arguments_) {
|
|
if (!arg->Accept(visitor)) {
|
|
cont = false;
|
|
break;
|
|
}
|
|
}
|
|
if (cont) {
|
|
for (auto &ident : result_identifiers_) {
|
|
if (!ident->Accept(visitor)) {
|
|
cont = false;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return visitor.PostVisit(*this);
|
|
}
|
|
cpp<#)
|
|
(:private
|
|
#>cpp
|
|
friend class AstStorage;
|
|
cpp<#)
|
|
(:serialize (:slk))
|
|
(:clone))
|
|
|
|
(lcp:define-class match (clause)
|
|
((patterns "std::vector<Pattern *>"
|
|
:scope :public
|
|
:slk-save #'slk-save-ast-vector
|
|
:slk-load (slk-load-ast-vector "Pattern"))
|
|
(where "Where *" :initval "nullptr" :scope :public
|
|
:slk-save #'slk-save-ast-pointer
|
|
:slk-load (slk-load-ast-pointer "Where"))
|
|
(optional :bool :initval "false" :scope :public))
|
|
(:public
|
|
#>cpp
|
|
Match() = default;
|
|
|
|
bool Accept(HierarchicalTreeVisitor &visitor) override {
|
|
if (visitor.PreVisit(*this)) {
|
|
bool cont = true;
|
|
for (auto &pattern : patterns_) {
|
|
if (!pattern->Accept(visitor)) {
|
|
cont = false;
|
|
break;
|
|
}
|
|
}
|
|
if (cont && where_) {
|
|
where_->Accept(visitor);
|
|
}
|
|
}
|
|
return visitor.PostVisit(*this);
|
|
}
|
|
cpp<#)
|
|
(:protected
|
|
#>cpp
|
|
explicit Match(bool optional) : optional_(optional) {}
|
|
Match(bool optional, Where *where, std::vector<Pattern *> patterns)
|
|
: patterns_(patterns), where_(where), optional_(optional) {}
|
|
cpp<#)
|
|
(:private
|
|
#>cpp
|
|
friend class AstStorage;
|
|
cpp<#)
|
|
(:serialize (:slk))
|
|
(:clone))
|
|
|
|
(lcp:define-enum ordering
|
|
(asc desc)
|
|
(:documentation "Defines the order for sorting values (ascending or descending).")
|
|
(:serialize))
|
|
|
|
(lcp:define-struct sort-item ()
|
|
((ordering "Ordering" :scope :public)
|
|
(expression "Expression *"
|
|
:slk-save #'slk-save-ast-pointer
|
|
:slk-load (slk-load-ast-pointer "Expression")))
|
|
(:serialize (:slk :load-args '((storage "query::AstStorage *"))))
|
|
(:clone :args '((storage "AstStorage *"))))
|
|
|
|
(lcp:define-struct return-body ()
|
|
((distinct :bool :initval "false"
|
|
:documentation "True if distinct results should be produced.")
|
|
(all-identifiers :bool :initval "false"
|
|
:documentation "True if asterisk was found in the return body.")
|
|
(named-expressions "std::vector<NamedExpression *>"
|
|
:slk-save #'slk-save-ast-vector
|
|
:slk-load (slk-load-ast-vector "NamedExpression")
|
|
:documentation "Expressions which are used to produce results.")
|
|
(order-by "std::vector<SortItem>"
|
|
:slk-load (lambda (member)
|
|
#>cpp
|
|
size_t size = 0;
|
|
slk::Load(&size, reader);
|
|
self->${member}.resize(size);
|
|
for (size_t i = 0; i < size; ++i) {
|
|
slk::Load(&self->${member}[i], reader, storage);
|
|
}
|
|
cpp<#)
|
|
:documentation "Expressions used for ordering the results.")
|
|
(skip "Expression *" :initval "nullptr"
|
|
:slk-save #'slk-save-ast-pointer
|
|
:slk-load (slk-load-ast-pointer "Expression")
|
|
:documentation "Optional expression on how many results to skip.")
|
|
(limit "Expression *" :initval "nullptr"
|
|
:slk-save #'slk-save-ast-pointer
|
|
:slk-load (slk-load-ast-pointer "Expression")
|
|
:documentation "Optional expression on how many results to produce."))
|
|
(:documentation "Contents common to @c Return and @c With clauses.")
|
|
(:serialize (:slk :load-args '((storage "query::AstStorage *"))))
|
|
(:clone :args '((storage "AstStorage *"))))
|
|
|
|
(lcp:define-class return (clause)
|
|
((body "ReturnBody" :scope :public
|
|
:slk-load (lambda (member)
|
|
#>cpp
|
|
slk::Load(&self->${member}, reader, storage);
|
|
cpp<#)))
|
|
(:public
|
|
#>cpp
|
|
Return() = default;
|
|
|
|
bool Accept(HierarchicalTreeVisitor &visitor) override {
|
|
if (visitor.PreVisit(*this)) {
|
|
bool cont = true;
|
|
for (auto &expr : body_.named_expressions) {
|
|
if (!expr->Accept(visitor)) {
|
|
cont = false;
|
|
break;
|
|
}
|
|
}
|
|
if (cont) {
|
|
for (auto &order_by : body_.order_by) {
|
|
if (!order_by.expression->Accept(visitor)) {
|
|
cont = false;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
if (cont && body_.skip) cont = body_.skip->Accept(visitor);
|
|
if (cont && body_.limit) cont = body_.limit->Accept(visitor);
|
|
}
|
|
return visitor.PostVisit(*this);
|
|
}
|
|
cpp<#)
|
|
(:protected
|
|
#>cpp
|
|
explicit Return(ReturnBody &body) : body_(body) {}
|
|
cpp<#)
|
|
(:private
|
|
#>cpp
|
|
friend class AstStorage;
|
|
cpp<#)
|
|
(:serialize (:slk))
|
|
(:clone))
|
|
|
|
(lcp:define-class with (clause)
|
|
((body "ReturnBody" :scope :public
|
|
:slk-load (lambda (member)
|
|
#>cpp
|
|
slk::Load(&self->${member}, reader, storage);
|
|
cpp<#))
|
|
(where "Where *" :initval "nullptr" :scope :public
|
|
:slk-save #'slk-save-ast-pointer
|
|
:slk-load (slk-load-ast-pointer "Where")))
|
|
(:public
|
|
#>cpp
|
|
With() = default;
|
|
|
|
bool Accept(HierarchicalTreeVisitor &visitor) override {
|
|
if (visitor.PreVisit(*this)) {
|
|
bool cont = true;
|
|
for (auto &expr : body_.named_expressions) {
|
|
if (!expr->Accept(visitor)) {
|
|
cont = false;
|
|
break;
|
|
}
|
|
}
|
|
if (cont) {
|
|
for (auto &order_by : body_.order_by) {
|
|
if (!order_by.expression->Accept(visitor)) {
|
|
cont = false;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
if (cont && where_) cont = where_->Accept(visitor);
|
|
if (cont && body_.skip) cont = body_.skip->Accept(visitor);
|
|
if (cont && body_.limit) cont = body_.limit->Accept(visitor);
|
|
}
|
|
return visitor.PostVisit(*this);
|
|
}
|
|
cpp<#)
|
|
(:protected
|
|
#>cpp
|
|
With(ReturnBody &body, Where *where) : body_(body), where_(where) {}
|
|
cpp<#)
|
|
(:private
|
|
#>cpp
|
|
friend class AstStorage;
|
|
cpp<#)
|
|
(:serialize (:slk))
|
|
(:clone))
|
|
|
|
(lcp:define-class delete (clause)
|
|
((expressions "std::vector<Expression *>"
|
|
:slk-save #'slk-save-ast-vector
|
|
:slk-load (slk-load-ast-vector "Expression")
|
|
:scope :public)
|
|
(detach :bool :initval "false" :scope :public))
|
|
(:public
|
|
#>cpp
|
|
Delete() = default;
|
|
|
|
bool Accept(HierarchicalTreeVisitor &visitor) override {
|
|
if (visitor.PreVisit(*this)) {
|
|
for (auto &expr : expressions_) {
|
|
if (!expr->Accept(visitor)) break;
|
|
}
|
|
}
|
|
return visitor.PostVisit(*this);
|
|
}
|
|
cpp<#)
|
|
(:protected
|
|
#>cpp
|
|
Delete(bool detach, std::vector<Expression *> expressions)
|
|
: expressions_(expressions), detach_(detach) {}
|
|
cpp<#)
|
|
(:private
|
|
#>cpp
|
|
friend class AstStorage;
|
|
cpp<#)
|
|
(:serialize (:slk))
|
|
(:clone))
|
|
|
|
(lcp:define-class set-property (clause)
|
|
((property-lookup "PropertyLookup *" :initval "nullptr" :scope :public
|
|
:slk-save #'slk-save-ast-pointer
|
|
:slk-load (slk-load-ast-pointer "PropertyLookup"))
|
|
(expression "Expression *" :initval "nullptr" :scope :public
|
|
:slk-save #'slk-save-ast-pointer
|
|
:slk-load (slk-load-ast-pointer "Expression")))
|
|
(:public
|
|
#>cpp
|
|
SetProperty() = default;
|
|
|
|
bool Accept(HierarchicalTreeVisitor &visitor) override {
|
|
if (visitor.PreVisit(*this)) {
|
|
property_lookup_->Accept(visitor) && expression_->Accept(visitor);
|
|
}
|
|
return visitor.PostVisit(*this);
|
|
}
|
|
cpp<#)
|
|
(:protected
|
|
#>cpp
|
|
SetProperty(PropertyLookup *property_lookup, Expression *expression)
|
|
: property_lookup_(property_lookup), expression_(expression) {}
|
|
cpp<#)
|
|
(:private
|
|
#>cpp
|
|
friend class AstStorage;
|
|
cpp<#)
|
|
(:serialize (:slk))
|
|
(:clone))
|
|
|
|
(lcp:define-class set-properties (clause)
|
|
((identifier "Identifier *" :initval "nullptr" :scope :public
|
|
:slk-save #'slk-save-ast-pointer
|
|
:slk-load (slk-load-ast-pointer "Identifier"))
|
|
(expression "Expression *" :initval "nullptr" :scope :public
|
|
:slk-save #'slk-save-ast-pointer
|
|
:slk-load (slk-load-ast-pointer "Expression"))
|
|
(update :bool :initval "false" :scope :public))
|
|
(:public
|
|
#>cpp
|
|
SetProperties() = default;
|
|
|
|
bool Accept(HierarchicalTreeVisitor &visitor) override {
|
|
if (visitor.PreVisit(*this)) {
|
|
identifier_->Accept(visitor) && expression_->Accept(visitor);
|
|
}
|
|
return visitor.PostVisit(*this);
|
|
}
|
|
cpp<#)
|
|
(:protected
|
|
#>cpp
|
|
SetProperties(Identifier *identifier, Expression *expression,
|
|
bool update = false)
|
|
: identifier_(identifier), expression_(expression), update_(update) {}
|
|
cpp<#)
|
|
(:private
|
|
#>cpp
|
|
friend class AstStorage;
|
|
cpp<#)
|
|
(:serialize (:slk))
|
|
(:clone))
|
|
|
|
(lcp:define-class set-labels (clause)
|
|
((identifier "Identifier *" :initval "nullptr" :scope :public
|
|
:slk-save #'slk-save-ast-pointer
|
|
:slk-load (slk-load-ast-pointer "Identifier"))
|
|
(labels "std::vector<LabelIx>" :scope :public
|
|
:slk-load (lambda (member)
|
|
#>cpp
|
|
size_t size = 0;
|
|
slk::Load(&size, reader);
|
|
self->${member}.resize(size);
|
|
for (size_t i = 0; i < size; ++i) {
|
|
slk::Load(&self->${member}[i], reader, storage);
|
|
}
|
|
cpp<#)
|
|
:clone (clone-name-ix-vector "Label")))
|
|
(:public
|
|
#>cpp
|
|
SetLabels() = default;
|
|
|
|
bool Accept(HierarchicalTreeVisitor &visitor) override {
|
|
if (visitor.PreVisit(*this)) {
|
|
identifier_->Accept(visitor);
|
|
}
|
|
return visitor.PostVisit(*this);
|
|
}
|
|
cpp<#)
|
|
(:protected
|
|
#>cpp
|
|
SetLabels(Identifier *identifier, const std::vector<LabelIx> &labels)
|
|
: identifier_(identifier), labels_(labels) {}
|
|
cpp<#)
|
|
(:private
|
|
#>cpp
|
|
friend class AstStorage;
|
|
cpp<#)
|
|
(:serialize (:slk))
|
|
(:clone))
|
|
|
|
(lcp:define-class remove-property (clause)
|
|
((property-lookup "PropertyLookup *" :initval "nullptr" :scope :public
|
|
:slk-save #'slk-save-ast-pointer
|
|
:slk-load (slk-load-ast-pointer "PropertyLookup")))
|
|
(:public
|
|
#>cpp
|
|
RemoveProperty() = default;
|
|
|
|
bool Accept(HierarchicalTreeVisitor &visitor) override {
|
|
if (visitor.PreVisit(*this)) {
|
|
property_lookup_->Accept(visitor);
|
|
}
|
|
return visitor.PostVisit(*this);
|
|
}
|
|
cpp<#)
|
|
(:protected
|
|
#>cpp
|
|
explicit RemoveProperty(PropertyLookup *property_lookup)
|
|
: property_lookup_(property_lookup) {}
|
|
cpp<#)
|
|
(:private
|
|
#>cpp
|
|
friend class AstStorage;
|
|
cpp<#)
|
|
(:serialize (:slk))
|
|
(:clone))
|
|
|
|
(lcp:define-class remove-labels (clause)
|
|
((identifier "Identifier *" :initval "nullptr" :scope :public
|
|
:slk-save #'slk-save-ast-pointer
|
|
:slk-load (slk-load-ast-pointer "Identifier"))
|
|
(labels "std::vector<LabelIx>" :scope :public
|
|
:slk-load (lambda (member)
|
|
#>cpp
|
|
size_t size = 0;
|
|
slk::Load(&size, reader);
|
|
self->${member}.resize(size);
|
|
for (size_t i = 0; i < size; ++i) {
|
|
slk::Load(&self->${member}[i], reader, storage);
|
|
}
|
|
cpp<#)
|
|
:clone (clone-name-ix-vector "Label")))
|
|
(:public
|
|
#>cpp
|
|
RemoveLabels() = default;
|
|
|
|
bool Accept(HierarchicalTreeVisitor &visitor) override {
|
|
if (visitor.PreVisit(*this)) {
|
|
identifier_->Accept(visitor);
|
|
}
|
|
return visitor.PostVisit(*this);
|
|
}
|
|
cpp<#)
|
|
(:protected
|
|
#>cpp
|
|
RemoveLabels(Identifier *identifier, const std::vector<LabelIx> &labels)
|
|
: identifier_(identifier), labels_(labels) {}
|
|
cpp<#)
|
|
(:private
|
|
#>cpp
|
|
friend class AstStorage;
|
|
cpp<#)
|
|
(:serialize (:slk))
|
|
(:clone))
|
|
|
|
(lcp:define-class merge (clause)
|
|
((pattern "Pattern *" :initval "nullptr" :scope :public
|
|
:slk-save #'slk-save-ast-pointer
|
|
:slk-load (slk-load-ast-pointer "Pattern"))
|
|
(on-match "std::vector<Clause *>"
|
|
:scope :public
|
|
:slk-save #'slk-save-ast-vector
|
|
:slk-load (slk-load-ast-vector "Clause"))
|
|
(on-create "std::vector<Clause *>"
|
|
:scope :public
|
|
:slk-save #'slk-save-ast-vector
|
|
:slk-load (slk-load-ast-vector "Clause")))
|
|
(:public
|
|
#>cpp
|
|
Merge() = default;
|
|
|
|
bool Accept(HierarchicalTreeVisitor &visitor) override {
|
|
if (visitor.PreVisit(*this)) {
|
|
bool cont = pattern_->Accept(visitor);
|
|
if (cont) {
|
|
for (auto &set : on_match_) {
|
|
if (!set->Accept(visitor)) {
|
|
cont = false;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
if (cont) {
|
|
for (auto &set : on_create_) {
|
|
if (!set->Accept(visitor)) {
|
|
cont = false;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return visitor.PostVisit(*this);
|
|
}
|
|
cpp<#)
|
|
(:protected
|
|
#>cpp
|
|
Merge(Pattern *pattern, std::vector<Clause *> on_match,
|
|
std::vector<Clause *> on_create)
|
|
: pattern_(pattern), on_match_(on_match), on_create_(on_create) {}
|
|
cpp<#)
|
|
(:private
|
|
#>cpp
|
|
friend class AstStorage;
|
|
cpp<#)
|
|
(:serialize (:slk))
|
|
(:clone))
|
|
|
|
(lcp:define-class unwind (clause)
|
|
((named-expression "NamedExpression *" :initval "nullptr" :scope :public
|
|
:slk-save #'slk-save-ast-pointer
|
|
:slk-load (slk-load-ast-pointer "NamedExpression")))
|
|
(:public
|
|
#>cpp
|
|
Unwind() = default;
|
|
|
|
bool Accept(HierarchicalTreeVisitor &visitor) override {
|
|
if (visitor.PreVisit(*this)) {
|
|
named_expression_->Accept(visitor);
|
|
}
|
|
return visitor.PostVisit(*this);
|
|
}
|
|
cpp<#)
|
|
(:protected
|
|
#>cpp
|
|
explicit Unwind(NamedExpression *named_expression)
|
|
: named_expression_(named_expression) {
|
|
DMG_ASSERT(named_expression, "Unwind cannot take nullptr for named_expression");
|
|
}
|
|
cpp<#)
|
|
(:private
|
|
#>cpp
|
|
friend class AstStorage;
|
|
cpp<#)
|
|
(:serialize (:slk))
|
|
(:clone))
|
|
|
|
(lcp:define-class auth-query (query)
|
|
((action "Action" :scope :public)
|
|
(user "std::string" :scope :public)
|
|
(role "std::string" :scope :public)
|
|
(user-or-role "std::string" :scope :public)
|
|
(password "Expression *" :initval "nullptr" :scope :public
|
|
:slk-save #'slk-save-ast-pointer
|
|
:slk-load (slk-load-ast-pointer "Expression"))
|
|
(privileges "std::vector<Privilege>" :scope :public))
|
|
(:public
|
|
(lcp:define-enum action
|
|
(create-role drop-role show-roles create-user set-password drop-user
|
|
show-users set-role clear-role grant-privilege deny-privilege
|
|
revoke-privilege show-privileges show-role-for-user
|
|
show-users-for-role)
|
|
(:serialize))
|
|
(lcp:define-enum privilege
|
|
(create delete match merge set remove index stats auth constraint
|
|
dump replication durability read_file free_memory trigger config stream module_read module_write
|
|
websocket)
|
|
(:serialize))
|
|
#>cpp
|
|
AuthQuery() = default;
|
|
|
|
DEFVISITABLE(QueryVisitor<void>);
|
|
cpp<#)
|
|
(:protected
|
|
#>cpp
|
|
AuthQuery(Action action, std::string user, std::string role,
|
|
std::string user_or_role, Expression *password,
|
|
std::vector<Privilege> privileges)
|
|
: action_(action),
|
|
user_(user),
|
|
role_(role),
|
|
user_or_role_(user_or_role),
|
|
password_(password),
|
|
privileges_(privileges) {}
|
|
cpp<#)
|
|
(:private
|
|
#>cpp
|
|
friend class AstStorage;
|
|
cpp<#)
|
|
(:serialize (:slk))
|
|
(:clone))
|
|
|
|
;; TODO: Generate this via LCP
|
|
#>cpp
|
|
/// Constant that holds all available privileges.
|
|
const std::vector<AuthQuery::Privilege> kPrivilegesAll = {
|
|
AuthQuery::Privilege::CREATE, AuthQuery::Privilege::DELETE,
|
|
AuthQuery::Privilege::MATCH, AuthQuery::Privilege::MERGE,
|
|
AuthQuery::Privilege::SET, AuthQuery::Privilege::REMOVE,
|
|
AuthQuery::Privilege::INDEX, AuthQuery::Privilege::STATS,
|
|
AuthQuery::Privilege::AUTH,
|
|
AuthQuery::Privilege::CONSTRAINT, AuthQuery::Privilege::DUMP,
|
|
AuthQuery::Privilege::REPLICATION,
|
|
AuthQuery::Privilege::READ_FILE,
|
|
AuthQuery::Privilege::DURABILITY,
|
|
AuthQuery::Privilege::FREE_MEMORY, AuthQuery::Privilege::TRIGGER,
|
|
AuthQuery::Privilege::CONFIG, AuthQuery::Privilege::STREAM,
|
|
AuthQuery::Privilege::MODULE_READ, AuthQuery::Privilege::MODULE_WRITE,
|
|
AuthQuery::Privilege::WEBSOCKET};
|
|
cpp<#
|
|
|
|
(lcp:define-class info-query (query)
|
|
((info-type "InfoType" :scope :public))
|
|
(:public
|
|
(lcp:define-enum info-type
|
|
(storage index constraint)
|
|
(:serialize))
|
|
|
|
#>cpp
|
|
DEFVISITABLE(QueryVisitor<void>);
|
|
cpp<#)
|
|
(:serialize (:slk))
|
|
(:clone))
|
|
|
|
(lcp:define-struct constraint ()
|
|
((type "Type")
|
|
(label "LabelIx" :scope :public
|
|
:slk-load (lambda (member)
|
|
#>cpp
|
|
slk::Load(&self->${member}, reader, storage);
|
|
cpp<#)
|
|
:clone (lambda (source dest)
|
|
#>cpp
|
|
${dest} = storage->GetLabelIx(${source}.name);
|
|
cpp<#))
|
|
(properties "std::vector<PropertyIx>" :scope :public
|
|
:slk-load (lambda (member)
|
|
#>cpp
|
|
size_t size = 0;
|
|
slk::Load(&size, reader);
|
|
self->${member}.resize(size);
|
|
for (size_t i = 0; i < size; ++i) {
|
|
slk::Load(&self->${member}[i], reader, storage);
|
|
}
|
|
cpp<#)
|
|
:clone (clone-name-ix-vector "Property")))
|
|
(:public
|
|
(lcp:define-enum type (exists unique node-key)
|
|
(:serialize (:lcp))))
|
|
(:serialize (:slk :load-args '((storage "query::AstStorage *"))))
|
|
(:clone :args '((storage "AstStorage *"))))
|
|
|
|
(lcp:define-class constraint-query (query)
|
|
((action-type "ActionType" :scope :public)
|
|
(constraint "Constraint" :scope :public
|
|
:slk-load (lambda (member)
|
|
#>cpp
|
|
slk::Load(&self->${member}, reader, storage);
|
|
cpp<#)))
|
|
(:public
|
|
(lcp:define-enum action-type
|
|
(create drop)
|
|
(:serialize))
|
|
|
|
#>cpp
|
|
DEFVISITABLE(QueryVisitor<void>);
|
|
cpp<#)
|
|
(:serialize (:slk))
|
|
(:clone))
|
|
|
|
(lcp:define-class dump-query (query) ()
|
|
(:public
|
|
#>cpp
|
|
DEFVISITABLE(QueryVisitor<void>);
|
|
cpp<#)
|
|
(:serialize (:slk))
|
|
(:clone))
|
|
|
|
(lcp:define-class replication-query (query)
|
|
((action "Action" :scope :public)
|
|
(role "ReplicationRole" :scope :public)
|
|
(replica_name "std::string" :scope :public)
|
|
(socket_address "Expression *" :initval "nullptr" :scope :public
|
|
:slk-save #'slk-save-ast-pointer
|
|
:slk-load (slk-load-ast-pointer "Expression"))
|
|
(port "Expression *" :initval "nullptr" :scope :public
|
|
:slk-save #'slk-save-ast-pointer
|
|
:slk-load (slk-load-ast-pointer "Expression"))
|
|
(sync_mode "SyncMode" :scope :public))
|
|
|
|
(:public
|
|
(lcp:define-enum action
|
|
(set-replication-role show-replication-role register-replica
|
|
drop-replica show-replicas)
|
|
(:serialize))
|
|
(lcp:define-enum replication-role
|
|
(main replica)
|
|
(:serialize))
|
|
(lcp:define-enum sync-mode
|
|
(sync async)
|
|
(:serialize))
|
|
(lcp:define-enum replica-state
|
|
(ready replicating recovery invalid)
|
|
(:serialize))
|
|
#>cpp
|
|
ReplicationQuery() = default;
|
|
|
|
DEFVISITABLE(QueryVisitor<void>);
|
|
cpp<#)
|
|
(:private
|
|
#>cpp
|
|
friend class AstStorage;
|
|
cpp<#)
|
|
(:serialize (:slk))
|
|
(:clone))
|
|
|
|
(lcp:define-class lock-path-query (query)
|
|
((action "Action" :scope :public))
|
|
|
|
(:public
|
|
(lcp:define-enum action
|
|
(lock-path unlock-path)
|
|
(:serialize))
|
|
#>cpp
|
|
LockPathQuery() = default;
|
|
|
|
DEFVISITABLE(QueryVisitor<void>);
|
|
cpp<#)
|
|
(:private
|
|
#>cpp
|
|
friend class AstStorage;
|
|
cpp<#)
|
|
(:serialize (:slk))
|
|
(:clone))
|
|
|
|
(lcp:define-class load-csv (clause)
|
|
((file "Expression *" :scope :public)
|
|
(with_header "bool" :scope :public)
|
|
(ignore_bad "bool" :scope :public)
|
|
(delimiter "Expression *" :initval "nullptr" :scope :public)
|
|
(quote "Expression *" :initval "nullptr" :scope :public)
|
|
(row_var "Identifier *" :initval "nullptr" :scope :public
|
|
:slk-save #'slk-save-ast-pointer
|
|
:slk-load (slk-load-ast-pointer "Identifier")))
|
|
|
|
(:public
|
|
#>cpp
|
|
LoadCsv() = default;
|
|
|
|
bool Accept(HierarchicalTreeVisitor &visitor) override {
|
|
if (visitor.PreVisit(*this)) {
|
|
row_var_->Accept(visitor);
|
|
}
|
|
return visitor.PostVisit(*this);
|
|
}
|
|
cpp<#)
|
|
(:protected
|
|
#>cpp
|
|
explicit LoadCsv(Expression *file, bool with_header, bool ignore_bad, Expression *delimiter,
|
|
Expression* quote, Identifier* row_var)
|
|
: file_(file),
|
|
with_header_(with_header),
|
|
ignore_bad_(ignore_bad),
|
|
delimiter_(delimiter),
|
|
quote_(quote),
|
|
row_var_(row_var) {
|
|
DMG_ASSERT(row_var, "LoadCsv cannot take nullptr for identifier");
|
|
}
|
|
cpp<#)
|
|
(:private
|
|
#>cpp
|
|
friend class AstStorage;
|
|
cpp<#)
|
|
(:serialize (:slk))
|
|
(:clone))
|
|
|
|
(lcp:define-class free-memory-query (query) ()
|
|
(:public
|
|
#>cpp
|
|
DEFVISITABLE(QueryVisitor<void>);
|
|
cpp<#)
|
|
(:serialize (:slk))
|
|
(:clone))
|
|
|
|
(lcp:define-class trigger-query (query)
|
|
((action "Action" :scope :public)
|
|
(event_type "EventType" :scope :public)
|
|
(trigger_name "std::string" :scope :public)
|
|
(before_commit "bool" :scope :public)
|
|
(statement "std::string" :scope :public))
|
|
|
|
(:public
|
|
(lcp:define-enum action
|
|
(create-trigger drop-trigger show-triggers)
|
|
(:serialize))
|
|
(lcp:define-enum event-type
|
|
(any vertex_create edge_create create vertex_delete edge_delete delete vertex_update edge_update update)
|
|
(:serialize))
|
|
#>cpp
|
|
TriggerQuery() = default;
|
|
|
|
DEFVISITABLE(QueryVisitor<void>);
|
|
cpp<#)
|
|
(:private
|
|
#>cpp
|
|
friend class AstStorage;
|
|
cpp<#)
|
|
(:serialize (:slk))
|
|
(:clone))
|
|
|
|
(lcp:define-class isolation-level-query (query)
|
|
((isolation_level "IsolationLevel" :scope :public)
|
|
(isolation_level_scope "IsolationLevelScope" :scope :public))
|
|
|
|
(:public
|
|
(lcp:define-enum isolation-level
|
|
(snapshot-isolation read-committed read-uncommitted)
|
|
(:serialize))
|
|
(lcp:define-enum isolation-level-scope
|
|
(next session global)
|
|
(:serialize))
|
|
#>cpp
|
|
IsolationLevelQuery() = default;
|
|
|
|
DEFVISITABLE(QueryVisitor<void>);
|
|
cpp<#)
|
|
(:private
|
|
#>cpp
|
|
friend class AstStorage;
|
|
cpp<#)
|
|
(:serialize (:slk))
|
|
(:clone))
|
|
|
|
(lcp:define-class create-snapshot-query (query) ()
|
|
(:public
|
|
#>cpp
|
|
DEFVISITABLE(QueryVisitor<void>);
|
|
cpp<#)
|
|
(:serialize (:slk))
|
|
(:clone))
|
|
|
|
(defun clone-variant-topic-names (source destination)
|
|
#>cpp
|
|
if (auto *topic_expression = std::get_if<Expression*>(&${source})) {
|
|
if (*topic_expression == nullptr) {
|
|
${destination} = nullptr;
|
|
} else {
|
|
${destination} = (*topic_expression)->Clone(storage);
|
|
}
|
|
} else {
|
|
${destination} = std::get<std::vector<std::string>>(${source});
|
|
}
|
|
cpp<#)
|
|
|
|
(lcp:define-class stream-query (query)
|
|
((action "Action" :scope :public)
|
|
(type "Type" :scope :public)
|
|
(stream_name "std::string" :scope :public)
|
|
|
|
(batch_limit "Expression *" :initval "nullptr" :scope :public
|
|
:slk-save #'slk-save-ast-pointer
|
|
:slk-load (slk-load-ast-pointer "Expression"))
|
|
(timeout "Expression *" :initval "nullptr" :scope :public
|
|
:slk-save #'slk-save-ast-pointer
|
|
:slk-load (slk-load-ast-pointer "Expression"))
|
|
|
|
(transform_name "std::string" :scope :public)
|
|
(batch_interval "Expression *" :initval "nullptr" :scope :public
|
|
:slk-save #'slk-save-ast-pointer
|
|
:slk-load (slk-load-ast-pointer "Expression"))
|
|
(batch_size "Expression *" :initval "nullptr" :scope :public
|
|
:slk-save #'slk-save-ast-pointer
|
|
:slk-load (slk-load-ast-pointer "Expression"))
|
|
|
|
(topic_names "std::variant<Expression*, std::vector<std::string>>" :initval "nullptr"
|
|
:clone #'clone-variant-topic-names
|
|
:scope :public)
|
|
(consumer_group "std::string" :scope :public)
|
|
(bootstrap_servers "Expression *" :initval "nullptr" :scope :public
|
|
:slk-save #'slk-save-ast-pointer
|
|
:slk-load (slk-load-ast-pointer "Expression"))
|
|
|
|
(service_url "Expression *" :initval "nullptr" :scope :public
|
|
:slk-save #'slk-save-ast-pointer
|
|
:slk-load (slk-load-ast-pointer "Expression"))
|
|
|
|
(configs "std::unordered_map<Expression *, Expression *>" :scope :public
|
|
:slk-save #'slk-save-expression-map
|
|
:slk-load #'slk-load-expression-map
|
|
:clone #'clone-expression-map)
|
|
|
|
(credentials "std::unordered_map<Expression *, Expression *>" :scope :public
|
|
:slk-save #'slk-save-expression-map
|
|
:slk-load #'slk-load-expression-map
|
|
:clone #'clone-expression-map))
|
|
|
|
(:public
|
|
(lcp:define-enum action
|
|
(create-stream drop-stream start-stream stop-stream start-all-streams stop-all-streams show-streams check-stream)
|
|
(:serialize))
|
|
(lcp:define-enum type
|
|
(kafka pulsar)
|
|
(:serialize))
|
|
#>cpp
|
|
StreamQuery() = default;
|
|
|
|
DEFVISITABLE(QueryVisitor<void>);
|
|
cpp<#)
|
|
(:private
|
|
#>cpp
|
|
friend class AstStorage;
|
|
cpp<#)
|
|
(:serialize (:slk))
|
|
(:clone))
|
|
|
|
(lcp:define-class setting-query (query)
|
|
((action "Action" :scope :public)
|
|
(setting_name "Expression *" :initval "nullptr" :scope :public)
|
|
(setting_value "Expression *" :initval "nullptr" :scope :public))
|
|
|
|
(:public
|
|
(lcp:define-enum action
|
|
(show-setting show-all-settings set-setting)
|
|
(:serialize))
|
|
#>cpp
|
|
SettingQuery() = default;
|
|
|
|
DEFVISITABLE(QueryVisitor<void>);
|
|
cpp<#)
|
|
(:private
|
|
#>cpp
|
|
friend class AstStorage;
|
|
cpp<#)
|
|
(:serialize (:slk))
|
|
(:clone))
|
|
|
|
(lcp:define-class version-query (query) ()
|
|
(:public
|
|
#>cpp
|
|
DEFVISITABLE(QueryVisitor<void>);
|
|
cpp<#)
|
|
(:serialize (:slk))
|
|
(:clone))
|
|
|
|
(lcp:define-class foreach (clause)
|
|
((named_expression "NamedExpression *" :initval "nullptr" :scope :public
|
|
:slk-save #'slk-save-ast-pointer
|
|
:slk-load (slk-load-ast-pointer "Expression"))
|
|
(clauses "std::vector<Clause *>"
|
|
:scope :public
|
|
:slk-save #'slk-save-ast-vector
|
|
:slk-load (slk-load-ast-vector "Clause")))
|
|
(:public
|
|
#>cpp
|
|
Foreach() = default;
|
|
|
|
bool Accept(HierarchicalTreeVisitor &visitor) override {
|
|
if (visitor.PreVisit(*this)) {
|
|
named_expression_->Accept(visitor);
|
|
for (auto &clause : clauses_) {
|
|
clause->Accept(visitor);
|
|
}
|
|
}
|
|
return visitor.PostVisit(*this);
|
|
}
|
|
cpp<#)
|
|
(:protected
|
|
#>cpp
|
|
Foreach(NamedExpression *expression, std::vector<Clause *> clauses)
|
|
: named_expression_(expression), clauses_(clauses) {}
|
|
cpp<#)
|
|
(:private
|
|
#>cpp
|
|
friend class AstStorage;
|
|
cpp<#)
|
|
(:serialize (:slk))
|
|
(:clone))
|
|
|
|
(lcp:pop-namespace) ;; namespace query
|
|
(lcp:pop-namespace) ;; namespace memgraph
|