yql_constraint.h 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563
  1. #pragma once
  2. #include <yql/essentials/utils/yql_panic.h>
  3. #include <library/cpp/containers/stack_vector/stack_vec.h>
  4. #include <library/cpp/containers/sorted_vector/sorted_vector.h>
  5. #include <library/cpp/json/json_writer.h>
  6. #include <library/cpp/yson/node/node_builder.h>
  7. #include <util/stream/output.h>
  8. #include <deque>
  9. #include <unordered_map>
  10. namespace NYql {
  11. struct TExprContext;
  12. class TTypeAnnotationNode;
  13. class TStructExprType;
  14. class TVariantExprType;
  15. class TConstraintNode {
  16. protected:
  17. TConstraintNode(TExprContext& ctx, std::string_view name);
  18. TConstraintNode(TConstraintNode&& constr);
  19. public:
  20. using TListType = std::vector<const TConstraintNode*>;
  21. struct THash {
  22. size_t operator()(const TConstraintNode* node) const {
  23. return node->GetHash();
  24. }
  25. };
  26. struct TEqual {
  27. bool operator()(const TConstraintNode* one, const TConstraintNode* two) const {
  28. return one->Equals(*two);
  29. }
  30. };
  31. struct TCompare {
  32. inline bool operator()(const TConstraintNode* l, const TConstraintNode* r) const {
  33. return l->GetName() < r->GetName();
  34. }
  35. inline bool operator()(const std::string_view name, const TConstraintNode* r) const {
  36. return name < r->GetName();
  37. }
  38. inline bool operator()(const TConstraintNode* l, const std::string_view name) const {
  39. return l->GetName() < name;
  40. }
  41. };
  42. virtual ~TConstraintNode() = default;
  43. ui64 GetHash() const {
  44. return Hash_;
  45. }
  46. virtual bool Equals(const TConstraintNode& node) const = 0;
  47. virtual bool Includes(const TConstraintNode& node) const {
  48. return Equals(node);
  49. }
  50. virtual void Out(IOutputStream& out) const;
  51. virtual void ToJson(NJson::TJsonWriter& out) const = 0;
  52. virtual NYT::TNode ToYson() const = 0;
  53. virtual bool IsApplicableToType(const TTypeAnnotationNode&) const { return true; }
  54. template <typename T>
  55. const T* Cast() const {
  56. static_assert(std::is_base_of<TConstraintNode, T>::value,
  57. "Should be derived from TConstraintNode");
  58. const auto ret = dynamic_cast<const T*>(this);
  59. YQL_ENSURE(ret, "Cannot cast '" << Name_ << "' constraint to " << T::Name());
  60. return ret;
  61. }
  62. const std::string_view& GetName() const {
  63. return Name_;
  64. }
  65. protected:
  66. ui64 Hash_;
  67. std::string_view Name_;
  68. };
  69. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  70. class TPartOfConstraintBase : public TConstraintNode {
  71. protected:
  72. TPartOfConstraintBase(TExprContext& ctx, std::string_view name);
  73. TPartOfConstraintBase(TPartOfConstraintBase&& constr) = default;
  74. public:
  75. // Path to constraint components through nested static containers (Struct/Tuple/Multi).
  76. // All elements is struct member name or tuple element index.
  77. // Empty deque means root.
  78. using TPathType = std::deque<std::string_view>;
  79. using TSetType = NSorted::TSimpleSet<TPathType>;
  80. using TSetOfSetsType = NSorted::TSimpleSet<TSetType>;
  81. using TPathFilter = std::function<bool(const TPathType&)>;
  82. using TPathReduce = std::function<std::vector<TPathType>(const TPathType&)>;
  83. static const TTypeAnnotationNode* GetSubTypeByPath(const TPathType& path, const TTypeAnnotationNode& type);
  84. static NYT::TNode PathToNode(const TPathType& path);
  85. static NYT::TNode SetToNode(const TSetType& set, bool withShortcut);
  86. static NYT::TNode SetOfSetsToNode(const TSetOfSetsType& sets);
  87. static TPathType NodeToPath(TExprContext& ctx, const NYT::TNode& node);
  88. static TSetType NodeToSet(TExprContext& ctx, const NYT::TNode& node);
  89. static TSetOfSetsType NodeToSetOfSets(TExprContext& ctx, const NYT::TNode& node);
  90. protected:
  91. virtual const TPartOfConstraintBase* DoFilterFields(TExprContext& ctx, const TPathFilter& predicate) const = 0;
  92. virtual const TPartOfConstraintBase* DoRenameFields(TExprContext& ctx, const TPathReduce& reduce) const = 0;
  93. static bool HasDuplicates(const TSetOfSetsType& sets);
  94. };
  95. class TConstraintWithFieldsNode : public TPartOfConstraintBase {
  96. protected:
  97. TConstraintWithFieldsNode(TExprContext& ctx, std::string_view name);
  98. TConstraintWithFieldsNode(TConstraintWithFieldsNode&& constr) = default;
  99. // Split fields with static containers (Struct/Tuple/Multi) on separeted list of all components.
  100. // As example (/tuple_of_two_elements) -> (/tuple_of_two_elements/0,/tuple_of_two_elements/1)
  101. virtual const TConstraintWithFieldsNode* DoGetComplicatedForType(const TTypeAnnotationNode& type, TExprContext& ctx) const = 0;
  102. // Combine list of separeted fields of static containers (Struct/Tuple/Multi) in single path if possible.
  103. // As example (/tuple_of_two_elements/0,/tuple_of_two_elements/1) -> (/tuple_of_two_elements)
  104. virtual const TConstraintWithFieldsNode* DoGetSimplifiedForType(const TTypeAnnotationNode& type, TExprContext& ctx) const = 0;
  105. public:
  106. // Leaves in the set of references only those that currently contain some complete constraint. Basically all or nothing.
  107. virtual void FilterUncompleteReferences(TPartOfConstraintBase::TSetType& references) const = 0;
  108. };
  109. template<class TTnheritConstraint>
  110. class TPartOfConstraintBaseT : public TPartOfConstraintBase {
  111. protected:
  112. TPartOfConstraintBaseT(TExprContext& ctx, std::string_view name)
  113. : TPartOfConstraintBase(ctx, name)
  114. {}
  115. TPartOfConstraintBaseT(TPartOfConstraintBaseT&& constr) = default;
  116. public:
  117. const TTnheritConstraint* FilterFields(TExprContext& ctx, const TPathFilter& predicate) const {
  118. return static_cast<const TTnheritConstraint*>(DoFilterFields(ctx, predicate));
  119. }
  120. const TTnheritConstraint* RenameFields(TExprContext& ctx, const TPathReduce& reduce) const {
  121. return static_cast<const TTnheritConstraint*>(DoRenameFields(ctx, reduce));
  122. }
  123. };
  124. template<class TTnheritConstraint>
  125. class TConstraintWithFieldsT : public TConstraintWithFieldsNode {
  126. protected:
  127. TConstraintWithFieldsT(TExprContext& ctx, std::string_view name)
  128. : TConstraintWithFieldsNode(ctx, name)
  129. {}
  130. TConstraintWithFieldsT(TConstraintWithFieldsT&& constr) = default;
  131. public:
  132. const TTnheritConstraint* FilterFields(TExprContext& ctx, const TPathFilter& predicate) const {
  133. return static_cast<const TTnheritConstraint*>(DoFilterFields(ctx, predicate));
  134. }
  135. const TTnheritConstraint* RenameFields(TExprContext& ctx, const TPathReduce& reduce) const {
  136. return static_cast<const TTnheritConstraint*>(DoRenameFields(ctx, reduce));
  137. }
  138. const TTnheritConstraint* GetComplicatedForType(const TTypeAnnotationNode& type, TExprContext& ctx) const {
  139. return static_cast<const TTnheritConstraint*>(DoGetComplicatedForType(type, ctx));
  140. }
  141. const TTnheritConstraint* GetSimplifiedForType(const TTypeAnnotationNode& type, TExprContext& ctx) const {
  142. return static_cast<const TTnheritConstraint*>(DoGetSimplifiedForType(type, ctx));
  143. }
  144. };
  145. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  146. class TConstraintSet {
  147. public:
  148. TConstraintSet() = default;
  149. TConstraintSet(const TConstraintSet&) = default;
  150. TConstraintSet(TConstraintSet&&) = default;
  151. TConstraintSet& operator =(const TConstraintSet&) = default;
  152. TConstraintSet& operator =(TConstraintSet&&) = default;
  153. template <class TConstraintType>
  154. const TConstraintType* GetConstraint() const {
  155. auto res = GetConstraint(TConstraintType::Name());
  156. return res ? res->template Cast<TConstraintType>() : nullptr;
  157. }
  158. template <class TConstraintType>
  159. const TConstraintType* RemoveConstraint() {
  160. auto res = RemoveConstraint(TConstraintType::Name());
  161. return res ? res->template Cast<TConstraintType>() : nullptr;
  162. }
  163. const TConstraintNode::TListType& GetAllConstraints() const {
  164. return Constraints_;
  165. }
  166. void Clear() {
  167. Constraints_.clear();
  168. }
  169. explicit operator bool() const {
  170. return !Constraints_.empty();
  171. }
  172. bool operator ==(const TConstraintSet& s) const {
  173. return Constraints_ == s.Constraints_;
  174. }
  175. bool operator !=(const TConstraintSet& s) const {
  176. return Constraints_ != s.Constraints_;
  177. }
  178. const TConstraintNode* GetConstraint(std::string_view name) const;
  179. void AddConstraint(const TConstraintNode* node);
  180. const TConstraintNode* RemoveConstraint(std::string_view name);
  181. using TPredicate = std::function<bool(const std::string_view& name)>;
  182. bool FilterConstraints(const TPredicate& predicate);
  183. void Out(IOutputStream& out) const;
  184. void ToJson(NJson::TJsonWriter& writer) const;
  185. NYT::TNode ToYson() const;
  186. private:
  187. TConstraintNode::TListType Constraints_;
  188. };
  189. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  190. class TSortedConstraintNode final: public TConstraintWithFieldsT<TSortedConstraintNode> {
  191. public:
  192. using TContainerType = TSmallVec<std::pair<TSetType, bool>>;
  193. private:
  194. friend struct TExprContext;
  195. TSortedConstraintNode(TExprContext& ctx, TContainerType&& content);
  196. TSortedConstraintNode(TExprContext& ctx, const NYT::TNode& serialized);
  197. TSortedConstraintNode(TSortedConstraintNode&& constr);
  198. public:
  199. static constexpr std::string_view Name() {
  200. return "Sorted";
  201. }
  202. const TContainerType& GetContent() const {
  203. return Content_;
  204. }
  205. TSetType GetFullSet() const;
  206. bool Equals(const TConstraintNode& node) const override;
  207. bool Includes(const TConstraintNode& node) const override;
  208. void Out(IOutputStream& out) const override;
  209. void ToJson(NJson::TJsonWriter& out) const override;
  210. NYT::TNode ToYson() const override;
  211. bool IsPrefixOf(const TSortedConstraintNode& node) const;
  212. bool StartsWith(const TSetType& prefix) const;
  213. const TSortedConstraintNode* CutPrefix(size_t newPrefixLength, TExprContext& ctx) const;
  214. void FilterUncompleteReferences(TSetType& references) const final;
  215. static const TSortedConstraintNode* MakeCommon(const std::vector<const TConstraintSet*>& constraints, TExprContext& ctx);
  216. const TSortedConstraintNode* MakeCommon(const TSortedConstraintNode* other, TExprContext& ctx) const;
  217. bool IsApplicableToType(const TTypeAnnotationNode& type) const override;
  218. private:
  219. const TConstraintWithFieldsNode* DoFilterFields(TExprContext& ctx, const TPathFilter& predicate) const final;
  220. const TConstraintWithFieldsNode* DoRenameFields(TExprContext& ctx, const TPathReduce& reduce) const final;
  221. const TConstraintWithFieldsNode* DoGetComplicatedForType(const TTypeAnnotationNode& type, TExprContext& ctx) const final;
  222. const TConstraintWithFieldsNode* DoGetSimplifiedForType(const TTypeAnnotationNode& type, TExprContext& ctx) const final;
  223. static TContainerType NodeToContainer(TExprContext& ctx, const NYT::TNode& serialized);
  224. TContainerType Content_;
  225. };
  226. class TChoppedConstraintNode final: public TConstraintWithFieldsT<TChoppedConstraintNode> {
  227. private:
  228. friend struct TExprContext;
  229. TChoppedConstraintNode(TExprContext& ctx, TSetOfSetsType&& sets);
  230. TChoppedConstraintNode(TExprContext& ctx, const TSetType& keys);
  231. TChoppedConstraintNode(TExprContext& ctx, const NYT::TNode& serialized);
  232. TChoppedConstraintNode(TChoppedConstraintNode&& constr);
  233. public:
  234. static constexpr std::string_view Name() {
  235. return "Chopped";
  236. }
  237. const TSetOfSetsType& GetContent() const { return Sets_; }
  238. TSetType GetFullSet() const;
  239. bool Equals(const TConstraintNode& node) const override;
  240. bool Includes(const TConstraintNode& node) const override;
  241. void Out(IOutputStream& out) const override;
  242. void ToJson(NJson::TJsonWriter& out) const override;
  243. NYT::TNode ToYson() const override;
  244. bool Equals(const TSetType& prefix) const;
  245. void FilterUncompleteReferences(TSetType& references) const final;
  246. static const TChoppedConstraintNode* MakeCommon(const std::vector<const TConstraintSet*>& constraints, TExprContext& ctx);
  247. const TChoppedConstraintNode* MakeCommon(const TChoppedConstraintNode* other, TExprContext& ctx) const;
  248. bool IsApplicableToType(const TTypeAnnotationNode& type) const override;
  249. private:
  250. const TConstraintWithFieldsNode* DoFilterFields(TExprContext& ctx, const TPathFilter& predicate) const final;
  251. const TConstraintWithFieldsNode* DoRenameFields(TExprContext& ctx, const TPathReduce& reduce) const final;
  252. const TConstraintWithFieldsNode* DoGetComplicatedForType(const TTypeAnnotationNode& type, TExprContext& ctx) const final;
  253. const TConstraintWithFieldsNode* DoGetSimplifiedForType(const TTypeAnnotationNode& type, TExprContext& ctx) const final;
  254. static TSetOfSetsType NodeToSets(TExprContext& ctx, const NYT::TNode& serialized);
  255. TSetOfSetsType Sets_;
  256. };
  257. template<bool Distinct>
  258. class TUniqueConstraintNodeBase final: public TConstraintWithFieldsT<TUniqueConstraintNodeBase<Distinct>> {
  259. public:
  260. using TBase = TConstraintWithFieldsT<TUniqueConstraintNodeBase<Distinct>>;
  261. using TContentType = NSorted::TSimpleSet<TConstraintWithFieldsNode::TSetOfSetsType>;
  262. protected:
  263. friend struct TExprContext;
  264. TUniqueConstraintNodeBase(TExprContext& ctx, const std::vector<std::string_view>& columns);
  265. TUniqueConstraintNodeBase(TExprContext& ctx, TContentType&& sets);
  266. TUniqueConstraintNodeBase(TExprContext& ctx, const NYT::TNode& serialized);
  267. TUniqueConstraintNodeBase(TUniqueConstraintNodeBase&& constr);
  268. public:
  269. static constexpr std::string_view Name() {
  270. return Distinct ? "Distinct" : "Unique";
  271. }
  272. const TContentType& GetContent() const { return Content_; }
  273. TPartOfConstraintBase::TSetType GetFullSet() const;
  274. bool Equals(const TConstraintNode& node) const override;
  275. bool Includes(const TConstraintNode& node) const override;
  276. void Out(IOutputStream& out) const override;
  277. void ToJson(NJson::TJsonWriter& out) const override;
  278. NYT::TNode ToYson() const override;
  279. bool IsOrderBy(const TSortedConstraintNode& sorted) const;
  280. bool ContainsCompleteSet(const std::vector<std::string_view>& columns) const;
  281. void FilterUncompleteReferences(TPartOfConstraintBase::TSetType& references) const final;
  282. static const TUniqueConstraintNodeBase* MakeCommon(const std::vector<const TConstraintSet*>& constraints, TExprContext& ctx);
  283. const TUniqueConstraintNodeBase* MakeCommon(const TUniqueConstraintNodeBase* other, TExprContext& ctx) const;
  284. static const TUniqueConstraintNodeBase* Merge(const TUniqueConstraintNodeBase* one, const TUniqueConstraintNodeBase* two, TExprContext& ctx);
  285. bool IsApplicableToType(const TTypeAnnotationNode& type) const override;
  286. private:
  287. const TConstraintWithFieldsNode* DoFilterFields(TExprContext& ctx, const TPartOfConstraintBase::TPathFilter& predicate) const final;
  288. const TConstraintWithFieldsNode* DoRenameFields(TExprContext& ctx, const TPartOfConstraintBase::TPathReduce& reduce) const final;
  289. const TConstraintWithFieldsNode* DoGetComplicatedForType(const TTypeAnnotationNode& type, TExprContext& ctx) const final;
  290. const TConstraintWithFieldsNode* DoGetSimplifiedForType(const TTypeAnnotationNode& type, TExprContext& ctx) const final;
  291. static TConstraintWithFieldsNode::TSetOfSetsType ColumnsListToSets(const std::vector<std::string_view>& columns);
  292. static TContentType DedupSets(TContentType&& sets);
  293. static TContentType MakeCommonContent(const TContentType& one, const TContentType& two);
  294. static TContentType NodeToContent(TExprContext& ctx, const NYT::TNode& serialized);
  295. TContentType Content_;
  296. };
  297. using TUniqueConstraintNode = TUniqueConstraintNodeBase<false>;
  298. using TDistinctConstraintNode = TUniqueConstraintNodeBase<true>;
  299. template<class TOriginalConstraintNode>
  300. class TPartOfConstraintNode final: public TPartOfConstraintBaseT<TPartOfConstraintNode<TOriginalConstraintNode>> {
  301. public:
  302. using TBase = TPartOfConstraintBaseT<TPartOfConstraintNode<TOriginalConstraintNode>>;
  303. using TMainConstraint = TOriginalConstraintNode;
  304. using TPartType = NSorted::TSimpleMap<typename TBase::TPathType, typename TBase::TPathType>;
  305. using TReversePartType = NSorted::TSimpleMap<typename TBase::TPathType, NSorted::TSimpleSet<typename TBase::TPathType>>;
  306. using TMapType = std::unordered_map<const TMainConstraint*, TPartType>;
  307. private:
  308. friend struct TExprContext;
  309. TPartOfConstraintNode(TPartOfConstraintNode&& constr);
  310. TPartOfConstraintNode(TExprContext& ctx, TMapType&& mapping);
  311. TPartOfConstraintNode(TExprContext& ctx, const NYT::TNode& serialized);
  312. public:
  313. static constexpr std::string_view Name();
  314. const TMapType& GetColumnMapping() const;
  315. TMapType GetColumnMapping(const std::string_view& asField) const;
  316. TMapType GetColumnMapping(TExprContext& ctx, const std::string_view& prefix) const;
  317. bool Equals(const TConstraintNode& node) const override;
  318. bool Includes(const TConstraintNode& node) const override;
  319. void Out(IOutputStream& out) const override;
  320. void ToJson(NJson::TJsonWriter& out) const override;
  321. NYT::TNode ToYson() const override;
  322. const TPartOfConstraintNode* ExtractField(TExprContext& ctx, const std::string_view& field) const;
  323. const TPartOfConstraintNode* CompleteOnly(TExprContext& ctx) const;
  324. const TPartOfConstraintNode* RemoveOriginal(TExprContext& ctx, const TMainConstraint* original) const;
  325. static const TPartOfConstraintNode* MakeCommon(const std::vector<const TConstraintSet*>& constraints, TExprContext& ctx);
  326. static TMapType GetCommonMapping(const TMainConstraint* complete, const TPartOfConstraintNode* incomplete = nullptr, const std::string_view& field = {});
  327. static void UniqueMerge(TMapType& output, TMapType&& input);
  328. static TMapType ExtractField(const TMapType& mapping, const std::string_view& field);
  329. static const TMainConstraint* MakeComplete(TExprContext& ctx, const TMapType& mapping, const TMainConstraint* original, const std::string_view& field = {});
  330. static const TMainConstraint* MakeComplete(TExprContext& ctx, const TPartOfConstraintNode* partial, const TMainConstraint* original, const std::string_view& field = {});
  331. bool IsApplicableToType(const TTypeAnnotationNode& type) const override;
  332. private:
  333. const TPartOfConstraintBase* DoFilterFields(TExprContext& ctx, const TPartOfConstraintBase::TPathFilter& predicate) const final;
  334. const TPartOfConstraintBase* DoRenameFields(TExprContext& ctx, const TPartOfConstraintBase::TPathReduce& reduce) const final;
  335. TMapType Mapping_;
  336. };
  337. using TPartOfSortedConstraintNode = TPartOfConstraintNode<TSortedConstraintNode>;
  338. using TPartOfChoppedConstraintNode = TPartOfConstraintNode<TChoppedConstraintNode>;
  339. using TPartOfUniqueConstraintNode = TPartOfConstraintNode<TUniqueConstraintNode>;
  340. using TPartOfDistinctConstraintNode = TPartOfConstraintNode<TDistinctConstraintNode>;
  341. template<>
  342. constexpr std::string_view TPartOfSortedConstraintNode::Name() {
  343. return "PartOfSorted";
  344. }
  345. template<>
  346. constexpr std::string_view TPartOfChoppedConstraintNode::Name() {
  347. return "PartOfChopped";
  348. }
  349. template<>
  350. constexpr std::string_view TPartOfUniqueConstraintNode::Name() {
  351. return "PartOfUnique";
  352. }
  353. template<>
  354. constexpr std::string_view TPartOfDistinctConstraintNode::Name() {
  355. return "PartOfDistinct";
  356. }
  357. class TEmptyConstraintNode final: public TConstraintNode {
  358. protected:
  359. friend struct TExprContext;
  360. TEmptyConstraintNode(TExprContext& ctx);
  361. TEmptyConstraintNode(TExprContext& ctx, const NYT::TNode& serialized);
  362. TEmptyConstraintNode(TEmptyConstraintNode&& constr);
  363. public:
  364. static constexpr std::string_view Name() {
  365. return "Empty";
  366. }
  367. bool Equals(const TConstraintNode& node) const override;
  368. void ToJson(NJson::TJsonWriter& out) const override;
  369. NYT::TNode ToYson() const override;
  370. static const TEmptyConstraintNode* MakeCommon(const std::vector<const TConstraintSet*>& constraints, TExprContext& ctx);
  371. };
  372. class TVarIndexConstraintNode final: public TConstraintNode {
  373. public:
  374. using TMapType = NSorted::TSimpleMap<ui32, ui32>;
  375. protected:
  376. friend struct TExprContext;
  377. TVarIndexConstraintNode(TExprContext& ctx, const TMapType& mapping);
  378. TVarIndexConstraintNode(TExprContext& ctx, const TVariantExprType& itemType);
  379. TVarIndexConstraintNode(TExprContext& ctx, size_t mapItemsCount);
  380. TVarIndexConstraintNode(TExprContext& ctx, const NYT::TNode& serialized);
  381. TVarIndexConstraintNode(TVarIndexConstraintNode&& constr);
  382. public:
  383. static constexpr std::string_view Name() {
  384. return "VarIndex";
  385. }
  386. // multimap: result index -> {original indices}
  387. const TMapType& GetIndexMapping() const {
  388. return Mapping_;
  389. }
  390. // original index -> {result indices}
  391. TMapType GetReverseMapping() const;
  392. bool Equals(const TConstraintNode& node) const override;
  393. bool Includes(const TConstraintNode& node) const override;
  394. void Out(IOutputStream& out) const override;
  395. void ToJson(NJson::TJsonWriter& out) const override;
  396. NYT::TNode ToYson() const override;
  397. static const TVarIndexConstraintNode* MakeCommon(const std::vector<const TConstraintSet*>& constraints, TExprContext& ctx);
  398. private:
  399. static TMapType NodeToMapping(const NYT::TNode& serialized);
  400. TMapType Mapping_;
  401. };
  402. class TMultiConstraintNode final: public TConstraintNode {
  403. public:
  404. using TMapType = NSorted::TSimpleMap<ui32, TConstraintSet>;
  405. public:
  406. TMultiConstraintNode(TExprContext& ctx, TMapType&& items);
  407. TMultiConstraintNode(TExprContext& ctx, ui32 index, const TConstraintSet& constraints);
  408. TMultiConstraintNode(TExprContext& ctx, const NYT::TNode& serialized);
  409. TMultiConstraintNode(TMultiConstraintNode&& constr);
  410. public:
  411. static constexpr std::string_view Name() {
  412. return "Multi";
  413. }
  414. const TMapType& GetItems() const {
  415. return Items_;
  416. }
  417. const TConstraintSet* GetItem(ui32 index) const {
  418. return Items_.FindPtr(index);
  419. }
  420. bool Equals(const TConstraintNode& node) const override;
  421. bool Includes(const TConstraintNode& node) const override;
  422. void Out(IOutputStream& out) const override;
  423. void ToJson(NJson::TJsonWriter& out) const override;
  424. NYT::TNode ToYson() const override;
  425. static const TMultiConstraintNode* MakeCommon(const std::vector<const TConstraintSet*>& constraints, TExprContext& ctx);
  426. const TMultiConstraintNode* FilterConstraints(TExprContext& ctx, const TConstraintSet::TPredicate& predicate) const;
  427. bool FilteredIncludes(const TConstraintNode& node, const THashSet<TString>& blacklist) const;
  428. private:
  429. static TMapType NodeToMapping(TExprContext& ctx, const NYT::TNode& serialized);
  430. TMapType Items_;
  431. };
  432. } // namespace NYql