diff --git a/src/query/frontend/ast/ast.cpp b/src/query/frontend/ast/ast.cpp index 9230324ed..188c9c0c5 100644 --- a/src/query/frontend/ast/ast.cpp +++ b/src/query/frontend/ast/ast.cpp @@ -1,5 +1,6 @@ #include "query/frontend/ast/ast.hpp" +#include // Include archives before registering most derived types. #include "boost/archive/binary_iarchive.hpp" #include "boost/archive/binary_oarchive.hpp" @@ -44,85 +45,121 @@ ReturnBody CloneReturnBody(AstTreeStorage &storage, const ReturnBody &body) { return new_body; } -// capnproto serialization +// Capnproto serialization. -Tree *AstTreeStorage::Load(capnp::Tree::Reader &tree) { +Tree *AstTreeStorage::Load(const capnp::Tree::Reader &tree, + std::vector *loaded_uids) { + auto uid = tree.getUid(); + + // Check if element already deserialized and if yes, return existing + // element from storage. + if (utils::Contains(*loaded_uids, uid)) { + auto found = std::find_if(storage_.begin(), storage_.end(), + [&](const auto &n) { return n->uid() == uid; }); + DCHECK(found != storage_.end()); + return found->get(); + } + + Tree *ret = nullptr; switch (tree.which()) { case capnp::Tree::EXPRESSION: { auto expr_reader = tree.getExpression(); - auto *ret = Expression::Construct(expr_reader, *this); - ret->Load(tree, *this); - return ret; + ret = Expression::Construct(expr_reader, this); + ret->Load(tree, this, loaded_uids); + break; } case capnp::Tree::WHERE: { auto where_reader = tree.getWhere(); - auto *ret = Where::Construct(where_reader, *this); - ret->Load(tree, *this); - return ret; + ret = Where::Construct(where_reader, this); + ret->Load(tree, this, loaded_uids); + break; } case capnp::Tree::CLAUSE: { auto clause_reader = tree.getClause(); - auto *ret = Clause::Construct(clause_reader, *this); - ret->Load(tree, *this); - return ret; + ret = Clause::Construct(clause_reader, this); + ret->Load(tree, this, loaded_uids); + break; } case capnp::Tree::CYPHER_UNION: { auto cu_reader = tree.getCypherUnion(); - auto *ret = CypherUnion::Construct(cu_reader, *this); - ret->Load(tree, *this); - return ret; + ret = CypherUnion::Construct(cu_reader, this); + ret->Load(tree, this, loaded_uids); + break; } case capnp::Tree::NAMED_EXPRESSION: { auto ne_reader = tree.getNamedExpression(); - auto *ret = NamedExpression::Construct(ne_reader, *this); - ret->Load(tree, *this); - return ret; + ret = NamedExpression::Construct(ne_reader, this); + ret->Load(tree, this, loaded_uids); + break; } case capnp::Tree::PATTERN: { auto pattern_reader = tree.getPattern(); - auto *ret = Pattern::Construct(pattern_reader, *this); - ret->Load(tree, *this); - return ret; + ret = Pattern::Construct(pattern_reader, this); + ret->Load(tree, this, loaded_uids); + break; } case capnp::Tree::PATTERN_ATOM: { auto pa_reader = tree.getPatternAtom(); - auto *ret = PatternAtom::Construct(pa_reader, *this); - ret->Load(tree, *this); - return ret; + ret = PatternAtom::Construct(pa_reader, this); + ret->Load(tree, this, loaded_uids); + break; } case capnp::Tree::QUERY: { - auto query_reader = tree.getQuery(); - auto *ret = Query::Construct(query_reader, *this); - ret->Load(tree, *this); - return ret; + this->query()->Load(tree, this, loaded_uids); + ret = this->query(); + break; } case capnp::Tree::SINGLE_QUERY: { auto single_reader = tree.getSingleQuery(); - auto *ret = SingleQuery::Construct(single_reader, *this); - ret->Load(tree, *this); - return ret; + ret = SingleQuery::Construct(single_reader, this); + ret->Load(tree, this, loaded_uids); + break; } } + DCHECK(ret != nullptr); + loaded_uids->emplace_back(ret->uid_); + auto previous_max = std::max_element( + storage_.begin(), storage_.end(), + [](const std::unique_ptr &a, const std::unique_ptr &b) { + return a->uid() < b->uid(); + }); + next_uid_ = (*previous_max)->uid() + 1; + return ret; } // Tree. -void Tree::Save(capnp::Tree::Builder &tree_builder) { - tree_builder.setUid(uid_); +void Tree::Save(capnp::Tree::Builder *tree_builder, + std::vector *saved_uids) { + tree_builder->setUid(uid_); } -void Tree::Load(capnp::Tree::Reader &reader, AstTreeStorage &storage) { +bool Tree::IsSaved(const std::vector &saved_uids) { + return utils::Contains(saved_uids, uid_); +} + +void Tree::Load(const capnp::Tree::Reader &reader, AstTreeStorage *storage, + std::vector *loaded_uids) { uid_ = reader.getUid(); } -// Expression. -void Expression::Save(capnp::Tree::Builder &tree_builder) { - Tree::Save(tree_builder); - auto expr_builder = tree_builder.initExpression(); - Save(expr_builder); +void Tree::AddToSaved(std::vector *saved_uids) { + saved_uids->emplace_back(uid_); } -Expression *Expression::Construct(capnp::Expression::Reader &reader, - AstTreeStorage &storage) { +// Expression. +void Expression::Save(capnp::Tree::Builder *tree_builder, + std::vector *saved_uids) { + Tree::Save(tree_builder, saved_uids); + if (IsSaved(*saved_uids)) { + return; + } + auto expr_builder = tree_builder->initExpression(); + Save(&expr_builder, saved_uids); + AddToSaved(saved_uids); +} + +Expression *Expression::Construct(const capnp::Expression::Reader &reader, + AstTreeStorage *storage) { switch (reader.which()) { case capnp::Expression::BINARY_OPERATOR: { auto bop_reader = reader.getBinaryOperator(); @@ -180,14 +217,15 @@ Expression *Expression::Construct(capnp::Expression::Reader &reader, } // Base Literal. -void BaseLiteral::Save(capnp::Expression::Builder &expr_builder) { - Expression::Save(expr_builder); - auto base_literal_builder = expr_builder.initBaseLiteral(); - Save(base_literal_builder); +void BaseLiteral::Save(capnp::Expression::Builder *expr_builder, + std::vector *saved_uids) { + Expression::Save(expr_builder, saved_uids); + auto base_literal_builder = expr_builder->initBaseLiteral(); + Save(&base_literal_builder, saved_uids); } -BaseLiteral *BaseLiteral::Construct(capnp::BaseLiteral::Reader &reader, - AstTreeStorage &storage) { +BaseLiteral *BaseLiteral::Construct(const capnp::BaseLiteral::Reader &reader, + AstTreeStorage *storage) { switch (reader.which()) { case capnp::BaseLiteral::PRIMITIVE_LITERAL: { auto literal = reader.getPrimitiveLiteral(); @@ -205,48 +243,64 @@ BaseLiteral *BaseLiteral::Construct(capnp::BaseLiteral::Reader &reader, } // Primitive Literal. -void PrimitiveLiteral::Save(capnp::BaseLiteral::Builder &base_literal_builder) { - BaseLiteral::Save(base_literal_builder); - auto primitive_literal_builder = base_literal_builder.initPrimitiveLiteral(); +void PrimitiveLiteral::Save(capnp::BaseLiteral::Builder *base_literal_builder, + std::vector *saved_uids) { + BaseLiteral::Save(base_literal_builder, saved_uids); + auto primitive_literal_builder = base_literal_builder->initPrimitiveLiteral(); primitive_literal_builder.setTokenPosition(token_position_); auto typed_value_builder = primitive_literal_builder.getValue(); utils::SaveCapnpTypedValue(value_, typed_value_builder); } +void PrimitiveLiteral::Load(const capnp::Tree::Reader &reader, + AstTreeStorage *storage, + std::vector *loaded_uids) { + BaseLiteral::Load(reader, storage, loaded_uids); + auto pl_reader = + reader.getExpression().getBaseLiteral().getPrimitiveLiteral(); + auto typed_value_reader = pl_reader.getValue(); + utils::LoadCapnpTypedValue(value_, typed_value_reader); + token_position_ = pl_reader.getTokenPosition(); +} + PrimitiveLiteral *PrimitiveLiteral::Construct( - capnp::PrimitiveLiteral::Reader &reader, AstTreeStorage &storage) { - auto typed_value_reader = reader.getValue(); - TypedValue value; - utils::LoadCapnpTypedValue(value, typed_value_reader); - return storage.Create(value, reader.getTokenPosition()); + const capnp::PrimitiveLiteral::Reader &reader, AstTreeStorage *storage) { + return storage->Create(); } // List Literal. -void ListLiteral::Save(capnp::BaseLiteral::Builder &base_literal_builder) { - BaseLiteral::Save(base_literal_builder); - auto list_literal_builder = base_literal_builder.initListLiteral(); +void ListLiteral::Save(capnp::BaseLiteral::Builder *base_literal_builder, + std::vector *saved_uids) { + BaseLiteral::Save(base_literal_builder, saved_uids); + auto list_literal_builder = base_literal_builder->initListLiteral(); ::capnp::List::Builder tree_builders = list_literal_builder.initElements(elements_.size()); for (size_t i = 0; i < elements_.size(); ++i) { auto tree_builder = tree_builders[i]; - elements_[i]->Save(tree_builder); + elements_[i]->Save(&tree_builder, saved_uids); } } -ListLiteral *ListLiteral::Construct(capnp::ListLiteral::Reader &reader, - AstTreeStorage &storage) { - auto *list = storage.Create(); - for (auto tree_reader : reader.getElements()) { - auto tree = storage.Load(tree_reader); - list->elements_.push_back(dynamic_cast(tree)); +void ListLiteral::Load(const capnp::Tree::Reader &base_reader, + AstTreeStorage *storage, std::vector *loaded_uids) { + BaseLiteral::Load(base_reader, storage, loaded_uids); + auto reader = base_reader.getExpression().getBaseLiteral().getListLiteral(); + for (const auto tree_reader : reader.getElements()) { + auto tree = storage->Load(tree_reader, loaded_uids); + elements_.push_back(dynamic_cast(tree)); } - return list; +} + +ListLiteral *ListLiteral::Construct(const capnp::ListLiteral::Reader &reader, + AstTreeStorage *storage) { + return storage->Create(); } // Map Literal. -void MapLiteral::Save(capnp::BaseLiteral::Builder &base_literal_builder) { - BaseLiteral::Save(base_literal_builder); - auto map_literal_builder = base_literal_builder.initMapLiteral(); +void MapLiteral::Save(capnp::BaseLiteral::Builder *base_literal_builder, + std::vector *saved_uids) { + BaseLiteral::Save(base_literal_builder, saved_uids); + auto map_literal_builder = base_literal_builder->initMapLiteral(); ::capnp::List::Builder map_builder = map_literal_builder.initElements(elements_.size()); size_t i = 0; @@ -257,63 +311,73 @@ void MapLiteral::Save(capnp::BaseLiteral::Builder &base_literal_builder) { auto storage_property_builder = key_builder.getSecond(); entry.first.second.Save(storage_property_builder); auto value_builder = entry_builder.getValue(); - if (entry.second) entry.second->Save(value_builder); + if (entry.second) entry.second->Save(&value_builder, saved_uids); ++i; } } -MapLiteral *MapLiteral::Construct(capnp::MapLiteral::Reader &reader, - AstTreeStorage &storage) { - auto *map = storage.Create(); +void MapLiteral::Load(const capnp::Tree::Reader &base_reader, + AstTreeStorage *storage, std::vector *loaded_uids) { + BaseLiteral::Load(base_reader, storage, loaded_uids); + auto reader = base_reader.getExpression().getBaseLiteral().getMapLiteral(); for (auto entry_reader : reader.getElements()) { auto key_pair_reader = entry_reader.getKey(); auto key_first = key_pair_reader.getFirst().cStr(); auto storage_property_reader = key_pair_reader.getSecond(); storage::Property key_second; key_second.Load(storage_property_reader); - auto value_reader = entry_reader.getValue(); - auto value = storage.Load(value_reader); + const auto value_reader = entry_reader.getValue(); + auto value = storage->Load(value_reader, loaded_uids); auto key = std::make_pair(key_first, key_second); // TODO Maybe check for nullptr expression? - map->elements_.emplace(key, dynamic_cast(value)); + elements_.emplace(key, dynamic_cast(value)); } - return map; +} + +MapLiteral *MapLiteral::Construct(const capnp::MapLiteral::Reader &reader, + AstTreeStorage *storage) { + return storage->Create(); } // Binary Operator. -void BinaryOperator::Save(capnp::Expression::Builder &expr_builder) { - Expression::Save(expr_builder); - auto builder = expr_builder.initBinaryOperator(); - Save(builder); +void BinaryOperator::Save(capnp::Expression::Builder *expr_builder, + std::vector *saved_uids) { + Expression::Save(expr_builder, saved_uids); + auto builder = expr_builder->initBinaryOperator(); + Save(&builder, saved_uids); } -void BinaryOperator::Save(capnp::BinaryOperator::Builder &builder) { +void BinaryOperator::Save(capnp::BinaryOperator::Builder *builder, + std::vector *saved_uids) { if (expression1_) { - auto expr1_builder = builder.getExpression1(); - expression1_->Save(expr1_builder); + auto expr1_builder = builder->getExpression1(); + expression1_->Save(&expr1_builder, saved_uids); } if (expression2_) { - auto expr2_builder = builder.getExpression2(); - expression2_->Save(expr2_builder); + auto expr2_builder = builder->getExpression2(); + expression2_->Save(&expr2_builder, saved_uids); } } -void BinaryOperator::Load(capnp::Tree::Reader &reader, - AstTreeStorage &storage) { - Expression::Load(reader, storage); +void BinaryOperator::Load(const capnp::Tree::Reader &reader, + AstTreeStorage *storage, + std::vector *loaded_uids) { + Expression::Load(reader, storage, loaded_uids); auto bop_reader = reader.getExpression().getBinaryOperator(); if (bop_reader.hasExpression1()) { - auto expr1_reader = bop_reader.getExpression1(); - expression1_ = dynamic_cast(storage.Load(expr1_reader)); + const auto expr1_reader = bop_reader.getExpression1(); + expression1_ = + dynamic_cast(storage->Load(expr1_reader, loaded_uids)); } if (bop_reader.hasExpression2()) { - auto expr2_reader = bop_reader.getExpression2(); - expression2_ = dynamic_cast(storage.Load(expr2_reader)); + const auto expr2_reader = bop_reader.getExpression2(); + expression2_ = + dynamic_cast(storage->Load(expr2_reader, loaded_uids)); } } -BinaryOperator *BinaryOperator::Construct(capnp::BinaryOperator::Reader &reader, - AstTreeStorage &storage) { +BinaryOperator *BinaryOperator::Construct( + const capnp::BinaryOperator::Reader &reader, AstTreeStorage *storage) { switch (reader.which()) { case capnp::BinaryOperator::ADDITION_OPERATOR: { auto literal = reader.getAdditionOperator(); @@ -386,169 +450,186 @@ BinaryOperator *BinaryOperator::Construct(capnp::BinaryOperator::Reader &reader, } } -void OrOperator::Save(capnp::BinaryOperator::Builder &builder) { - BinaryOperator::Save(builder); - builder.initOrOperator(); +void OrOperator::Save(capnp::BinaryOperator::Builder *builder, + std::vector *saved_uids) { + BinaryOperator::Save(builder, saved_uids); + builder->initOrOperator(); } -OrOperator *OrOperator::Construct(capnp::OrOperator::Reader &, - AstTreeStorage &storage) { - return storage.Create(); +OrOperator *OrOperator::Construct(const capnp::OrOperator::Reader &, + AstTreeStorage *storage) { + return storage->Create(); } -void XorOperator::Save(capnp::BinaryOperator::Builder &builder) { - BinaryOperator::Save(builder); - builder.initXorOperator(); +void XorOperator::Save(capnp::BinaryOperator::Builder *builder, + std::vector *saved_uids) { + BinaryOperator::Save(builder, saved_uids); + builder->initXorOperator(); } -XorOperator *XorOperator::Construct(capnp::XorOperator::Reader &, - AstTreeStorage &storage) { - return storage.Create(); +XorOperator *XorOperator::Construct(const capnp::XorOperator::Reader &, + AstTreeStorage *storage) { + return storage->Create(); } -void AndOperator::Save(capnp::BinaryOperator::Builder &builder) { - BinaryOperator::Save(builder); - builder.initAndOperator(); +void AndOperator::Save(capnp::BinaryOperator::Builder *builder, + std::vector *saved_uids) { + BinaryOperator::Save(builder, saved_uids); + builder->initAndOperator(); } -AndOperator *AndOperator::Construct(capnp::AndOperator::Reader &, - AstTreeStorage &storage) { - return storage.Create(); +AndOperator *AndOperator::Construct(const capnp::AndOperator::Reader &, + AstTreeStorage *storage) { + return storage->Create(); } -void AdditionOperator::Save(capnp::BinaryOperator::Builder &builder) { - BinaryOperator::Save(builder); - builder.initAdditionOperator(); +void AdditionOperator::Save(capnp::BinaryOperator::Builder *builder, + std::vector *saved_uids) { + BinaryOperator::Save(builder, saved_uids); + builder->initAdditionOperator(); } -AdditionOperator *AdditionOperator::Construct(capnp::AdditionOperator::Reader &, - AstTreeStorage &storage) { - return storage.Create(); +AdditionOperator *AdditionOperator::Construct( + const capnp::AdditionOperator::Reader &, AstTreeStorage *storage) { + return storage->Create(); } -void SubtractionOperator::Save(capnp::BinaryOperator::Builder &builder) { - BinaryOperator::Save(builder); - builder.initSubtractionOperator(); +void SubtractionOperator::Save(capnp::BinaryOperator::Builder *builder, + std::vector *saved_uids) { + BinaryOperator::Save(builder, saved_uids); + builder->initSubtractionOperator(); } SubtractionOperator *SubtractionOperator::Construct( - capnp::SubtractionOperator::Reader &, AstTreeStorage &storage) { - return storage.Create(); + capnp::SubtractionOperator::Reader &, AstTreeStorage *storage) { + return storage->Create(); } -void MultiplicationOperator::Save(capnp::BinaryOperator::Builder &builder) { - BinaryOperator::Save(builder); - builder.initMultiplicationOperator(); +void MultiplicationOperator::Save(capnp::BinaryOperator::Builder *builder, + std::vector *saved_uids) { + BinaryOperator::Save(builder, saved_uids); + builder->initMultiplicationOperator(); } MultiplicationOperator *MultiplicationOperator::Construct( - capnp::MultiplicationOperator::Reader &, AstTreeStorage &storage) { - return storage.Create(); + capnp::MultiplicationOperator::Reader &, AstTreeStorage *storage) { + return storage->Create(); } -void DivisionOperator::Save(capnp::BinaryOperator::Builder &builder) { - BinaryOperator::Save(builder); - builder.initDivisionOperator(); +void DivisionOperator::Save(capnp::BinaryOperator::Builder *builder, + std::vector *saved_uids) { + BinaryOperator::Save(builder, saved_uids); + builder->initDivisionOperator(); } -DivisionOperator *DivisionOperator::Construct(capnp::DivisionOperator::Reader &, - AstTreeStorage &storage) { - return storage.Create(); +DivisionOperator *DivisionOperator::Construct( + const capnp::DivisionOperator::Reader &, AstTreeStorage *storage) { + return storage->Create(); } -void ModOperator::Save(capnp::BinaryOperator::Builder &builder) { - BinaryOperator::Save(builder); - builder.initModOperator(); +void ModOperator::Save(capnp::BinaryOperator::Builder *builder, + std::vector *saved_uids) { + BinaryOperator::Save(builder, saved_uids); + builder->initModOperator(); } -ModOperator *ModOperator::Construct(capnp::ModOperator::Reader &, - AstTreeStorage &storage) { - return storage.Create(); +ModOperator *ModOperator::Construct(const capnp::ModOperator::Reader &, + AstTreeStorage *storage) { + return storage->Create(); } -void NotEqualOperator::Save(capnp::BinaryOperator::Builder &builder) { - BinaryOperator::Save(builder); - builder.initNotEqualOperator(); +void NotEqualOperator::Save(capnp::BinaryOperator::Builder *builder, + std::vector *saved_uids) { + BinaryOperator::Save(builder, saved_uids); + builder->initNotEqualOperator(); } -NotEqualOperator *NotEqualOperator::Construct(capnp::NotEqualOperator::Reader &, - AstTreeStorage &storage) { - return storage.Create(); +NotEqualOperator *NotEqualOperator::Construct( + const capnp::NotEqualOperator::Reader &, AstTreeStorage *storage) { + return storage->Create(); } -void EqualOperator::Save(capnp::BinaryOperator::Builder &builder) { - BinaryOperator::Save(builder); - builder.initEqualOperator(); +void EqualOperator::Save(capnp::BinaryOperator::Builder *builder, + std::vector *saved_uids) { + BinaryOperator::Save(builder, saved_uids); + builder->initEqualOperator(); } -EqualOperator *EqualOperator::Construct(capnp::EqualOperator::Reader &, - AstTreeStorage &storage) { - return storage.Create(); +EqualOperator *EqualOperator::Construct(const capnp::EqualOperator::Reader &, + AstTreeStorage *storage) { + return storage->Create(); } -void LessOperator::Save(capnp::BinaryOperator::Builder &builder) { - BinaryOperator::Save(builder); - builder.initLessOperator(); +void LessOperator::Save(capnp::BinaryOperator::Builder *builder, + std::vector *saved_uids) { + BinaryOperator::Save(builder, saved_uids); + builder->initLessOperator(); } -LessOperator *LessOperator::Construct(capnp::LessOperator::Reader &, - AstTreeStorage &storage) { - return storage.Create(); +LessOperator *LessOperator::Construct(const capnp::LessOperator::Reader &, + AstTreeStorage *storage) { + return storage->Create(); } -void GreaterOperator::Save(capnp::BinaryOperator::Builder &builder) { - BinaryOperator::Save(builder); - builder.initGreaterOperator(); +void GreaterOperator::Save(capnp::BinaryOperator::Builder *builder, + std::vector *saved_uids) { + BinaryOperator::Save(builder, saved_uids); + builder->initGreaterOperator(); } -GreaterOperator *GreaterOperator::Construct(capnp::GreaterOperator::Reader &, - AstTreeStorage &storage) { - return storage.Create(); +GreaterOperator *GreaterOperator::Construct( + const capnp::GreaterOperator::Reader &, AstTreeStorage *storage) { + return storage->Create(); } -void LessEqualOperator::Save(capnp::BinaryOperator::Builder &builder) { - BinaryOperator::Save(builder); - builder.initLessEqualOperator(); +void LessEqualOperator::Save(capnp::BinaryOperator::Builder *builder, + std::vector *saved_uids) { + BinaryOperator::Save(builder, saved_uids); + builder->initLessEqualOperator(); } LessEqualOperator *LessEqualOperator::Construct( - capnp::LessEqualOperator::Reader &, AstTreeStorage &storage) { - return storage.Create(); + const capnp::LessEqualOperator::Reader &, AstTreeStorage *storage) { + return storage->Create(); } -void GreaterEqualOperator::Save(capnp::BinaryOperator::Builder &builder) { - BinaryOperator::Save(builder); - builder.initGreaterEqualOperator(); +void GreaterEqualOperator::Save(capnp::BinaryOperator::Builder *builder, + std::vector *saved_uids) { + BinaryOperator::Save(builder, saved_uids); + builder->initGreaterEqualOperator(); } GreaterEqualOperator *GreaterEqualOperator::Construct( - capnp::GreaterEqualOperator::Reader &, AstTreeStorage &storage) { - return storage.Create(); + const capnp::GreaterEqualOperator::Reader &, AstTreeStorage *storage) { + return storage->Create(); } -void InListOperator::Save(capnp::BinaryOperator::Builder &builder) { - BinaryOperator::Save(builder); - builder.initInListOperator(); +void InListOperator::Save(capnp::BinaryOperator::Builder *builder, + std::vector *saved_uids) { + BinaryOperator::Save(builder, saved_uids); + builder->initInListOperator(); } -InListOperator *InListOperator::Construct(capnp::InListOperator::Reader &, - AstTreeStorage &storage) { - return storage.Create(); +InListOperator *InListOperator::Construct(const capnp::InListOperator::Reader &, + AstTreeStorage *storage) { + return storage->Create(); } -void ListMapIndexingOperator::Save(capnp::BinaryOperator::Builder &builder) { - BinaryOperator::Save(builder); - builder.initListMapIndexingOperator(); +void ListMapIndexingOperator::Save(capnp::BinaryOperator::Builder *builder, + std::vector *saved_uids) { + BinaryOperator::Save(builder, saved_uids); + builder->initListMapIndexingOperator(); } ListMapIndexingOperator *ListMapIndexingOperator::Construct( - capnp::ListMapIndexingOperator::Reader &, AstTreeStorage &storage) { - return storage.Create(); + capnp::ListMapIndexingOperator::Reader &, AstTreeStorage *storage) { + return storage->Create(); } -void Aggregation::Save(capnp::BinaryOperator::Builder &builder) { - BinaryOperator::Save(builder); - auto ag_builder = builder.initAggregation(); +void Aggregation::Save(capnp::BinaryOperator::Builder *builder, + std::vector *saved_uids) { + BinaryOperator::Save(builder, saved_uids); + auto ag_builder = builder->initAggregation(); switch (op_) { case Op::AVG: ag_builder.setOp(capnp::Aggregation::Op::AVG); @@ -574,8 +655,8 @@ void Aggregation::Save(capnp::BinaryOperator::Builder &builder) { } } -Aggregation *Aggregation::Construct(capnp::Aggregation::Reader &reader, - AstTreeStorage &storage) { +Aggregation *Aggregation::Construct(const capnp::Aggregation::Reader &reader, + AstTreeStorage *storage) { Op op; switch (reader.getOp()) { case capnp::Aggregation::Op::AVG: @@ -600,34 +681,39 @@ Aggregation *Aggregation::Construct(capnp::Aggregation::Reader &reader, op = Op::SUM; break; } - return storage.Create(op); + return storage->Create(op); } // Unary Operator. -void UnaryOperator::Save(capnp::Expression::Builder &expr_builder) { - Expression::Save(expr_builder); - auto builder = expr_builder.initUnaryOperator(); - Save(builder); +void UnaryOperator::Save(capnp::Expression::Builder *expr_builder, + std::vector *saved_uids) { + Expression::Save(expr_builder, saved_uids); + auto builder = expr_builder->initUnaryOperator(); + Save(&builder, saved_uids); } -void UnaryOperator::Save(capnp::UnaryOperator::Builder &builder) { +void UnaryOperator::Save(capnp::UnaryOperator::Builder *builder, + std::vector *saved_uids) { if (expression_) { - auto expr_builder = builder.getExpression(); - expression_->Save(expr_builder); + auto expr_builder = builder->getExpression(); + expression_->Save(&expr_builder, saved_uids); } } -void UnaryOperator::Load(capnp::Tree::Reader &reader, AstTreeStorage &storage) { - Expression::Load(reader, storage); +void UnaryOperator::Load(const capnp::Tree::Reader &reader, + AstTreeStorage *storage, + std::vector *loaded_uids) { + Expression::Load(reader, storage, loaded_uids); if (reader.hasExpression()) { - auto expr_reader = + const auto expr_reader = reader.getExpression().getUnaryOperator().getExpression(); - expression_ = dynamic_cast(storage.Load(expr_reader)); + expression_ = + dynamic_cast(storage->Load(expr_reader, loaded_uids)); } } -UnaryOperator *UnaryOperator::Construct(capnp::UnaryOperator::Reader &reader, - AstTreeStorage &storage) { +UnaryOperator *UnaryOperator::Construct( + const capnp::UnaryOperator::Reader &reader, AstTreeStorage *storage) { switch (reader.which()) { case capnp::UnaryOperator::IS_NULL_OPERATOR: { auto op = reader.getIsNullOperator(); @@ -649,371 +735,467 @@ UnaryOperator *UnaryOperator::Construct(capnp::UnaryOperator::Reader &reader, } // IsNull Operator. -void IsNullOperator::Save(capnp::UnaryOperator::Builder &builder) { - UnaryOperator::Save(builder); - builder.initIsNullOperator(); +void IsNullOperator::Save(capnp::UnaryOperator::Builder *builder, + std::vector *saved_uids) { + UnaryOperator::Save(builder, saved_uids); + builder->initIsNullOperator(); } -IsNullOperator *IsNullOperator::Construct(capnp::IsNullOperator::Reader &, - AstTreeStorage &storage) { - return storage.Create(); +IsNullOperator *IsNullOperator::Construct(const capnp::IsNullOperator::Reader &, + AstTreeStorage *storage) { + return storage->Create(); } // Not Operator. -void NotOperator::Save(capnp::UnaryOperator::Builder &builder) { - UnaryOperator::Save(builder); - builder.initNotOperator(); +void NotOperator::Save(capnp::UnaryOperator::Builder *builder, + std::vector *saved_uids) { + UnaryOperator::Save(builder, saved_uids); + builder->initNotOperator(); } -NotOperator *NotOperator::Construct(capnp::NotOperator::Reader &, - AstTreeStorage &storage) { - return storage.Create(); +NotOperator *NotOperator::Construct(const capnp::NotOperator::Reader &, + AstTreeStorage *storage) { + return storage->Create(); } // UnaryPlus Operator. -void UnaryPlusOperator::Save(capnp::UnaryOperator::Builder &builder) { - UnaryOperator::Save(builder); - builder.initUnaryPlusOperator(); +void UnaryPlusOperator::Save(capnp::UnaryOperator::Builder *builder, + std::vector *saved_uids) { + UnaryOperator::Save(builder, saved_uids); + builder->initUnaryPlusOperator(); } UnaryPlusOperator *UnaryPlusOperator::Construct( - capnp::UnaryPlusOperator::Reader &, AstTreeStorage &storage) { - return storage.Create(); + const capnp::UnaryPlusOperator::Reader &, AstTreeStorage *storage) { + return storage->Create(); } // UnaryMinus Operator. -void UnaryMinusOperator::Save(capnp::UnaryOperator::Builder &builder) { - UnaryOperator::Save(builder); - builder.initUnaryMinusOperator(); +void UnaryMinusOperator::Save(capnp::UnaryOperator::Builder *builder, + std::vector *saved_uids) { + UnaryOperator::Save(builder, saved_uids); + builder->initUnaryMinusOperator(); } UnaryMinusOperator *UnaryMinusOperator::Construct( - capnp::UnaryMinusOperator::Reader &, AstTreeStorage &storage) { - return storage.Create(); + capnp::UnaryMinusOperator::Reader &, AstTreeStorage *storage) { + return storage->Create(); } // ListSlicing Operator. -void ListSlicingOperator::Save(capnp::Expression::Builder &expr_builder) { - Expression::Save(expr_builder); - auto builder = expr_builder.initListSlicingOperator(); - Save(builder); +void ListSlicingOperator::Save(capnp::Expression::Builder *expr_builder, + std::vector *saved_uids) { + Expression::Save(expr_builder, saved_uids); + auto builder = expr_builder->initListSlicingOperator(); + Save(&builder, saved_uids); } -void ListSlicingOperator::Save(capnp::ListSlicingOperator::Builder &builder) { +void ListSlicingOperator::Save(capnp::ListSlicingOperator::Builder *builder, + std::vector *saved_uids) { if (list_) { - auto list_builder = builder.getList(); - list_->Save(list_builder); + auto list_builder = builder->getList(); + list_->Save(&list_builder, saved_uids); } if (lower_bound_) { - auto lb_builder = builder.getLowerBound(); - lower_bound_->Save(lb_builder); + auto lb_builder = builder->getLowerBound(); + lower_bound_->Save(&lb_builder, saved_uids); } if (upper_bound_) { - auto up_builder = builder.getUpperBound(); - upper_bound_->Save(up_builder); + auto up_builder = builder->getUpperBound(); + upper_bound_->Save(&up_builder, saved_uids); + } +} + +void ListSlicingOperator::Load(const capnp::Tree::Reader &base_reader, + AstTreeStorage *storage, + std::vector *loaded_uids) { + Expression::Load(base_reader, storage, loaded_uids); + auto reader = base_reader.getExpression().getListSlicingOperator(); + if (reader.hasList()) { + const auto list_reader = reader.getList(); + list_ = dynamic_cast(storage->Load(list_reader, loaded_uids)); + } + if (reader.hasUpperBound()) { + const auto ub_reader = reader.getUpperBound(); + upper_bound_ = + dynamic_cast(storage->Load(ub_reader, loaded_uids)); + } + if (reader.hasLowerBound()) { + const auto lb_reader = reader.getLowerBound(); + lower_bound_ = + dynamic_cast(storage->Load(lb_reader, loaded_uids)); } } ListSlicingOperator *ListSlicingOperator::Construct( - capnp::ListSlicingOperator::Reader &reader, AstTreeStorage &storage) { - Expression *list = nullptr; - Expression *upper_bound = nullptr; - Expression *lower_bound = nullptr; - if (reader.hasList()) { - auto list_reader = reader.getList(); - list = dynamic_cast(storage.Load(list_reader)); - } - if (reader.hasUpperBound()) { - auto ub_reader = reader.getUpperBound(); - upper_bound = dynamic_cast(storage.Load(ub_reader)); - } - if (reader.hasLowerBound()) { - auto lb_reader = reader.getLowerBound(); - lower_bound = dynamic_cast(storage.Load(lb_reader)); - } - return storage.Create(list, lower_bound, upper_bound); + const capnp::ListSlicingOperator::Reader &reader, AstTreeStorage *storage) { + return storage->Create(nullptr, nullptr, nullptr); } // If Operator. -void IfOperator::Save(capnp::Expression::Builder &expr_builder) { - Expression::Save(expr_builder); - auto builder = expr_builder.initIfOperator(); - Save(builder); +void IfOperator::Save(capnp::Expression::Builder *expr_builder, + std::vector *saved_uids) { + Expression::Save(expr_builder, saved_uids); + auto builder = expr_builder->initIfOperator(); + Save(&builder, saved_uids); } -void IfOperator::Save(capnp::IfOperator::Builder &builder) { - auto condition_builder = builder.getCondition(); - condition_->Save(condition_builder); - auto then_builder = builder.getThenExpression(); - then_expression_->Save(then_builder); - auto else_builder = builder.getElseExpression(); - else_expression_->Save(else_builder); +void IfOperator::Save(capnp::IfOperator::Builder *builder, + std::vector *saved_uids) { + auto condition_builder = builder->getCondition(); + condition_->Save(&condition_builder, saved_uids); + auto then_builder = builder->getThenExpression(); + then_expression_->Save(&then_builder, saved_uids); + auto else_builder = builder->getElseExpression(); + else_expression_->Save(&else_builder, saved_uids); } -IfOperator *IfOperator::Construct(capnp::IfOperator::Reader &reader, - AstTreeStorage &storage) { - auto condition_reader = reader.getCondition(); - auto condition = dynamic_cast(storage.Load(condition_reader)); - auto then_reader = reader.getThenExpression(); - auto then_expression = dynamic_cast(storage.Load(then_reader)); - auto else_reader = reader.getElseExpression(); - auto else_expression = dynamic_cast(storage.Load(else_reader)); - return storage.Create(condition, then_expression, - else_expression); +void IfOperator::Load(const capnp::Tree::Reader &base_reader, + AstTreeStorage *storage, std::vector *loaded_uids) { + Expression::Load(base_reader, storage, loaded_uids); + auto reader = base_reader.getExpression().getIfOperator(); + const auto condition_reader = reader.getCondition(); + condition_ = + dynamic_cast(storage->Load(condition_reader, loaded_uids)); + const auto then_reader = reader.getThenExpression(); + then_expression_ = + dynamic_cast(storage->Load(then_reader, loaded_uids)); + const auto else_reader = reader.getElseExpression(); + else_expression_ = + dynamic_cast(storage->Load(else_reader, loaded_uids)); +} + +IfOperator *IfOperator::Construct(const capnp::IfOperator::Reader &reader, + AstTreeStorage *storage) { + return storage->Create(nullptr, nullptr, nullptr); } // All -void All::Save(capnp::Expression::Builder &expr_builder) { - Expression::Save(expr_builder); - auto builder = expr_builder.initAll(); - Save(builder); +void All::Save(capnp::Expression::Builder *expr_builder, + std::vector *saved_uids) { + Expression::Save(expr_builder, saved_uids); + auto builder = expr_builder->initAll(); + Save(&builder, saved_uids); } -void All::Save(capnp::All::Builder &builder) { - auto identifier_builder = builder.getIdentifier(); - identifier_->Save(identifier_builder); - auto expr_builder = builder.getListExpression(); - list_expression_->Save(expr_builder); - auto where_builder = builder.getWhere(); - where_->Save(where_builder); +void All::Save(capnp::All::Builder *builder, std::vector *saved_uids) { + auto identifier_builder = builder->getIdentifier(); + identifier_->Save(&identifier_builder, saved_uids); + auto expr_builder = builder->getListExpression(); + list_expression_->Save(&expr_builder, saved_uids); + auto where_builder = builder->getWhere(); + where_->Save(&where_builder, saved_uids); } -All *All::Construct(capnp::All::Reader &reader, AstTreeStorage &storage) { - auto id_reader = reader.getIdentifier(); - auto identifier = dynamic_cast(storage.Load(id_reader)); - auto expr_reader = reader.getListExpression(); - auto list_expression = dynamic_cast(storage.Load(expr_reader)); - auto where_reader = reader.getWhere(); - auto where = dynamic_cast(storage.Load(where_reader)); - return storage.Create(identifier, list_expression, where); +void All::Load(const capnp::Tree::Reader &base_reader, AstTreeStorage *storage, + std::vector *loaded_uids) { + Expression::Load(base_reader, storage, loaded_uids); + auto reader = base_reader.getExpression().getAll(); + const auto id_reader = reader.getIdentifier(); + identifier_ = + dynamic_cast(storage->Load(id_reader, loaded_uids)); + const auto expr_reader = reader.getListExpression(); + list_expression_ = + dynamic_cast(storage->Load(expr_reader, loaded_uids)); + const auto where_reader = reader.getWhere(); + where_ = dynamic_cast(storage->Load(where_reader, loaded_uids)); +} + +All *All::Construct(const capnp::All::Reader &reader, AstTreeStorage *storage) { + return storage->Create(nullptr, nullptr, nullptr); } // Function -void Function::Save(capnp::Expression::Builder &expr_builder) { - Expression::Save(expr_builder); - auto builder = expr_builder.initFunction(); - Save(builder); +void Function::Save(capnp::Expression::Builder *expr_builder, + std::vector *saved_uids) { + Expression::Save(expr_builder, saved_uids); + auto builder = expr_builder->initFunction(); + Save(&builder, saved_uids); } -void Function::Save(capnp::Function::Builder &builder) { - builder.setFunctionName(function_name_); +void Function::Save(capnp::Function::Builder *builder, + std::vector *saved_uids) { + builder->setFunctionName(function_name_); ::capnp::List::Builder tree_builders = - builder.initArguments(arguments_.size()); + builder->initArguments(arguments_.size()); for (size_t i = 0; i < arguments_.size(); ++i) { auto tree_builder = tree_builders[i]; - arguments_[i]->Save(tree_builder); + arguments_[i]->Save(&tree_builder, saved_uids); } } -Function *Function::Construct(capnp::Function::Reader &reader, - AstTreeStorage &storage) { - auto name = reader.getFunctionName().cStr(); - std::vector arguments; - for (auto tree_reader : reader.getArguments()) { - auto tree = storage.Load(tree_reader); - arguments.push_back(dynamic_cast(tree)); +void Function::Load(const capnp::Tree::Reader &base_reader, + AstTreeStorage *storage, std::vector *loaded_uids) { + Expression::Load(base_reader, storage, loaded_uids); + auto reader = base_reader.getExpression().getFunction(); + function_name_ = reader.getFunctionName().cStr(); + for (const auto tree_reader : reader.getArguments()) { + auto tree = storage->Load(tree_reader, loaded_uids); + arguments_.push_back(dynamic_cast(tree)); } - return storage.Create(name, arguments); + function_ = NameToFunction(function_name_); +} + +Function *Function::Construct(const capnp::Function::Reader &reader, + AstTreeStorage *storage) { + return storage->Create(); } // Identifier -void Identifier::Save(capnp::Expression::Builder &expr_builder) { - Expression::Save(expr_builder); - auto builder = expr_builder.initIdentifier(); - Save(builder); +void Identifier::Save(capnp::Expression::Builder *expr_builder, + std::vector *saved_uids) { + Expression::Save(expr_builder, saved_uids); + auto builder = expr_builder->initIdentifier(); + Save(&builder, saved_uids); } -void Identifier::Save(capnp::Identifier::Builder &builder) { - builder.setName(name_); - builder.setUserDeclared(user_declared_); +void Identifier::Save(capnp::Identifier::Builder *builder, + std::vector *saved_uids) { + builder->setName(name_); + builder->setUserDeclared(user_declared_); } -Identifier *Identifier::Construct(capnp::Identifier::Reader &reader, - AstTreeStorage &storage) { +Identifier *Identifier::Construct(const capnp::Identifier::Reader &reader, + AstTreeStorage *storage) { auto name = reader.getName().cStr(); auto user_declared = reader.getUserDeclared(); - return storage.Create(name, user_declared); + return storage->Create(name, user_declared); } // LabelsTest -void LabelsTest::Save(capnp::Expression::Builder &expr_builder) { - Expression::Save(expr_builder); - auto builder = expr_builder.initLabelsTest(); - Save(builder); +void LabelsTest::Save(capnp::Expression::Builder *expr_builder, + std::vector *saved_uids) { + Expression::Save(expr_builder, saved_uids); + auto builder = expr_builder->initLabelsTest(); + Save(&builder, saved_uids); } -void LabelsTest::Save(capnp::LabelsTest::Builder &builder) { +void LabelsTest::Save(capnp::LabelsTest::Builder *builder, + std::vector *saved_uids) { if (expression_) { - auto expr_builder = builder.initExpression(); - expression_->Save(expr_builder); + auto expr_builder = builder->initExpression(); + expression_->Save(&expr_builder, saved_uids); } ::capnp::List::Builder common_builders = - builder.initLabels(labels_.size()); + builder->initLabels(labels_.size()); for (size_t i = 0; i < labels_.size(); ++i) { auto common_builder = common_builders[i]; labels_[i].Save(common_builder); } } -LabelsTest *LabelsTest::Construct(capnp::LabelsTest::Reader &reader, - AstTreeStorage &storage) { - Expression *expression = nullptr; +void LabelsTest::Load(const capnp::Tree::Reader &base_reader, + AstTreeStorage *storage, std::vector *loaded_uids) { + Expression::Load(base_reader, storage, loaded_uids); + auto reader = base_reader.getExpression().getLabelsTest(); if (reader.hasExpression()) { - auto expr_reader = reader.getExpression(); - expression = dynamic_cast(storage.Load(expr_reader)); + const auto expr_reader = reader.getExpression(); + expression_ = + dynamic_cast(storage->Load(expr_reader, loaded_uids)); } - std::vector labels; for (auto label_reader : reader.getLabels()) { storage::Label label; label.Load(label_reader); - labels.push_back(label); + labels_.push_back(label); } - return storage.Create(expression, labels); +} + +LabelsTest *LabelsTest::Construct(const capnp::LabelsTest::Reader &reader, + AstTreeStorage *storage) { + return storage->Create(nullptr, std::vector()); } // ParameterLookup -void ParameterLookup::Save(capnp::Expression::Builder &expr_builder) { - Expression::Save(expr_builder); - auto builder = expr_builder.initParameterLookup(); - Save(builder); +void ParameterLookup::Save(capnp::Expression::Builder *expr_builder, + std::vector *saved_uids) { + Expression::Save(expr_builder, saved_uids); + auto builder = expr_builder->initParameterLookup(); + Save(&builder, saved_uids); } -void ParameterLookup::Save(capnp::ParameterLookup::Builder &builder) { - builder.setTokenPosition(token_position_); +void ParameterLookup::Save(capnp::ParameterLookup::Builder *builder, + std::vector *saved_uids) { + builder->setTokenPosition(token_position_); } ParameterLookup *ParameterLookup::Construct( - capnp::ParameterLookup::Reader &reader, AstTreeStorage &storage) { + const capnp::ParameterLookup::Reader &reader, AstTreeStorage *storage) { auto token_position = reader.getTokenPosition(); - return storage.Create(token_position); + return storage->Create(token_position); } // PropertyLookup -void PropertyLookup::Save(capnp::Expression::Builder &expr_builder) { - Expression::Save(expr_builder); - auto builder = expr_builder.initPropertyLookup(); - Save(builder); +void PropertyLookup::Save(capnp::Expression::Builder *expr_builder, + std::vector *saved_uids) { + Expression::Save(expr_builder, saved_uids); + auto builder = expr_builder->initPropertyLookup(); + Save(&builder, saved_uids); } -void PropertyLookup::Save(capnp::PropertyLookup::Builder &builder) { +void PropertyLookup::Save(capnp::PropertyLookup::Builder *builder, + std::vector *saved_uids) { if (expression_) { - auto expr_builder = builder.initExpression(); - expression_->Save(expr_builder); + auto expr_builder = builder->initExpression(); + expression_->Save(&expr_builder, saved_uids); } - builder.setPropertyName(property_name_); - auto storage_property_builder = builder.initProperty(); + builder->setPropertyName(property_name_); + auto storage_property_builder = builder->initProperty(); property_.Save(storage_property_builder); } -PropertyLookup *PropertyLookup::Construct(capnp::PropertyLookup::Reader &reader, - AstTreeStorage &storage) { - Expression *expression = nullptr; +void PropertyLookup::Load(const capnp::Tree::Reader &base_reader, + AstTreeStorage *storage, + std::vector *loaded_uids) { + Expression::Load(base_reader, storage, loaded_uids); + auto reader = base_reader.getExpression().getPropertyLookup(); if (reader.hasExpression()) { - auto expr_reader = reader.getExpression(); - expression = dynamic_cast(storage.Load(expr_reader)); + const auto expr_reader = reader.getExpression(); + expression_ = + dynamic_cast(storage->Load(expr_reader, loaded_uids)); } - auto property_name = reader.getPropertyName().cStr(); + property_name_ = reader.getPropertyName().cStr(); auto storage_property_reader = reader.getProperty(); - storage::Property property; - property.Load(storage_property_reader); - return storage.Create(expression, property_name, property); + property_.Load(storage_property_reader); +} + +PropertyLookup *PropertyLookup::Construct( + const capnp::PropertyLookup::Reader &reader, AstTreeStorage *storage) { + return storage->Create(nullptr, "", storage::Property()); } // Reduce -void Reduce::Save(capnp::Expression::Builder &expr_builder) { - Expression::Save(expr_builder); - auto builder = expr_builder.initReduce(); - Save(builder); +void Reduce::Save(capnp::Expression::Builder *expr_builder, + std::vector *saved_uids) { + Expression::Save(expr_builder, saved_uids); + auto builder = expr_builder->initReduce(); + Save(&builder, saved_uids); } -void Reduce::Save(capnp::Reduce::Builder &builder) { - auto acc_builder = builder.initAccumulator(); - accumulator_->Save(acc_builder); - auto init_builder = builder.initInitializer(); - initializer_->Save(init_builder); - auto id_builder = builder.initIdentifier(); - identifier_->Save(id_builder); - auto list_builder = builder.initList(); - list_->Save(list_builder); - auto expr_builder = builder.initExpression(); - expression_->Save(expr_builder); +void Reduce::Save(capnp::Reduce::Builder *builder, + std::vector *saved_uids) { + auto acc_builder = builder->initAccumulator(); + accumulator_->Save(&acc_builder, saved_uids); + auto init_builder = builder->initInitializer(); + initializer_->Save(&init_builder, saved_uids); + auto id_builder = builder->initIdentifier(); + identifier_->Save(&id_builder, saved_uids); + auto list_builder = builder->initList(); + list_->Save(&list_builder, saved_uids); + auto expr_builder = builder->initExpression(); + expression_->Save(&expr_builder, saved_uids); } -Reduce *Reduce::Construct(capnp::Reduce::Reader &reader, - AstTreeStorage &storage) { - auto acc_reader = reader.getAccumulator(); - auto accumulator = dynamic_cast(storage.Load(acc_reader)); - auto init_reader = reader.getInitializer(); - auto initializer = dynamic_cast(storage.Load(init_reader)); - auto id_reader = reader.getIdentifier(); - auto identifier = dynamic_cast(storage.Load(id_reader)); - auto list_reader = reader.getList(); - auto list = dynamic_cast(storage.Load(list_reader)); - auto expr_reader = reader.getExpression(); - auto expression = dynamic_cast(storage.Load(expr_reader)); - return storage.Create(accumulator, initializer, identifier, list, - expression); +void Reduce::Load(const capnp::Tree::Reader &base_reader, + AstTreeStorage *storage, std::vector *loaded_uids) { + Expression::Load(base_reader, storage, loaded_uids); + auto reader = base_reader.getExpression().getReduce(); + const auto acc_reader = reader.getAccumulator(); + accumulator_ = + dynamic_cast(storage->Load(acc_reader, loaded_uids)); + const auto init_reader = reader.getInitializer(); + initializer_ = + dynamic_cast(storage->Load(init_reader, loaded_uids)); + const auto id_reader = reader.getIdentifier(); + identifier_ = + dynamic_cast(storage->Load(id_reader, loaded_uids)); + const auto list_reader = reader.getList(); + list_ = dynamic_cast(storage->Load(list_reader, loaded_uids)); + const auto expr_reader = reader.getExpression(); + expression_ = + dynamic_cast(storage->Load(expr_reader, loaded_uids)); +} + +Reduce *Reduce::Construct(const capnp::Reduce::Reader &reader, + AstTreeStorage *storage) { + return storage->Create(nullptr, nullptr, nullptr, nullptr, nullptr); } // Single -void Single::Save(capnp::Expression::Builder &expr_builder) { - Expression::Save(expr_builder); - auto builder = expr_builder.initSingle(); - Save(builder); +void Single::Save(capnp::Expression::Builder *expr_builder, + std::vector *saved_uids) { + Expression::Save(expr_builder, saved_uids); + auto builder = expr_builder->initSingle(); + Save(&builder, saved_uids); } -void Single::Save(capnp::Single::Builder &builder) { - auto where_builder = builder.initWhere(); - where_->Save(where_builder); - auto id_builder = builder.initIdentifier(); - identifier_->Save(id_builder); - auto expr_builder = builder.initListExpression(); - list_expression_->Save(expr_builder); +void Single::Save(capnp::Single::Builder *builder, + std::vector *saved_uids) { + auto where_builder = builder->initWhere(); + where_->Save(&where_builder, saved_uids); + auto id_builder = builder->initIdentifier(); + identifier_->Save(&id_builder, saved_uids); + auto expr_builder = builder->initListExpression(); + list_expression_->Save(&expr_builder, saved_uids); } -Single *Single::Construct(capnp::Single::Reader &reader, - AstTreeStorage &storage) { - auto id_reader = reader.getIdentifier(); - auto identifier = dynamic_cast(storage.Load(id_reader)); - auto list_reader = reader.getListExpression(); - auto list_expression = dynamic_cast(storage.Load(list_reader)); - auto where_reader = reader.getWhere(); - auto where = dynamic_cast(storage.Load(where_reader)); - return storage.Create(identifier, list_expression, where); +void Single::Load(const capnp::Tree::Reader &base_reader, + AstTreeStorage *storage, std::vector *loaded_uids) { + Expression::Load(base_reader, storage, loaded_uids); + auto reader = base_reader.getExpression().getSingle(); + const auto id_reader = reader.getIdentifier(); + identifier_ = + dynamic_cast(storage->Load(id_reader, loaded_uids)); + const auto list_reader = reader.getListExpression(); + list_expression_ = + dynamic_cast(storage->Load(list_reader, loaded_uids)); + const auto where_reader = reader.getWhere(); + where_ = dynamic_cast(storage->Load(where_reader, loaded_uids)); +} + +Single *Single::Construct(const capnp::Single::Reader &reader, + AstTreeStorage *storage) { + return storage->Create(nullptr, nullptr, nullptr); } // Where -void Where::Save(capnp::Tree::Builder &tree_builder) { - Tree::Save(tree_builder); - auto builder = tree_builder.initWhere(); - Save(builder); +void Where::Save(capnp::Tree::Builder *tree_builder, + std::vector *saved_uids) { + Tree::Save(tree_builder, saved_uids); + if (IsSaved(*saved_uids)) { + return; + } + auto builder = tree_builder->initWhere(); + Save(&builder, saved_uids); + AddToSaved(saved_uids); } -void Where::Save(capnp::Where::Builder &builder) { +void Where::Save(capnp::Where::Builder *builder, std::vector *saved_uids) { if (expression_) { - auto expr_builder = builder.initExpression(); - expression_->Save(expr_builder); + auto expr_builder = builder->initExpression(); + expression_->Save(&expr_builder, saved_uids); } } -Where *Where::Construct(capnp::Where::Reader &reader, AstTreeStorage &storage) { - Expression *expression = nullptr; +void Where::Load(const capnp::Tree::Reader &base_reader, + AstTreeStorage *storage, std::vector *loaded_uids) { + Tree::Load(base_reader, storage, loaded_uids); + auto reader = base_reader.getWhere(); if (reader.hasExpression()) { - auto expr_reader = reader.getExpression(); - expression = dynamic_cast(storage.Load(expr_reader)); + const auto expr_reader = reader.getExpression(); + expression_ = + dynamic_cast(storage->Load(expr_reader, loaded_uids)); } - return storage.Create(expression); +} + +Where *Where::Construct(const capnp::Where::Reader &reader, + AstTreeStorage *storage) { + return storage->Create(); } // Clause. -void Clause::Save(capnp::Tree::Builder &tree_builder) { - Tree::Save(tree_builder); - auto clause_builder = tree_builder.initClause(); - Save(clause_builder); +void Clause::Save(capnp::Tree::Builder *tree_builder, + std::vector *saved_uids) { + Tree::Save(tree_builder, saved_uids); + if (IsSaved(*saved_uids)) { + return; + } + auto clause_builder = tree_builder->initClause(); + Save(&clause_builder, saved_uids); + AddToSaved(saved_uids); } -Clause *Clause::Construct(capnp::Clause::Reader &reader, - AstTreeStorage &storage) { +Clause *Clause::Construct(const capnp::Clause::Reader &reader, + AstTreeStorage *storage) { switch (reader.which()) { case capnp::Clause::CREATE: { auto create_reader = reader.getCreate(); @@ -1072,249 +1254,294 @@ Clause *Clause::Construct(capnp::Clause::Reader &reader, } // Create. -void Create::Save(capnp::Clause::Builder &builder) { - Clause::Save(builder); - auto create_builder = builder.initCreate(); - Create::Save(create_builder); +void Create::Save(capnp::Clause::Builder *builder, + std::vector *saved_uids) { + Clause::Save(builder, saved_uids); + auto create_builder = builder->initCreate(); + Create::Save(&create_builder, saved_uids); } -void Create::Save(capnp::Create::Builder &builder) { +void Create::Save(capnp::Create::Builder *builder, + std::vector *saved_uids) { ::capnp::List::Builder tree_builders = - builder.initPatterns(patterns_.size()); + builder->initPatterns(patterns_.size()); for (size_t i = 0; i < patterns_.size(); ++i) { auto tree_builder = tree_builders[i]; - patterns_[i]->Save(tree_builder); + patterns_[i]->Save(&tree_builder, saved_uids); } } -Create *Create::Construct(capnp::Create::Reader &reader, - AstTreeStorage &storage) { - std::vector patterns; - for (auto tree_reader : reader.getPatterns()) { - auto tree = storage.Load(tree_reader); - patterns.push_back(dynamic_cast(tree)); +void Create::Load(const capnp::Tree::Reader &base_reader, + AstTreeStorage *storage, std::vector *loaded_uids) { + Clause::Load(base_reader, storage, loaded_uids); + auto reader = base_reader.getClause().getCreate(); + for (const auto pattern_reader : reader.getPatterns()) { + auto tree = storage->Load(pattern_reader, loaded_uids); + patterns_.push_back(dynamic_cast(tree)); } - return storage.Create(patterns); +} + +Create *Create::Construct(const capnp::Create::Reader &reader, + AstTreeStorage *storage) { + return storage->Create(); } // CreateIndex. -void CreateIndex::Save(capnp::Clause::Builder &builder) { - Clause::Save(builder); - auto create_builder = builder.initCreateIndex(); - CreateIndex::Save(create_builder); +void CreateIndex::Save(capnp::Clause::Builder *builder, + std::vector *saved_uids) { + Clause::Save(builder, saved_uids); + auto create_builder = builder->initCreateIndex(); + CreateIndex::Save(&create_builder, saved_uids); } -void CreateIndex::Save(capnp::CreateIndex::Builder &builder) { - auto label_builder = builder.getLabel(); +void CreateIndex::Save(capnp::CreateIndex::Builder *builder, + std::vector *saved_uids) { + auto label_builder = builder->getLabel(); label_.Save(label_builder); - auto property_builder = builder.getProperty(); + auto property_builder = builder->getProperty(); property_.Save(property_builder); } -CreateIndex *CreateIndex::Construct(capnp::CreateIndex::Reader &reader, - AstTreeStorage &storage) { +CreateIndex *CreateIndex::Construct(const capnp::CreateIndex::Reader &reader, + AstTreeStorage *storage) { auto label_reader = reader.getLabel(); storage::Label label; label.Load(label_reader); auto property_reader = reader.getProperty(); storage::Property property; property.Load(property_reader); - return storage.Create(label, property); + return storage->Create(label, property); } // Delete. -void Delete::Save(capnp::Clause::Builder &builder) { - Clause::Save(builder); - auto del_builder = builder.initDelete(); - Delete::Save(del_builder); +void Delete::Save(capnp::Clause::Builder *builder, + std::vector *saved_uids) { + Clause::Save(builder, saved_uids); + auto del_builder = builder->initDelete(); + Delete::Save(&del_builder, saved_uids); } -void Delete::Save(capnp::Delete::Builder &builder) { +void Delete::Save(capnp::Delete::Builder *builder, + std::vector *saved_uids) { ::capnp::List::Builder tree_builders = - builder.initExpressions(expressions_.size()); + builder->initExpressions(expressions_.size()); for (size_t i = 0; i < expressions_.size(); ++i) { auto tree_builder = tree_builders[i]; - expressions_[i]->Save(tree_builder); + expressions_[i]->Save(&tree_builder, saved_uids); } - builder.setDetach(detach_); + builder->setDetach(detach_); } -Delete *Delete::Construct(capnp::Delete::Reader &reader, - AstTreeStorage &storage) { - std::vector expressions; - for (auto tree_reader : reader.getExpressions()) { - auto tree = storage.Load(tree_reader); - expressions.push_back(dynamic_cast(tree)); +void Delete::Load(const capnp::Tree::Reader &base_reader, + AstTreeStorage *storage, std::vector *loaded_uids) { + Clause::Load(base_reader, storage, loaded_uids); + auto reader = base_reader.getClause().getDelete(); + for (const auto tree_reader : reader.getExpressions()) { + auto tree = storage->Load(tree_reader, loaded_uids); + expressions_.push_back(dynamic_cast(tree)); } - auto detach = reader.getDetach(); - return storage.Create(detach, expressions); + detach_ = reader.getDetach(); +} + +Delete *Delete::Construct(const capnp::Delete::Reader &reader, + AstTreeStorage *storage) { + return storage->Create(); } // Match. -void Match::Save(capnp::Clause::Builder &clause_builder) { - Clause::Save(clause_builder); - auto builder = clause_builder.initMatch(); - Match::Save(builder); +void Match::Save(capnp::Clause::Builder *clause_builder, + std::vector *saved_uids) { + Clause::Save(clause_builder, saved_uids); + auto builder = clause_builder->initMatch(); + Match::Save(&builder, saved_uids); } -void Match::Save(capnp::Match::Builder &builder) { +void Match::Save(capnp::Match::Builder *builder, std::vector *saved_uids) { ::capnp::List::Builder tree_builders = - builder.initPatterns(patterns_.size()); + builder->initPatterns(patterns_.size()); for (size_t i = 0; i < patterns_.size(); ++i) { auto tree_builder = tree_builders[i]; - patterns_[i]->Save(tree_builder); + patterns_[i]->Save(&tree_builder, saved_uids); } if (where_) { - auto where_builder = builder.initWhere(); - where_->Save(where_builder); + auto where_builder = builder->initWhere(); + where_->Save(&where_builder, saved_uids); } - builder.setOptional(optional_); + builder->setOptional(optional_); } -Match *Match::Construct(capnp::Match::Reader &reader, AstTreeStorage &storage) { - std::vector patterns; - for (auto tree_reader : reader.getPatterns()) { - auto tree = storage.Load(tree_reader); - patterns.push_back(dynamic_cast(tree)); +void Match::Load(const capnp::Tree::Reader &base_reader, + AstTreeStorage *storage, std::vector *loaded_uids) { + Clause::Load(base_reader, storage, loaded_uids); + auto reader = base_reader.getClause().getMatch(); + for (const auto tree_reader : reader.getPatterns()) { + auto tree = storage->Load(tree_reader, loaded_uids); + patterns_.push_back(dynamic_cast(tree)); } - Where *where = nullptr; if (reader.hasWhere()) { - auto where_reader = reader.getWhere(); - where = dynamic_cast(storage.Load(where_reader)); + const auto where_reader = reader.getWhere(); + where_ = dynamic_cast(storage->Load(where_reader, loaded_uids)); } - auto optional = reader.getOptional(); - return storage.Create(optional, where, patterns); + optional_ = reader.getOptional(); +} + +Match *Match::Construct(const capnp::Match::Reader &reader, + AstTreeStorage *storage) { + return storage->Create(); } // Merge. -void Merge::Save(capnp::Clause::Builder &clause_builder) { - Clause::Save(clause_builder); - auto builder = clause_builder.initMerge(); - Merge::Save(builder); +void Merge::Save(capnp::Clause::Builder *clause_builder, + std::vector *saved_uids) { + Clause::Save(clause_builder, saved_uids); + auto builder = clause_builder->initMerge(); + Merge::Save(&builder, saved_uids); } -void Merge::Save(capnp::Merge::Builder &builder) { +void Merge::Save(capnp::Merge::Builder *builder, std::vector *saved_uids) { ::capnp::List::Builder match_builder = - builder.initOnMatch(on_match_.size()); + builder->initOnMatch(on_match_.size()); for (size_t i = 0; i < on_match_.size(); ++i) { auto tree_builder = match_builder[i]; - on_match_[i]->Save(tree_builder); + on_match_[i]->Save(&tree_builder, saved_uids); } ::capnp::List::Builder create_builder = - builder.initOnCreate(on_create_.size()); + builder->initOnCreate(on_create_.size()); for (size_t i = 0; i < on_create_.size(); ++i) { auto tree_builder = create_builder[i]; - on_create_[i]->Save(tree_builder); + on_create_[i]->Save(&tree_builder, saved_uids); } if (pattern_) { - auto pattern_builder = builder.getPattern(); - pattern_->Save(pattern_builder); + auto pattern_builder = builder->getPattern(); + pattern_->Save(&pattern_builder, saved_uids); } } -Merge *Merge::Construct(capnp::Merge::Reader &reader, AstTreeStorage &storage) { - std::vector on_match; - for (auto tree_reader : reader.getOnMatch()) { - auto tree = storage.Load(tree_reader); - on_match.push_back(dynamic_cast(tree)); +void Merge::Load(const capnp::Tree::Reader &base_reader, + AstTreeStorage *storage, std::vector *loaded_uids) { + Clause::Load(base_reader, storage, loaded_uids); + auto reader = base_reader.getClause().getMerge(); + for (const auto tree_reader : reader.getOnMatch()) { + auto tree = storage->Load(tree_reader, loaded_uids); + on_match_.push_back(dynamic_cast(tree)); } - std::vector on_create; - for (auto tree_reader : reader.getOnCreate()) { - auto tree = storage.Load(tree_reader); - on_create.push_back(dynamic_cast(tree)); + for (const auto tree_reader : reader.getOnCreate()) { + auto tree = storage->Load(tree_reader, loaded_uids); + on_create_.push_back(dynamic_cast(tree)); } - Pattern *pattern = nullptr; if (reader.hasPattern()) { - auto pattern_reader = reader.getPattern(); - pattern = dynamic_cast(storage.Load(pattern_reader)); + const auto pattern_reader = reader.getPattern(); + pattern_ = + dynamic_cast(storage->Load(pattern_reader, loaded_uids)); } - return storage.Create(pattern, on_match, on_create); +} +Merge *Merge::Construct(const capnp::Merge::Reader &reader, + AstTreeStorage *storage) { + return storage->Create(); } // RemoveLabels. -void RemoveLabels::Save(capnp::Clause::Builder &clause_builder) { - Clause::Save(clause_builder); - auto builder = clause_builder.initRemoveLabels(); - RemoveLabels::Save(builder); +void RemoveLabels::Save(capnp::Clause::Builder *clause_builder, + std::vector *saved_uids) { + Clause::Save(clause_builder, saved_uids); + auto builder = clause_builder->initRemoveLabels(); + RemoveLabels::Save(&builder, saved_uids); } -void RemoveLabels::Save(capnp::RemoveLabels::Builder &builder) { +void RemoveLabels::Save(capnp::RemoveLabels::Builder *builder, + std::vector *saved_uids) { if (identifier_) { - auto id_builder = builder.getIdentifier(); - identifier_->Save(id_builder); + auto id_builder = builder->getIdentifier(); + identifier_->Save(&id_builder, saved_uids); } ::capnp::List::Builder common_builders = - builder.initLabels(labels_.size()); + builder->initLabels(labels_.size()); for (size_t i = 0; i < labels_.size(); ++i) { auto common_builder = common_builders[i]; labels_[i].Save(common_builder); } } - -RemoveLabels *RemoveLabels::Construct(capnp::RemoveLabels::Reader &reader, - AstTreeStorage &storage) { - Identifier *identifier = nullptr; +void RemoveLabels::Load(const capnp::Tree::Reader &base_reader, + AstTreeStorage *storage, + std::vector *loaded_uids) { + Clause::Load(base_reader, storage, loaded_uids); + auto reader = base_reader.getClause().getRemoveLabels(); if (reader.hasIdentifier()) { - auto id_reader = reader.getIdentifier(); - identifier = dynamic_cast(storage.Load(id_reader)); + const auto id_reader = reader.getIdentifier(); + identifier_ = + dynamic_cast(storage->Load(id_reader, loaded_uids)); } - std::vector labels; for (auto label_reader : reader.getLabels()) { storage::Label label; label.Load(label_reader); - labels.push_back(label); + labels_.push_back(label); } - return storage.Create(identifier, labels); +} + +RemoveLabels *RemoveLabels::Construct(const capnp::RemoveLabels::Reader &reader, + AstTreeStorage *storage) { + return storage->Create(); } // RemoveProperty. -void RemoveProperty::Save(capnp::Clause::Builder &clause_builder) { - Clause::Save(clause_builder); - auto builder = clause_builder.initRemoveProperty(); - RemoveProperty::Save(builder); +void RemoveProperty::Save(capnp::Clause::Builder *clause_builder, + std::vector *saved_uids) { + Clause::Save(clause_builder, saved_uids); + auto builder = clause_builder->initRemoveProperty(); + RemoveProperty::Save(&builder, saved_uids); } -void RemoveProperty::Save(capnp::RemoveProperty::Builder &builder) { +void RemoveProperty::Save(capnp::RemoveProperty::Builder *builder, + std::vector *saved_uids) { if (property_lookup_) { - auto pl_builder = builder.getPropertyLookup(); - property_lookup_->Save(pl_builder); + auto pl_builder = builder->getPropertyLookup(); + property_lookup_->Save(&pl_builder, saved_uids); } } -RemoveProperty *RemoveProperty::Construct(capnp::RemoveProperty::Reader &reader, - AstTreeStorage &storage) { - PropertyLookup *property_lookup; +void RemoveProperty::Load(const capnp::Tree::Reader &base_reader, + AstTreeStorage *storage, + std::vector *loaded_uids) { + Clause::Load(base_reader, storage, loaded_uids); + auto reader = base_reader.getClause().getRemoveProperty(); if (reader.hasPropertyLookup()) { - auto pl_reader = reader.getPropertyLookup(); - property_lookup = dynamic_cast(storage.Load(pl_reader)); + const auto pl_reader = reader.getPropertyLookup(); + property_lookup_ = + dynamic_cast(storage->Load(pl_reader, loaded_uids)); } - return storage.Create(property_lookup); +} + +RemoveProperty *RemoveProperty::Construct( + const capnp::RemoveProperty::Reader &reader, AstTreeStorage *storage) { + return storage->Create(); } // Return. -void Return::Save(capnp::Clause::Builder &clause_builder) { - Clause::Save(clause_builder); - auto builder = clause_builder.initReturn(); - Return::Save(builder); +void Return::Save(capnp::Clause::Builder *clause_builder, + std::vector *saved_uids) { + Clause::Save(clause_builder, saved_uids); + auto builder = clause_builder->initReturn(); + Return::Save(&builder, saved_uids); } -void SaveReturnBody(capnp::ReturnBody::Builder &rb_builder, ReturnBody &body) { - rb_builder.setDistinct(body.distinct); - rb_builder.setAllIdentifiers(body.all_identifiers); +void SaveReturnBody(capnp::ReturnBody::Builder *rb_builder, ReturnBody &body, + std::vector *saved_uids) { + rb_builder->setDistinct(body.distinct); + rb_builder->setAllIdentifiers(body.all_identifiers); ::capnp::List::Builder named_expressions = - rb_builder.initNamedExpressions(body.named_expressions.size()); + rb_builder->initNamedExpressions(body.named_expressions.size()); for (size_t i = 0; i < body.named_expressions.size(); ++i) { auto tree_builder = named_expressions[i]; - body.named_expressions[i]->Save(tree_builder); + body.named_expressions[i]->Save(&tree_builder, saved_uids); } ::capnp::List::Builder order_by = - rb_builder.initOrderBy(body.order_by.size()); + rb_builder->initOrderBy(body.order_by.size()); for (size_t i = 0; i < body.order_by.size(); ++i) { auto pair_builder = order_by[i]; auto ordering = body.order_by[i].first == Ordering::ASC @@ -1322,31 +1549,32 @@ void SaveReturnBody(capnp::ReturnBody::Builder &rb_builder, ReturnBody &body) { : capnp::Ordering::DESC; pair_builder.setOrdering(ordering); auto tree_builder = pair_builder.getExpression(); - body.order_by[i].second->Save(tree_builder); + body.order_by[i].second->Save(&tree_builder, saved_uids); } if (body.skip) { - auto skip_builder = rb_builder.getSkip(); - body.skip->Save(skip_builder); + auto skip_builder = rb_builder->getSkip(); + body.skip->Save(&skip_builder, saved_uids); } if (body.limit) { - auto limit_builder = rb_builder.getLimit(); - body.limit->Save(limit_builder); + auto limit_builder = rb_builder->getLimit(); + body.limit->Save(&limit_builder, saved_uids); } } -void Return::Save(capnp::Return::Builder &builder) { - auto rb_builder = builder.initReturnBody(); - SaveReturnBody(rb_builder, body_); +void Return::Save(capnp::Return::Builder *builder, + std::vector *saved_uids) { + auto rb_builder = builder->initReturnBody(); + SaveReturnBody(&rb_builder, body_, saved_uids); } void LoadReturnBody(capnp::ReturnBody::Reader &rb_reader, ReturnBody &body, - AstTreeStorage &storage) { + AstTreeStorage *storage, std::vector *loaded_uids) { body.distinct = rb_reader.getDistinct(); body.all_identifiers = rb_reader.getAllIdentifiers(); - for (auto tree_reader : rb_reader.getNamedExpressions()) { - auto tree = storage.Load(tree_reader); + for (const auto tree_reader : rb_reader.getNamedExpressions()) { + auto tree = storage->Load(tree_reader, loaded_uids); body.named_expressions.push_back(dynamic_cast(tree)); } @@ -1354,302 +1582,390 @@ void LoadReturnBody(capnp::ReturnBody::Reader &rb_reader, ReturnBody &body, auto ordering = pair_reader.getOrdering() == capnp::Ordering::ASC ? Ordering::ASC : Ordering::DESC; - auto tree_reader = pair_reader.getExpression(); + const auto tree_reader = pair_reader.getExpression(); // TODO Check if expression is null? - auto tree = dynamic_cast(storage.Load(tree_reader)); + auto tree = + dynamic_cast(storage->Load(tree_reader, loaded_uids)); body.order_by.push_back(std::make_pair(ordering, tree)); } if (rb_reader.hasSkip()) { - auto skip_reader = rb_reader.getSkip(); - body.skip = dynamic_cast(storage.Load(skip_reader)); + const auto skip_reader = rb_reader.getSkip(); + body.skip = + dynamic_cast(storage->Load(skip_reader, loaded_uids)); } if (rb_reader.hasLimit()) { - auto limit_reader = rb_reader.getLimit(); - body.limit = dynamic_cast(storage.Load(limit_reader)); + const auto limit_reader = rb_reader.getLimit(); + body.limit = + dynamic_cast(storage->Load(limit_reader, loaded_uids)); } } -Return *Return::Construct(capnp::Return::Reader &reader, - AstTreeStorage &storage) { +void Return::Load(const capnp::Tree::Reader &base_reader, + AstTreeStorage *storage, std::vector *loaded_uids) { + Clause::Load(base_reader, storage, loaded_uids); + auto reader = base_reader.getClause().getReturn(); auto rb_reader = reader.getReturnBody(); - ReturnBody body; - LoadReturnBody(rb_reader, body, storage); - return storage.Create(body); + LoadReturnBody(rb_reader, body_, storage, loaded_uids); +} + +Return *Return::Construct(const capnp::Return::Reader &reader, + AstTreeStorage *storage) { + return storage->Create(); } // SetLabels. -void SetLabels::Save(capnp::Clause::Builder &clause_builder) { - Clause::Save(clause_builder); - auto builder = clause_builder.initSetLabels(); - SetLabels::Save(builder); +void SetLabels::Save(capnp::Clause::Builder *clause_builder, + std::vector *saved_uids) { + Clause::Save(clause_builder, saved_uids); + auto builder = clause_builder->initSetLabels(); + SetLabels::Save(&builder, saved_uids); } -void SetLabels::Save(capnp::SetLabels::Builder &builder) { +void SetLabels::Save(capnp::SetLabels::Builder *builder, + std::vector *saved_uids) { if (identifier_) { - auto id_builder = builder.getIdentifier(); - identifier_->Save(id_builder); + auto id_builder = builder->getIdentifier(); + identifier_->Save(&id_builder, saved_uids); } ::capnp::List::Builder common_builders = - builder.initLabels(labels_.size()); + builder->initLabels(labels_.size()); for (size_t i = 0; i < labels_.size(); ++i) { auto common_builder = common_builders[i]; labels_[i].Save(common_builder); } } -SetLabels *SetLabels::Construct(capnp::SetLabels::Reader &reader, - AstTreeStorage &storage) { - Identifier *identifier = nullptr; +void SetLabels::Load(const capnp::Tree::Reader &base_reader, + AstTreeStorage *storage, std::vector *loaded_uids) { + Clause::Load(base_reader, storage, loaded_uids); + auto reader = base_reader.getClause().getSetLabels(); if (reader.hasIdentifier()) { - auto id_reader = reader.getIdentifier(); - identifier = dynamic_cast(storage.Load(id_reader)); + const auto id_reader = reader.getIdentifier(); + identifier_ = + dynamic_cast(storage->Load(id_reader, loaded_uids)); } - std::vector labels; for (auto label_reader : reader.getLabels()) { storage::Label label; label.Load(label_reader); - labels.push_back(label); + labels_.push_back(label); } - return storage.Create(identifier, labels); +} + +SetLabels *SetLabels::Construct(const capnp::SetLabels::Reader &reader, + AstTreeStorage *storage) { + return storage->Create(); } // SetProperty. -void SetProperty::Save(capnp::Clause::Builder &clause_builder) { - Clause::Save(clause_builder); - auto builder = clause_builder.initSetProperty(); - SetProperty::Save(builder); +void SetProperty::Save(capnp::Clause::Builder *clause_builder, + std::vector *saved_uids) { + Clause::Save(clause_builder, saved_uids); + auto builder = clause_builder->initSetProperty(); + SetProperty::Save(&builder, saved_uids); } -void SetProperty::Save(capnp::SetProperty::Builder &builder) { +void SetProperty::Save(capnp::SetProperty::Builder *builder, + std::vector *saved_uids) { if (property_lookup_) { - auto pl_builder = builder.getPropertyLookup(); - property_lookup_->Save(pl_builder); + auto pl_builder = builder->getPropertyLookup(); + property_lookup_->Save(&pl_builder, saved_uids); } if (expression_) { - auto expr_builder = builder.getExpression(); - expression_->Save(expr_builder); + auto expr_builder = builder->getExpression(); + expression_->Save(&expr_builder, saved_uids); } } -SetProperty *SetProperty::Construct(capnp::SetProperty::Reader &reader, - AstTreeStorage &storage) { - PropertyLookup *property_lookup = nullptr; +void SetProperty::Load(const capnp::Tree::Reader &base_reader, + AstTreeStorage *storage, std::vector *loaded_uids) { + Clause::Load(base_reader, storage, loaded_uids); + auto reader = base_reader.getClause().getSetProperty(); if (reader.hasPropertyLookup()) { - auto pl_reader = reader.getPropertyLookup(); - property_lookup = dynamic_cast(storage.Load(pl_reader)); + const auto pl_reader = reader.getPropertyLookup(); + property_lookup_ = + dynamic_cast(storage->Load(pl_reader, loaded_uids)); } - Expression *expression; if (reader.hasExpression()) { - auto expr_reader = reader.getExpression(); - expression = dynamic_cast(storage.Load(expr_reader)); + const auto expr_reader = reader.getExpression(); + expression_ = + dynamic_cast(storage->Load(expr_reader, loaded_uids)); } - return storage.Create(property_lookup, expression); +} + +SetProperty *SetProperty::Construct(const capnp::SetProperty::Reader &reader, + AstTreeStorage *storage) { + return storage->Create(); } // SetProperties. -void SetProperties::Save(capnp::Clause::Builder &clause_builder) { - Clause::Save(clause_builder); - auto builder = clause_builder.initSetProperties(); - SetProperties::Save(builder); +void SetProperties::Save(capnp::Clause::Builder *clause_builder, + std::vector *saved_uids) { + Clause::Save(clause_builder, saved_uids); + auto builder = clause_builder->initSetProperties(); + SetProperties::Save(&builder, saved_uids); } -void SetProperties::Save(capnp::SetProperties::Builder &builder) { +void SetProperties::Save(capnp::SetProperties::Builder *builder, + std::vector *saved_uids) { if (identifier_) { - auto id_builder = builder.getIdentifier(); - identifier_->Save(id_builder); + auto id_builder = builder->getIdentifier(); + identifier_->Save(&id_builder, saved_uids); } if (expression_) { - auto expr_builder = builder.getExpression(); - expression_->Save(expr_builder); + auto expr_builder = builder->getExpression(); + expression_->Save(&expr_builder, saved_uids); } - builder.setUpdate(update_); + builder->setUpdate(update_); } -SetProperties *SetProperties::Construct(capnp::SetProperties::Reader &reader, - AstTreeStorage &storage) { - Identifier *identifier = nullptr; +void SetProperties::Load(const capnp::Tree::Reader &base_reader, + AstTreeStorage *storage, + std::vector *loaded_uids) { + Clause::Load(base_reader, storage, loaded_uids); + auto reader = base_reader.getClause().getSetProperties(); if (reader.hasIdentifier()) { - auto id_reader = reader.getIdentifier(); - identifier = dynamic_cast(storage.Load(id_reader)); + const auto id_reader = reader.getIdentifier(); + identifier_ = + dynamic_cast(storage->Load(id_reader, loaded_uids)); } - Expression *expression = nullptr; if (reader.hasExpression()) { - auto expr_reader = reader.getExpression(); - expression = dynamic_cast(storage.Load(expr_reader)); + const auto expr_reader = reader.getExpression(); + expression_ = + dynamic_cast(storage->Load(expr_reader, loaded_uids)); } - auto update = reader.getUpdate(); - return storage.Create(identifier, expression, update); + update_ = reader.getUpdate(); +} + +SetProperties *SetProperties::Construct( + const capnp::SetProperties::Reader &reader, AstTreeStorage *storage) { + return storage->Create(); } // Unwind. -void Unwind::Save(capnp::Clause::Builder &clause_builder) { - Clause::Save(clause_builder); - auto builder = clause_builder.initUnwind(); - Unwind::Save(builder); +void Unwind::Save(capnp::Clause::Builder *clause_builder, + std::vector *saved_uids) { + Clause::Save(clause_builder, saved_uids); + auto builder = clause_builder->initUnwind(); + Unwind::Save(&builder, saved_uids); } -void Unwind::Save(capnp::Unwind::Builder &builder) { +void Unwind::Save(capnp::Unwind::Builder *builder, + std::vector *saved_uids) { if (named_expression_) { - auto expr_builder = builder.getNamedExpression(); - named_expression_->Save(expr_builder); + auto expr_builder = builder->getNamedExpression(); + named_expression_->Save(&expr_builder, saved_uids); } } -Unwind *Unwind::Construct(capnp::Unwind::Reader &reader, - AstTreeStorage &storage) { - NamedExpression *expression = nullptr; +void Unwind::Load(const capnp::Tree::Reader &base_reader, + AstTreeStorage *storage, std::vector *loaded_uids) { + Clause::Load(base_reader, storage, loaded_uids); + auto reader = base_reader.getClause().getUnwind(); if (reader.hasNamedExpression()) { - auto expr_reader = reader.getNamedExpression(); - expression = dynamic_cast(storage.Load(expr_reader)); + const auto expr_reader = reader.getNamedExpression(); + named_expression_ = dynamic_cast( + storage->Load(expr_reader, loaded_uids)); } - return storage.Create(expression); +} + +Unwind *Unwind::Construct(const capnp::Unwind::Reader &reader, + AstTreeStorage *storage) { + return storage->Create(); } // With. -void With::Save(capnp::Clause::Builder &clause_builder) { - Clause::Save(clause_builder); - auto builder = clause_builder.initWith(); - With::Save(builder); +void With::Save(capnp::Clause::Builder *clause_builder, + std::vector *saved_uids) { + Clause::Save(clause_builder, saved_uids); + auto builder = clause_builder->initWith(); + With::Save(&builder, saved_uids); } -void With::Save(capnp::With::Builder &builder) { +void With::Save(capnp::With::Builder *builder, std::vector *saved_uids) { if (where_) { - auto where_builder = builder.getWhere(); - where_->Save(where_builder); + auto where_builder = builder->getWhere(); + where_->Save(&where_builder, saved_uids); } - auto rb_builder = builder.initReturnBody(); - SaveReturnBody(rb_builder, body_); + auto rb_builder = builder->initReturnBody(); + SaveReturnBody(&rb_builder, body_, saved_uids); } -With *With::Construct(capnp::With::Reader &reader, AstTreeStorage &storage) { - Where *where = nullptr; +void With::Load(const capnp::Tree::Reader &base_reader, AstTreeStorage *storage, + std::vector *loaded_uids) { + Clause::Load(base_reader, storage, loaded_uids); + auto reader = base_reader.getClause().getWith(); if (reader.hasWhere()) { - auto where_reader = reader.getWhere(); - where = dynamic_cast(storage.Load(where_reader)); + const auto where_reader = reader.getWhere(); + where_ = dynamic_cast(storage->Load(where_reader, loaded_uids)); } auto rb_reader = reader.getReturnBody(); - ReturnBody body; - LoadReturnBody(rb_reader, body, storage); - return storage.Create(body, where); + LoadReturnBody(rb_reader, body_, storage, loaded_uids); +} + +With *With::Construct(const capnp::With::Reader &reader, + AstTreeStorage *storage) { + return storage->Create(); } // CypherUnion -void CypherUnion::Save(capnp::Tree::Builder &tree_builder) { - Tree::Save(tree_builder); - auto builder = tree_builder.initCypherUnion(); - Save(builder); +void CypherUnion::Save(capnp::Tree::Builder *tree_builder, + std::vector *saved_uids) { + Tree::Save(tree_builder, saved_uids); + if (IsSaved(*saved_uids)) { + return; + } + auto builder = tree_builder->initCypherUnion(); + Save(&builder, saved_uids); + AddToSaved(saved_uids); } -void CypherUnion::Save(capnp::CypherUnion::Builder &builder) { +void CypherUnion::Save(capnp::CypherUnion::Builder *builder, + std::vector *saved_uids) { if (single_query_) { - auto sq_builder = builder.initSingleQuery(); - single_query_->Save(sq_builder); + auto sq_builder = builder->initSingleQuery(); + single_query_->Save(&sq_builder, saved_uids); } - builder.setDistinct(distinct_); + builder->setDistinct(distinct_); ::capnp::List::Builder symbol_builders = - builder.initUnionSymbols(union_symbols_.size()); + builder->initUnionSymbols(union_symbols_.size()); for (size_t i = 0; i < union_symbols_.size(); ++i) { auto symbol_builder = symbol_builders[i]; union_symbols_[i].Save(symbol_builder); } } -CypherUnion *CypherUnion::Construct(capnp::CypherUnion::Reader &reader, - AstTreeStorage &storage) { - SingleQuery *single_query = nullptr; +void CypherUnion::Load(const capnp::Tree::Reader &base_reader, + AstTreeStorage *storage, std::vector *loaded_uids) { + Tree::Load(base_reader, storage, loaded_uids); + auto reader = base_reader.getCypherUnion(); if (reader.hasSingleQuery()) { - auto sq_reader = reader.getSingleQuery(); - single_query = dynamic_cast(storage.Load(sq_reader)); + const auto sq_reader = reader.getSingleQuery(); + single_query_ = + dynamic_cast(storage->Load(sq_reader, loaded_uids)); } - auto distinct = reader.getDistinct(); - std::vector symbols; + distinct_ = reader.getDistinct(); for (auto symbol_reader : reader.getUnionSymbols()) { Symbol symbol; symbol.Load(symbol_reader); - symbols.push_back(symbol); + union_symbols_.push_back(symbol); } - return storage.Create(distinct, single_query, symbols); +} + +CypherUnion *CypherUnion::Construct(const capnp::CypherUnion::Reader &reader, + AstTreeStorage *storage) { + return storage->Create(); } // NamedExpression -void NamedExpression::Save(capnp::Tree::Builder &tree_builder) { - Tree::Save(tree_builder); - auto builder = tree_builder.initNamedExpression(); - Save(builder); +void NamedExpression::Save(capnp::Tree::Builder *tree_builder, + std::vector *saved_uids) { + Tree::Save(tree_builder, saved_uids); + if (IsSaved(*saved_uids)) { + return; + } + auto builder = tree_builder->initNamedExpression(); + Save(&builder, saved_uids); + AddToSaved(saved_uids); } -void NamedExpression::Save(capnp::NamedExpression::Builder &builder) { - builder.setName(name_); - builder.setTokenPosition(token_position_); +void NamedExpression::Save(capnp::NamedExpression::Builder *builder, + std::vector *saved_uids) { + builder->setName(name_); + builder->setTokenPosition(token_position_); if (expression_) { - auto expr_builder = builder.getExpression(); - expression_->Save(expr_builder); + auto expr_builder = builder->getExpression(); + expression_->Save(&expr_builder, saved_uids); + } +} + +void NamedExpression::Load(const capnp::Tree::Reader &base_reader, + AstTreeStorage *storage, + std::vector *loaded_uids) { + Tree::Load(base_reader, storage, loaded_uids); + auto reader = base_reader.getNamedExpression(); + name_ = reader.getName().cStr(); + token_position_ = reader.getTokenPosition(); + if (reader.hasExpression()) { + const auto expr_reader = reader.getExpression(); + expression_ = + dynamic_cast(storage->Load(expr_reader, loaded_uids)); } } NamedExpression *NamedExpression::Construct( - capnp::NamedExpression::Reader &reader, AstTreeStorage &storage) { - auto name = reader.getName().cStr(); - auto token_position = reader.getTokenPosition(); - Expression *expression = nullptr; - if (reader.hasExpression()) { - auto expr_reader = reader.getExpression(); - expression = dynamic_cast(storage.Load(expr_reader)); - } - return storage.Create(name, expression, token_position); + const capnp::NamedExpression::Reader &reader, AstTreeStorage *storage) { + return storage->Create(); } // Pattern -void Pattern::Save(capnp::Tree::Builder &tree_builder) { - Tree::Save(tree_builder); - auto builder = tree_builder.initPattern(); - Save(builder); +void Pattern::Save(capnp::Tree::Builder *tree_builder, + std::vector *saved_uids) { + Tree::Save(tree_builder, saved_uids); + if (IsSaved(*saved_uids)) { + return; + } + auto builder = tree_builder->initPattern(); + Save(&builder, saved_uids); + AddToSaved(saved_uids); } -void Pattern::Save(capnp::Pattern::Builder &builder) { +void Pattern::Save(capnp::Pattern::Builder *builder, + std::vector *saved_uids) { if (identifier_) { - auto id_builder = builder.getIdentifier(); - identifier_->Save(id_builder); + auto id_builder = builder->getIdentifier(); + identifier_->Save(&id_builder, saved_uids); } ::capnp::List::Builder tree_builders = - builder.initAtoms(atoms_.size()); + builder->initAtoms(atoms_.size()); for (size_t i = 0; i < atoms_.size(); ++i) { auto tree_builder = tree_builders[i]; - atoms_[i]->Save(tree_builder); + atoms_[i]->Save(&tree_builder, saved_uids); } } -Pattern *Pattern::Construct(capnp::Pattern::Reader &reader, - AstTreeStorage &storage) { - auto pattern = storage.Create(); +void Pattern::Load(const capnp::Tree::Reader &base_reader, + AstTreeStorage *storage, std::vector *loaded_uids) { + Tree::Load(base_reader, storage, loaded_uids); + auto reader = base_reader.getPattern(); if (reader.hasIdentifier()) { - auto id_reader = reader.getIdentifier(); - pattern->identifier_ = dynamic_cast(storage.Load(id_reader)); + const auto id_reader = reader.getIdentifier(); + identifier_ = + dynamic_cast(storage->Load(id_reader, loaded_uids)); } - for (auto tree_reader : reader.getAtoms()) { - auto tree = storage.Load(tree_reader); - pattern->atoms_.push_back(dynamic_cast(tree)); + for (const auto tree_reader : reader.getAtoms()) { + auto tree = storage->Load(tree_reader, loaded_uids); + atoms_.push_back(dynamic_cast(tree)); } - return pattern; +} + +Pattern *Pattern::Construct(const capnp::Pattern::Reader &reader, + AstTreeStorage *storage) { + return storage->Create(); } // PatternAtom. -void PatternAtom::Save(capnp::Tree::Builder &tree_builder) { - Tree::Save(tree_builder); - auto pattern_builder = tree_builder.initPatternAtom(); - Save(pattern_builder); +void PatternAtom::Save(capnp::Tree::Builder *tree_builder, + std::vector *saved_uids) { + Tree::Save(tree_builder, saved_uids); + if (IsSaved(*saved_uids)) { + return; + } + auto pattern_builder = tree_builder->initPatternAtom(); + Save(&pattern_builder, saved_uids); + AddToSaved(saved_uids); } -void PatternAtom::Save(capnp::PatternAtom::Builder &builder) { +void PatternAtom::Save(capnp::PatternAtom::Builder *builder, + std::vector *saved_uids) { if (identifier_) { - auto id_builder = builder.getIdentifier(); - identifier_->Save(id_builder); + auto id_builder = builder->getIdentifier(); + identifier_->Save(&id_builder, saved_uids); } } -PatternAtom *PatternAtom::Construct(capnp::PatternAtom::Reader &reader, - AstTreeStorage &storage) { +PatternAtom *PatternAtom::Construct(const capnp::PatternAtom::Reader &reader, + AstTreeStorage *storage) { switch (reader.which()) { case capnp::PatternAtom::EDGE_ATOM: { auto edge_reader = reader.getEdgeAtom(); @@ -1662,25 +1978,29 @@ PatternAtom *PatternAtom::Construct(capnp::PatternAtom::Reader &reader, } } -void PatternAtom::Load(capnp::Tree::Reader &reader, AstTreeStorage &storage) { - Tree::Load(reader, storage); +void PatternAtom::Load(const capnp::Tree::Reader &reader, + AstTreeStorage *storage, std::vector *loaded_uids) { + Tree::Load(reader, storage, loaded_uids); auto pa_reader = reader.getPatternAtom(); if (pa_reader.hasIdentifier()) { - auto id_reader = pa_reader.getIdentifier(); - identifier_ = dynamic_cast(storage.Load(id_reader)); + const auto id_reader = pa_reader.getIdentifier(); + identifier_ = + dynamic_cast(storage->Load(id_reader, loaded_uids)); } } // NodeAtom -void NodeAtom::Save(capnp::PatternAtom::Builder &pattern_builder) { - PatternAtom::Save(pattern_builder); - auto builder = pattern_builder.initNodeAtom(); - Save(builder); +void NodeAtom::Save(capnp::PatternAtom::Builder *pattern_builder, + std::vector *saved_uids) { + PatternAtom::Save(pattern_builder, saved_uids); + auto builder = pattern_builder->initNodeAtom(); + Save(&builder, saved_uids); } -void NodeAtom::Save(capnp::NodeAtom::Builder &builder) { +void NodeAtom::Save(capnp::NodeAtom::Builder *builder, + std::vector *saved_uids) { ::capnp::List::Builder map_builder = - builder.initProperties(properties_.size()); + builder->initProperties(properties_.size()); size_t i = 0; for (auto &entry : properties_) { auto entry_builder = map_builder[i]; @@ -1689,100 +2009,108 @@ void NodeAtom::Save(capnp::NodeAtom::Builder &builder) { auto storage_property_builder = key_builder.getSecond(); entry.first.second.Save(storage_property_builder); auto value_builder = entry_builder.getValue(); - if (entry.second) entry.second->Save(value_builder); + if (entry.second) entry.second->Save(&value_builder, saved_uids); ++i; } ::capnp::List::Builder common_builders = - builder.initLabels(labels_.size()); + builder->initLabels(labels_.size()); for (size_t i = 0; i < labels_.size(); ++i) { auto common_builder = common_builders[i]; labels_[i].Save(common_builder); } } -NodeAtom *NodeAtom::Construct(capnp::NodeAtom::Reader &reader, - AstTreeStorage &storage) { - auto *atom = storage.Create(); +void NodeAtom::Load(const capnp::Tree::Reader &base_reader, + AstTreeStorage *storage, std::vector *loaded_uids) { + PatternAtom::Load(base_reader, storage, loaded_uids); + auto reader = base_reader.getPatternAtom().getNodeAtom(); for (auto entry_reader : reader.getProperties()) { auto key_pair_reader = entry_reader.getKey(); auto key_first = key_pair_reader.getFirst().cStr(); auto storage_property_reader = key_pair_reader.getSecond(); storage::Property property; property.Load(storage_property_reader); - auto value_reader = entry_reader.getValue(); - auto value = storage.Load(value_reader); + const auto value_reader = entry_reader.getValue(); + auto value = storage->Load(value_reader, loaded_uids); auto key = std::make_pair(key_first, property); // TODO Maybe check if expression is nullptr? - atom->properties_.emplace(key, dynamic_cast(value)); + properties_.emplace(key, dynamic_cast(value)); } for (auto label_reader : reader.getLabels()) { storage::Label label; label.Load(label_reader); - atom->labels_.push_back(label); + labels_.push_back(label); } - return atom; +} + +NodeAtom *NodeAtom::Construct(const capnp::NodeAtom::Reader &reader, + AstTreeStorage *storage) { + return storage->Create(); } // EdgeAtom -void EdgeAtom::Save(capnp::PatternAtom::Builder &pattern_builder) { - PatternAtom::Save(pattern_builder); - auto builder = pattern_builder.initEdgeAtom(); - Save(builder); +void EdgeAtom::Save(capnp::PatternAtom::Builder *pattern_builder, + std::vector *saved_uids) { + PatternAtom::Save(pattern_builder, saved_uids); + auto builder = pattern_builder->initEdgeAtom(); + Save(&builder, saved_uids); } void SaveLambda(query::EdgeAtom::Lambda &lambda, - capnp::EdgeAtom::Lambda::Builder &builder) { + capnp::EdgeAtom::Lambda::Builder *builder, + std::vector *saved_uids) { if (lambda.inner_edge) { - auto ie_builder = builder.getInnerEdge(); - lambda.inner_edge->Save(ie_builder); + auto ie_builder = builder->getInnerEdge(); + lambda.inner_edge->Save(&ie_builder, saved_uids); } if (lambda.inner_node) { - auto in_builder = builder.getInnerNode(); - lambda.inner_node->Save(in_builder); + auto in_builder = builder->getInnerNode(); + lambda.inner_node->Save(&in_builder, saved_uids); } if (lambda.expression) { - auto expr_builder = builder.getExpression(); - lambda.expression->Save(expr_builder); + auto expr_builder = builder->getExpression(); + lambda.expression->Save(&expr_builder, saved_uids); } } -void EdgeAtom::Save(capnp::EdgeAtom::Builder &builder) { +void EdgeAtom::Save(capnp::EdgeAtom::Builder *builder, + std::vector *saved_uids) { switch (type_) { case Type::BREADTH_FIRST: - builder.setType(capnp::EdgeAtom::Type::BREADTH_FIRST); + builder->setType(capnp::EdgeAtom::Type::BREADTH_FIRST); break; case Type::DEPTH_FIRST: - builder.setType(capnp::EdgeAtom::Type::DEPTH_FIRST); + builder->setType(capnp::EdgeAtom::Type::DEPTH_FIRST); break; case Type::SINGLE: - builder.setType(capnp::EdgeAtom::Type::SINGLE); + builder->setType(capnp::EdgeAtom::Type::SINGLE); break; case Type::WEIGHTED_SHORTEST_PATH: - builder.setType(capnp::EdgeAtom::Type::WEIGHTED_SHORTEST_PATH); + builder->setType(capnp::EdgeAtom::Type::WEIGHTED_SHORTEST_PATH); break; } switch (direction_) { case Direction::BOTH: - builder.setDirection(capnp::EdgeAtom::Direction::BOTH); + builder->setDirection(capnp::EdgeAtom::Direction::BOTH); break; case Direction::IN: - builder.setDirection(capnp::EdgeAtom::Direction::IN); + builder->setDirection(capnp::EdgeAtom::Direction::IN); break; case Direction::OUT: - builder.setDirection(capnp::EdgeAtom::Direction::OUT); + builder->setDirection(capnp::EdgeAtom::Direction::OUT); break; } ::capnp::List::Builder common_builders = - builder.initEdgeTypes(edge_types_.size()); + builder->initEdgeTypes(edge_types_.size()); for (size_t i = 0; i < edge_types_.size(); ++i) { auto common_builder = common_builders[i]; edge_types_[i].Save(common_builder); } ::capnp::List::Builder map_builder = - builder.initProperties(properties_.size()); + builder->initProperties(properties_.size()); size_t i = 0; for (auto &entry : properties_) { auto entry_builder = map_builder[i]; @@ -1791,93 +2119,100 @@ void EdgeAtom::Save(capnp::EdgeAtom::Builder &builder) { auto storage_property_builder = key_builder.getSecond(); entry.first.second.Save(storage_property_builder); auto value_builder = entry_builder.getValue(); - if (entry.second) entry.second->Save(value_builder); + if (entry.second) entry.second->Save(&value_builder, saved_uids); ++i; } if (lower_bound_) { - auto lb_builder = builder.getLowerBound(); - lower_bound_->Save(lb_builder); + auto lb_builder = builder->getLowerBound(); + lower_bound_->Save(&lb_builder, saved_uids); } if (upper_bound_) { - auto ub_builder = builder.getUpperBound(); - upper_bound_->Save(ub_builder); + auto ub_builder = builder->getUpperBound(); + upper_bound_->Save(&ub_builder, saved_uids); } - auto filter_builder = builder.initFilterLambda(); - SaveLambda(filter_lambda_, filter_builder); - auto weight_builder = builder.initWeightLambda(); - SaveLambda(weight_lambda_, weight_builder); + auto filter_builder = builder->initFilterLambda(); + SaveLambda(filter_lambda_, &filter_builder, saved_uids); + auto weight_builder = builder->initWeightLambda(); + SaveLambda(weight_lambda_, &weight_builder, saved_uids); if (total_weight_) { - auto total_weight_builder = builder.getTotalWeight(); - total_weight_->Save(total_weight_builder); + auto total_weight_builder = builder->getTotalWeight(); + total_weight_->Save(&total_weight_builder, saved_uids); } } void LoadLambda(capnp::EdgeAtom::Lambda::Reader &reader, - query::EdgeAtom::Lambda &lambda, AstTreeStorage &storage) { + query::EdgeAtom::Lambda &lambda, AstTreeStorage *storage, + std::vector *loaded_uids) { if (reader.hasInnerEdge()) { - auto ie_reader = reader.getInnerEdge(); - lambda.inner_edge = dynamic_cast(storage.Load(ie_reader)); + const auto ie_reader = reader.getInnerEdge(); + lambda.inner_edge = + dynamic_cast(storage->Load(ie_reader, loaded_uids)); } if (reader.hasInnerNode()) { - auto in_reader = reader.getInnerNode(); - lambda.inner_node = dynamic_cast(storage.Load(in_reader)); + const auto in_reader = reader.getInnerNode(); + lambda.inner_node = + dynamic_cast(storage->Load(in_reader, loaded_uids)); } if (reader.hasExpression()) { - auto expr_reader = reader.getExpression(); - lambda.expression = dynamic_cast(storage.Load(expr_reader)); + const auto expr_reader = reader.getExpression(); + lambda.expression = + dynamic_cast(storage->Load(expr_reader, loaded_uids)); } } -EdgeAtom *EdgeAtom::Construct(capnp::EdgeAtom::Reader &reader, - AstTreeStorage &storage) { - auto *atom = storage.Create(); - +void EdgeAtom::Load(const capnp::Tree::Reader &base_reader, + AstTreeStorage *storage, std::vector *loaded_uids) { + PatternAtom::Load(base_reader, storage, loaded_uids); + auto reader = base_reader.getPatternAtom().getEdgeAtom(); switch (reader.getType()) { case capnp::EdgeAtom::Type::BREADTH_FIRST: - atom->type_ = Type::BREADTH_FIRST; + type_ = Type::BREADTH_FIRST; break; case capnp::EdgeAtom::Type::DEPTH_FIRST: - atom->type_ = Type::DEPTH_FIRST; + type_ = Type::DEPTH_FIRST; break; case capnp::EdgeAtom::Type::SINGLE: - atom->type_ = Type::SINGLE; + type_ = Type::SINGLE; break; case capnp::EdgeAtom::Type::WEIGHTED_SHORTEST_PATH: - atom->type_ = Type::WEIGHTED_SHORTEST_PATH; + type_ = Type::WEIGHTED_SHORTEST_PATH; break; } switch (reader.getDirection()) { case capnp::EdgeAtom::Direction::BOTH: - atom->direction_ = Direction::BOTH; + direction_ = Direction::BOTH; break; case capnp::EdgeAtom::Direction::IN: - atom->direction_ = Direction::IN; + direction_ = Direction::IN; break; case capnp::EdgeAtom::Direction::OUT: - atom->direction_ = Direction::OUT; + direction_ = Direction::OUT; break; } if (reader.hasTotalWeight()) { - auto id_reader = reader.getTotalWeight(); - atom->total_weight_ = dynamic_cast(storage.Load(id_reader)); + const auto id_reader = reader.getTotalWeight(); + total_weight_ = + dynamic_cast(storage->Load(id_reader, loaded_uids)); } if (reader.hasLowerBound()) { - auto lb_reader = reader.getLowerBound(); - atom->lower_bound_ = dynamic_cast(storage.Load(lb_reader)); + const auto lb_reader = reader.getLowerBound(); + lower_bound_ = + dynamic_cast(storage->Load(lb_reader, loaded_uids)); } if (reader.hasUpperBound()) { - auto ub_reader = reader.getUpperBound(); - atom->upper_bound_ = dynamic_cast(storage.Load(ub_reader)); + const auto ub_reader = reader.getUpperBound(); + upper_bound_ = + dynamic_cast(storage->Load(ub_reader, loaded_uids)); } auto filter_reader = reader.getFilterLambda(); - LoadLambda(filter_reader, atom->filter_lambda_, storage); + LoadLambda(filter_reader, filter_lambda_, storage, loaded_uids); auto weight_reader = reader.getWeightLambda(); - LoadLambda(weight_reader, atom->weight_lambda_, storage); + LoadLambda(weight_reader, weight_lambda_, storage, loaded_uids); for (auto entry_reader : reader.getProperties()) { auto key_pair_reader = entry_reader.getKey(); @@ -1885,78 +2220,100 @@ EdgeAtom *EdgeAtom::Construct(capnp::EdgeAtom::Reader &reader, auto storage_property_reader = key_pair_reader.getSecond(); storage::Property property; property.Load(storage_property_reader); - auto value_reader = entry_reader.getValue(); - auto value = storage.Load(value_reader); + const auto value_reader = entry_reader.getValue(); + auto value = storage->Load(value_reader, loaded_uids); auto key = std::make_pair(key_first, property); // TODO Check if expression is null? - atom->properties_.emplace(key, dynamic_cast(value)); + properties_.emplace(key, dynamic_cast(value)); } for (auto edge_type_reader : reader.getEdgeTypes()) { storage::EdgeType edge_type; edge_type.Load(edge_type_reader); - atom->edge_types_.push_back(edge_type); + edge_types_.push_back(edge_type); } - return atom; +} + +EdgeAtom *EdgeAtom::Construct(const capnp::EdgeAtom::Reader &reader, + AstTreeStorage *storage) { + return storage->Create(); } // Query -void Query::Save(capnp::Tree::Builder &tree_builder) { - Tree::Save(tree_builder); - auto builder = tree_builder.initQuery(); - Save(builder); +void Query::Save(capnp::Tree::Builder *tree_builder, + std::vector *saved_uids) { + Tree::Save(tree_builder, saved_uids); + if (IsSaved(*saved_uids)) { + return; + } + auto builder = tree_builder->initQuery(); + Save(&builder, saved_uids); + AddToSaved(saved_uids); } -void Query::Save(capnp::Query::Builder &builder) { +void Query::Save(capnp::Query::Builder *builder, std::vector *saved_uids) { if (single_query_) { - auto sq_builder = builder.initSingleQuery(); - single_query_->Save(sq_builder); + auto sq_builder = builder->initSingleQuery(); + single_query_->Save(&sq_builder, saved_uids); } ::capnp::List::Builder tree_builders = - builder.initCypherUnions(cypher_unions_.size()); + builder->initCypherUnions(cypher_unions_.size()); for (size_t i = 0; i < cypher_unions_.size(); ++i) { auto tree_builder = tree_builders[i]; - cypher_unions_[i]->Save(tree_builder); + cypher_unions_[i]->Save(&tree_builder, saved_uids); } } -Query *Query::Construct(capnp::Query::Reader &reader, AstTreeStorage &storage) { - auto query = storage.query(); - if (reader.hasSingleQuery()) { - auto sq_reader = reader.getSingleQuery(); - query->single_query_ = dynamic_cast(storage.Load(sq_reader)); +void Query::Load(const capnp::Tree::Reader &reader, AstTreeStorage *storage, + std::vector *loaded_uids) { + Tree::Load(reader, storage, loaded_uids); + auto query_reader = reader.getQuery(); + if (query_reader.hasSingleQuery()) { + const auto sq_reader = query_reader.getSingleQuery(); + single_query_ = + dynamic_cast(storage->Load(sq_reader, loaded_uids)); } - for (auto tree_reader : reader.getCypherUnions()) { - auto tree = storage.Load(tree_reader); - query->cypher_unions_.push_back(dynamic_cast(tree)); + for (const auto tree_reader : query_reader.getCypherUnions()) { + auto tree = storage->Load(tree_reader, loaded_uids); + cypher_unions_.push_back(dynamic_cast(tree)); } - return query; } // SingleQuery -void SingleQuery::Save(capnp::Tree::Builder &tree_builder) { - Tree::Save(tree_builder); - auto builder = tree_builder.initSingleQuery(); - Save(builder); +void SingleQuery::Save(capnp::Tree::Builder *tree_builder, + std::vector *saved_uids) { + Tree::Save(tree_builder, saved_uids); + if (IsSaved(*saved_uids)) { + return; + } + auto builder = tree_builder->initSingleQuery(); + Save(&builder, saved_uids); + AddToSaved(saved_uids); } -void SingleQuery::Save(capnp::SingleQuery::Builder &builder) { +void SingleQuery::Save(capnp::SingleQuery::Builder *builder, + std::vector *saved_uids) { ::capnp::List::Builder tree_builders = - builder.initClauses(clauses_.size()); + builder->initClauses(clauses_.size()); for (size_t i = 0; i < clauses_.size(); ++i) { auto tree_builder = tree_builders[i]; - clauses_[i]->Save(tree_builder); + clauses_[i]->Save(&tree_builder, saved_uids); } } -SingleQuery *SingleQuery::Construct(capnp::SingleQuery::Reader &reader, - AstTreeStorage &storage) { - auto query = storage.Create(); - for (auto tree_reader : reader.getClauses()) { - auto tree = storage.Load(tree_reader); - query->clauses_.push_back(dynamic_cast(tree)); +void SingleQuery::Load(const capnp::Tree::Reader &base_reader, + AstTreeStorage *storage, std::vector *loaded_uids) { + Tree::Load(base_reader, storage, loaded_uids); + auto reader = base_reader.getSingleQuery(); + for (const auto tree_reader : reader.getClauses()) { + auto tree = storage->Load(tree_reader, loaded_uids); + clauses_.push_back(dynamic_cast(tree)); } - return query; +} + +SingleQuery *SingleQuery::Construct(const capnp::SingleQuery::Reader &reader, + AstTreeStorage *storage) { + return storage->Create(); } } // namespace query diff --git a/src/query/frontend/ast/ast.hpp b/src/query/frontend/ast/ast.hpp index 9e9929d71..122dc50dc 100644 --- a/src/query/frontend/ast/ast.hpp +++ b/src/query/frontend/ast/ast.hpp @@ -103,7 +103,7 @@ class AstTreeStorage { Load(ar, *query()); } - Tree *Load(capnp::Tree::Reader &tree); + Tree *Load(const capnp::Tree::Reader &tree, std::vector *loaded_uids); private: int next_uid_ = 0; @@ -169,12 +169,16 @@ class Tree : public ::utils::Visitable, int uid() const { return uid_; } virtual Tree *Clone(AstTreeStorage &storage) const = 0; - virtual void Save(capnp::Tree::Builder &builder); + virtual void Save(capnp::Tree::Builder *builder, + std::vector *saved_uids); protected: explicit Tree(int uid) : uid_(uid) {} - virtual void Load(capnp::Tree::Reader &reader, AstTreeStorage &storage); + virtual void Load(const capnp::Tree::Reader &reader, AstTreeStorage *storage, + std::vector *loaded_uids); + bool IsSaved(const std::vector &saved_uids); + void AddToSaved(std::vector *saved_uids); private: int uid_; @@ -194,15 +198,16 @@ class Expression : public Tree { public: Expression *Clone(AstTreeStorage &storage) const override = 0; - static Expression *Construct(capnp::Expression::Reader &reader, - AstTreeStorage &storage); + static Expression *Construct(const capnp::Expression::Reader &reader, + AstTreeStorage *storage); - void Save(capnp::Tree::Builder &builder) override; + void Save(capnp::Tree::Builder *builder, + std::vector *saved_uids) override; protected: explicit Expression(int uid) : Tree(uid) {} - virtual void Save(capnp::Expression::Builder &) {} + virtual void Save(capnp::Expression::Builder *, std::vector *) {} private: friend class boost::serialization::access; @@ -225,10 +230,11 @@ class Where : public Tree { return storage.Create(expression_->Clone(storage)); } - static Where *Construct(capnp::Where::Reader &reader, - AstTreeStorage &storage); + static Where *Construct(const capnp::Where::Reader &reader, + AstTreeStorage *storage); - void Save(capnp::Tree::Builder &builder) override; + void Save(capnp::Tree::Builder *builder, + std::vector *saved_uids) override; Expression *expression_ = nullptr; @@ -236,7 +242,9 @@ class Where : public Tree { explicit Where(int uid) : Tree(uid) {} Where(int uid, Expression *expression) : Tree(uid), expression_(expression) {} - virtual void Save(capnp::Where::Builder &); + virtual void Save(capnp::Where::Builder *, std::vector *saved_uids); + void Load(const capnp::Tree::Reader &tree_reader, AstTreeStorage *storage, + std::vector *loaded_uids) override; private: friend class boost::serialization::access; @@ -268,18 +276,21 @@ class BinaryOperator : public Expression { Expression *expression2_ = nullptr; BinaryOperator *Clone(AstTreeStorage &storage) const override = 0; - static BinaryOperator *Construct(capnp::BinaryOperator::Reader &reader, - AstTreeStorage &storage); + static BinaryOperator *Construct(const capnp::BinaryOperator::Reader &reader, + AstTreeStorage *storage); protected: explicit BinaryOperator(int uid) : Expression(uid) {} BinaryOperator(int uid, Expression *expression1, Expression *expression2) : Expression(uid), expression1_(expression1), expression2_(expression2) {} - void Save(capnp::Expression::Builder &builder) override; + void Save(capnp::Expression::Builder *builder, + std::vector *saved_uids) override; using Expression::Save; - virtual void Save(capnp::BinaryOperator::Builder &builder); - void Load(capnp::Tree::Reader &reader, AstTreeStorage &storage) override; + virtual void Save(capnp::BinaryOperator::Builder *builder, + std::vector *saved_uids); + void Load(const capnp::Tree::Reader &reader, AstTreeStorage *storage, + std::vector *loaded_uids) override; private: friend class boost::serialization::access; @@ -308,18 +319,21 @@ class UnaryOperator : public Expression { Expression *expression_ = nullptr; UnaryOperator *Clone(AstTreeStorage &storage) const override = 0; - static UnaryOperator *Construct(capnp::UnaryOperator::Reader &reader, - AstTreeStorage &storage); + static UnaryOperator *Construct(const capnp::UnaryOperator::Reader &reader, + AstTreeStorage *storage); protected: explicit UnaryOperator(int uid) : Expression(uid) {} UnaryOperator(int uid, Expression *expression) : Expression(uid), expression_(expression) {} - void Save(capnp::Expression::Builder &) override; + void Save(capnp::Expression::Builder *, + std::vector *saved_uids) override; using Expression::Save; - virtual void Save(capnp::UnaryOperator::Builder &builder); - void Load(capnp::Tree::Reader &reader, AstTreeStorage &storage) override; + virtual void Save(capnp::UnaryOperator::Builder *builder, + std::vector *saved_uids); + void Load(const capnp::Tree::Reader &reader, AstTreeStorage *storage, + std::vector *loaded_uids) override; private: friend class boost::serialization::access; @@ -352,12 +366,13 @@ class OrOperator : public BinaryOperator { } CLONE_BINARY_EXPRESSION; - static OrOperator *Construct(capnp::OrOperator::Reader &reader, - AstTreeStorage &storage); + static OrOperator *Construct(const capnp::OrOperator::Reader &reader, + AstTreeStorage *storage); protected: using BinaryOperator::BinaryOperator; - void Save(capnp::BinaryOperator::Builder &builder) override; + void Save(capnp::BinaryOperator::Builder *builder, + std::vector *saved_uids) override; private: friend class boost::serialization::access; @@ -380,12 +395,13 @@ class XorOperator : public BinaryOperator { return visitor.PostVisit(*this); } CLONE_BINARY_EXPRESSION; - static XorOperator *Construct(capnp::XorOperator::Reader &reader, - AstTreeStorage &storage); + static XorOperator *Construct(const capnp::XorOperator::Reader &reader, + AstTreeStorage *storage); protected: using BinaryOperator::BinaryOperator; - void Save(capnp::BinaryOperator::Builder &builder) override; + void Save(capnp::BinaryOperator::Builder *builder, + std::vector *saved_uids) override; private: friend class boost::serialization::access; @@ -408,12 +424,13 @@ class AndOperator : public BinaryOperator { return visitor.PostVisit(*this); } CLONE_BINARY_EXPRESSION; - static AndOperator *Construct(capnp::AndOperator::Reader &reader, - AstTreeStorage &storage); + static AndOperator *Construct(const capnp::AndOperator::Reader &reader, + AstTreeStorage *storage); protected: using BinaryOperator::BinaryOperator; - void Save(capnp::BinaryOperator::Builder &builder) override; + void Save(capnp::BinaryOperator::Builder *builder, + std::vector *saved_uids) override; private: friend class boost::serialization::access; @@ -436,12 +453,13 @@ class AdditionOperator : public BinaryOperator { return visitor.PostVisit(*this); } CLONE_BINARY_EXPRESSION; - static AdditionOperator *Construct(capnp::AdditionOperator::Reader &reader, - AstTreeStorage &storage); + static AdditionOperator *Construct( + const capnp::AdditionOperator::Reader &reader, AstTreeStorage *storage); protected: using BinaryOperator::BinaryOperator; - void Save(capnp::BinaryOperator::Builder &builder) override; + void Save(capnp::BinaryOperator::Builder *builder, + std::vector *saved_uids) override; private: friend class boost::serialization::access; @@ -465,11 +483,12 @@ class SubtractionOperator : public BinaryOperator { } CLONE_BINARY_EXPRESSION; static SubtractionOperator *Construct( - capnp::SubtractionOperator::Reader &reader, AstTreeStorage &storage); + capnp::SubtractionOperator::Reader &reader, AstTreeStorage *storage); protected: using BinaryOperator::BinaryOperator; - void Save(capnp::BinaryOperator::Builder &builder) override; + void Save(capnp::BinaryOperator::Builder *builder, + std::vector *saved_uids) override; private: friend class boost::serialization::access; @@ -493,11 +512,12 @@ class MultiplicationOperator : public BinaryOperator { } CLONE_BINARY_EXPRESSION; static MultiplicationOperator *Construct( - capnp::MultiplicationOperator::Reader &reader, AstTreeStorage &storage); + capnp::MultiplicationOperator::Reader &reader, AstTreeStorage *storage); protected: using BinaryOperator::BinaryOperator; - void Save(capnp::BinaryOperator::Builder &builder) override; + void Save(capnp::BinaryOperator::Builder *builder, + std::vector *saved_uids) override; private: friend class boost::serialization::access; @@ -519,12 +539,13 @@ class DivisionOperator : public BinaryOperator { return visitor.PostVisit(*this); } CLONE_BINARY_EXPRESSION; - static DivisionOperator *Construct(capnp::DivisionOperator::Reader &reader, - AstTreeStorage &storage); + static DivisionOperator *Construct( + const capnp::DivisionOperator::Reader &reader, AstTreeStorage *storage); protected: using BinaryOperator::BinaryOperator; - void Save(capnp::BinaryOperator::Builder &builder) override; + void Save(capnp::BinaryOperator::Builder *builder, + std::vector *saved_uids) override; private: friend class boost::serialization::access; @@ -547,12 +568,13 @@ class ModOperator : public BinaryOperator { return visitor.PostVisit(*this); } CLONE_BINARY_EXPRESSION; - static ModOperator *Construct(capnp::ModOperator::Reader &reader, - AstTreeStorage &storage); + static ModOperator *Construct(const capnp::ModOperator::Reader &reader, + AstTreeStorage *storage); protected: using BinaryOperator::BinaryOperator; - void Save(capnp::BinaryOperator::Builder &builder) override; + void Save(capnp::BinaryOperator::Builder *builder, + std::vector *saved_uids) override; private: friend class boost::serialization::access; @@ -575,12 +597,13 @@ class NotEqualOperator : public BinaryOperator { return visitor.PostVisit(*this); } CLONE_BINARY_EXPRESSION; - static NotEqualOperator *Construct(capnp::NotEqualOperator::Reader &reader, - AstTreeStorage &storage); + static NotEqualOperator *Construct( + const capnp::NotEqualOperator::Reader &reader, AstTreeStorage *storage); protected: using BinaryOperator::BinaryOperator; - void Save(capnp::BinaryOperator::Builder &builder) override; + void Save(capnp::BinaryOperator::Builder *builder, + std::vector *saved_uids) override; private: friend class boost::serialization::access; @@ -603,12 +626,13 @@ class EqualOperator : public BinaryOperator { return visitor.PostVisit(*this); } CLONE_BINARY_EXPRESSION; - static EqualOperator *Construct(capnp::EqualOperator::Reader &reader, - AstTreeStorage &storage); + static EqualOperator *Construct(const capnp::EqualOperator::Reader &reader, + AstTreeStorage *storage); protected: using BinaryOperator::BinaryOperator; - void Save(capnp::BinaryOperator::Builder &builder) override; + void Save(capnp::BinaryOperator::Builder *builder, + std::vector *saved_uids) override; private: friend class boost::serialization::access; @@ -631,12 +655,13 @@ class LessOperator : public BinaryOperator { return visitor.PostVisit(*this); } CLONE_BINARY_EXPRESSION; - static LessOperator *Construct(capnp::LessOperator::Reader &reader, - AstTreeStorage &storage); + static LessOperator *Construct(const capnp::LessOperator::Reader &reader, + AstTreeStorage *storage); protected: using BinaryOperator::BinaryOperator; - void Save(capnp::BinaryOperator::Builder &builder) override; + void Save(capnp::BinaryOperator::Builder *builder, + std::vector *saved_uids) override; private: friend class boost::serialization::access; @@ -659,12 +684,13 @@ class GreaterOperator : public BinaryOperator { return visitor.PostVisit(*this); } CLONE_BINARY_EXPRESSION; - static GreaterOperator *Construct(capnp::GreaterOperator::Reader &reader, - AstTreeStorage &storage); + static GreaterOperator *Construct( + const capnp::GreaterOperator::Reader &reader, AstTreeStorage *storage); protected: using BinaryOperator::BinaryOperator; - void Save(capnp::BinaryOperator::Builder &builder) override; + void Save(capnp::BinaryOperator::Builder *builder, + std::vector *saved_uids) override; private: friend class boost::serialization::access; @@ -687,12 +713,13 @@ class LessEqualOperator : public BinaryOperator { return visitor.PostVisit(*this); } CLONE_BINARY_EXPRESSION; - static LessEqualOperator *Construct(capnp::LessEqualOperator::Reader &reader, - AstTreeStorage &storage); + static LessEqualOperator *Construct( + const capnp::LessEqualOperator::Reader &reader, AstTreeStorage *storage); protected: using BinaryOperator::BinaryOperator; - void Save(capnp::BinaryOperator::Builder &builder) override; + void Save(capnp::BinaryOperator::Builder *builder, + std::vector *saved_uids) override; private: friend class boost::serialization::access; @@ -716,11 +743,13 @@ class GreaterEqualOperator : public BinaryOperator { } CLONE_BINARY_EXPRESSION; static GreaterEqualOperator *Construct( - capnp::GreaterEqualOperator::Reader &reader, AstTreeStorage &storage); + const capnp::GreaterEqualOperator::Reader &reader, + AstTreeStorage *storage); protected: using BinaryOperator::BinaryOperator; - void Save(capnp::BinaryOperator::Builder &builder) override; + void Save(capnp::BinaryOperator::Builder *builder, + std::vector *saved_uids) override; private: friend class boost::serialization::access; @@ -743,12 +772,13 @@ class InListOperator : public BinaryOperator { return visitor.PostVisit(*this); } CLONE_BINARY_EXPRESSION; - static InListOperator *Construct(capnp::InListOperator::Reader &reader, - AstTreeStorage &storage); + static InListOperator *Construct(const capnp::InListOperator::Reader &reader, + AstTreeStorage *storage); protected: using BinaryOperator::BinaryOperator; - void Save(capnp::BinaryOperator::Builder &builder) override; + void Save(capnp::BinaryOperator::Builder *builder, + std::vector *saved_uids) override; private: friend class boost::serialization::access; @@ -772,11 +802,12 @@ class ListMapIndexingOperator : public BinaryOperator { } CLONE_BINARY_EXPRESSION; static ListMapIndexingOperator *Construct( - capnp::ListMapIndexingOperator::Reader &reader, AstTreeStorage &storage); + capnp::ListMapIndexingOperator::Reader &reader, AstTreeStorage *storage); protected: using BinaryOperator::BinaryOperator; - void Save(capnp::BinaryOperator::Builder &builder) override; + void Save(capnp::BinaryOperator::Builder *builder, + std::vector *saved_uids) override; private: friend class boost::serialization::access; @@ -812,7 +843,8 @@ class ListSlicingOperator : public Expression { } static ListSlicingOperator *Construct( - capnp::ListSlicingOperator::Reader &reader, AstTreeStorage &storage); + const capnp::ListSlicingOperator::Reader &reader, + AstTreeStorage *storage); Expression *list_ = nullptr; Expression *lower_bound_ = nullptr; @@ -826,9 +858,13 @@ class ListSlicingOperator : public Expression { lower_bound_(lower_bound), upper_bound_(upper_bound) {} - void Save(capnp::Expression::Builder &builder) override; + void Save(capnp::Expression::Builder *builder, + std::vector *saved_uids) override; using Expression::Save; - virtual void Save(capnp::ListSlicingOperator::Builder &builder); + virtual void Save(capnp::ListSlicingOperator::Builder *builder, + std::vector *saved_uids); + void Load(const capnp::Tree::Reader &reader, AstTreeStorage *storage, + std::vector *loaded_uids) override; private: friend class boost::serialization::access; @@ -876,8 +912,8 @@ class IfOperator : public Expression { else_expression_->Clone(storage)); } - static IfOperator *Construct(capnp::IfOperator::Reader &reader, - AstTreeStorage &storage); + static IfOperator *Construct(const capnp::IfOperator::Reader &reader, + AstTreeStorage *storage); // None of the expressions should be nullptrs. If there is no else_expression // you probably want to make it NULL PrimitiveLiteral. Expression *condition_; @@ -892,9 +928,13 @@ class IfOperator : public Expression { then_expression_(then_expression), else_expression_(else_expression) {} - void Save(capnp::Expression::Builder &builder) override; + void Save(capnp::Expression::Builder *builder, + std::vector *saved_uids) override; using Expression::Save; - virtual void Save(capnp::IfOperator::Builder &builder); + virtual void Save(capnp::IfOperator::Builder *builder, + std::vector *saved_uids); + void Load(const capnp::Tree::Reader &reader, AstTreeStorage *storage, + std::vector *loaded_uids) override; private: friend class boost::serialization::access; @@ -935,12 +975,13 @@ class NotOperator : public UnaryOperator { return visitor.PostVisit(*this); } CLONE_UNARY_EXPRESSION; - static NotOperator *Construct(capnp::NotOperator::Reader &reader, - AstTreeStorage &storage); + static NotOperator *Construct(const capnp::NotOperator::Reader &reader, + AstTreeStorage *storage); protected: using UnaryOperator::UnaryOperator; - void Save(capnp::UnaryOperator::Builder &builder) override; + void Save(capnp::UnaryOperator::Builder *builder, + std::vector *saved_uids) override; private: friend class boost::serialization::access; @@ -963,12 +1004,13 @@ class UnaryPlusOperator : public UnaryOperator { return visitor.PostVisit(*this); } CLONE_UNARY_EXPRESSION; - static UnaryPlusOperator *Construct(capnp::UnaryPlusOperator::Reader &reader, - AstTreeStorage &storage); + static UnaryPlusOperator *Construct( + const capnp::UnaryPlusOperator::Reader &reader, AstTreeStorage *storage); protected: using UnaryOperator::UnaryOperator; - void Save(capnp::UnaryOperator::Builder &builder) override; + void Save(capnp::UnaryOperator::Builder *builder, + std::vector *saved_uids) override; private: friend class boost::serialization::access; @@ -992,11 +1034,12 @@ class UnaryMinusOperator : public UnaryOperator { } CLONE_UNARY_EXPRESSION; static UnaryMinusOperator *Construct( - capnp::UnaryMinusOperator::Reader &reader, AstTreeStorage &storage); + capnp::UnaryMinusOperator::Reader &reader, AstTreeStorage *storage); protected: using UnaryOperator::UnaryOperator; - void Save(capnp::UnaryOperator::Builder &builder) override; + void Save(capnp::UnaryOperator::Builder *builder, + std::vector *saved_uids) override; private: friend class boost::serialization::access; @@ -1019,12 +1062,13 @@ class IsNullOperator : public UnaryOperator { return visitor.PostVisit(*this); } CLONE_UNARY_EXPRESSION; - static IsNullOperator *Construct(capnp::IsNullOperator::Reader &reader, - AstTreeStorage &storage); + static IsNullOperator *Construct(const capnp::IsNullOperator::Reader &reader, + AstTreeStorage *storage); protected: using UnaryOperator::UnaryOperator; - void Save(capnp::UnaryOperator::Builder &builder) override; + void Save(capnp::UnaryOperator::Builder *builder, + std::vector *saved_uids) override; private: friend class boost::serialization::access; @@ -1040,15 +1084,17 @@ class BaseLiteral : public Expression { public: BaseLiteral *Clone(AstTreeStorage &storage) const override = 0; - static BaseLiteral *Construct(capnp::BaseLiteral::Reader &reader, - AstTreeStorage &storage); + static BaseLiteral *Construct(const capnp::BaseLiteral::Reader &reader, + AstTreeStorage *storage); protected: explicit BaseLiteral(int uid) : Expression(uid) {} - void Save(capnp::Expression::Builder &builder) override; + void Save(capnp::Expression::Builder *builder, + std::vector *saved_uids) override; using Expression::Save; - virtual void Save(capnp::BaseLiteral::Builder &) {} + virtual void Save(capnp::BaseLiteral::Builder *, + std::vector *saved_uids) {} private: friend class boost::serialization::access; @@ -1066,8 +1112,8 @@ class PrimitiveLiteral : public BaseLiteral { return storage.Create(value_, token_position_); } - static PrimitiveLiteral *Construct(capnp::PrimitiveLiteral::Reader &reader, - AstTreeStorage &storage); + static PrimitiveLiteral *Construct( + const capnp::PrimitiveLiteral::Reader &reader, AstTreeStorage *storage); TypedValue value_; // This field contains token position of literal used to create @@ -1083,7 +1129,10 @@ class PrimitiveLiteral : public BaseLiteral { PrimitiveLiteral(int uid, T value, int token_position) : BaseLiteral(uid), value_(value), token_position_(token_position) {} - void Save(capnp::BaseLiteral::Builder &builder) override; + void Save(capnp::BaseLiteral::Builder *builder, + std::vector *saved_uids) override; + void Load(const capnp::Tree::Reader &reader, AstTreeStorage *storage, + std::vector *loaded_uids) override; private: friend class boost::serialization::access; @@ -1131,8 +1180,8 @@ class ListLiteral : public BaseLiteral { return list; } - static ListLiteral *Construct(capnp::ListLiteral::Reader &reader, - AstTreeStorage &storage); + static ListLiteral *Construct(const capnp::ListLiteral::Reader &reader, + AstTreeStorage *storage); std::vector elements_; @@ -1141,7 +1190,10 @@ class ListLiteral : public BaseLiteral { ListLiteral(int uid, const std::vector &elements) : BaseLiteral(uid), elements_(elements) {} - void Save(capnp::BaseLiteral::Builder &builder) override; + void Save(capnp::BaseLiteral::Builder *builder, + std::vector *saved_uids) override; + void Load(const capnp::Tree::Reader &reader, AstTreeStorage *storage, + std::vector *loaded_uids) override; private: friend class boost::serialization::access; @@ -1186,8 +1238,8 @@ class MapLiteral : public BaseLiteral { return map; } - static MapLiteral *Construct(capnp::MapLiteral::Reader &reader, - AstTreeStorage &storage); + static MapLiteral *Construct(const capnp::MapLiteral::Reader &reader, + AstTreeStorage *storage); // maps (property_name, property) to expressions std::unordered_map, Expression *> @@ -1200,7 +1252,10 @@ class MapLiteral : public BaseLiteral { Expression *> &elements) : BaseLiteral(uid), elements_(elements) {} - void Save(capnp::BaseLiteral::Builder &builder) override; + void Save(capnp::BaseLiteral::Builder *builder, + std::vector *saved_uids) override; + void Load(const capnp::Tree::Reader &reader, AstTreeStorage *storage, + std::vector *loaded_uids) override; private: friend class boost::serialization::access; @@ -1252,8 +1307,8 @@ class Identifier : public Expression { return storage.Create(name_, user_declared_); } - static Identifier *Construct(capnp::Identifier::Reader &reader, - AstTreeStorage &storage); + static Identifier *Construct(const capnp::Identifier::Reader &reader, + AstTreeStorage *storage); using Expression::Save; std::string name_; @@ -1264,8 +1319,10 @@ class Identifier : public Expression { Identifier(int uid, const std::string &name, bool user_declared) : Expression(uid), name_(name), user_declared_(user_declared) {} - void Save(capnp::Expression::Builder &builder) override; - virtual void Save(capnp::Identifier::Builder &builder); + void Save(capnp::Expression::Builder *builder, + std::vector *saved_uids) override; + virtual void Save(capnp::Identifier::Builder *builder, + std::vector *saved_uids); private: friend class boost::serialization::access; @@ -1300,8 +1357,8 @@ class PropertyLookup : public Expression { property_name_, property_); } - static PropertyLookup *Construct(capnp::PropertyLookup::Reader &reader, - AstTreeStorage &storage); + static PropertyLookup *Construct(const capnp::PropertyLookup::Reader &reader, + AstTreeStorage *storage); using Expression::Save; Expression *expression_ = nullptr; @@ -1322,8 +1379,12 @@ class PropertyLookup : public Expression { property_name_(property.first), property_(property.second) {} - void Save(capnp::Expression::Builder &builder) override; - virtual void Save(capnp::PropertyLookup::Builder &builder); + void Save(capnp::Expression::Builder *builder, + std::vector *saved_uids) override; + virtual void Save(capnp::PropertyLookup::Builder *builder, + std::vector *saved_uids); + void Load(const capnp::Tree::Reader &reader, AstTreeStorage *storage, + std::vector *loaded_uids) override; private: friend class boost::serialization::access; @@ -1368,8 +1429,8 @@ class LabelsTest : public Expression { return storage.Create(expression_->Clone(storage), labels_); } - static LabelsTest *Construct(capnp::LabelsTest::Reader &reader, - AstTreeStorage &storage); + static LabelsTest *Construct(const capnp::LabelsTest::Reader &reader, + AstTreeStorage *storage); using Expression::Save; Expression *expression_ = nullptr; @@ -1380,8 +1441,12 @@ class LabelsTest : public Expression { const std::vector &labels) : Expression(uid), expression_(expression), labels_(labels) {} - void Save(capnp::Expression::Builder &builder) override; - virtual void Save(capnp::LabelsTest::Builder &builder); + void Save(capnp::Expression::Builder *builder, + std::vector *saved_uids) override; + virtual void Save(capnp::LabelsTest::Builder *builder, + std::vector *saved_uids); + void Load(const capnp::Tree::Reader &tree_reader, AstTreeStorage *storage, + std::vector *loaded_uids) override; private: friend class boost::serialization::access; @@ -1430,8 +1495,8 @@ class Function : public Expression { return storage.Create(function_name_, arguments); } - static Function *Construct(capnp::Function::Reader &reader, - AstTreeStorage &storage); + static Function *Construct(const capnp::Function::Reader &reader, + AstTreeStorage *storage); const auto &function() const { return function_; } const auto &function_name() const { return function_name_; } @@ -1448,9 +1513,13 @@ class Function : public Expression { function_(NameToFunction(function_name_)) { DCHECK(function_) << "Unexpected missing function: " << function_name_; } - void Save(capnp::Expression::Builder &builder) override; + void Save(capnp::Expression::Builder *builder, + std::vector *saved_uids) override; using Expression::Save; - virtual void Save(capnp::Function::Builder &builder); + virtual void Save(capnp::Function::Builder *builder, + std::vector *saved_uids); + void Load(const capnp::Tree::Reader &tree_reader, AstTreeStorage *storage, + std::vector *loaded_uids) override; private: std::string function_name_; @@ -1517,8 +1586,8 @@ class Aggregation : public BinaryOperator { } Op op_; - static Aggregation *Construct(capnp::Aggregation::Reader &, - AstTreeStorage &storage); + static Aggregation *Construct(const capnp::Aggregation::Reader &, + AstTreeStorage *storage); protected: // Use only for serialization. @@ -1536,7 +1605,8 @@ class Aggregation : public BinaryOperator { "invalid otherwise"; } - void Save(capnp::BinaryOperator::Builder &builder) override; + void Save(capnp::BinaryOperator::Builder *builder, + std::vector *saved_uids) override; private: friend class boost::serialization::access; @@ -1574,8 +1644,8 @@ class Reduce : public Expression { expression_->Clone(storage)); } - static Reduce *Construct(capnp::Reduce::Reader &reader, - AstTreeStorage &storage); + static Reduce *Construct(const capnp::Reduce::Reader &reader, + AstTreeStorage *storage); using Expression::Save; // None of these should be nullptr after construction. @@ -1602,8 +1672,12 @@ class Reduce : public Expression { list_(list), expression_(expression) {} - void Save(capnp::Expression::Builder &builder) override; - virtual void Save(capnp::Reduce::Builder &builder); + void Save(capnp::Expression::Builder *builder, + std::vector *saved_uids) override; + virtual void Save(capnp::Reduce::Builder *builder, + std::vector *saved_uids); + void Load(const capnp::Tree::Reader &tree_reader, AstTreeStorage *storage, + std::vector *loaded_uids) override; private: friend class boost::serialization::access; @@ -1655,7 +1729,8 @@ class All : public Expression { where_->Clone(storage)); } - static All *Construct(capnp::All::Reader &reader, AstTreeStorage &storage); + static All *Construct(const capnp::All::Reader &reader, + AstTreeStorage *storage); // None of these should be nullptr after construction. Identifier *identifier_ = nullptr; @@ -1670,9 +1745,12 @@ class All : public Expression { list_expression_(list_expression), where_(where) {} - void Save(capnp::Expression::Builder &builder) override; + void Save(capnp::Expression::Builder *builder, + std::vector *saved_uids) override; using Expression::Save; - virtual void Save(capnp::All::Builder &builder); + virtual void Save(capnp::All::Builder *builder, std::vector *saved_uids); + void Load(const capnp::Tree::Reader &tree_reader, AstTreeStorage *storage, + std::vector *loaded_uids) override; private: friend class boost::serialization::access; @@ -1722,8 +1800,8 @@ class Single : public Expression { where_->Clone(storage)); } - static Single *Construct(capnp::Single::Reader &reader, - AstTreeStorage &storage); + static Single *Construct(const capnp::Single::Reader &reader, + AstTreeStorage *storage); using Expression::Save; // None of these should be nullptr after construction. @@ -1739,8 +1817,12 @@ class Single : public Expression { list_expression_(list_expression), where_(where) {} - void Save(capnp::Expression::Builder &builder) override; - virtual void Save(capnp::Single::Builder &builder); + void Save(capnp::Expression::Builder *builder, + std::vector *saved_uids) override; + virtual void Save(capnp::Single::Builder *builder, + std::vector *saved_uids); + void Load(const capnp::Tree::Reader &tree_reader, AstTreeStorage *storage, + std::vector *loaded_uids) override; private: friend class boost::serialization::access; @@ -1779,8 +1861,8 @@ class ParameterLookup : public Expression { return storage.Create(token_position_); } - static ParameterLookup *Construct(capnp::ParameterLookup::Reader &reader, - AstTreeStorage &storage); + static ParameterLookup *Construct( + const capnp::ParameterLookup::Reader &reader, AstTreeStorage *storage); using Expression::Save; // This field contains token position of *literal* used to create @@ -1793,8 +1875,10 @@ class ParameterLookup : public Expression { ParameterLookup(int uid, int token_position) : Expression(uid), token_position_(token_position) {} - void Save(capnp::Expression::Builder &builder) override; - virtual void Save(capnp::ParameterLookup::Builder &builder); + void Save(capnp::Expression::Builder *builder, + std::vector *saved_uids) override; + virtual void Save(capnp::ParameterLookup::Builder *builder, + std::vector *saved_uids); friend class boost::serialization::access; @@ -1827,9 +1911,10 @@ class NamedExpression : public Tree { token_position_); } - static NamedExpression *Construct(capnp::NamedExpression::Reader &reader, - AstTreeStorage &storage); - void Save(capnp::Tree::Builder &builder) override; + static NamedExpression *Construct( + const capnp::NamedExpression::Reader &reader, AstTreeStorage *storage); + void Save(capnp::Tree::Builder *builder, + std::vector *saved_uids) override; std::string name_; Expression *expression_ = nullptr; @@ -1850,7 +1935,10 @@ class NamedExpression : public Tree { expression_(expression), token_position_(token_position) {} - virtual void Save(capnp::NamedExpression::Builder &); + virtual void Save(capnp::NamedExpression::Builder *, + std::vector *saved_uids); + void Load(const capnp::Tree::Reader &base_reader, AstTreeStorage *storage, + std::vector *loaded_uids) override; private: friend class boost::serialization::access; @@ -1889,17 +1977,20 @@ class PatternAtom : public Tree { PatternAtom *Clone(AstTreeStorage &storage) const override = 0; - static PatternAtom *Construct(capnp::PatternAtom::Reader &reader, - AstTreeStorage &storage); - void Save(capnp::Tree::Builder &builder) override; + static PatternAtom *Construct(const capnp::PatternAtom::Reader &reader, + AstTreeStorage *storage); + void Save(capnp::Tree::Builder *builder, + std::vector *saved_uids) override; protected: explicit PatternAtom(int uid) : Tree(uid) {} PatternAtom(int uid, Identifier *identifier) : Tree(uid), identifier_(identifier) {} - virtual void Save(capnp::PatternAtom::Builder &); - void Load(capnp::Tree::Reader &reader, AstTreeStorage &storage) override; + virtual void Save(capnp::PatternAtom::Builder *, + std::vector *saved_uids); + void Load(const capnp::Tree::Reader &reader, AstTreeStorage *storage, + std::vector *loaded_uids) override; private: friend class boost::serialization::access; @@ -1945,8 +2036,8 @@ class NodeAtom : public PatternAtom { return node_atom; } - static NodeAtom *Construct(capnp::NodeAtom::Reader &reader, - AstTreeStorage &storage); + static NodeAtom *Construct(const capnp::NodeAtom::Reader &reader, + AstTreeStorage *storage); using PatternAtom::Save; std::vector labels_; @@ -1957,8 +2048,12 @@ class NodeAtom : public PatternAtom { protected: using PatternAtom::PatternAtom; - void Save(capnp::PatternAtom::Builder &builder) override; - virtual void Save(capnp::NodeAtom::Builder &builder); + void Save(capnp::PatternAtom::Builder *builder, + std::vector *saved_uids) override; + virtual void Save(capnp::NodeAtom::Builder *builder, + std::vector *saved_uids); + void Load(const capnp::Tree::Reader &base_reader, AstTreeStorage *storage, + std::vector *loaded_uids) override; private: friend class boost::serialization::access; @@ -2017,7 +2112,8 @@ class EdgeAtom : public PatternAtom { }; enum class Direction { IN, OUT, BOTH }; - /// Lambda for use in filtering or weight calculation during variable expands. + /// Lambda for use in filtering or weight calculation during variable + /// expands. struct Lambda { /// Argument identifier for the edge currently being traversed. Identifier *inner_edge = nullptr; @@ -2081,8 +2177,8 @@ class EdgeAtom : public PatternAtom { } } - static EdgeAtom *Construct(capnp::EdgeAtom::Reader &reader, - AstTreeStorage &storage); + static EdgeAtom *Construct(const capnp::EdgeAtom::Reader &reader, + AstTreeStorage *storage); using PatternAtom::Save; Type type_ = Type::SINGLE; @@ -2105,7 +2201,8 @@ class EdgeAtom : public PatternAtom { /// It must have valid expressions and identifiers. In all other expand /// types, it is empty. Lambda weight_lambda_; - /// Variable where the total weight for weighted shortest path will be stored. + /// Variable where the total weight for weighted shortest path will be + /// stored. Identifier *total_weight_ = nullptr; protected: @@ -2121,8 +2218,12 @@ class EdgeAtom : public PatternAtom { direction_(direction), edge_types_(edge_types) {} - void Save(capnp::PatternAtom::Builder &builder) override; - virtual void Save(capnp::EdgeAtom::Builder &builder); + void Save(capnp::PatternAtom::Builder *builder, + std::vector *saved_uids) override; + virtual void Save(capnp::EdgeAtom::Builder *builder, + std::vector *saved_uids); + void Load(const capnp::Tree::Reader &base_reader, AstTreeStorage *storage, + std::vector *loaded_uids) override; private: friend class boost::serialization::access; @@ -2214,9 +2315,10 @@ class Pattern : public Tree { return pattern; } - static Pattern *Construct(capnp::Pattern::Reader &reader, - AstTreeStorage &storage); - void Save(capnp::Tree::Builder &builder) override; + static Pattern *Construct(const capnp::Pattern::Reader &reader, + AstTreeStorage *storage); + void Save(capnp::Tree::Builder *builder, + std::vector *saved_uids) override; Identifier *identifier_ = nullptr; std::vector atoms_; @@ -2224,7 +2326,9 @@ class Pattern : public Tree { protected: explicit Pattern(int uid) : Tree(uid) {} - virtual void Save(capnp::Pattern::Builder &); + virtual void Save(capnp::Pattern::Builder *, std::vector *saved_uids); + void Load(const capnp::Tree::Reader &base_reader, AstTreeStorage *storage, + std::vector *loaded_uids) override; private: friend class boost::serialization::access; @@ -2260,13 +2364,14 @@ class Clause : public Tree { Clause *Clone(AstTreeStorage &storage) const override = 0; - static Clause *Construct(capnp::Clause::Reader &reader, - AstTreeStorage &storage); + static Clause *Construct(const capnp::Clause::Reader &reader, + AstTreeStorage *storage); - void Save(capnp::Tree::Builder &builder) override; + void Save(capnp::Tree::Builder *builder, + std::vector *saved_uids) override; protected: - virtual void Save(capnp::Clause::Builder &) {} + virtual void Save(capnp::Clause::Builder *, std::vector *saved_uids) {} private: friend class boost::serialization::access; @@ -2297,17 +2402,21 @@ class SingleQuery : public Tree { return single_query; } - static SingleQuery *Construct(capnp::SingleQuery::Reader &reader, - AstTreeStorage &storage); + static SingleQuery *Construct(const capnp::SingleQuery::Reader &reader, + AstTreeStorage *storage); - void Save(capnp::Tree::Builder &builder) override; + void Save(capnp::Tree::Builder *builder, + std::vector *saved_uids) override; std::vector clauses_; protected: explicit SingleQuery(int uid) : Tree(uid) {} - virtual void Save(capnp::SingleQuery::Builder &); + virtual void Save(capnp::SingleQuery::Builder *, + std::vector *saved_uids); + void Load(const capnp::Tree::Reader &base_reader, AstTreeStorage *storage, + std::vector *loaded_uids) override; private: friend class boost::serialization::access; @@ -2353,14 +2462,16 @@ class CypherUnion : public Tree { return cypher_union; } - static CypherUnion *Construct(capnp::CypherUnion::Reader &reader, - AstTreeStorage &storage); - void Save(capnp::Tree::Builder &builder) override; + static CypherUnion *Construct(const capnp::CypherUnion::Reader &reader, + AstTreeStorage *storage); + void Save(capnp::Tree::Builder *builder, + std::vector *saved_uids) override; SingleQuery *single_query_ = nullptr; bool distinct_ = false; /// Holds symbols that are created during symbol generation phase. - /// These symbols are used when UNION/UNION ALL combines single query results. + /// These symbols are used when UNION/UNION ALL combines single query + /// results. std::vector union_symbols_; protected: @@ -2373,7 +2484,10 @@ class CypherUnion : public Tree { distinct_(distinct), union_symbols_(union_symbols) {} - virtual void Save(capnp::CypherUnion::Builder &); + virtual void Save(capnp::CypherUnion::Builder *, + std::vector *saved_uids); + void Load(const capnp::Tree::Reader &base_reader, AstTreeStorage *storage, + std::vector *loaded_uids) override; private: friend class boost::serialization::access; @@ -2431,9 +2545,10 @@ class Query : public Tree { return query; } - static Query *Construct(capnp::Query::Reader &reader, - AstTreeStorage &storage); - void Save(capnp::Tree::Builder &builder) override; + void Load(const capnp::Tree::Reader &reader, AstTreeStorage *storage, + std::vector *loaded_uids) override; + void Save(capnp::Tree::Builder *builder, + std::vector *saved_uids) override; SingleQuery *single_query_ = nullptr; std::vector cypher_unions_; @@ -2441,7 +2556,7 @@ class Query : public Tree { protected: explicit Query(int uid) : Tree(uid) {} - virtual void Save(capnp::Query::Builder &); + virtual void Save(capnp::Query::Builder *, std::vector *saved_uids); private: friend class boost::serialization::access; @@ -2491,8 +2606,8 @@ class Create : public Clause { return create; } - static Create *Construct(capnp::Create::Reader &reader, - AstTreeStorage &storage); + static Create *Construct(const capnp::Create::Reader &reader, + AstTreeStorage *storage); using Clause::Save; std::vector patterns_; @@ -2502,8 +2617,12 @@ class Create : public Clause { Create(int uid, std::vector patterns) : Clause(uid), patterns_(patterns) {} - void Save(capnp::Clause::Builder &builder) override; - virtual void Save(capnp::Create::Builder &builder); + void Save(capnp::Clause::Builder *builder, + std::vector *saved_uids) override; + virtual void Save(capnp::Create::Builder *builder, + std::vector *saved_uids); + void Load(const capnp::Tree::Reader &tree_reader, AstTreeStorage *storage, + std::vector *loaded_uids) override; private: friend class boost::serialization::access; @@ -2558,8 +2677,8 @@ class Match : public Clause { } using Clause::Save; - static Match *Construct(capnp::Match::Reader &reader, - AstTreeStorage &storage); + static Match *Construct(const capnp::Match::Reader &reader, + AstTreeStorage *storage); std::vector patterns_; Where *where_ = nullptr; @@ -2571,8 +2690,12 @@ class Match : public Clause { Match(int uid, bool optional, Where *where, std::vector patterns) : Clause(uid), patterns_(patterns), where_(where), optional_(optional) {} - void Save(capnp::Clause::Builder &builder) override; - virtual void Save(capnp::Match::Builder &builder); + void Save(capnp::Clause::Builder *builder, + std::vector *saved_uids) override; + virtual void Save(capnp::Match::Builder *builder, + std::vector *saved_uids); + void Load(const capnp::Tree::Reader &base_reader, AstTreeStorage *storage, + std::vector *loaded_uids) override; private: friend class boost::serialization::access; @@ -2697,8 +2820,8 @@ class Return : public Clause { } using Clause::Save; - static Return *Construct(capnp::Return::Reader &reader, - AstTreeStorage &storage); + static Return *Construct(const capnp::Return::Reader &reader, + AstTreeStorage *storage); ReturnBody body_; @@ -2706,8 +2829,12 @@ class Return : public Clause { explicit Return(int uid) : Clause(uid) {} Return(int uid, ReturnBody &body) : Clause(uid), body_(body) {} - void Save(capnp::Clause::Builder &builder) override; - virtual void Save(capnp::Return::Builder &builder); + void Save(capnp::Clause::Builder *builder, + std::vector *saved_uids) override; + virtual void Save(capnp::Return::Builder *builder, + std::vector *saved_uids); + void Load(const capnp::Tree::Reader &base_reader, AstTreeStorage *storage, + std::vector *loaded_uids) override; private: friend class boost::serialization::access; @@ -2760,7 +2887,8 @@ class With : public Clause { } using Clause::Save; - static With *Construct(capnp::With::Reader &reader, AstTreeStorage &storage); + static With *Construct(const capnp::With::Reader &reader, + AstTreeStorage *storage); ReturnBody body_; Where *where_ = nullptr; @@ -2770,8 +2898,12 @@ class With : public Clause { With(int uid, ReturnBody &body, Where *where) : Clause(uid), body_(body), where_(where) {} - void Save(capnp::Clause::Builder &builder) override; - virtual void Save(capnp::With::Builder &builder); + void Save(capnp::Clause::Builder *builder, + std::vector *saved_uids) override; + virtual void Save(capnp::With::Builder *builder, + std::vector *saved_uids); + void Load(const capnp::Tree::Reader &base_reader, AstTreeStorage *storage, + std::vector *loaded_uids) override; private: friend class boost::serialization::access; @@ -2821,8 +2953,8 @@ class Delete : public Clause { } using Clause::Save; - static Delete *Construct(capnp::Delete::Reader &reader, - AstTreeStorage &storage); + static Delete *Construct(const capnp::Delete::Reader &reader, + AstTreeStorage *storage); std::vector expressions_; @@ -2833,8 +2965,12 @@ class Delete : public Clause { Delete(int uid, bool detach, std::vector expressions) : Clause(uid), expressions_(expressions), detach_(detach) {} - void Save(capnp::Clause::Builder &builder) override; - virtual void Save(capnp::Delete::Builder &builder); + void Save(capnp::Clause::Builder *builder, + std::vector *saved_uids) override; + virtual void Save(capnp::Delete::Builder *builder, + std::vector *saved_uids); + void Load(const capnp::Tree::Reader &base_reader, AstTreeStorage *storage, + std::vector *loaded_uids) override; private: friend class boost::serialization::access; @@ -2878,8 +3014,8 @@ class SetProperty : public Clause { } using Clause::Save; - static SetProperty *Construct(capnp::SetProperty::Reader &reader, - AstTreeStorage &storage); + static SetProperty *Construct(const capnp::SetProperty::Reader &reader, + AstTreeStorage *storage); PropertyLookup *property_lookup_ = nullptr; Expression *expression_ = nullptr; @@ -2891,8 +3027,12 @@ class SetProperty : public Clause { property_lookup_(property_lookup), expression_(expression) {} - void Save(capnp::Clause::Builder &builder) override; - virtual void Save(capnp::SetProperty::Builder &builder); + void Save(capnp::Clause::Builder *builder, + std::vector *saved_uids) override; + virtual void Save(capnp::SetProperty::Builder *builder, + std::vector *saved_uids); + void Load(const capnp::Tree::Reader &base_reader, AstTreeStorage *storage, + std::vector *loaded_uids) override; private: friend class boost::serialization::access; @@ -2937,8 +3077,8 @@ class SetProperties : public Clause { } using Clause::Save; - static SetProperties *Construct(capnp::SetProperties::Reader &reader, - AstTreeStorage &storage); + static SetProperties *Construct(const capnp::SetProperties::Reader &reader, + AstTreeStorage *storage); Identifier *identifier_ = nullptr; Expression *expression_ = nullptr; @@ -2953,8 +3093,12 @@ class SetProperties : public Clause { expression_(expression), update_(update) {} - void Save(capnp::Clause::Builder &builder) override; - virtual void Save(capnp::SetProperties::Builder &builder); + void Save(capnp::Clause::Builder *builder, + std::vector *saved_uids) override; + virtual void Save(capnp::SetProperties::Builder *builder, + std::vector *saved_uids); + void Load(const capnp::Tree::Reader &base_reader, AstTreeStorage *storage, + std::vector *loaded_uids) override; private: friend class boost::serialization::access; @@ -3000,8 +3144,8 @@ class SetLabels : public Clause { } using Clause::Save; - static SetLabels *Construct(capnp::SetLabels::Reader &reader, - AstTreeStorage &storage); + static SetLabels *Construct(const capnp::SetLabels::Reader &reader, + AstTreeStorage *storage); Identifier *identifier_ = nullptr; std::vector labels_; @@ -3012,8 +3156,12 @@ class SetLabels : public Clause { const std::vector &labels) : Clause(uid), identifier_(identifier), labels_(labels) {} - void Save(capnp::Clause::Builder &builder) override; - virtual void Save(capnp::SetLabels::Builder &builder); + void Save(capnp::Clause::Builder *builder, + std::vector *saved_uids) override; + virtual void Save(capnp::SetLabels::Builder *builder, + std::vector *saved_uids); + void Load(const capnp::Tree::Reader &base_reader, AstTreeStorage *storage, + std::vector *loaded_uids) override; private: friend class boost::serialization::access; @@ -3056,8 +3204,8 @@ class RemoveProperty : public Clause { } using Clause::Save; - static RemoveProperty *Construct(capnp::RemoveProperty::Reader &reader, - AstTreeStorage &storage); + static RemoveProperty *Construct(const capnp::RemoveProperty::Reader &reader, + AstTreeStorage *storage); PropertyLookup *property_lookup_ = nullptr; @@ -3066,8 +3214,12 @@ class RemoveProperty : public Clause { RemoveProperty(int uid, PropertyLookup *property_lookup) : Clause(uid), property_lookup_(property_lookup) {} - void Save(capnp::Clause::Builder &builder) override; - virtual void Save(capnp::RemoveProperty::Builder &builder); + void Save(capnp::Clause::Builder *builder, + std::vector *saved_uids) override; + virtual void Save(capnp::RemoveProperty::Builder *builder, + std::vector *saved_uids); + void Load(const capnp::Tree::Reader &base_reader, AstTreeStorage *storage, + std::vector *loaded_uids) override; private: friend class boost::serialization::access; @@ -3109,8 +3261,8 @@ class RemoveLabels : public Clause { } using Clause::Save; - static RemoveLabels *Construct(capnp::RemoveLabels::Reader &reader, - AstTreeStorage &storage); + static RemoveLabels *Construct(const capnp::RemoveLabels::Reader &reader, + AstTreeStorage *storage); Identifier *identifier_ = nullptr; std::vector labels_; @@ -3121,8 +3273,12 @@ class RemoveLabels : public Clause { const std::vector &labels) : Clause(uid), identifier_(identifier), labels_(labels) {} - void Save(capnp::Clause::Builder &builder) override; - virtual void Save(capnp::RemoveLabels::Builder &builder); + void Save(capnp::Clause::Builder *builder, + std::vector *saved_uids) override; + virtual void Save(capnp::RemoveLabels::Builder *builder, + std::vector *saved_uids); + void Load(const capnp::Tree::Reader &base_reader, AstTreeStorage *storage, + std::vector *loaded_uids) override; private: friend class boost::serialization::access; @@ -3190,8 +3346,8 @@ class Merge : public Clause { } using Clause::Save; - static Merge *Construct(capnp::Merge::Reader &reader, - AstTreeStorage &storage); + static Merge *Construct(const capnp::Merge::Reader &reader, + AstTreeStorage *storage); Pattern *pattern_ = nullptr; std::vector on_match_; @@ -3206,8 +3362,12 @@ class Merge : public Clause { on_match_(on_match), on_create_(on_create) {} - void Save(capnp::Clause::Builder &builder) override; - virtual void Save(capnp::Merge::Builder &builder); + void Save(capnp::Clause::Builder *builder, + std::vector *saved_uids) override; + virtual void Save(capnp::Merge::Builder *builder, + std::vector *saved_uids); + void Load(const capnp::Tree::Reader &base_reader, AstTreeStorage *storage, + std::vector *loaded_uids) override; private: friend class boost::serialization::access; @@ -3252,8 +3412,8 @@ class Unwind : public Clause { } using Clause::Save; - static Unwind *Construct(capnp::Unwind::Reader &reader, - AstTreeStorage &storage); + static Unwind *Construct(const capnp::Unwind::Reader &reader, + AstTreeStorage *storage); NamedExpression *named_expression_ = nullptr; @@ -3266,8 +3426,12 @@ class Unwind : public Clause { << "Unwind cannot take nullptr for named_expression"; } - void Save(capnp::Clause::Builder &builder) override; - virtual void Save(capnp::Unwind::Builder &builder); + void Save(capnp::Clause::Builder *builder, + std::vector *saved_uids) override; + virtual void Save(capnp::Unwind::Builder *builder, + std::vector *saved_uids); + void Load(const capnp::Tree::Reader &base_reader, AstTreeStorage *storage, + std::vector *loaded_uids) override; private: friend class boost::serialization::access; @@ -3302,8 +3466,8 @@ class CreateIndex : public Clause { return storage.Create(label_, property_); } - static CreateIndex *Construct(capnp::CreateIndex::Reader &reader, - AstTreeStorage &storage); + static CreateIndex *Construct(const capnp::CreateIndex::Reader &reader, + AstTreeStorage *storage); using Clause::Save; storage::Label label_; @@ -3314,8 +3478,10 @@ class CreateIndex : public Clause { CreateIndex(int uid, storage::Label label, storage::Property property) : Clause(uid), label_(label), property_(property) {} - void Save(capnp::Clause::Builder &builder) override; - virtual void Save(capnp::CreateIndex::Builder &builder); + void Save(capnp::Clause::Builder *builder, + std::vector *saved_uids) override; + virtual void Save(capnp::CreateIndex::Builder *builder, + std::vector *saved_uids); private: friend class boost::serialization::access; diff --git a/tests/unit/cypher_main_visitor.cpp b/tests/unit/cypher_main_visitor.cpp index 333aac2a4..26dd1d9a8 100644 --- a/tests/unit/cypher_main_visitor.cpp +++ b/tests/unit/cypher_main_visitor.cpp @@ -154,14 +154,16 @@ class CapnpAstGenerator : public Base { { query::capnp::Tree::Builder builder = message.initRoot(); - visitor.query()->Save(builder); + std::vector saved_uids; + visitor.query()->Save(&builder, &saved_uids); } AstTreeStorage new_ast; { - query::capnp::Tree::Reader reader = + const query::capnp::Tree::Reader reader = message.getRoot(); - new_ast.Load(reader); + std::vector loaded_uids; + new_ast.Load(reader, &loaded_uids); } return new_ast; }()),