yql_constraint.h 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468
  1. #pragma once
  2. #include <ydb/library/yql/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 <util/generic/strbuf.h>
  7. #include <util/generic/string.h>
  8. #include <util/stream/output.h>
  9. #include <deque>
  10. #include <unordered_map>
  11. namespace NYql {
  12. struct TExprContext;
  13. class TTypeAnnotationNode;
  14. class TStructExprType;
  15. class TVariantExprType;
  16. class TConstraintNode {
  17. protected:
  18. TConstraintNode(TExprContext& ctx, std::string_view name);
  19. TConstraintNode(TConstraintNode&& constr);
  20. public:
  21. using TPathType = std::deque<std::string_view>;
  22. using TSetType = NSorted::TSimpleSet<TPathType>;
  23. using TListType = std::vector<const TConstraintNode*>;
  24. using TPathFilter = std::function<bool(const TPathType&)>;
  25. using TPathReduce = std::function<std::vector<TPathType>(const TPathType&)>;
  26. struct THash {
  27. size_t operator()(const TConstraintNode* node) const {
  28. return node->GetHash();
  29. }
  30. };
  31. struct TEqual {
  32. bool operator()(const TConstraintNode* one, const TConstraintNode* two) const {
  33. return one->Equals(*two);
  34. }
  35. };
  36. struct TCompare {
  37. inline bool operator()(const TConstraintNode* l, const TConstraintNode* r) const {
  38. return l->GetName() < r->GetName();
  39. }
  40. inline bool operator()(const std::string_view name, const TConstraintNode* r) const {
  41. return name < r->GetName();
  42. }
  43. inline bool operator()(const TConstraintNode* l, const std::string_view name) const {
  44. return l->GetName() < name;
  45. }
  46. };
  47. virtual ~TConstraintNode() = default;
  48. ui64 GetHash() const {
  49. return Hash_;
  50. }
  51. virtual bool Equals(const TConstraintNode& node) const = 0;
  52. virtual bool Includes(const TConstraintNode& node) const {
  53. return Equals(node);
  54. }
  55. virtual void Out(IOutputStream& out) const;
  56. virtual void ToJson(NJson::TJsonWriter& out) const = 0;
  57. virtual bool IsApplicableToType(const TTypeAnnotationNode&) const { return true; }
  58. virtual const TConstraintNode* OnlySimpleColumns(TExprContext&) const { return this; }
  59. template <typename T>
  60. const T* Cast() const {
  61. static_assert(std::is_base_of<TConstraintNode, T>::value,
  62. "Should be derived from TConstraintNode");
  63. const auto ret = dynamic_cast<const T*>(this);
  64. YQL_ENSURE(ret, "Cannot cast '" << Name_ << "' constraint to " << T::Name());
  65. return ret;
  66. }
  67. const std::string_view& GetName() const {
  68. return Name_;
  69. }
  70. static const TTypeAnnotationNode* GetSubTypeByPath(const TPathType& path, const TTypeAnnotationNode& type);
  71. protected:
  72. ui64 Hash_;
  73. std::string_view Name_;
  74. };
  75. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  76. class TConstraintSet {
  77. public:
  78. TConstraintSet() = default;
  79. TConstraintSet(const TConstraintSet&) = default;
  80. TConstraintSet(TConstraintSet&&) = default;
  81. TConstraintSet& operator =(const TConstraintSet&) = default;
  82. TConstraintSet& operator =(TConstraintSet&&) = default;
  83. template <class TConstraintType>
  84. const TConstraintType* GetConstraint() const {
  85. auto res = GetConstraint(TConstraintType::Name());
  86. return res ? res->template Cast<TConstraintType>() : nullptr;
  87. }
  88. template <class TConstraintType>
  89. const TConstraintType* RemoveConstraint() {
  90. auto res = RemoveConstraint(TConstraintType::Name());
  91. return res ? res->template Cast<TConstraintType>() : nullptr;
  92. }
  93. const TConstraintNode::TListType& GetAllConstraints() const {
  94. return Constraints_;
  95. }
  96. void Clear() {
  97. Constraints_.clear();
  98. }
  99. explicit operator bool() const {
  100. return !Constraints_.empty();
  101. }
  102. bool operator ==(const TConstraintSet& s) const {
  103. return Constraints_ == s.Constraints_;
  104. }
  105. bool operator !=(const TConstraintSet& s) const {
  106. return Constraints_ != s.Constraints_;
  107. }
  108. const TConstraintNode* GetConstraint(std::string_view name) const;
  109. void AddConstraint(const TConstraintNode* node);
  110. const TConstraintNode* RemoveConstraint(std::string_view name);
  111. using TPredicate = std::function<bool(const std::string_view& name)>;
  112. bool FilterConstraints(const TPredicate& predicate);
  113. void ToJson(NJson::TJsonWriter& writer) const;
  114. private:
  115. TConstraintNode::TListType Constraints_;
  116. };
  117. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  118. class TColumnSetConstraintNodeBase: public TConstraintNode {
  119. public:
  120. using TSetType = NSorted::TSimpleSet<TStringBuf>;
  121. protected:
  122. TColumnSetConstraintNodeBase(TExprContext& ctx, TStringBuf name, const TSetType& columns);
  123. TColumnSetConstraintNodeBase(TExprContext& ctx, TStringBuf name, const std::vector<TStringBuf>& columns);
  124. TColumnSetConstraintNodeBase(TExprContext& ctx, TStringBuf name, const std::vector<TString>& columns);
  125. TColumnSetConstraintNodeBase(TColumnSetConstraintNodeBase&& constr);
  126. public:
  127. const TSetType& GetColumns() const {
  128. return Columns_;
  129. }
  130. bool Equals(const TConstraintNode& node) const override;
  131. bool Includes(const TConstraintNode& node) const override;
  132. void Out(IOutputStream& out) const override;
  133. void ToJson(NJson::TJsonWriter& out) const override;
  134. protected:
  135. TSetType Columns_;
  136. };
  137. class TSortedConstraintNode final: public TConstraintNode {
  138. public:
  139. using TContainerType = TSmallVec<std::pair<TSetType, bool>>;
  140. using TFullSetType = NSorted::TSimpleSet<TSetType>;
  141. private:
  142. friend struct TExprContext;
  143. TSortedConstraintNode(TExprContext& ctx, TContainerType&& content);
  144. TSortedConstraintNode(TSortedConstraintNode&& constr);
  145. public:
  146. static constexpr std::string_view Name() {
  147. return "Sorted";
  148. }
  149. const TContainerType& GetContent() const {
  150. return Content_;
  151. }
  152. const TFullSetType GetAllSets() const;
  153. bool Equals(const TConstraintNode& node) const override;
  154. bool Includes(const TConstraintNode& node) const override;
  155. void Out(IOutputStream& out) const override;
  156. void ToJson(NJson::TJsonWriter& out) const override;
  157. bool IsPrefixOf(const TSortedConstraintNode& node) const;
  158. const TSortedConstraintNode* CutPrefix(size_t newPrefixLength, TExprContext& ctx) const;
  159. static const TSortedConstraintNode* MakeCommon(const std::vector<const TConstraintSet*>& constraints, TExprContext& ctx);
  160. const TSortedConstraintNode* MakeCommon(const TSortedConstraintNode* other, TExprContext& ctx) const;
  161. const TSortedConstraintNode* FilterFields(TExprContext& ctx, const TPathFilter& predicate) const;
  162. const TSortedConstraintNode* RenameFields(TExprContext& ctx, const TPathReduce& reduce) const;
  163. bool IsApplicableToType(const TTypeAnnotationNode& type) const override;
  164. const TConstraintNode* OnlySimpleColumns(TExprContext& ctx) const override;
  165. protected:
  166. TContainerType Content_;
  167. };
  168. template<bool Distinct>
  169. class TUniqueConstraintNodeBase final: public TConstraintNode {
  170. public:
  171. using TFullSetType = NSorted::TSimpleSet<TSetType>;
  172. protected:
  173. friend struct TExprContext;
  174. TUniqueConstraintNodeBase(TExprContext& ctx, const std::vector<std::string_view>& columns);
  175. TUniqueConstraintNodeBase(TExprContext& ctx, TFullSetType&& sets);
  176. TUniqueConstraintNodeBase(TUniqueConstraintNodeBase&& constr);
  177. public:
  178. static constexpr std::string_view Name() {
  179. return Distinct ? "Distinct" : "Unique";
  180. }
  181. const TFullSetType& GetAllSets() const { return Sets_; }
  182. bool Equals(const TConstraintNode& node) const override;
  183. bool Includes(const TConstraintNode& node) const override;
  184. void Out(IOutputStream& out) const override;
  185. void ToJson(NJson::TJsonWriter& out) const override;
  186. bool IsOrderBy(const TSortedConstraintNode& sorted) const;
  187. bool HasEqualColumns(const std::vector<std::string_view>& columns) const;
  188. static const TUniqueConstraintNodeBase* MakeCommon(const std::vector<const TConstraintSet*>& constraints, TExprContext& ctx);
  189. const TUniqueConstraintNodeBase* FilterFields(TExprContext& ctx, const TPathFilter& predicate) const;
  190. const TUniqueConstraintNodeBase* RenameFields(TExprContext& ctx, const TPathReduce& reduce) const;
  191. const TUniqueConstraintNodeBase* MakeCommon(const TUniqueConstraintNodeBase* other, TExprContext& ctx) const;
  192. bool IsApplicableToType(const TTypeAnnotationNode& type) const override;
  193. const TConstraintNode* OnlySimpleColumns(TExprContext& ctx) const override;
  194. private:
  195. static TSetType ColumnsListToSet(const std::vector<std::string_view>& columns);
  196. static TFullSetType DedupSets(TFullSetType&& sets);
  197. TFullSetType Sets_;
  198. };
  199. using TUniqueConstraintNode = TUniqueConstraintNodeBase<false>;
  200. using TDistinctConstraintNode = TUniqueConstraintNodeBase<true>;
  201. class TGroupByConstraintNode final: public TColumnSetConstraintNodeBase {
  202. protected:
  203. friend struct TExprContext;
  204. TGroupByConstraintNode(TExprContext& ctx, const std::vector<TStringBuf>& columns);
  205. TGroupByConstraintNode(TExprContext& ctx, const std::vector<TString>& columns);
  206. TGroupByConstraintNode(TExprContext& ctx, const TGroupByConstraintNode& constr, size_t prefixLength);
  207. TGroupByConstraintNode(TGroupByConstraintNode&& constr);
  208. size_t GetCommonPrefixLength(const TGroupByConstraintNode& node) const;
  209. public:
  210. static constexpr std::string_view Name() {
  211. return "GroupBy";
  212. }
  213. static const TGroupByConstraintNode* MakeCommon(const std::vector<const TConstraintSet*>& constraints, TExprContext& ctx);
  214. };
  215. template<class TOriginalConstraintNode>
  216. class TPartOfConstraintNode : public TConstraintNode {
  217. public:
  218. using TMainConstraint = TOriginalConstraintNode;
  219. using TPartType = NSorted::TSimpleMap<TPathType, TPathType>;
  220. using TReversePartType = NSorted::TSimpleMap<TPathType, NSorted::TSimpleSet<TPathType>>;
  221. using TMapType = std::unordered_map<const TMainConstraint*, TPartType>;
  222. private:
  223. friend struct TExprContext;
  224. TPartOfConstraintNode(TPartOfConstraintNode&& constr);
  225. TPartOfConstraintNode(TExprContext& ctx, TMapType&& mapping);
  226. public:
  227. static constexpr std::string_view Name();
  228. const TMapType& GetColumnMapping() const;
  229. TMapType GetColumnMapping(const std::string_view& asField) const;
  230. bool Equals(const TConstraintNode& node) const override;
  231. bool Includes(const TConstraintNode& node) const override;
  232. void Out(IOutputStream& out) const override;
  233. void ToJson(NJson::TJsonWriter& out) const override;
  234. const TPartOfConstraintNode* ExtractField(TExprContext& ctx, const std::string_view& field) const;
  235. const TPartOfConstraintNode* FilterFields(TExprContext& ctx, const TPathFilter& predicate) const;
  236. const TPartOfConstraintNode* RenameFields(TExprContext& ctx, const TPathReduce& reduce) const;
  237. static const TPartOfConstraintNode* MakeCommon(const std::vector<const TConstraintSet*>& constraints, TExprContext& ctx);
  238. static TMapType GetCommonMapping(const TMainConstraint* complete, const TPartOfConstraintNode* incomplete = nullptr, const std::string_view& field = {});
  239. static void UniqueMerge(TMapType& output, TMapType&& input);
  240. static TMapType ExtractField(const TMapType& mapping, const std::string_view& field);
  241. static const TMainConstraint* MakeComplete(TExprContext& ctx, const TMapType& mapping, const TMainConstraint* original);
  242. bool IsApplicableToType(const TTypeAnnotationNode& type) const override;
  243. private:
  244. TMapType Mapping_;
  245. };
  246. using TPartOfSortedConstraintNode = TPartOfConstraintNode<TSortedConstraintNode>;
  247. using TPartOfUniqueConstraintNode = TPartOfConstraintNode<TUniqueConstraintNode>;
  248. using TPartOfDistinctConstraintNode = TPartOfConstraintNode<TDistinctConstraintNode>;
  249. template<>
  250. constexpr std::string_view TPartOfSortedConstraintNode::Name() {
  251. return "PartOfSoted";
  252. }
  253. template<>
  254. constexpr std::string_view TPartOfUniqueConstraintNode::Name() {
  255. return "PartOfUnique";
  256. }
  257. template<>
  258. constexpr std::string_view TPartOfDistinctConstraintNode::Name() {
  259. return "PartOfDistinct";
  260. }
  261. class TPassthroughConstraintNode final: public TConstraintNode {
  262. public:
  263. using TPartType = NSorted::TSimpleMap<TPathType, std::string_view>;
  264. using TMapType = std::unordered_map<const TPassthroughConstraintNode*, TPartType>;
  265. using TReverseMapType = NSorted::TSimpleMap<std::string_view, std::string_view>;
  266. private:
  267. friend struct TExprContext;
  268. TPassthroughConstraintNode(TExprContext& ctx, const TStructExprType& itemType);
  269. TPassthroughConstraintNode(TExprContext& ctx, const ui32 width);
  270. TPassthroughConstraintNode(TPassthroughConstraintNode&& constr);
  271. TPassthroughConstraintNode(TExprContext& ctx, TMapType&& mapping);
  272. public:
  273. static constexpr std::string_view Name() {
  274. return "Passthrough";
  275. }
  276. const TMapType& GetColumnMapping() const;
  277. TReverseMapType GetReverseMapping() const;
  278. bool Equals(const TConstraintNode& node) const override;
  279. bool Includes(const TConstraintNode& node) const override;
  280. void Out(IOutputStream& out) const override;
  281. void ToJson(NJson::TJsonWriter& out) const override;
  282. const TPassthroughConstraintNode* ExtractField(TExprContext& ctx, const std::string_view& field) const;
  283. static const TPassthroughConstraintNode* MakeCommon(const std::vector<const TConstraintSet*>& constraints, TExprContext& ctx);
  284. const TPassthroughConstraintNode* MakeCommon(const TPassthroughConstraintNode* other, TExprContext& ctx) const;
  285. private:
  286. TMapType Mapping_;
  287. };
  288. class TEmptyConstraintNode final: public TConstraintNode {
  289. protected:
  290. friend struct TExprContext;
  291. TEmptyConstraintNode(TExprContext& ctx);
  292. TEmptyConstraintNode(TEmptyConstraintNode&& constr);
  293. public:
  294. static constexpr std::string_view Name() {
  295. return "Empty";
  296. }
  297. bool Equals(const TConstraintNode& node) const override;
  298. void ToJson(NJson::TJsonWriter& out) const override;
  299. static const TEmptyConstraintNode* MakeCommon(const std::vector<const TConstraintSet*>& constraints, TExprContext& ctx);
  300. };
  301. class TVarIndexConstraintNode final: public TConstraintNode {
  302. public:
  303. using TMapType = NSorted::TSimpleMap<ui32, ui32>;
  304. protected:
  305. friend struct TExprContext;
  306. TVarIndexConstraintNode(TExprContext& ctx, const TMapType& mapping);
  307. TVarIndexConstraintNode(TExprContext& ctx, const TVariantExprType& itemType);
  308. TVarIndexConstraintNode(TExprContext& ctx, size_t mapItemsCount);
  309. TVarIndexConstraintNode(TVarIndexConstraintNode&& constr);
  310. public:
  311. static constexpr std::string_view Name() {
  312. return "VarIndex";
  313. }
  314. // multimap: result index -> {original indices}
  315. const TMapType& GetIndexMapping() const {
  316. return Mapping_;
  317. }
  318. // original index -> {result indices}
  319. TMapType GetReverseMapping() const;
  320. bool Equals(const TConstraintNode& node) const override;
  321. bool Includes(const TConstraintNode& node) const override;
  322. void Out(IOutputStream& out) const override;
  323. void ToJson(NJson::TJsonWriter& out) const override;
  324. static const TVarIndexConstraintNode* MakeCommon(const std::vector<const TConstraintSet*>& constraints, TExprContext& ctx);
  325. private:
  326. TMapType Mapping_;
  327. };
  328. class TMultiConstraintNode: public TConstraintNode {
  329. public:
  330. struct TConstraintKey {
  331. TStringBuf operator()(const TConstraintNode* node) const {
  332. return node->GetName();
  333. }
  334. };
  335. using TMapType = NSorted::TSimpleMap<ui32, TConstraintSet>;
  336. public:
  337. TMultiConstraintNode(TExprContext& ctx, const TMapType& items);
  338. TMultiConstraintNode(TExprContext& ctx, ui32 index, const TConstraintSet& constraints);
  339. TMultiConstraintNode(TMultiConstraintNode&& constr);
  340. public:
  341. static constexpr std::string_view Name() {
  342. return "Multi";
  343. }
  344. const TMapType& GetItems() const {
  345. return Items_;
  346. }
  347. const TConstraintSet* GetItem(ui32 index) const {
  348. return Items_.FindPtr(index);
  349. }
  350. bool Equals(const TConstraintNode& node) const override;
  351. bool Includes(const TConstraintNode& node) const override;
  352. void Out(IOutputStream& out) const override;
  353. void ToJson(NJson::TJsonWriter& out) const override;
  354. static const TMultiConstraintNode* MakeCommon(const std::vector<const TConstraintSet*>& constraints, TExprContext& ctx);
  355. const TMultiConstraintNode* FilterConstraints(TExprContext& ctx, const TConstraintSet::TPredicate& predicate) const;
  356. bool FilteredIncludes(const TConstraintNode& node, const THashSet<TString>& blacklist) const;
  357. const TConstraintNode* OnlySimpleColumns(TExprContext& ctx) const override;
  358. protected:
  359. TMapType Items_;
  360. };
  361. } // namespace NYql