123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468 |
- #pragma once
- #include <ydb/library/yql/utils/yql_panic.h>
- #include <library/cpp/containers/stack_vector/stack_vec.h>
- #include <library/cpp/containers/sorted_vector/sorted_vector.h>
- #include <library/cpp/json/json_writer.h>
- #include <util/generic/strbuf.h>
- #include <util/generic/string.h>
- #include <util/stream/output.h>
- #include <deque>
- #include <unordered_map>
- namespace NYql {
- struct TExprContext;
- class TTypeAnnotationNode;
- class TStructExprType;
- class TVariantExprType;
- class TConstraintNode {
- protected:
- TConstraintNode(TExprContext& ctx, std::string_view name);
- TConstraintNode(TConstraintNode&& constr);
- public:
- using TPathType = std::deque<std::string_view>;
- using TSetType = NSorted::TSimpleSet<TPathType>;
- using TListType = std::vector<const TConstraintNode*>;
- using TPathFilter = std::function<bool(const TPathType&)>;
- using TPathReduce = std::function<std::vector<TPathType>(const TPathType&)>;
- struct THash {
- size_t operator()(const TConstraintNode* node) const {
- return node->GetHash();
- }
- };
- struct TEqual {
- bool operator()(const TConstraintNode* one, const TConstraintNode* two) const {
- return one->Equals(*two);
- }
- };
- struct TCompare {
- inline bool operator()(const TConstraintNode* l, const TConstraintNode* r) const {
- return l->GetName() < r->GetName();
- }
- inline bool operator()(const std::string_view name, const TConstraintNode* r) const {
- return name < r->GetName();
- }
- inline bool operator()(const TConstraintNode* l, const std::string_view name) const {
- return l->GetName() < name;
- }
- };
- virtual ~TConstraintNode() = default;
- ui64 GetHash() const {
- return Hash_;
- }
- virtual bool Equals(const TConstraintNode& node) const = 0;
- virtual bool Includes(const TConstraintNode& node) const {
- return Equals(node);
- }
- virtual void Out(IOutputStream& out) const;
- virtual void ToJson(NJson::TJsonWriter& out) const = 0;
- virtual bool IsApplicableToType(const TTypeAnnotationNode&) const { return true; }
- virtual const TConstraintNode* OnlySimpleColumns(TExprContext&) const { return this; }
- template <typename T>
- const T* Cast() const {
- static_assert(std::is_base_of<TConstraintNode, T>::value,
- "Should be derived from TConstraintNode");
- const auto ret = dynamic_cast<const T*>(this);
- YQL_ENSURE(ret, "Cannot cast '" << Name_ << "' constraint to " << T::Name());
- return ret;
- }
- const std::string_view& GetName() const {
- return Name_;
- }
- static const TTypeAnnotationNode* GetSubTypeByPath(const TPathType& path, const TTypeAnnotationNode& type);
- protected:
- ui64 Hash_;
- std::string_view Name_;
- };
- //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- class TConstraintSet {
- public:
- TConstraintSet() = default;
- TConstraintSet(const TConstraintSet&) = default;
- TConstraintSet(TConstraintSet&&) = default;
- TConstraintSet& operator =(const TConstraintSet&) = default;
- TConstraintSet& operator =(TConstraintSet&&) = default;
- template <class TConstraintType>
- const TConstraintType* GetConstraint() const {
- auto res = GetConstraint(TConstraintType::Name());
- return res ? res->template Cast<TConstraintType>() : nullptr;
- }
- template <class TConstraintType>
- const TConstraintType* RemoveConstraint() {
- auto res = RemoveConstraint(TConstraintType::Name());
- return res ? res->template Cast<TConstraintType>() : nullptr;
- }
- const TConstraintNode::TListType& GetAllConstraints() const {
- return Constraints_;
- }
- void Clear() {
- Constraints_.clear();
- }
- explicit operator bool() const {
- return !Constraints_.empty();
- }
- bool operator ==(const TConstraintSet& s) const {
- return Constraints_ == s.Constraints_;
- }
- bool operator !=(const TConstraintSet& s) const {
- return Constraints_ != s.Constraints_;
- }
- const TConstraintNode* GetConstraint(std::string_view name) const;
- void AddConstraint(const TConstraintNode* node);
- const TConstraintNode* RemoveConstraint(std::string_view name);
- using TPredicate = std::function<bool(const std::string_view& name)>;
- bool FilterConstraints(const TPredicate& predicate);
- void ToJson(NJson::TJsonWriter& writer) const;
- private:
- TConstraintNode::TListType Constraints_;
- };
- //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- class TColumnSetConstraintNodeBase: public TConstraintNode {
- public:
- using TSetType = NSorted::TSimpleSet<TStringBuf>;
- protected:
- TColumnSetConstraintNodeBase(TExprContext& ctx, TStringBuf name, const TSetType& columns);
- TColumnSetConstraintNodeBase(TExprContext& ctx, TStringBuf name, const std::vector<TStringBuf>& columns);
- TColumnSetConstraintNodeBase(TExprContext& ctx, TStringBuf name, const std::vector<TString>& columns);
- TColumnSetConstraintNodeBase(TColumnSetConstraintNodeBase&& constr);
- public:
- const TSetType& GetColumns() const {
- return Columns_;
- }
- bool Equals(const TConstraintNode& node) const override;
- bool Includes(const TConstraintNode& node) const override;
- void Out(IOutputStream& out) const override;
- void ToJson(NJson::TJsonWriter& out) const override;
- protected:
- TSetType Columns_;
- };
- class TSortedConstraintNode final: public TConstraintNode {
- public:
- using TContainerType = TSmallVec<std::pair<TSetType, bool>>;
- using TFullSetType = NSorted::TSimpleSet<TSetType>;
- private:
- friend struct TExprContext;
- TSortedConstraintNode(TExprContext& ctx, TContainerType&& content);
- TSortedConstraintNode(TSortedConstraintNode&& constr);
- public:
- static constexpr std::string_view Name() {
- return "Sorted";
- }
- const TContainerType& GetContent() const {
- return Content_;
- }
- const TFullSetType GetAllSets() const;
- bool Equals(const TConstraintNode& node) const override;
- bool Includes(const TConstraintNode& node) const override;
- void Out(IOutputStream& out) const override;
- void ToJson(NJson::TJsonWriter& out) const override;
- bool IsPrefixOf(const TSortedConstraintNode& node) const;
- const TSortedConstraintNode* CutPrefix(size_t newPrefixLength, TExprContext& ctx) const;
- static const TSortedConstraintNode* MakeCommon(const std::vector<const TConstraintSet*>& constraints, TExprContext& ctx);
- const TSortedConstraintNode* MakeCommon(const TSortedConstraintNode* other, TExprContext& ctx) const;
- const TSortedConstraintNode* FilterFields(TExprContext& ctx, const TPathFilter& predicate) const;
- const TSortedConstraintNode* RenameFields(TExprContext& ctx, const TPathReduce& reduce) const;
- bool IsApplicableToType(const TTypeAnnotationNode& type) const override;
- const TConstraintNode* OnlySimpleColumns(TExprContext& ctx) const override;
- protected:
- TContainerType Content_;
- };
- template<bool Distinct>
- class TUniqueConstraintNodeBase final: public TConstraintNode {
- public:
- using TFullSetType = NSorted::TSimpleSet<TSetType>;
- protected:
- friend struct TExprContext;
- TUniqueConstraintNodeBase(TExprContext& ctx, const std::vector<std::string_view>& columns);
- TUniqueConstraintNodeBase(TExprContext& ctx, TFullSetType&& sets);
- TUniqueConstraintNodeBase(TUniqueConstraintNodeBase&& constr);
- public:
- static constexpr std::string_view Name() {
- return Distinct ? "Distinct" : "Unique";
- }
- const TFullSetType& GetAllSets() const { return Sets_; }
- bool Equals(const TConstraintNode& node) const override;
- bool Includes(const TConstraintNode& node) const override;
- void Out(IOutputStream& out) const override;
- void ToJson(NJson::TJsonWriter& out) const override;
- bool IsOrderBy(const TSortedConstraintNode& sorted) const;
- bool HasEqualColumns(const std::vector<std::string_view>& columns) const;
- static const TUniqueConstraintNodeBase* MakeCommon(const std::vector<const TConstraintSet*>& constraints, TExprContext& ctx);
- const TUniqueConstraintNodeBase* FilterFields(TExprContext& ctx, const TPathFilter& predicate) const;
- const TUniqueConstraintNodeBase* RenameFields(TExprContext& ctx, const TPathReduce& reduce) const;
- const TUniqueConstraintNodeBase* MakeCommon(const TUniqueConstraintNodeBase* other, TExprContext& ctx) const;
- bool IsApplicableToType(const TTypeAnnotationNode& type) const override;
- const TConstraintNode* OnlySimpleColumns(TExprContext& ctx) const override;
- private:
- static TSetType ColumnsListToSet(const std::vector<std::string_view>& columns);
- static TFullSetType DedupSets(TFullSetType&& sets);
- TFullSetType Sets_;
- };
- using TUniqueConstraintNode = TUniqueConstraintNodeBase<false>;
- using TDistinctConstraintNode = TUniqueConstraintNodeBase<true>;
- class TGroupByConstraintNode final: public TColumnSetConstraintNodeBase {
- protected:
- friend struct TExprContext;
- TGroupByConstraintNode(TExprContext& ctx, const std::vector<TStringBuf>& columns);
- TGroupByConstraintNode(TExprContext& ctx, const std::vector<TString>& columns);
- TGroupByConstraintNode(TExprContext& ctx, const TGroupByConstraintNode& constr, size_t prefixLength);
- TGroupByConstraintNode(TGroupByConstraintNode&& constr);
- size_t GetCommonPrefixLength(const TGroupByConstraintNode& node) const;
- public:
- static constexpr std::string_view Name() {
- return "GroupBy";
- }
- static const TGroupByConstraintNode* MakeCommon(const std::vector<const TConstraintSet*>& constraints, TExprContext& ctx);
- };
- template<class TOriginalConstraintNode>
- class TPartOfConstraintNode : public TConstraintNode {
- public:
- using TMainConstraint = TOriginalConstraintNode;
- using TPartType = NSorted::TSimpleMap<TPathType, TPathType>;
- using TReversePartType = NSorted::TSimpleMap<TPathType, NSorted::TSimpleSet<TPathType>>;
- using TMapType = std::unordered_map<const TMainConstraint*, TPartType>;
- private:
- friend struct TExprContext;
- TPartOfConstraintNode(TPartOfConstraintNode&& constr);
- TPartOfConstraintNode(TExprContext& ctx, TMapType&& mapping);
- public:
- static constexpr std::string_view Name();
- const TMapType& GetColumnMapping() const;
- TMapType GetColumnMapping(const std::string_view& asField) const;
- bool Equals(const TConstraintNode& node) const override;
- bool Includes(const TConstraintNode& node) const override;
- void Out(IOutputStream& out) const override;
- void ToJson(NJson::TJsonWriter& out) const override;
- const TPartOfConstraintNode* ExtractField(TExprContext& ctx, const std::string_view& field) const;
- const TPartOfConstraintNode* FilterFields(TExprContext& ctx, const TPathFilter& predicate) const;
- const TPartOfConstraintNode* RenameFields(TExprContext& ctx, const TPathReduce& reduce) const;
- static const TPartOfConstraintNode* MakeCommon(const std::vector<const TConstraintSet*>& constraints, TExprContext& ctx);
- static TMapType GetCommonMapping(const TMainConstraint* complete, const TPartOfConstraintNode* incomplete = nullptr, const std::string_view& field = {});
- static void UniqueMerge(TMapType& output, TMapType&& input);
- static TMapType ExtractField(const TMapType& mapping, const std::string_view& field);
- static const TMainConstraint* MakeComplete(TExprContext& ctx, const TMapType& mapping, const TMainConstraint* original);
- bool IsApplicableToType(const TTypeAnnotationNode& type) const override;
- private:
- TMapType Mapping_;
- };
- using TPartOfSortedConstraintNode = TPartOfConstraintNode<TSortedConstraintNode>;
- using TPartOfUniqueConstraintNode = TPartOfConstraintNode<TUniqueConstraintNode>;
- using TPartOfDistinctConstraintNode = TPartOfConstraintNode<TDistinctConstraintNode>;
- template<>
- constexpr std::string_view TPartOfSortedConstraintNode::Name() {
- return "PartOfSoted";
- }
- template<>
- constexpr std::string_view TPartOfUniqueConstraintNode::Name() {
- return "PartOfUnique";
- }
- template<>
- constexpr std::string_view TPartOfDistinctConstraintNode::Name() {
- return "PartOfDistinct";
- }
- class TPassthroughConstraintNode final: public TConstraintNode {
- public:
- using TPartType = NSorted::TSimpleMap<TPathType, std::string_view>;
- using TMapType = std::unordered_map<const TPassthroughConstraintNode*, TPartType>;
- using TReverseMapType = NSorted::TSimpleMap<std::string_view, std::string_view>;
- private:
- friend struct TExprContext;
- TPassthroughConstraintNode(TExprContext& ctx, const TStructExprType& itemType);
- TPassthroughConstraintNode(TExprContext& ctx, const ui32 width);
- TPassthroughConstraintNode(TPassthroughConstraintNode&& constr);
- TPassthroughConstraintNode(TExprContext& ctx, TMapType&& mapping);
- public:
- static constexpr std::string_view Name() {
- return "Passthrough";
- }
- const TMapType& GetColumnMapping() const;
- TReverseMapType GetReverseMapping() const;
- bool Equals(const TConstraintNode& node) const override;
- bool Includes(const TConstraintNode& node) const override;
- void Out(IOutputStream& out) const override;
- void ToJson(NJson::TJsonWriter& out) const override;
- const TPassthroughConstraintNode* ExtractField(TExprContext& ctx, const std::string_view& field) const;
- static const TPassthroughConstraintNode* MakeCommon(const std::vector<const TConstraintSet*>& constraints, TExprContext& ctx);
- const TPassthroughConstraintNode* MakeCommon(const TPassthroughConstraintNode* other, TExprContext& ctx) const;
- private:
- TMapType Mapping_;
- };
- class TEmptyConstraintNode final: public TConstraintNode {
- protected:
- friend struct TExprContext;
- TEmptyConstraintNode(TExprContext& ctx);
- TEmptyConstraintNode(TEmptyConstraintNode&& constr);
- public:
- static constexpr std::string_view Name() {
- return "Empty";
- }
- bool Equals(const TConstraintNode& node) const override;
- void ToJson(NJson::TJsonWriter& out) const override;
- static const TEmptyConstraintNode* MakeCommon(const std::vector<const TConstraintSet*>& constraints, TExprContext& ctx);
- };
- class TVarIndexConstraintNode final: public TConstraintNode {
- public:
- using TMapType = NSorted::TSimpleMap<ui32, ui32>;
- protected:
- friend struct TExprContext;
- TVarIndexConstraintNode(TExprContext& ctx, const TMapType& mapping);
- TVarIndexConstraintNode(TExprContext& ctx, const TVariantExprType& itemType);
- TVarIndexConstraintNode(TExprContext& ctx, size_t mapItemsCount);
- TVarIndexConstraintNode(TVarIndexConstraintNode&& constr);
- public:
- static constexpr std::string_view Name() {
- return "VarIndex";
- }
- // multimap: result index -> {original indices}
- const TMapType& GetIndexMapping() const {
- return Mapping_;
- }
- // original index -> {result indices}
- TMapType GetReverseMapping() const;
- bool Equals(const TConstraintNode& node) const override;
- bool Includes(const TConstraintNode& node) const override;
- void Out(IOutputStream& out) const override;
- void ToJson(NJson::TJsonWriter& out) const override;
- static const TVarIndexConstraintNode* MakeCommon(const std::vector<const TConstraintSet*>& constraints, TExprContext& ctx);
- private:
- TMapType Mapping_;
- };
- class TMultiConstraintNode: public TConstraintNode {
- public:
- struct TConstraintKey {
- TStringBuf operator()(const TConstraintNode* node) const {
- return node->GetName();
- }
- };
- using TMapType = NSorted::TSimpleMap<ui32, TConstraintSet>;
- public:
- TMultiConstraintNode(TExprContext& ctx, const TMapType& items);
- TMultiConstraintNode(TExprContext& ctx, ui32 index, const TConstraintSet& constraints);
- TMultiConstraintNode(TMultiConstraintNode&& constr);
- public:
- static constexpr std::string_view Name() {
- return "Multi";
- }
- const TMapType& GetItems() const {
- return Items_;
- }
- const TConstraintSet* GetItem(ui32 index) const {
- return Items_.FindPtr(index);
- }
- bool Equals(const TConstraintNode& node) const override;
- bool Includes(const TConstraintNode& node) const override;
- void Out(IOutputStream& out) const override;
- void ToJson(NJson::TJsonWriter& out) const override;
- static const TMultiConstraintNode* MakeCommon(const std::vector<const TConstraintSet*>& constraints, TExprContext& ctx);
- const TMultiConstraintNode* FilterConstraints(TExprContext& ctx, const TConstraintSet::TPredicate& predicate) const;
- bool FilteredIncludes(const TConstraintNode& node, const THashSet<TString>& blacklist) const;
- const TConstraintNode* OnlySimpleColumns(TExprContext& ctx) const override;
- protected:
- TMapType Items_;
- };
- } // namespace NYql
|