diff options
author | vvvv <[email protected]> | 2025-10-03 08:43:30 +0300 |
---|---|---|
committer | vvvv <[email protected]> | 2025-10-03 08:57:52 +0300 |
commit | fca550e88eedcef3b7ac2e13570d6ef22f962f85 (patch) | |
tree | 18e97db9b39a613139fe1c4a664e2df2a4813583 /yql/essentials/ast/yql_constraint.cpp | |
parent | ae5c83168cc92405e6adc682be0a3ecffdf83bd5 (diff) |
YQL-20086 ast
init
commit_hash:89d6b4ea7383b4155af171f44b946fc80550d517
Diffstat (limited to 'yql/essentials/ast/yql_constraint.cpp')
-rw-r--r-- | yql/essentials/ast/yql_constraint.cpp | 726 |
1 files changed, 420 insertions, 306 deletions
diff --git a/yql/essentials/ast/yql_constraint.cpp b/yql/essentials/ast/yql_constraint.cpp index b19bf96c98a..577ebafca52 100644 --- a/yql/essentials/ast/yql_constraint.cpp +++ b/yql/essentials/ast/yql_constraint.cpp @@ -33,15 +33,18 @@ void TConstraintNode::Out(IOutputStream& out) const { TPartOfConstraintBase::TPartOfConstraintBase(TExprContext& ctx, std::string_view name) : TConstraintNode(ctx, name) -{} +{ +} TConstraintWithFieldsNode::TConstraintWithFieldsNode(TExprContext& ctx, std::string_view name) : TPartOfConstraintBase(ctx, name) -{} +{ +} const TTypeAnnotationNode* TPartOfConstraintBase::GetSubTypeByPath(const TPathType& path, const TTypeAnnotationNode& type) { - if (path.empty() && ETypeAnnotationKind::Optional != type.GetKind()) + if (path.empty() && ETypeAnnotationKind::Optional != type.GetKind()) { return &type; + } const auto tail = [](const TPathType& path) { auto p(path); @@ -54,28 +57,37 @@ const TTypeAnnotationNode* TPartOfConstraintBase::GetSubTypeByPath(const TPathTy case ETypeAnnotationKind::List: // TODO: Remove later: temporary stub for single AsList in FlatMap and same cases. return GetSubTypeByPath(path, *type.Cast<TListExprType>()->GetItemType()); case ETypeAnnotationKind::Struct: - if (const auto itemType = type.Cast<TStructExprType>()->FindItemType(path.front())) + if (const auto itemType = type.Cast<TStructExprType>()->FindItemType(path.front())) { return GetSubTypeByPath(tail(path), *itemType); + } break; case ETypeAnnotationKind::Tuple: - if (const auto index = TryFromString<ui64>(TStringBuf(path.front()))) - if (const auto typleType = type.Cast<TTupleExprType>(); typleType->GetSize() > *index) + if (const auto index = TryFromString<ui64>(TStringBuf(path.front()))) { + if (const auto typleType = type.Cast<TTupleExprType>(); typleType->GetSize() > *index) { return GetSubTypeByPath(tail(path), *typleType->GetItems()[*index]); + } + } break; case ETypeAnnotationKind::Multi: - if (const auto index = TryFromString<ui64>(TStringBuf(path.front()))) - if (const auto multiType = type.Cast<TMultiExprType>(); multiType->GetSize() > *index) + if (const auto index = TryFromString<ui64>(TStringBuf(path.front()))) { + if (const auto multiType = type.Cast<TMultiExprType>(); multiType->GetSize() > *index) { return GetSubTypeByPath(tail(path), *multiType->GetItems()[*index]); + } + } break; case ETypeAnnotationKind::Variant: return GetSubTypeByPath(path, *type.Cast<TVariantExprType>()->GetUnderlyingType()); case ETypeAnnotationKind::Dict: - if (const auto index = TryFromString<ui8>(TStringBuf(path.front()))) + if (const auto index = TryFromString<ui8>(TStringBuf(path.front()))) { switch (*index) { - case 0U: return GetSubTypeByPath(tail(path), *type.Cast<TDictExprType>()->GetKeyType()); - case 1U: return GetSubTypeByPath(tail(path), *type.Cast<TDictExprType>()->GetPayloadType()); - default: break; + case 0U: + return GetSubTypeByPath(tail(path), *type.Cast<TDictExprType>()->GetKeyType()); + case 1U: + return GetSubTypeByPath(tail(path), *type.Cast<TDictExprType>()->GetPayloadType()); + default: + break; } + } break; default: break; @@ -86,44 +98,46 @@ const TTypeAnnotationNode* TPartOfConstraintBase::GetSubTypeByPath(const TPathTy bool TPartOfConstraintBase::HasDuplicates(const TSetOfSetsType& sets) { for (auto ot = sets.cbegin(); sets.cend() != ot; ++ot) { for (auto it = sets.cbegin(); sets.cend() != it; ++it) { - if (ot->size() < it->size() && std::all_of(ot->cbegin(), ot->cend(), [it](const TPathType& path) { return it->contains(path); })) + if (ot->size() < it->size() && std::all_of(ot->cbegin(), ot->cend(), [it](const TPathType& path) { return it->contains(path); })) { return true; + } } } return false; } NYT::TNode TPartOfConstraintBase::PathToNode(const TPartOfConstraintBase::TPathType& path) { - if (1U == path.size()) + if (1U == path.size()) { return TStringBuf(path.front()); + } return std::accumulate(path.cbegin(), path.cend(), - NYT::TNode::CreateList(), - [](NYT::TNode node, std::string_view p) -> NYT::TNode { return std::move(node).Add(TStringBuf(p)); } - ); + NYT::TNode::CreateList(), + [](NYT::TNode node, std::string_view p) -> NYT::TNode { return std::move(node).Add(TStringBuf(p)); }); }; NYT::TNode TPartOfConstraintBase::SetToNode(const TPartOfConstraintBase::TSetType& set, bool withShortcut) { - if (withShortcut && 1U == set.size() && 1U == set.front().size()) + if (withShortcut && 1U == set.size() && 1U == set.front().size()) { return TStringBuf(set.front().front()); + } return std::accumulate(set.cbegin(), set.cend(), - NYT::TNode::CreateList(), - [](NYT::TNode node, const TPathType& path) -> NYT::TNode { return std::move(node).Add(PathToNode(path)); } - ); + NYT::TNode::CreateList(), + [](NYT::TNode node, const TPathType& path) -> NYT::TNode { return std::move(node).Add(PathToNode(path)); }); }; NYT::TNode TPartOfConstraintBase::SetOfSetsToNode(const TPartOfConstraintBase::TSetOfSetsType& sets) { return std::accumulate(sets.cbegin(), sets.cend(), - NYT::TNode::CreateList(), - [](NYT::TNode node, const TSetType& s) { - return std::move(node).Add(TPartOfConstraintBase::SetToNode(s, true)); - }); + NYT::TNode::CreateList(), + [](NYT::TNode node, const TSetType& s) { + return std::move(node).Add(TPartOfConstraintBase::SetToNode(s, true)); + }); } TPartOfConstraintBase::TPathType TPartOfConstraintBase::NodeToPath(TExprContext& ctx, const NYT::TNode& node) { - if (node.IsString()) + if (node.IsString()) { return TPartOfConstraintBase::TPathType{ctx.AppendString(node.AsString())}; + } TPartOfConstraintBase::TPathType path; for (const auto& col : node.AsList()) { @@ -133,8 +147,9 @@ TPartOfConstraintBase::TPathType TPartOfConstraintBase::NodeToPath(TExprContext& }; TPartOfConstraintBase::TSetType TPartOfConstraintBase::NodeToSet(TExprContext& ctx, const NYT::TNode& node) { - if (node.IsString()) + if (node.IsString()) { return TPartOfConstraintBase::TSetType{TPartOfConstraintBase::TPathType(1U, ctx.AppendString(node.AsString()))}; + } TPartOfConstraintBase::TSetType set; for (const auto& col : node.AsList()) { @@ -186,9 +201,10 @@ const TConstraintNode* TConstraintSet::RemoveConstraint(std::string_view name) { void TConstraintSet::Out(IOutputStream& out) const { out.Write('{'); bool first = true; - for (const auto& c: Constraints_) { - if (!first) + for (const auto& c : Constraints_) { + if (!first) { out.Write(','); + } out << *c; first = false; } @@ -216,11 +232,13 @@ NYT::TNode TConstraintSet::ToYson() const { bool TConstraintSet::FilterConstraints(const TPredicate& predicate) { const auto size = Constraints_.size(); - for (auto it = Constraints_.begin(); Constraints_.end() != it;) - if (predicate((*it)->GetName())) + for (auto it = Constraints_.begin(); Constraints_.end() != it;) { + if (predicate((*it)->GetName())) { ++it; - else + } else { it = Constraints_.erase(it); + } + } return Constraints_.size() != size; } @@ -231,10 +249,14 @@ namespace { size_t GetElementsCount(const TTypeAnnotationNode* type) { if (type) { switch (type->GetKind()) { - case ETypeAnnotationKind::Tuple: return type->Cast<TTupleExprType>()->GetSize(); - case ETypeAnnotationKind::Multi: return type->Cast<TMultiExprType>()->GetSize(); - case ETypeAnnotationKind::Struct: return type->Cast<TStructExprType>()->GetSize(); - default: break; + case ETypeAnnotationKind::Tuple: + return type->Cast<TTupleExprType>()->GetSize(); + case ETypeAnnotationKind::Multi: + return type->Cast<TMultiExprType>()->GetSize(); + case ETypeAnnotationKind::Struct: + return type->Cast<TStructExprType>()->GetSize(); + default: + break; } } return 0U; @@ -274,12 +296,13 @@ std::deque<std::string_view> GetAllItemTypeFields(const TTypeAnnotationNode* typ TPartOfConstraintBase::TSetOfSetsType MakeFullSet(const TPartOfConstraintBase::TSetType& keys) { TPartOfConstraintBase::TSetOfSetsType sets; sets.reserve(sets.size()); - for (const auto& key : keys) + for (const auto& key : keys) { sets.insert_unique(TPartOfConstraintBase::TSetType{key}); + } return sets; } -} +} // namespace ////////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -290,8 +313,9 @@ TSortedConstraintNode::TSortedConstraintNode(TExprContext& ctx, TContainerType&& YQL_ENSURE(!Content_.empty()); for (const auto& c : Content_) { YQL_ENSURE(!c.first.empty()); - for (const auto& path : c.first) + for (const auto& path : c.first) { Hash_ = std::accumulate(path.cbegin(), path.cend(), c.second ? Hash_ : ~Hash_, [](ui64 hash, const std::string_view& field) { return MurmurHash<ui64>(field.data(), field.size(), hash); }); + } } } @@ -335,12 +359,14 @@ bool TSortedConstraintNode::Includes(const TConstraintNode& node) const { } const auto& content = static_cast<const TSortedConstraintNode&>(node).GetContent(); - if (content.size() > Content_.size()) + if (content.size() > Content_.size()) { return false; + } for (TContainerType::size_type i = 0U; i < content.size(); ++i) { if (Content_[i].second != content[i].second || - !(std::includes(Content_[i].first.cbegin(), Content_[i].first.cend(), content[i].first.cbegin(), content[i].first.cend()) || std::includes(content[i].first.cbegin(), content[i].first.cend(), Content_[i].first.cbegin(), Content_[i].first.cend()))) + !(std::includes(Content_[i].first.cbegin(), Content_[i].first.cend(), content[i].first.cbegin(), content[i].first.cend()) || std::includes(content[i].first.cbegin(), content[i].first.cend(), Content_[i].first.cbegin(), Content_[i].first.cend()))) { return false; + } } return true; @@ -351,10 +377,11 @@ void TSortedConstraintNode::Out(IOutputStream& out) const { out.Write('('); bool first = true; for (const auto& c : Content_) { - if (first) + if (first) { first = false; - else + } else { out.Write(';'); + } out.Write(JoinSeq(',', c.first)); out.Write('['); @@ -377,10 +404,10 @@ void TSortedConstraintNode::ToJson(NJson::TJsonWriter& out) const { NYT::TNode TSortedConstraintNode::ToYson() const { return std::accumulate(Content_.cbegin(), Content_.cend(), - NYT::TNode::CreateList(), - [](NYT::TNode node, const std::pair<TSetType, bool>& pair) { - return std::move(node).Add(NYT::TNode::CreateList().Add(TPartOfConstraintBase::SetToNode(pair.first, false)).Add(pair.second)); - }); + NYT::TNode::CreateList(), + [](NYT::TNode node, const std::pair<TSetType, bool>& pair) { + return std::move(node).Add(NYT::TNode::CreateList().Add(TPartOfConstraintBase::SetToNode(pair.first, false)).Add(pair.second)); + }); } bool TSortedConstraintNode::IsPrefixOf(const TSortedConstraintNode& node) const { @@ -391,15 +418,16 @@ bool TSortedConstraintNode::StartsWith(const TSetType& prefix) const { auto set = prefix; for (const auto& key : Content_) { bool found = false; - std::for_each(key.first.cbegin(), key.first.cend(), [&set, &found] (const TPathType& path) { + std::for_each(key.first.cbegin(), key.first.cend(), [&set, &found](const TPathType& path) { if (const auto it = set.find(path); set.cend() != it) { set.erase(it); found = true; } }); - if (!found) + if (!found) { break; + } } return set.empty(); @@ -408,8 +436,9 @@ bool TSortedConstraintNode::StartsWith(const TSetType& prefix) const { TPartOfConstraintBase::TSetType TSortedConstraintNode::GetFullSet() const { TSetType set; set.reserve(Content_.size()); - for (const auto& key : Content_) + for (const auto& key : Content_) { set.insert_unique(key.first.cbegin(), key.first.cend()); + } return set; } @@ -426,8 +455,9 @@ void TSortedConstraintNode::FilterUncompleteReferences(TSetType& references) con } } - if (!found) + if (!found) { break; + } } references = std::move(complete); @@ -460,11 +490,13 @@ const TSortedConstraintNode* TSortedConstraintNode::MakeCommon(const std::vector if (common.empty() || one.second != two.second) { content->resize(j); break; - } else + } else { one.first = std::move(common); + } } - if (content->empty()) + if (content->empty()) { break; + } } else { content = nextContent; } @@ -496,19 +528,22 @@ const TSortedConstraintNode* TSortedConstraintNode::MakeCommon(const TSortedCons if (common.empty() || one.second != two.second) { content.resize(j); break; - } else + } else { one.first = std::move(common); + } } return content.empty() ? nullptr : ctx.MakeConstraint<TSortedConstraintNode>(std::move(content)); } const TSortedConstraintNode* TSortedConstraintNode::CutPrefix(size_t newPrefixLength, TExprContext& ctx) const { - if (!newPrefixLength) + if (!newPrefixLength) { return nullptr; + } - if (newPrefixLength >= Content_.size()) + if (newPrefixLength >= Content_.size()) { return this; + } auto content = Content_; content.resize(newPrefixLength); @@ -516,8 +551,9 @@ const TSortedConstraintNode* TSortedConstraintNode::CutPrefix(size_t newPrefixLe } const TConstraintWithFieldsNode* TSortedConstraintNode::DoFilterFields(TExprContext& ctx, const TPathFilter& filter) const { - if (!filter) + if (!filter) { return this; + } TContainerType sorted; sorted.reserve(Content_.size()); @@ -525,21 +561,24 @@ const TConstraintWithFieldsNode* TSortedConstraintNode::DoFilterFields(TExprCont TSetType newSet; newSet.reserve(item.first.size()); for (const auto& path : item.first) { - if (filter(path)) + if (filter(path)) { newSet.insert_unique(path); + } } - if (newSet.empty()) + if (newSet.empty()) { break; - else + } else { sorted.emplace_back(std::move(newSet), item.second); + } } return sorted.empty() ? nullptr : ctx.MakeConstraint<TSortedConstraintNode>(std::move(sorted)); } const TConstraintWithFieldsNode* TSortedConstraintNode::DoRenameFields(TExprContext& ctx, const TPathReduce& reduce) const { - if (!reduce) + if (!reduce) { return this; + } TContainerType sorted; sorted.reserve(Content_.size()); @@ -547,14 +586,16 @@ const TConstraintWithFieldsNode* TSortedConstraintNode::DoRenameFields(TExprCont TSetType newSet; newSet.reserve(item.first.size()); for (const auto& path : item.first) { - if (const auto& newPaths = reduce(path); !newPaths.empty()) + if (const auto& newPaths = reduce(path); !newPaths.empty()) { newSet.insert_unique(newPaths.cbegin(), newPaths.cend()); + } } - if (newSet.empty()) + if (newSet.empty()) { break; - else + } else { sorted.emplace_back(std::move(newSet), item.second); + } } return sorted.empty() ? nullptr : ctx.MakeConstraint<TSortedConstraintNode>(std::move(sorted)); } @@ -566,7 +607,6 @@ bool TSortedConstraintNode::IsApplicableToType(const TTypeAnnotationNode& type) }); } - const TConstraintWithFieldsNode* TSortedConstraintNode::DoGetComplicatedForType(const TTypeAnnotationNode& type, TExprContext& ctx) const { const auto& rowType = GetSeqItemType(type); @@ -582,18 +622,20 @@ TSortedConstraintNode::DoGetComplicatedForType(const TTypeAnnotationNode& type, } } - if (fields.empty() || ETypeAnnotationKind::Struct == subType->GetKind()) + if (fields.empty() || ETypeAnnotationKind::Struct == subType->GetKind()) { ++it; - else { + } else { changed = true; const bool dir = it->second; auto set = it->first; - for (auto& path : set) + for (auto& path : set) { path.emplace_back(); + } for (it = content.erase(it); !fields.empty(); fields.pop_front()) { auto paths = set; - for (auto& path : paths) + for (auto& path : paths) { path.back() = fields.front(); + } it = content.emplace(it, std::move(paths), dir); ++it; } @@ -605,8 +647,9 @@ TSortedConstraintNode::DoGetComplicatedForType(const TTypeAnnotationNode& type, const TConstraintWithFieldsNode* TSortedConstraintNode::DoGetSimplifiedForType(const TTypeAnnotationNode& type, TExprContext& ctx) const { - if (Content_.size() == 1U && Content_.front().first.size() == 1U && Content_.front().first.front().empty()) + if (Content_.size() == 1U && Content_.front().first.size() == 1U && Content_.front().first.front().empty()) { return DoGetComplicatedForType(type, ctx); + } const auto& rowType = GetSeqItemType(type); const auto getPrefix = [](TPartOfConstraintBase::TPathType path) { @@ -635,8 +678,9 @@ TSortedConstraintNode::DoGetSimplifiedForType(const TTypeAnnotationNode& type, T const auto prefix = getPrefix(it->first.front()); if (const auto subType = GetSubTypeByPath(prefix, rowType); it->first.front().back() == ctx.GetIndexAsString(0U) && ETypeAnnotationKind::Struct != subType->GetKind()) { auto from = it++; - for (auto i = 1U; content.cend() != it && it->first.size() == 1U && it->first.front().size() > 1U && ctx.GetIndexAsString(i) == it->first.front().back() && prefix == getPrefix(it->first.front()) && from->second == it->second; ++i) + for (auto i = 1U; content.cend() != it && it->first.size() == 1U && it->first.front().size() > 1U && ctx.GetIndexAsString(i) == it->first.front().back() && prefix == getPrefix(it->first.front()) && from->second == it->second; ++i) { ++it; + } if (ssize_t(GetElementsCount(subType)) == std::distance(from, it)) { *from = std::make_pair(TPartOfConstraintBase::TSetType{std::move(prefix)}, from->second); @@ -644,10 +688,12 @@ TSortedConstraintNode::DoGetSimplifiedForType(const TTypeAnnotationNode& type, T it = content.erase(from, it); changed = setChanged = true; } - } else + } else { ++it; - } else + } + } else { ++it; + } } } @@ -666,14 +712,16 @@ TChoppedConstraintNode::TChoppedConstraintNode(TExprContext& ctx, TSetOfSetsType Hash_ = MurmurHash<ui64>(&size, sizeof(size), Hash_); for (const auto& set : Sets_) { YQL_ENSURE(!set.empty()); - for (const auto& path : set) + for (const auto& path : set) { Hash_ = std::accumulate(path.cbegin(), path.cend(), Hash_, [](ui64 hash, const std::string_view& field) { return MurmurHash<ui64>(field.data(), field.size(), hash); }); + } } } TChoppedConstraintNode::TChoppedConstraintNode(TExprContext& ctx, const TSetType& keys) : TChoppedConstraintNode(ctx, MakeFullSet(keys)) -{} +{ +} TChoppedConstraintNode::TChoppedConstraintNode(TExprContext& ctx, const NYT::TNode& serialized) : TChoppedConstraintNode(ctx, NodeToSets(ctx, serialized)) @@ -694,8 +742,9 @@ TChoppedConstraintNode::TChoppedConstraintNode(TChoppedConstraintNode&& constr) TPartOfConstraintBase::TSetType TChoppedConstraintNode::GetFullSet() const { TSetType set; set.reserve(Sets_.size()); - for (const auto& key : Sets_) + for (const auto& key : Sets_) { set.insert_unique(key.cbegin(), key.cend()); + } return set; } @@ -730,10 +779,11 @@ void TChoppedConstraintNode::Out(IOutputStream& out) const { out.Write('('); bool first = true; for (const auto& path : set) { - if (first) + if (first) { first = false; - else + } else { out.Write(','); + } out << path; } out.Write(')'); @@ -761,21 +811,21 @@ bool TChoppedConstraintNode::Equals(const TSetType& prefix) const { auto set = prefix; for (const auto& key : Sets_) { bool found = false; - std::for_each(key.cbegin(), key.cend(), [&set, &found] (const TPathType& path) { + std::for_each(key.cbegin(), key.cend(), [&set, &found](const TPathType& path) { if (const auto it = set.find(path); set.cend() != it) { set.erase(it); found = true; } }); - if (!found) + if (!found) { return false; + } } return set.empty(); } - void TChoppedConstraintNode::FilterUncompleteReferences(TSetType& references) const { TSetType complete; complete.reserve(references.size()); @@ -789,8 +839,9 @@ void TChoppedConstraintNode::FilterUncompleteReferences(TSetType& references) co } } - if (!found) + if (!found) { break; + } } references = std::move(complete); @@ -805,19 +856,21 @@ const TChoppedConstraintNode* TChoppedConstraintNode::MakeCommon(const std::vect } TSetOfSetsType sets; - for (auto c: constraints) { + for (auto c : constraints) { if (const auto uniq = c->GetConstraint<TChoppedConstraintNode>()) { - if (sets.empty()) + if (sets.empty()) { sets = uniq->GetContent(); - else { + } else { TSetOfSetsType both; both.reserve(std::min(sets.size(), uniq->GetContent().size())); std::set_intersection(sets.cbegin(), sets.cend(), uniq->GetContent().cbegin(), uniq->GetContent().cend(), std::back_inserter(both)); if (both.empty()) { - if (!c->GetConstraint<TEmptyConstraintNode>()) + if (!c->GetConstraint<TEmptyConstraintNode>()) { return nullptr; - } else + } + } else { sets = std::move(both); + } } } else if (!c->GetConstraint<TEmptyConstraintNode>()) { return nullptr; @@ -829,22 +882,25 @@ const TChoppedConstraintNode* TChoppedConstraintNode::MakeCommon(const std::vect const TConstraintWithFieldsNode* TChoppedConstraintNode::DoFilterFields(TExprContext& ctx, const TPathFilter& predicate) const { - if (!predicate) + if (!predicate) { return this; + } TSetOfSetsType chopped; chopped.reserve(Sets_.size()); for (const auto& set : Sets_) { auto newSet = set; for (auto it = newSet.cbegin(); newSet.cend() != it;) { - if (predicate(*it)) + if (predicate(*it)) { ++it; - else + } else { it = newSet.erase(it); + } } - if (newSet.empty()) - return nullptr;; + if (newSet.empty()) { + return nullptr; + }; chopped.insert_unique(std::move(newSet)); } @@ -853,8 +909,9 @@ TChoppedConstraintNode::DoFilterFields(TExprContext& ctx, const TPathFilter& pre const TConstraintWithFieldsNode* TChoppedConstraintNode::DoRenameFields(TExprContext& ctx, const TPathReduce& reduce) const { - if (!reduce) + if (!reduce) { return this; + } TSetOfSetsType chopped; chopped.reserve(Sets_.size()); @@ -862,12 +919,14 @@ TChoppedConstraintNode::DoRenameFields(TExprContext& ctx, const TPathReduce& red TSetType newSet; newSet.reserve(set.size()); for (const auto& path : set) { - if (const auto& newPaths = reduce(path); !newPaths.empty()) + if (const auto& newPaths = reduce(path); !newPaths.empty()) { newSet.insert_unique(newPaths.cbegin(), newPaths.cend()); + } } - if (newSet.empty()) + if (newSet.empty()) { return nullptr; + } chopped.insert_unique(std::move(newSet)); } @@ -911,17 +970,19 @@ TChoppedConstraintNode::DoGetComplicatedForType(const TTypeAnnotationNode& type, } } - if (fields.empty()) + if (fields.empty()) { ++it; - else { + } else { changed = true; auto set = *it; - for (auto& path : set) + for (auto& path : set) { path.emplace_back(); + } for (it = sets.erase(it); !fields.empty(); fields.pop_front()) { auto paths = set; - for (auto& path : paths) + for (auto& path : paths) { path.back() = fields.front(); + } it = sets.insert_unique(std::move(paths)).first; } } @@ -932,8 +993,9 @@ TChoppedConstraintNode::DoGetComplicatedForType(const TTypeAnnotationNode& type, const TConstraintWithFieldsNode* TChoppedConstraintNode::DoGetSimplifiedForType(const TTypeAnnotationNode& type, TExprContext& ctx) const { - if (Sets_.size() == 1U && Sets_.front().size() == 1U && Sets_.front().front().empty()) + if (Sets_.size() == 1U && Sets_.front().size() == 1U && Sets_.front().front().empty()) { return DoGetComplicatedForType(type, ctx); + } const auto& rowType = GetSeqItemType(type); const auto getPrefix = [](TPartOfConstraintBase::TPathType path) { @@ -946,13 +1008,14 @@ TChoppedConstraintNode::DoGetSimplifiedForType(const TTypeAnnotationNode& type, for (bool setChanged = true; setChanged;) { setChanged = false; for (auto it = sets.begin(); sets.end() != it;) { - if (it->size() != 1U || it->front().size() <= 1U) + if (it->size() != 1U || it->front().size() <= 1U) { ++it; - else { + } else { auto from = it++; const auto prefix = getPrefix(from->front()); - while (sets.cend() != it && it->size() == 1U && it->front().size() > 1U && prefix == getPrefix(it->front())) + while (sets.cend() != it && it->size() == 1U && it->front().size() > 1U && prefix == getPrefix(it->front())) { ++it; + } if (ssize_t(GetElementsCount(GetSubTypeByPath(prefix, rowType))) == std::distance(from, it)) { *from++ = TPartOfConstraintBase::TSetType{std::move(prefix)}; @@ -968,7 +1031,7 @@ TChoppedConstraintNode::DoGetSimplifiedForType(const TTypeAnnotationNode& type, ////////////////////////////////////////////////////////////////////////////////////////////////////////////// -template<bool Distinct> +template <bool Distinct> TConstraintWithFieldsNode::TSetOfSetsType TUniqueConstraintNodeBase<Distinct>::ColumnsListToSets(const std::vector<std::string_view>& columns) { YQL_ENSURE(!columns.empty()); @@ -978,7 +1041,7 @@ TUniqueConstraintNodeBase<Distinct>::ColumnsListToSets(const std::vector<std::st return sets; } -template<bool Distinct> +template <bool Distinct> typename TUniqueConstraintNodeBase<Distinct>::TContentType TUniqueConstraintNodeBase<Distinct>::DedupSets(TContentType&& sets) { for (bool found = true; found && sets.size() > 1U;) { @@ -989,8 +1052,9 @@ TUniqueConstraintNodeBase<Distinct>::DedupSets(TContentType&& sets) { it = sets.erase(it); found = true; break; - } else + } else { ++it; + } } } } @@ -998,7 +1062,7 @@ TUniqueConstraintNodeBase<Distinct>::DedupSets(TContentType&& sets) { return std::move(sets); } -template<bool Distinct> +template <bool Distinct> typename TUniqueConstraintNodeBase<Distinct>::TContentType TUniqueConstraintNodeBase<Distinct>::MakeCommonContent(const TContentType& one, const TContentType& two) { TContentType both; @@ -1013,19 +1077,21 @@ TUniqueConstraintNodeBase<Distinct>::MakeCommonContent(const TContentType& one, TConstraintWithFieldsNode::TSetType set; set.reserve(std::min(setOne.size(), setTwo.size())); std::set_intersection(setOne.cbegin(), setOne.cend(), setTwo.cbegin(), setTwo.cend(), std::back_inserter(set)); - if (!set.empty()) + if (!set.empty()) { sets.insert_unique(std::move(set)); + } } } - if (sets.size() == setsOne.size()) + if (sets.size() == setsOne.size()) { both.insert_unique(std::move(sets)); + } } } } return both; } -template<bool Distinct> +template <bool Distinct> TUniqueConstraintNodeBase<Distinct>::TUniqueConstraintNodeBase(TExprContext& ctx, TContentType&& sets) : TBase(ctx, Name()) , Content_(DedupSets(std::move(sets))) @@ -1038,24 +1104,26 @@ TUniqueConstraintNodeBase<Distinct>::TUniqueConstraintNodeBase(TExprContext& ctx YQL_ENSURE(!TConstraintWithFieldsNode::HasDuplicates(sets)); for (const auto& set : sets) { YQL_ENSURE(!set.empty()); - for (const auto& path : set) + for (const auto& path : set) { TBase::Hash_ = std::accumulate(path.cbegin(), path.cend(), TBase::Hash_, [](ui64 hash, const std::string_view& field) { return MurmurHash<ui64>(field.data(), field.size(), hash); }); + } } } } -template<bool Distinct> +template <bool Distinct> TUniqueConstraintNodeBase<Distinct>::TUniqueConstraintNodeBase(TExprContext& ctx, const std::vector<std::string_view>& columns) : TUniqueConstraintNodeBase(ctx, TContentType{TPartOfConstraintBase::TSetOfSetsType{ColumnsListToSets(columns)}}) -{} +{ +} -template<bool Distinct> +template <bool Distinct> TUniqueConstraintNodeBase<Distinct>::TUniqueConstraintNodeBase(TExprContext& ctx, const NYT::TNode& serialized) : TUniqueConstraintNodeBase(ctx, NodeToContent(ctx, serialized)) { } -template<bool Distinct> +template <bool Distinct> typename TUniqueConstraintNodeBase<Distinct>::TContentType TUniqueConstraintNodeBase<Distinct>::NodeToContent(TExprContext& ctx, const NYT::TNode& serialized) { TUniqueConstraintNode::TContentType content; try { @@ -1068,21 +1136,23 @@ typename TUniqueConstraintNodeBase<Distinct>::TContentType TUniqueConstraintNode return content; } -template<bool Distinct> +template <bool Distinct> TUniqueConstraintNodeBase<Distinct>::TUniqueConstraintNodeBase(TUniqueConstraintNodeBase&& constr) = default; -template<bool Distinct> +template <bool Distinct> TPartOfConstraintBase::TSetType TUniqueConstraintNodeBase<Distinct>::GetFullSet() const { TPartOfConstraintBase::TSetType set; set.reserve(Content_.size()); - for (const auto& sets : Content_) - for (const auto& key : sets) + for (const auto& sets : Content_) { + for (const auto& key : sets) { set.insert_unique(key.cbegin(), key.cend()); + } + } return set; } -template<bool Distinct> +template <bool Distinct> bool TUniqueConstraintNodeBase<Distinct>::Equals(const TConstraintNode& node) const { if (this == &node) { return true; @@ -1096,26 +1166,27 @@ bool TUniqueConstraintNodeBase<Distinct>::Equals(const TConstraintNode& node) co return false; } -template<bool Distinct> +template <bool Distinct> bool TUniqueConstraintNodeBase<Distinct>::Includes(const TConstraintNode& node) const { - if (this == &node) + if (this == &node) { return true; + } if (const auto c = dynamic_cast<const TUniqueConstraintNodeBase*>(&node)) { - return std::all_of(c->Content_.cbegin(), c->Content_.cend(), [&] (const TConstraintWithFieldsNode::TSetOfSetsType& oldSets) { - return std::any_of(Content_.cbegin(), Content_.cend(), [&] (const TConstraintWithFieldsNode::TSetOfSetsType& newSets) { - return oldSets.size() == newSets.size() && std::all_of(oldSets.cbegin(), oldSets.cend(), [&] (const TConstraintWithFieldsNode::TSetType& oldSet) { - return std::any_of(newSets.cbegin(), newSets.cend(), [&] (const TConstraintWithFieldsNode::TSetType& newSet) { - return std::includes(newSet.cbegin(), newSet.cend(), oldSet.cbegin(), oldSet.cend()); - }); - }); + return std::all_of(c->Content_.cbegin(), c->Content_.cend(), [&](const TConstraintWithFieldsNode::TSetOfSetsType& oldSets) { + return std::any_of(Content_.cbegin(), Content_.cend(), [&](const TConstraintWithFieldsNode::TSetOfSetsType& newSets) { + return oldSets.size() == newSets.size() && std::all_of(oldSets.cbegin(), oldSets.cend(), [&](const TConstraintWithFieldsNode::TSetType& oldSet) { + return std::any_of(newSets.cbegin(), newSets.cend(), [&](const TConstraintWithFieldsNode::TSetType& newSet) { + return std::includes(newSet.cbegin(), newSet.cend(), oldSet.cbegin(), oldSet.cend()); + }); + }); }); }); } return false; } -template<bool Distinct> +template <bool Distinct> void TUniqueConstraintNodeBase<Distinct>::Out(IOutputStream& out) const { TConstraintNode::Out(out); out.Write('('); @@ -1123,21 +1194,23 @@ void TUniqueConstraintNodeBase<Distinct>::Out(IOutputStream& out) const { out.Write('('); bool first = true; for (const auto& set : sets) { - if (first) + if (first) { first = false; - else + } else { out << ','; - if (1U == set.size()) + } + if (1U == set.size()) { out << set.front(); - else + } else { out << set; + } } out.Write(')'); } out.Write(')'); } -template<bool Distinct> +template <bool Distinct> void TUniqueConstraintNodeBase<Distinct>::ToJson(NJson::TJsonWriter& out) const { out.OpenArray(); for (const auto& sets : Content_) { @@ -1154,16 +1227,16 @@ void TUniqueConstraintNodeBase<Distinct>::ToJson(NJson::TJsonWriter& out) const out.CloseArray(); } -template<bool Distinct> +template <bool Distinct> NYT::TNode TUniqueConstraintNodeBase<Distinct>::ToYson() const { return std::accumulate(Content_.cbegin(), Content_.cend(), - NYT::TNode::CreateList(), - [](NYT::TNode node, const TConstraintWithFieldsNode::TSetOfSetsType& sets) { - return std::move(node).Add(TConstraintWithFieldsNode::SetOfSetsToNode(sets)); - }); + NYT::TNode::CreateList(), + [](NYT::TNode node, const TConstraintWithFieldsNode::TSetOfSetsType& sets) { + return std::move(node).Add(TConstraintWithFieldsNode::SetOfSetsToNode(sets)); + }); } -template<bool Distinct> +template <bool Distinct> const TUniqueConstraintNodeBase<Distinct>* TUniqueConstraintNodeBase<Distinct>::MakeCommon(const std::vector<const TConstraintSet*>& constraints, TExprContext& ctx) { if (constraints.empty()) { return nullptr; @@ -1173,16 +1246,18 @@ const TUniqueConstraintNodeBase<Distinct>* TUniqueConstraintNodeBase<Distinct>:: } TContentType content; - for (auto c: constraints) { + for (auto c : constraints) { if (const auto uniq = c->GetConstraint<TUniqueConstraintNodeBase>()) { - if (content.empty()) + if (content.empty()) { content = uniq->GetContent(); - else { + } else { if (auto both = MakeCommonContent(content, uniq->Content_); both.empty()) { - if (!c->GetConstraint<TEmptyConstraintNode>()) + if (!c->GetConstraint<TEmptyConstraintNode>()) { return nullptr; - } else + } + } else { content = std::move(both); + } } } else if (!c->GetConstraint<TEmptyConstraintNode>()) { return nullptr; @@ -1192,7 +1267,7 @@ const TUniqueConstraintNodeBase<Distinct>* TUniqueConstraintNodeBase<Distinct>:: return content.empty() ? nullptr : ctx.MakeConstraint<TUniqueConstraintNodeBase>(std::move(content)); } -template<bool Distinct> +template <bool Distinct> bool TUniqueConstraintNodeBase<Distinct>::IsOrderBy(const TSortedConstraintNode& sorted) const { TConstraintWithFieldsNode::TSetType ordered; TConstraintWithFieldsNode::TSetOfSetsType columns; @@ -1203,56 +1278,63 @@ bool TUniqueConstraintNodeBase<Distinct>::IsOrderBy(const TSortedConstraintNode& for (const auto& sets : Content_) { if (std::all_of(sets.cbegin(), sets.cend(), [&ordered](const TConstraintWithFieldsNode::TSetType& set) { - return std::any_of(set.cbegin(), set.cend(), [&ordered](const TConstraintWithFieldsNode::TPathType& path) { return ordered.contains(path); }); - })) { + return std::any_of(set.cbegin(), set.cend(), [&ordered](const TConstraintWithFieldsNode::TPathType& path) { return ordered.contains(path); }); + })) { std::for_each(sets.cbegin(), sets.cend(), [&columns](const TConstraintWithFieldsNode::TSetType& set) { std::for_each(set.cbegin(), set.cend(), [&columns](const TConstraintWithFieldsNode::TPathType& path) { - if (const auto it = std::find_if(columns.cbegin(), columns.cend(), [&path](const TConstraintWithFieldsNode::TSetType& s) { return s.contains(path); }); columns.cend() != it) + if (const auto it = std::find_if(columns.cbegin(), columns.cend(), [&path](const TConstraintWithFieldsNode::TSetType& s) { return s.contains(path); }); columns.cend() != it) { columns.erase(it); + } }); }); - if (columns.empty()) + if (columns.empty()) { return true; + } } } return false; } -template<bool Distinct> +template <bool Distinct> bool TUniqueConstraintNodeBase<Distinct>::ContainsCompleteSet(const std::vector<std::string_view>& columns) const { - if (columns.empty()) + if (columns.empty()) { return false; + } const std::unordered_set<std::string_view> ordered(columns.cbegin(), columns.cend()); for (const auto& sets : Content_) { if (std::all_of(sets.cbegin(), sets.cend(), [&ordered](const TConstraintWithFieldsNode::TSetType& set) { - return std::any_of(set.cbegin(), set.cend(), [&ordered](const TConstraintWithFieldsNode::TPathType& path) { return !path.empty() && ordered.contains(path.front()); }); - })) + return std::any_of(set.cbegin(), set.cend(), [&ordered](const TConstraintWithFieldsNode::TPathType& path) { return !path.empty() && ordered.contains(path.front()); }); + })) { return true; + } } return false; } -template<bool Distinct> +template <bool Distinct> void TUniqueConstraintNodeBase<Distinct>::FilterUncompleteReferences(TPartOfConstraintBase::TSetType& references) const { TPartOfConstraintBase::TSetType input(std::move(references)); references.clear(); references.reserve(input.size()); for (const auto& sets : Content_) { - if (std::all_of(sets.cbegin(), sets.cend(), [&input] (const TPartOfConstraintBase::TSetType& set) { return std::any_of(set.cbegin(), set.cend(), std::bind(&TPartOfConstraintBase::TSetType::contains<TPartOfConstraintBase::TPathType>, std::cref(input), std::placeholders::_1)); })) - std::for_each(sets.cbegin(), sets.cend(), [&] (const TPartOfConstraintBase::TSetType& set) { std::for_each(set.cbegin(), set.cend(), [&] (const TPartOfConstraintBase::TPathType& path) { - if (input.contains(path)) - references.insert_unique(path); - }); }); + if (std::all_of(sets.cbegin(), sets.cend(), [&input](const TPartOfConstraintBase::TSetType& set) { return std::any_of(set.cbegin(), set.cend(), std::bind(&TPartOfConstraintBase::TSetType::contains<TPartOfConstraintBase::TPathType>, std::cref(input), std::placeholders::_1)); })) { + std::for_each(sets.cbegin(), sets.cend(), [&](const TPartOfConstraintBase::TSetType& set) { std::for_each(set.cbegin(), set.cend(), [&](const TPartOfConstraintBase::TPathType& path) { + if (input.contains(path)) { + references.insert_unique(path); + } + }); }); + } } } -template<bool Distinct> +template <bool Distinct> const TConstraintWithFieldsNode* TUniqueConstraintNodeBase<Distinct>::DoFilterFields(TExprContext& ctx, const TPartOfConstraintBase::TPathFilter& predicate) const { - if (!predicate) + if (!predicate) { return this; + } TContentType content; content.reserve(Content_.size()); @@ -1272,11 +1354,12 @@ TUniqueConstraintNodeBase<Distinct>::DoFilterFields(TExprContext& ctx, const TPa return content.empty() ? nullptr : ctx.MakeConstraint<TUniqueConstraintNodeBase>(std::move(content)); } -template<bool Distinct> +template <bool Distinct> const TConstraintWithFieldsNode* TUniqueConstraintNodeBase<Distinct>::DoRenameFields(TExprContext& ctx, const TPartOfConstraintBase::TPathReduce& reduce) const { - if (!reduce) + if (!reduce) { return this; + } TContentType content; content.reserve(Content_.size()); @@ -1290,41 +1373,47 @@ TUniqueConstraintNodeBase<Distinct>::DoRenameFields(TExprContext& ctx, const TPa const auto newPaths = reduce(path); newSet.insert_unique(newPaths.cbegin(), newPaths.cend()); } - if (!newSet.empty()) - newSets.insert_unique(std::move(newSet)); + if (!newSet.empty()) { + newSets.insert_unique(std::move(newSet)); + } } - if (sets.size() == newSets.size()) + if (sets.size() == newSets.size()) { content.insert_unique(std::move(newSets)); + } } return content.empty() ? nullptr : ctx.MakeConstraint<TUniqueConstraintNodeBase>(std::move(content)); } -template<bool Distinct> +template <bool Distinct> const TUniqueConstraintNodeBase<Distinct>* TUniqueConstraintNodeBase<Distinct>::MakeCommon(const TUniqueConstraintNodeBase* other, TExprContext& ctx) const { - if (!other) + if (!other) { return nullptr; + } - if (this == other) + if (this == other) { return this; + } auto both = MakeCommonContent(Content_, other->Content_); return both.empty() ? nullptr : ctx.MakeConstraint<TUniqueConstraintNodeBase>(std::move(both)); } -template<bool Distinct> +template <bool Distinct> const TUniqueConstraintNodeBase<Distinct>* TUniqueConstraintNodeBase<Distinct>::Merge(const TUniqueConstraintNodeBase* one, const TUniqueConstraintNodeBase* two, TExprContext& ctx) { - if (!one) + if (!one) { return two; - if (!two) + } + if (!two) { return one; + } auto content = one->Content_; content.insert_unique(two->Content_.cbegin(), two->Content_.cend()); return ctx.MakeConstraint<TUniqueConstraintNodeBase<Distinct>>(std::move(content)); } -template<bool Distinct> +template <bool Distinct> const TConstraintWithFieldsNode* TUniqueConstraintNodeBase<Distinct>::DoGetComplicatedForType(const TTypeAnnotationNode& type, TExprContext& ctx) const { const auto& rowType = GetSeqItemType(type); @@ -1340,17 +1429,19 @@ TUniqueConstraintNodeBase<Distinct>::DoGetComplicatedForType(const TTypeAnnotati } } - if (fields.empty()) + if (fields.empty()) { ++it; - else { + } else { changed = true; auto set = *it; - for (auto& path : set) + for (auto& path : set) { path.emplace_back(); + } for (it = sets.erase(it); !fields.empty(); fields.pop_front()) { auto paths = set; - for (auto& path : paths) + for (auto& path : paths) { path.back() = fields.front(); + } it = sets.insert_unique(std::move(paths)).first; } } @@ -1360,11 +1451,12 @@ TUniqueConstraintNodeBase<Distinct>::DoGetComplicatedForType(const TTypeAnnotati return changed ? ctx.MakeConstraint<TUniqueConstraintNodeBase<Distinct>>(std::move(content)) : this; } -template<bool Distinct> +template <bool Distinct> const TConstraintWithFieldsNode* TUniqueConstraintNodeBase<Distinct>::DoGetSimplifiedForType(const TTypeAnnotationNode& type, TExprContext& ctx) const { - if (Content_.size() == 1U && Content_.front().size() == 1U && Content_.front().front().size() == 1U && Content_.front().front().front().empty()) + if (Content_.size() == 1U && Content_.front().size() == 1U && Content_.front().front().size() == 1U && Content_.front().front().front().empty()) { return DoGetComplicatedForType(type, ctx); + } const auto& rowType = GetSeqItemType(type); const auto getPrefix = [](TPartOfConstraintBase::TPathType path) { @@ -1388,22 +1480,24 @@ TUniqueConstraintNodeBase<Distinct>::DoGetSimplifiedForType(const TTypeAnnotatio } auto from = it++; - if (prefixes.size() < from->size()) + if (prefixes.size() < from->size()) { continue; + } while (sets.cend() != it && it->size() == prefixes.size() && - std::all_of(it->cbegin(), it->cend(), [&](const TPartOfConstraintBase::TPathType& path) { return path.size() > 1U && prefixes.contains(getPrefix(path)); })) { - ++it; + std::all_of(it->cbegin(), it->cend(), [&](const TPartOfConstraintBase::TPathType& path) { return path.size() > 1U && prefixes.contains(getPrefix(path)); })) { + ++it; } if (std::all_of(prefixes.cbegin(), prefixes.cend(), - [width = std::distance(from, it), &rowType] (const TPartOfConstraintBase::TPathType& path) { return width == ssize_t(GetElementsCount(TBase::GetSubTypeByPath(path, rowType))); })) { - *from++ =std::move(prefixes); + [width = std::distance(from, it), &rowType](const TPartOfConstraintBase::TPathType& path) { return width == ssize_t(GetElementsCount(TBase::GetSubTypeByPath(path, rowType))); })) { + *from++ = std::move(prefixes); it = sets.erase(from, it); changed = setChanged = true; } - } else + } else { ++it; + } } } } @@ -1411,10 +1505,11 @@ TUniqueConstraintNodeBase<Distinct>::DoGetSimplifiedForType(const TTypeAnnotatio return changed ? ctx.MakeConstraint<TUniqueConstraintNodeBase<Distinct>>(std::move(content)) : this; } -template<bool Distinct> +template <bool Distinct> bool TUniqueConstraintNodeBase<Distinct>::IsApplicableToType(const TTypeAnnotationNode& type) const { - if (ETypeAnnotationKind::Dict == type.GetKind()) + if (ETypeAnnotationKind::Dict == type.GetKind()) { return true; // TODO: check for dict. + } const auto& itemType = GetSeqItemType(type); return std::all_of(Content_.cbegin(), Content_.cend(), [&itemType](const TConstraintWithFieldsNode::TSetOfSetsType& sets) { return std::all_of(sets.cbegin(), sets.cend(), [&itemType](const TConstraintWithFieldsNode::TSetType& set) { @@ -1428,7 +1523,7 @@ template class TUniqueConstraintNodeBase<true>; ////////////////////////////////////////////////////////////////////////////////////////////////////////////// -template<class TOriginalConstraintNode> +template <class TOriginalConstraintNode> TPartOfConstraintNode<TOriginalConstraintNode>::TPartOfConstraintNode(TExprContext& ctx, TMapType&& mapping) : TBase(ctx, Name()) , Mapping_(std::move(mapping)) @@ -1438,24 +1533,24 @@ TPartOfConstraintNode<TOriginalConstraintNode>::TPartOfConstraintNode(TExprConte YQL_ENSURE(!part.second.empty()); const auto hash = part.first->GetHash(); TBase::Hash_ = MurmurHash<ui64>(&hash, sizeof(hash), TBase::Hash_); - for (const auto& item: part.second) { + for (const auto& item : part.second) { TBase::Hash_ = std::accumulate(item.first.cbegin(), item.first.cend(), TBase::Hash_, [](ui64 hash, const std::string_view& field) { return MurmurHash<ui64>(field.data(), field.size(), hash); }); TBase::Hash_ = std::accumulate(item.second.cbegin(), item.second.cend(), TBase::Hash_, [](ui64 hash, const std::string_view& field) { return MurmurHash<ui64>(field.data(), field.size(), hash); }); } } } -template<class TOriginalConstraintNode> +template <class TOriginalConstraintNode> TPartOfConstraintNode<TOriginalConstraintNode>::TPartOfConstraintNode(TExprContext& ctx, const NYT::TNode&) : TBase(ctx, Name()) { YQL_ENSURE(false, "TPartOfConstraintNode cannot be deserialized"); } -template<class TOriginalConstraintNode> +template <class TOriginalConstraintNode> TPartOfConstraintNode<TOriginalConstraintNode>::TPartOfConstraintNode(TPartOfConstraintNode&& constr) = default; -template<class TOriginalConstraintNode> +template <class TOriginalConstraintNode> bool TPartOfConstraintNode<TOriginalConstraintNode>::Equals(const TConstraintNode& node) const { if (this == &node) { return true; @@ -1469,7 +1564,7 @@ bool TPartOfConstraintNode<TOriginalConstraintNode>::Equals(const TConstraintNod return false; } -template<class TOriginalConstraintNode> +template <class TOriginalConstraintNode> bool TPartOfConstraintNode<TOriginalConstraintNode>::Includes(const TConstraintNode& node) const { if (this == &node) { return true; @@ -1482,25 +1577,27 @@ bool TPartOfConstraintNode<TOriginalConstraintNode>::Includes(const TConstraintN return false; } } - } else + } else { return false; + } } return true; } return false; } -template<class TOriginalConstraintNode> +template <class TOriginalConstraintNode> void TPartOfConstraintNode<TOriginalConstraintNode>::Out(IOutputStream& out) const { TConstraintNode::Out(out); out.Write('('); bool first = true; for (const auto& part : Mapping_) { for (const auto& item : part.second) { - if (first) + if (first) { first = false; - else + } else { out.Write(','); + } out << item.first; out.Write(':'); @@ -1510,7 +1607,7 @@ void TPartOfConstraintNode<TOriginalConstraintNode>::Out(IOutputStream& out) con out.Write(')'); } -template<class TOriginalConstraintNode> +template <class TOriginalConstraintNode> void TPartOfConstraintNode<TOriginalConstraintNode>::ToJson(NJson::TJsonWriter& out) const { out.OpenMap(); for (const auto& part : Mapping_) { @@ -1521,19 +1618,20 @@ void TPartOfConstraintNode<TOriginalConstraintNode>::ToJson(NJson::TJsonWriter& out.CloseMap(); } -template<class TOriginalConstraintNode> +template <class TOriginalConstraintNode> NYT::TNode TPartOfConstraintNode<TOriginalConstraintNode>::ToYson() const { return {}; // cannot be serialized } -template<class TOriginalConstraintNode> +template <class TOriginalConstraintNode> const TPartOfConstraintNode<TOriginalConstraintNode>* TPartOfConstraintNode<TOriginalConstraintNode>::ExtractField(TExprContext& ctx, const std::string_view& field) const { TMapType passtrought; for (const auto& part : Mapping_) { auto it = part.second.lower_bound(TPartOfConstraintBase::TPathType(1U, field)); - if (part.second.cend() == it || it->first.front() != field) + if (part.second.cend() == it || it->first.front() != field) { continue; + } TPartType mapping; mapping.reserve(part.second.size()); @@ -1550,34 +1648,38 @@ TPartOfConstraintNode<TOriginalConstraintNode>::ExtractField(TExprContext& ctx, return passtrought.empty() ? nullptr : ctx.MakeConstraint<TPartOfConstraintNode>(std::move(passtrought)); } -template<class TOriginalConstraintNode> +template <class TOriginalConstraintNode> const TPartOfConstraintBase* TPartOfConstraintNode<TOriginalConstraintNode>::DoFilterFields(TExprContext& ctx, const TPartOfConstraintBase::TPathFilter& predicate) const { - if (!predicate) + if (!predicate) { return this; + } auto mapping = Mapping_; for (auto part = mapping.begin(); mapping.end() != part;) { for (auto it = part->second.cbegin(); part->second.cend() != it;) { - if (predicate(it->first)) + if (predicate(it->first)) { ++it; - else + } else { it = part->second.erase(it); + } } - if (part->second.empty()) + if (part->second.empty()) { part = mapping.erase(part); - else + } else { ++part; + } } return mapping.empty() ? nullptr : ctx.MakeConstraint<TPartOfConstraintNode>(std::move(mapping)); } -template<class TOriginalConstraintNode> +template <class TOriginalConstraintNode> const TPartOfConstraintBase* TPartOfConstraintNode<TOriginalConstraintNode>::DoRenameFields(TExprContext& ctx, const TPartOfConstraintBase::TPathReduce& rename) const { - if (!rename) + if (!rename) { return this; + } TMapType mapping(Mapping_.size()); for (const auto& part : Mapping_) { @@ -1590,13 +1692,14 @@ TPartOfConstraintNode<TOriginalConstraintNode>::DoRenameFields(TExprContext& ctx } } - if (!map.empty()) + if (!map.empty()) { mapping.emplace(part.first, std::move(map)); + } } return mapping.empty() ? nullptr : ctx.MakeConstraint<TPartOfConstraintNode>(std::move(mapping)); } -template<class TOriginalConstraintNode> +template <class TOriginalConstraintNode> const TPartOfConstraintNode<TOriginalConstraintNode>* TPartOfConstraintNode<TOriginalConstraintNode>::CompleteOnly(TExprContext& ctx) const { TMapType mapping(Mapping_); @@ -1609,30 +1712,32 @@ TPartOfConstraintNode<TOriginalConstraintNode>::CompleteOnly(TExprContext& ctx) it->first->FilterUncompleteReferences(set); for (auto jt = it->second.cbegin(); it->second.cend() != jt;) { - if (set.contains(jt->second)) + if (set.contains(jt->second)) { ++jt; - else + } else { jt = it->second.erase(jt); + } } - if (it->second.empty()) + if (it->second.empty()) { it = mapping.erase(it); - else + } else { ++it; + } } return mapping.empty() ? nullptr : ctx.MakeConstraint<TPartOfConstraintNode>(std::move(mapping)); } -template<class TOriginalConstraintNode> +template <class TOriginalConstraintNode> const TPartOfConstraintNode<TOriginalConstraintNode>* -TPartOfConstraintNode<TOriginalConstraintNode>:: RemoveOriginal(TExprContext& ctx, const TMainConstraint* original) const { +TPartOfConstraintNode<TOriginalConstraintNode>::RemoveOriginal(TExprContext& ctx, const TMainConstraint* original) const { TMapType mapping(Mapping_); mapping.erase(original); return mapping.empty() ? nullptr : ctx.MakeConstraint<TPartOfConstraintNode>(std::move(mapping)); } -template<class TOriginalConstraintNode> +template <class TOriginalConstraintNode> typename TPartOfConstraintNode<TOriginalConstraintNode>::TMapType TPartOfConstraintNode<TOriginalConstraintNode>::GetColumnMapping(const std::string_view& asField) const { auto mapping = Mapping_; @@ -1646,7 +1751,7 @@ TPartOfConstraintNode<TOriginalConstraintNode>::GetColumnMapping(const std::stri return mapping; } -template<class TOriginalConstraintNode> +template <class TOriginalConstraintNode> typename TPartOfConstraintNode<TOriginalConstraintNode>::TMapType TPartOfConstraintNode<TOriginalConstraintNode>::GetColumnMapping(TExprContext& ctx, const std::string_view& prefix) const { auto mapping = Mapping_; @@ -1654,17 +1759,18 @@ TPartOfConstraintNode<TOriginalConstraintNode>::GetColumnMapping(TExprContext& c const TString str(prefix); for (auto& item : mapping) { for (auto& part : item.second) { - if (part.first.empty()) + if (part.first.empty()) { part.first.emplace_front(prefix); - else + } else { part.first.front() = ctx.AppendString(str + part.first.front()); + } } } } return mapping; } -template<class TOriginalConstraintNode> +template <class TOriginalConstraintNode> const TPartOfConstraintNode<TOriginalConstraintNode>* TPartOfConstraintNode<TOriginalConstraintNode>::MakeCommon(const std::vector<const TConstraintSet*>& constraints, TExprContext& ctx) { if (constraints.empty()) { @@ -1679,8 +1785,9 @@ TPartOfConstraintNode<TOriginalConstraintNode>::MakeCommon(const std::vector<con TMapType mapping; for (size_t i = 0; i < constraints.size(); ++i) { const auto part = constraints[i]->GetConstraint<TPartOfConstraintNode>(); - if (!part) + if (!part) { return nullptr; + } if (first) { mapping = part->GetColumnMapping(); first = false; @@ -1692,14 +1799,14 @@ TPartOfConstraintNode<TOriginalConstraintNode>::MakeCommon(const std::vector<con it->second.cbegin(), it->second.cend(), nextMapping.second.cbegin(), nextMapping.second.cend(), std::back_inserter(result), - [] (const typename TPartType::value_type& c1, const typename TPartType::value_type& c2) { + [](const typename TPartType::value_type& c1, const typename TPartType::value_type& c2) { return c1 < c2; - } - ); - if (result.empty()) + }); + if (result.empty()) { mapping.erase(it); - else + } else { it->second = std::move(result); + } } } } @@ -1711,13 +1818,13 @@ TPartOfConstraintNode<TOriginalConstraintNode>::MakeCommon(const std::vector<con return mapping.empty() ? nullptr : ctx.MakeConstraint<TPartOfConstraintNode>(std::move(mapping)); } -template<class TOriginalConstraintNode> +template <class TOriginalConstraintNode> const typename TPartOfConstraintNode<TOriginalConstraintNode>::TMapType& TPartOfConstraintNode<TOriginalConstraintNode>::GetColumnMapping() const { return Mapping_; } -template<class TOriginalConstraintNode> +template <class TOriginalConstraintNode> typename TPartOfConstraintNode<TOriginalConstraintNode>::TMapType TPartOfConstraintNode<TOriginalConstraintNode>::GetCommonMapping(const TOriginalConstraintNode* complete, const TPartOfConstraintNode* incomplete, const std::string_view& field) { TMapType mapping; @@ -1735,8 +1842,9 @@ TPartOfConstraintNode<TOriginalConstraintNode>::GetCommonMapping(const TOriginal auto& part = mapping[complete]; for (const auto& path : complete->GetFullSet()) { auto key = path; - if (!field.empty()) + if (!field.empty()) { key.emplace_front(field); + } part.insert_unique(std::make_pair(key, path)); } } @@ -1744,26 +1852,28 @@ TPartOfConstraintNode<TOriginalConstraintNode>::GetCommonMapping(const TOriginal return mapping; } -template<class TOriginalConstraintNode> +template <class TOriginalConstraintNode> void TPartOfConstraintNode<TOriginalConstraintNode>::UniqueMerge(TMapType& output, TMapType&& input) { output.merge(input); while (!input.empty()) { const auto exists = input.extract(input.cbegin()); auto& target = output[exists.key()]; target.reserve(target.size() + exists.mapped().size()); - for (auto& item : exists.mapped()) + for (auto& item : exists.mapped()) { target.insert_unique(std::move(item)); + } } } -template<class TOriginalConstraintNode> +template <class TOriginalConstraintNode> typename TPartOfConstraintNode<TOriginalConstraintNode>::TMapType TPartOfConstraintNode<TOriginalConstraintNode>::ExtractField(const TMapType& mapping, const std::string_view& field) { TMapType parts; for (const auto& part : mapping) { auto it = part.second.lower_bound(TPartOfConstraintBase::TPathType(1U, field)); - if (part.second.cend() == it || it->first.empty() || it->first.front() != field) + if (part.second.cend() == it || it->first.empty() || it->first.front() != field) { continue; + } TPartType mapping; mapping.reserve(part.second.size()); @@ -1780,20 +1890,22 @@ TPartOfConstraintNode<TOriginalConstraintNode>::ExtractField(const TMapType& map return parts; } -template<class TOriginalConstraintNode> +template <class TOriginalConstraintNode> const TOriginalConstraintNode* TPartOfConstraintNode<TOriginalConstraintNode>::MakeComplete(TExprContext& ctx, const TMapType& mapping, const TOriginalConstraintNode* original, const std::string_view& field) { if (const auto it = mapping.find(original); mapping.cend() != it) { TReversePartType reverseMap; reverseMap.reserve(it->second.size()); - for (const auto& map : it->second) + for (const auto& map : it->second) { reverseMap[map.second].insert_unique(map.first); + } const auto rename = [&](const TPartOfConstraintBase::TPathType& path) { const auto& set = reverseMap[path]; std::vector<TPartOfConstraintBase::TPathType> out(set.cbegin(), set.cend()); - if (!field.empty()) + if (!field.empty()) { std::for_each(out.begin(), out.end(), [&field](TPartOfConstraintBase::TPathType& path) { path.emplace_front(field); }); + } return out; }; @@ -1803,19 +1915,21 @@ TPartOfConstraintNode<TOriginalConstraintNode>::MakeComplete(TExprContext& ctx, return nullptr; } -template<class TOriginalConstraintNode> +template <class TOriginalConstraintNode> const TOriginalConstraintNode* TPartOfConstraintNode<TOriginalConstraintNode>::MakeComplete(TExprContext& ctx, const TPartOfConstraintNode* partial, const TOriginalConstraintNode* original, const std::string_view& field) { - if (!partial) + if (!partial) { return nullptr; + } return MakeComplete(ctx, partial->GetColumnMapping(), original, field); } -template<class TOriginalConstraintNode> +template <class TOriginalConstraintNode> bool TPartOfConstraintNode<TOriginalConstraintNode>::IsApplicableToType(const TTypeAnnotationNode& type) const { - if (ETypeAnnotationKind::Dict == type.GetKind()) + if (ETypeAnnotationKind::Dict == type.GetKind()) { return true; // TODO: check for dict. + } const auto itemType = GetSeqItemType(&type); const auto& actualType = itemType ? *itemType : type; @@ -1917,7 +2031,7 @@ TVarIndexConstraintNode::TVarIndexConstraintNode(TVarIndexConstraintNode&& const TVarIndexConstraintNode::TMapType TVarIndexConstraintNode::NodeToMapping(const NYT::TNode& serialized) { TMapType mapping; try { - for (const auto& pair: serialized.AsList()) { + for (const auto& pair : serialized.AsList()) { mapping.insert(std::make_pair<ui32, ui32>(pair.AsList().front().AsUint64(), pair.AsList().back().AsUint64())); } } catch (...) { @@ -1929,9 +2043,8 @@ TVarIndexConstraintNode::TMapType TVarIndexConstraintNode::NodeToMapping(const N TVarIndexConstraintNode::TMapType TVarIndexConstraintNode::GetReverseMapping() const { TMapType reverseMapping; std::transform(Mapping_.cbegin(), Mapping_.cend(), - std::back_inserter(reverseMapping), - [] (const std::pair<size_t, size_t>& p) { return std::make_pair(p.second, p.first); } - ); + std::back_inserter(reverseMapping), + [](const std::pair<size_t, size_t>& p) { return std::make_pair(p.second, p.first); }); ::Sort(reverseMapping); return reverseMapping; } @@ -1960,7 +2073,7 @@ bool TVarIndexConstraintNode::Includes(const TConstraintNode& node) const { return false; } if (auto c = dynamic_cast<const TVarIndexConstraintNode*>(&node)) { - for (auto& pair: c->Mapping_) { + for (auto& pair : c->Mapping_) { if (auto p = Mapping_.FindPtr(pair.first)) { if (*p != pair.second) { return false; @@ -1979,7 +2092,7 @@ void TVarIndexConstraintNode::Out(IOutputStream& out) const { out.Write('('); bool first = true; - for (auto& item: Mapping_) { + for (auto& item : Mapping_) { if (!first) { out.Write(','); } @@ -1991,7 +2104,7 @@ void TVarIndexConstraintNode::Out(IOutputStream& out) const { void TVarIndexConstraintNode::ToJson(NJson::TJsonWriter& out) const { out.OpenArray(); - for (const auto& [resultIndex, originalIndex]: Mapping_) { + for (const auto& [resultIndex, originalIndex] : Mapping_) { out.OpenArray(); out.Write(resultIndex); out.Write(originalIndex); @@ -2002,10 +2115,10 @@ void TVarIndexConstraintNode::ToJson(NJson::TJsonWriter& out) const { NYT::TNode TVarIndexConstraintNode::ToYson() const { return std::accumulate(Mapping_.cbegin(), Mapping_.cend(), - NYT::TNode::CreateList(), - [](NYT::TNode node, const TMapType::value_type& p) { - return std::move(node).Add(NYT::TNode::CreateList().Add(p.first).Add(p.second)); - }); + NYT::TNode::CreateList(), + [](NYT::TNode node, const TMapType::value_type& p) { + return std::move(node).Add(NYT::TNode::CreateList().Add(p.first).Add(p.second)); + }); } const TVarIndexConstraintNode* TVarIndexConstraintNode::MakeCommon(const std::vector<const TConstraintSet*>& constraints, TExprContext& ctx) { @@ -2037,9 +2150,9 @@ TMultiConstraintNode::TMultiConstraintNode(TExprContext& ctx, TMapType&& items) , Items_(std::move(items)) { YQL_ENSURE(Items_.size()); - for (auto& item: Items_) { + for (auto& item : Items_) { Hash_ = MurmurHash<ui64>(&item.first, sizeof(item.first), Hash_); - for (auto c: item.second.GetAllConstraints()) { + for (auto c : item.second.GetAllConstraints()) { const auto itemHash = c->GetHash(); Hash_ = MurmurHash<ui64>(&itemHash, sizeof(itemHash), Hash_); } @@ -2065,7 +2178,7 @@ TMultiConstraintNode::TMultiConstraintNode(TMultiConstraintNode&& constr) TMultiConstraintNode::TMapType TMultiConstraintNode::NodeToMapping(TExprContext& ctx, const NYT::TNode& serialized) { TMapType mapping; try { - for (const auto& pair: serialized.AsList()) { + for (const auto& pair : serialized.AsList()) { mapping.insert(std::make_pair((ui32)pair.AsList().front().AsUint64(), ctx.MakeConstraintSet(pair.AsList().back()))); } } catch (...) { @@ -2099,7 +2212,7 @@ bool TMultiConstraintNode::Includes(const TConstraintNode& node) const { } if (auto m = dynamic_cast<const TMultiConstraintNode*>(&node)) { - for (auto& item: Items_) { + for (auto& item : Items_) { const auto it = m->Items_.find(item.first); if (it == m->Items_.end()) { if (!item.second.GetConstraint<TEmptyConstraintNode>()) { @@ -2108,7 +2221,7 @@ bool TMultiConstraintNode::Includes(const TConstraintNode& node) const { continue; } - for (auto c: it->second.GetAllConstraints()) { + for (auto c : it->second.GetAllConstraints()) { auto cit = item.second.GetConstraint(c->GetName()); if (!cit) { return false; @@ -2132,7 +2245,7 @@ bool TMultiConstraintNode::FilteredIncludes(const TConstraintNode& node, const T } if (auto m = dynamic_cast<const TMultiConstraintNode*>(&node)) { - for (auto& item: Items_) { + for (auto& item : Items_) { const auto it = m->Items_.find(item.first); if (it == m->Items_.end()) { if (!item.second.GetConstraint<TEmptyConstraintNode>()) { @@ -2141,7 +2254,7 @@ bool TMultiConstraintNode::FilteredIncludes(const TConstraintNode& node, const T continue; } - for (auto c: it->second.GetAllConstraints()) { + for (auto c : it->second.GetAllConstraints()) { if (!blacklist.contains(c->GetName())) { const auto cit = item.second.GetConstraint(c->GetName()); if (!cit) { @@ -2162,13 +2275,13 @@ void TMultiConstraintNode::Out(IOutputStream& out) const { TConstraintNode::Out(out); out.Write('('); bool first = true; - for (auto& item: Items_) { + for (auto& item : Items_) { if (!first) { out.Write(','); } out << item.first << ':' << '{'; bool firstConstr = true; - for (auto c: item.second.GetAllConstraints()) { + for (auto c : item.second.GetAllConstraints()) { if (!firstConstr) { out.Write(','); } @@ -2192,10 +2305,10 @@ void TMultiConstraintNode::ToJson(NJson::TJsonWriter& out) const { NYT::TNode TMultiConstraintNode::ToYson() const { return std::accumulate(Items_.cbegin(), Items_.cend(), - NYT::TNode::CreateList(), - [](NYT::TNode node, const TMapType::value_type& p) { - return std::move(node).Add(NYT::TNode::CreateList().Add(p.first).Add(p.second.ToYson())); - }); + NYT::TNode::CreateList(), + [](NYT::TNode node, const TMapType::value_type& p) { + return std::move(node).Add(NYT::TNode::CreateList().Add(p.first).Add(p.second.ToYson())); + }); } const TMultiConstraintNode* TMultiConstraintNode::MakeCommon(const std::vector<const TConstraintSet*>& constraints, TExprContext& ctx) { @@ -2206,7 +2319,7 @@ const TMultiConstraintNode* TMultiConstraintNode::MakeCommon(const std::vector<c } TMapType multiItems; - for (auto c: constraints) { + for (auto c : constraints) { if (auto m = c->GetConstraint<TMultiConstraintNode>()) { multiItems.insert(m->GetItems().begin(), m->GetItems().end()); } else if (!c->GetConstraint<TEmptyConstraintNode>()) { @@ -2228,21 +2341,19 @@ const TMultiConstraintNode* TMultiConstraintNode::MakeCommon(const std::vector<c } while (cur != multiItems.end() && start->first == cur->first); switch (std::distance(start, cur)) { - case 0: - break; - case 1: - if (start->second.GetConstraint<TEmptyConstraintNode>()) { - cur = multiItems.erase(start, cur); - } - break; - default: - { + case 0: + break; + case 1: + if (start->second.GetConstraint<TEmptyConstraintNode>()) { + cur = multiItems.erase(start, cur); + } + break; + default: { std::vector<TMapType::value_type> nonEmpty; std::copy_if(start, cur, std::back_inserter(nonEmpty), - [] (const TMapType::value_type& v) { - return !v.second.GetConstraint<TEmptyConstraintNode>(); - } - ); + [](const TMapType::value_type& v) { + return !v.second.GetConstraint<TEmptyConstraintNode>(); + }); start->second.Clear(); if (nonEmpty.empty()) { start->second.AddConstraint(ctx.MakeConstraint<TEmptyConstraintNode>()); @@ -2275,111 +2386,114 @@ const TMultiConstraintNode* TMultiConstraintNode::FilterConstraints(TExprContext ////////////////////////////////////////////////////////////////////////////////////////////////////////////// -template<> +template <> void Out<NYql::TPartOfConstraintBase::TPathType>(IOutputStream& out, const NYql::TPartOfConstraintBase::TPathType& path) { - if (path.empty()) + if (path.empty()) { out.Write('/'); - else { + } else { bool first = true; for (const auto& c : path) { - if (first) + if (first) { first = false; - else + } else { out.Write('/'); + } out.Write(c); } } } -template<> +template <> void Out<NYql::TPartOfConstraintBase::TSetType>(IOutputStream& out, const NYql::TPartOfConstraintBase::TSetType& c) { out.Write('{'); bool first = true; for (const auto& path : c) { - if (first) + if (first) { first = false; - else + } else { out.Write(','); + } out << path; } out.Write('}'); } -template<> +template <> void Out<NYql::TPartOfConstraintBase::TSetOfSetsType>(IOutputStream& out, const NYql::TPartOfConstraintBase::TSetOfSetsType& c) { out.Write('{'); bool first = true; for (const auto& path : c) { - if (first) + if (first) { first = false; - else + } else { out.Write(','); + } out << path; } out.Write('}'); } -template<> +template <> void Out<NYql::TConstraintNode>(IOutputStream& out, const NYql::TConstraintNode& c) { c.Out(out); } -template<> +template <> void Out<NYql::TConstraintSet>(IOutputStream& out, const NYql::TConstraintSet& s) { s.Out(out); } -template<> +template <> void Out<NYql::TSortedConstraintNode>(IOutputStream& out, const NYql::TSortedConstraintNode& c) { c.Out(out); } -template<> +template <> void Out<NYql::TChoppedConstraintNode>(IOutputStream& out, const NYql::TChoppedConstraintNode& c) { c.Out(out); } -template<> +template <> void Out<NYql::TUniqueConstraintNode>(IOutputStream& out, const NYql::TUniqueConstraintNode& c) { c.Out(out); } -template<> +template <> void Out<NYql::TDistinctConstraintNode>(IOutputStream& out, const NYql::TDistinctConstraintNode& c) { c.Out(out); } -template<> +template <> void Out<NYql::TPartOfSortedConstraintNode>(IOutputStream& out, const NYql::TPartOfSortedConstraintNode& c) { c.Out(out); } -template<> +template <> void Out<NYql::TPartOfChoppedConstraintNode>(IOutputStream& out, const NYql::TPartOfChoppedConstraintNode& c) { c.Out(out); } -template<> +template <> void Out<NYql::TPartOfUniqueConstraintNode>(IOutputStream& out, const NYql::TPartOfUniqueConstraintNode& c) { c.Out(out); } -template<> +template <> void Out<NYql::TPartOfDistinctConstraintNode>(IOutputStream& out, const NYql::TPartOfDistinctConstraintNode& c) { c.Out(out); } -template<> +template <> void Out<NYql::TEmptyConstraintNode>(IOutputStream& out, const NYql::TEmptyConstraintNode& c) { c.Out(out); } -template<> +template <> void Out<NYql::TVarIndexConstraintNode>(IOutputStream& out, const NYql::TVarIndexConstraintNode& c) { c.Out(out); } -template<> +template <> void Out<NYql::TMultiConstraintNode>(IOutputStream& out, const NYql::TMultiConstraintNode& c) { c.Out(out); } |