mkql_node.h 46 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677
  1. #pragma once
  2. #include "defs.h"
  3. #include "mkql_mem_info.h"
  4. #include "mkql_alloc.h"
  5. #include <yql/essentials/public/udf/udf_value.h>
  6. #include <util/generic/hash.h>
  7. #include <util/generic/hash_set.h>
  8. #include <util/generic/maybe.h>
  9. #include <library/cpp/deprecated/enum_codegen/enum_codegen.h>
  10. #include <stack>
  11. namespace NKikimr {
  12. namespace NMiniKQL {
  13. class TType;
  14. class INodeVisitor;
  15. class TNode;
  16. class TListLiteral;
  17. template <typename T>
  18. class TTaggedPointer {
  19. public:
  20. TTaggedPointer() {}
  21. TTaggedPointer(T* ptr, bool mark) {
  22. Y_DEBUG_ABORT_UNLESS((uintptr_t(ptr) & 1) == 0);
  23. Raw = (void*)(uintptr_t(ptr) | (mark ? 1 : 0));
  24. }
  25. T* GetPtr() const {
  26. return (T*)(uintptr_t(Raw) & ~uintptr_t(1));
  27. }
  28. bool GetMark() const {
  29. return (uintptr_t(Raw) & 1) != 0;
  30. }
  31. private:
  32. void* Raw;
  33. };
  34. struct TRuntimeNode {
  35. using TList = TSmallVec<TRuntimeNode>;
  36. TRuntimeNode()
  37. : Data(nullptr, true)
  38. {}
  39. TRuntimeNode(TNode* node, bool isImmediate)
  40. : Data(node, isImmediate)
  41. {}
  42. explicit operator bool() const {
  43. return Data.GetPtr();
  44. }
  45. ~TRuntimeNode() {}
  46. TType* GetRuntimeType() const;
  47. TType* GetStaticType() const;
  48. bool HasValue() const;
  49. TNode* GetValue() const;
  50. void Freeze();
  51. bool operator==(const TRuntimeNode& other) const;
  52. bool operator!=(const TRuntimeNode& other) const {
  53. return !(*this == other);
  54. }
  55. bool IsImmediate() const {
  56. return Data.GetMark();
  57. }
  58. TNode* GetNode() const {
  59. return Data.GetPtr();
  60. }
  61. TTaggedPointer<TNode> Data;
  62. };
  63. using TRuntimeNodePair = std::array<TRuntimeNode, 2U>;
  64. class TTypeEnvironment;
  65. class TNode : private TNonCopyable {
  66. friend class TTypeEnvironment;
  67. public:
  68. TType* GetType() const {
  69. return Type;
  70. }
  71. TType* GetGenericType() const {
  72. return Type;
  73. }
  74. // may be used only as temporary storage, should be zero before visitation
  75. ui64 GetCookie() const {
  76. return Cookie;
  77. }
  78. void SetCookie(ui64 cookie) {
  79. Cookie = cookie;
  80. }
  81. void Accept(INodeVisitor& visitor);
  82. bool Equals(const TNode& nodeToCompare) const;
  83. void UpdateLinks(const THashMap<TNode*, TNode*>& links);
  84. // replace map stored in cookies
  85. TNode* CloneOnCallableWrite(const TTypeEnvironment& env) const;
  86. void Freeze(const TTypeEnvironment& env);
  87. bool IsMergeable() const;
  88. protected:
  89. TNode(TType* type)
  90. : Type(type)
  91. , Cookie(0)
  92. {}
  93. TType* Type;
  94. ui64 Cookie;
  95. };
  96. class TTypeType;
  97. class TTypeEnvironment;
  98. // if kind is above 0xf, it must ends with 0x02 pattern (like Void)
  99. #define MKQL_TYPE_KINDS(XX) \
  100. XX(Type, 0) \
  101. XX(Variant, 1) \
  102. XX(Void, 2) \
  103. XX(Data, 3) \
  104. XX(Stream, 4) \
  105. XX(Struct, 5) \
  106. XX(List, 6) \
  107. XX(Optional, 7) \
  108. XX(Dict, 8) \
  109. XX(Callable, 9) \
  110. XX(Any, 10) \
  111. XX(Tuple, 11) \
  112. XX(Resource, 12) \
  113. XX(Flow, 13) \
  114. XX(Null, 14) \
  115. XX(ReservedKind, 15) \
  116. XX(EmptyList, 16 + 2) \
  117. XX(EmptyDict, 32 + 2) \
  118. XX(Tagged, 48 + 7) \
  119. XX(Block, 16 + 13) \
  120. XX(Pg, 16 + 3) \
  121. XX(Multi, 16 + 11)
  122. class TTypeBase : public TNode {
  123. public:
  124. enum class EKind : ui8 {
  125. MKQL_TYPE_KINDS(ENUM_VALUE_GEN)
  126. };
  127. inline EKind GetKind() const {
  128. return Kind;
  129. }
  130. bool IsSameType(const TTypeBase& typeToCompare) const;
  131. size_t CalcHash() const;
  132. TTypeBase(const TTypeBase& other)
  133. : TNode(other.Type)
  134. , Kind(other.Kind)
  135. , SupportsPresort(other.SupportsPresort)
  136. {}
  137. protected:
  138. TTypeBase(EKind kind, TTypeType* type, bool supportsPresort);
  139. TTypeBase()
  140. : TNode(nullptr)
  141. , Kind(EKind::Type)
  142. , SupportsPresort(false)
  143. {}
  144. const EKind Kind;
  145. const bool SupportsPresort;
  146. };
  147. class TType: public TTypeBase {
  148. protected:
  149. TType(EKind kind, TTypeType* type, bool supportsPresort)
  150. : TTypeBase(kind, type, supportsPresort)
  151. {}
  152. TType()
  153. : TTypeBase()
  154. {}
  155. public:
  156. static TStringBuf KindAsStr(EKind kind);
  157. TStringBuf GetKindAsStr() const;
  158. #define MKQL_KIND_ACCESSOR(name, value) \
  159. inline bool Is##name() const { return Kind == EKind::name; }
  160. MKQL_TYPE_KINDS(MKQL_KIND_ACCESSOR)
  161. #undef MKQL_KIND_ACCESSOR
  162. using TTypeBase::IsSameType;
  163. bool IsConvertableTo(const TType& typeToCompare, bool ignoreTagged = false) const;
  164. void Accept(INodeVisitor& visitor);
  165. void UpdateLinks(const THashMap<TNode*, TNode*>& links);
  166. TNode* CloneOnCallableWrite(const TTypeEnvironment& env) const;
  167. void Freeze(const TTypeEnvironment& env);
  168. bool IsPresortSupported() const {
  169. return SupportsPresort;
  170. }
  171. };
  172. class TTypeType : public TType {
  173. friend class TTypeEnvironment;
  174. friend class TType;
  175. public:
  176. using TType::IsSameType;
  177. bool IsSameType(const TTypeType& typeToCompare) const;
  178. size_t CalcHash() const;
  179. using TType::IsConvertableTo;
  180. bool IsConvertableTo(const TTypeType& typeToCompare, bool ignoreTagged = false) const;
  181. private:
  182. TTypeType()
  183. : TType()
  184. {
  185. }
  186. void DoUpdateLinks(const THashMap<TNode*, TNode*>& links);
  187. TNode* DoCloneOnCallableWrite(const TTypeEnvironment& env) const;
  188. void DoFreeze(const TTypeEnvironment& env);
  189. static TTypeType* Create(const TTypeEnvironment& env);
  190. };
  191. template <TType::EKind SingularKind>
  192. class TSingularType : public TType {
  193. friend class TTypeEnvironment;
  194. friend class TType;
  195. public:
  196. using TType::IsSameType;
  197. bool IsSameType(const TSingularType<SingularKind>& typeToCompare) const;
  198. size_t CalcHash() const;
  199. using TType::IsConvertableTo;
  200. bool IsConvertableTo(const TSingularType<SingularKind>& typeToCompare, bool ignoreTagged = false) const;
  201. private:
  202. TSingularType(TTypeType* type)
  203. : TType(SingularKind, type, true)
  204. {}
  205. void DoUpdateLinks(const THashMap<TNode*, TNode*>& links);
  206. TNode* DoCloneOnCallableWrite(const TTypeEnvironment& env) const;
  207. void DoFreeze(const TTypeEnvironment& env);
  208. static TSingularType<SingularKind>* Create(TTypeType* type, const TTypeEnvironment& env);
  209. };
  210. using TVoidType = TSingularType<TType::EKind::Void>;
  211. using TNullType = TSingularType<TType::EKind::Null>;
  212. using TEmptyListType = TSingularType<TType::EKind::EmptyList>;
  213. using TEmptyDictType = TSingularType<TType::EKind::EmptyDict>;
  214. template <TType::EKind SingularKind>
  215. TType* GetTypeOfSingular(const TTypeEnvironment& env);
  216. template <typename TLiteralType>
  217. TLiteralType* GetEmptyLiteral(const TTypeEnvironment& env);
  218. template <TType::EKind SingularKind>
  219. class TSingular : public TNode {
  220. friend class TTypeEnvironment;
  221. friend class TNode;
  222. public:
  223. TSingularType<SingularKind>* GetType() const {
  224. return static_cast<TSingularType<SingularKind>*>(GetGenericType());
  225. }
  226. private:
  227. TSingular(const TTypeEnvironment& env)
  228. : TNode(GetTypeOfSingular<SingularKind>(env))
  229. {}
  230. void DoUpdateLinks(const THashMap<TNode*, TNode*>& links);
  231. TNode* DoCloneOnCallableWrite(const TTypeEnvironment& env) const;
  232. void DoFreeze(const TTypeEnvironment& env);
  233. using TNode::Equals;
  234. bool Equals(const TSingular<SingularKind>& nodeToCompare) const;
  235. static TSingular<SingularKind>* Create(const TTypeEnvironment& env);
  236. };
  237. using TVoid = TSingular<TType::EKind::Void>;
  238. using TNull = TSingular<TType::EKind::Null>;
  239. using TEmptyList = TSingular<TType::EKind::EmptyList>;
  240. using TEmptyDict = TSingular<TType::EKind::EmptyDict>;
  241. class TDataLiteral;
  242. class TStructLiteral;
  243. class TListLiteral;
  244. class TOptionalLiteral;
  245. class TAnyType;
  246. class TTupleLiteral;
  247. class TResourceType;
  248. class TDataType;
  249. class TPgType;
  250. // A non-owning reference to internalized string
  251. // Created only by TTypeEnvironment::InternName
  252. class TInternName {
  253. public:
  254. TInternName()
  255. {}
  256. TInternName(const TInternName& other)
  257. : StrBuf(other.StrBuf)
  258. {}
  259. const TInternName& operator = (const TInternName& other) {
  260. StrBuf = other.StrBuf;
  261. return *this;
  262. }
  263. size_t Hash() const {
  264. return (size_t)StrBuf.data();
  265. }
  266. operator bool() const {
  267. return (bool)StrBuf;
  268. }
  269. const TStringBuf& Str() const {
  270. return StrBuf;
  271. }
  272. // Optimized comparison (only by pointer)
  273. bool operator == (const TInternName& other) const {
  274. Y_DEBUG_ABORT_UNLESS(StrBuf.data() != other.StrBuf.data() || StrBuf.size() == other.StrBuf.size(),
  275. "Lengths must be equal if pointers are equal");
  276. return StrBuf.data() == other.StrBuf.data();
  277. }
  278. bool operator != (const TInternName& other) const {
  279. return !this->operator ==(other);
  280. }
  281. // Regular comparison (by content)
  282. bool operator == (const TStringBuf& other) const {
  283. return StrBuf == other;
  284. }
  285. bool operator != (const TStringBuf& other) const {
  286. return !this->operator ==(other);
  287. }
  288. private:
  289. friend class TTypeEnvironment;
  290. explicit TInternName(const TStringBuf& strBuf)
  291. : StrBuf(strBuf)
  292. {}
  293. private:
  294. TStringBuf StrBuf;
  295. };
  296. }} // namespaces
  297. template <>
  298. struct THash<NKikimr::NMiniKQL::TInternName> {
  299. size_t operator ()(const NKikimr::NMiniKQL::TInternName& val) const {
  300. return val.Hash();
  301. }
  302. };
  303. namespace NKikimr {
  304. namespace NMiniKQL {
  305. class TTypeEnvironment : private TNonCopyable {
  306. public:
  307. explicit TTypeEnvironment(TScopedAlloc& alloc);
  308. ~TTypeEnvironment();
  309. template <typename T>
  310. T* Allocate() const {
  311. return (T*)Arena.Alloc(sizeof(T));
  312. }
  313. void* AllocateBuffer(ui64 size) const {
  314. return Arena.Alloc(size);
  315. }
  316. TInternName InternName(const TStringBuf& name) const;
  317. TTypeType* GetTypeOfTypeLazy() const;
  318. TVoidType* GetTypeOfVoidLazy() const;
  319. TVoid* GetVoidLazy() const;
  320. TNullType* GetTypeOfNullLazy() const;
  321. TNull* GetNullLazy() const;
  322. TEmptyListType* GetTypeOfEmptyListLazy() const;
  323. TEmptyList* GetEmptyListLazy() const;
  324. TEmptyDictType* GetTypeOfEmptyDictLazy() const;
  325. TEmptyDict* GetEmptyDictLazy() const;
  326. TStructLiteral* GetEmptyStructLazy() const;
  327. TListLiteral* GetListOfVoidLazy() const;
  328. TAnyType* GetAnyTypeLazy() const;
  329. TTupleLiteral* GetEmptyTupleLazy() const;
  330. TDataType* GetUi32Lazy() const;
  331. TDataType* GetUi64Lazy() const;
  332. std::vector<TNode*>& GetNodeStack() const;
  333. void ClearCookies() const;
  334. NUdf::TUnboxedValuePod NewStringValue(const NUdf::TStringRef& data) const {
  335. Y_DEBUG_ABORT_UNLESS(TlsAllocState);
  336. Y_DEBUG_ABORT_UNLESS(&Alloc.Ref() == TlsAllocState, "%s", (TStringBuilder()
  337. << "typeEnv's: " << Alloc.Ref().GetDebugInfo() << " Tls: " << TlsAllocState->GetDebugInfo()
  338. ).data());
  339. if (data.Size() > NUdf::TUnboxedValue::InternalBufferSize) {
  340. auto value = NewString(data.Size());
  341. std::memcpy(value.Data(), data.Data(), data.Size());
  342. return NUdf::TUnboxedValuePod(std::move(value));
  343. } else {
  344. return NUdf::TUnboxedValuePod::Embedded(data);
  345. }
  346. }
  347. TGuard<TScopedAlloc> BindAllocator() const {
  348. return Guard(Alloc);
  349. }
  350. TScopedAlloc& GetAllocator() const { return Alloc; }
  351. const NUdf::TStringValue& NewString(ui32 size) const {
  352. Y_DEBUG_ABORT_UNLESS(TlsAllocState);
  353. Y_DEBUG_ABORT_UNLESS(&Alloc.Ref() == TlsAllocState, "%s", (TStringBuilder()
  354. << "typeEnv's: " << Alloc.Ref().GetDebugInfo() << " Tls: " << TlsAllocState->GetDebugInfo()
  355. ).data());
  356. Strings.emplace(size);
  357. return Strings.top();
  358. }
  359. private:
  360. TScopedAlloc& Alloc;
  361. mutable TPagedArena Arena;
  362. mutable std::stack<NUdf::TStringValue> Strings;
  363. mutable THashSet<TStringBuf> NamesPool;
  364. mutable std::vector<TNode*> Stack;
  365. mutable TTypeType* TypeOfType = nullptr;
  366. mutable TVoidType* TypeOfVoid = nullptr;
  367. mutable TVoid* Void = nullptr;
  368. mutable TNullType* TypeOfNull = nullptr;
  369. mutable TNull* Null = nullptr;
  370. mutable TEmptyListType* TypeOfEmptyList = nullptr;
  371. mutable TEmptyList* EmptyList = nullptr;
  372. mutable TEmptyDictType* TypeOfEmptyDict = nullptr;
  373. mutable TEmptyDict* EmptyDict = nullptr;
  374. mutable TDataType* Ui32 = nullptr;
  375. mutable TDataType* Ui64 = nullptr;
  376. mutable TAnyType* AnyType = nullptr;
  377. mutable TStructLiteral* EmptyStruct = nullptr;
  378. mutable TTupleLiteral* EmptyTuple = nullptr;
  379. mutable TListLiteral* ListOfVoid = nullptr;
  380. };
  381. template <>
  382. inline TType* GetTypeOfSingular<TType::EKind::Void>(const TTypeEnvironment& env) {
  383. return env.GetTypeOfVoidLazy();
  384. }
  385. template <>
  386. inline TType* GetTypeOfSingular<TType::EKind::Null>(const TTypeEnvironment& env) {
  387. return env.GetTypeOfNullLazy();
  388. }
  389. template <>
  390. inline TType* GetTypeOfSingular<TType::EKind::EmptyList>(const TTypeEnvironment& env) {
  391. return env.GetTypeOfEmptyListLazy();
  392. }
  393. template <>
  394. inline TType* GetTypeOfSingular<TType::EKind::EmptyDict>(const TTypeEnvironment& env) {
  395. return env.GetTypeOfEmptyDictLazy();
  396. }
  397. template <>
  398. inline TTupleLiteral* GetEmptyLiteral(const TTypeEnvironment& env) {
  399. return env.GetEmptyTupleLazy();
  400. }
  401. class TDataType : public TType {
  402. friend class TType;
  403. public:
  404. static TDataType* Create(NUdf::TDataTypeId schemeType, const TTypeEnvironment& env);
  405. using TType::IsSameType;
  406. bool IsSameType(const TDataType& typeToCompare) const;
  407. size_t CalcHash() const;
  408. using TType::IsConvertableTo;
  409. bool IsConvertableTo(const TDataType& typeToCompare, bool ignoreTagged = false) const;
  410. NUdf::TDataTypeId GetSchemeType() const {
  411. return SchemeType;
  412. }
  413. TMaybe<NUdf::EDataSlot> GetDataSlot() const {
  414. return DataSlot;
  415. }
  416. protected:
  417. TDataType(NUdf::TDataTypeId schemeType, const TTypeEnvironment& env);
  418. void DoUpdateLinks(const THashMap<TNode*, TNode*>& links);
  419. TNode* DoCloneOnCallableWrite(const TTypeEnvironment& env) const;
  420. void DoFreeze(const TTypeEnvironment& env);
  421. private:
  422. const NUdf::TDataTypeId SchemeType;
  423. const TMaybe<NUdf::EDataSlot> DataSlot;
  424. };
  425. class TDataDecimalType : public TDataType {
  426. friend class TType;
  427. public:
  428. static TDataDecimalType* Create(ui8 precision, ui8 scale, const TTypeEnvironment& env);
  429. bool IsSameType(const TDataDecimalType& typeToCompare) const;
  430. size_t CalcHash() const;
  431. bool IsConvertableTo(const TDataDecimalType& typeToCompare, bool ignoreTagged = false) const;
  432. std::pair<ui8, ui8> GetParams() const;
  433. private:
  434. TDataDecimalType(ui8 precision, ui8 scale, const TTypeEnvironment& env);
  435. const ui8 Precision;
  436. const ui8 Scale;
  437. };
  438. class TDataLiteral : public TNode, private NUdf::TUnboxedValuePod {
  439. friend class TNode;
  440. public:
  441. static TDataLiteral* Create(const NUdf::TUnboxedValuePod& value, TDataType* type, const TTypeEnvironment& env);
  442. TDataType* GetType() const {
  443. return static_cast<TDataType*>(GetGenericType());
  444. }
  445. const NUdf::TUnboxedValuePod& AsValue() const {
  446. return *this;
  447. }
  448. private:
  449. TDataLiteral(const NUdf::TUnboxedValuePod& value, TDataType* type);
  450. using TNode::Equals;
  451. bool Equals(const TDataLiteral& nodeToCompare) const;
  452. void DoUpdateLinks(const THashMap<TNode*, TNode*>& links);
  453. TNode* DoCloneOnCallableWrite(const TTypeEnvironment& env) const;
  454. void DoFreeze(const TTypeEnvironment& env);
  455. };
  456. class TPgType : public TType {
  457. friend class TType;
  458. public:
  459. static TPgType* Create(ui32 typeId, const TTypeEnvironment& env);
  460. using TType::IsSameType;
  461. bool IsSameType(const TPgType& typeToCompare) const;
  462. size_t CalcHash() const;
  463. using TType::IsConvertableTo;
  464. bool IsConvertableTo(const TPgType& typeToCompare, bool ignoreTagged = false) const;
  465. ui32 GetTypeId() const {
  466. return TypeId;
  467. }
  468. const TString& GetName() const;
  469. protected:
  470. TPgType(ui32 typeId, const TTypeEnvironment& env);
  471. void DoUpdateLinks(const THashMap<TNode*, TNode*>& links);
  472. TNode* DoCloneOnCallableWrite(const TTypeEnvironment& env) const;
  473. void DoFreeze(const TTypeEnvironment& env);
  474. private:
  475. const ui32 TypeId;
  476. };
  477. struct TStructMember {
  478. TStructMember()
  479. : Type(nullptr)
  480. , Index(nullptr)
  481. {
  482. }
  483. TStructMember(const TStringBuf& name, TType* type, ui32* index = nullptr)
  484. : Name(name)
  485. , Type(type)
  486. , Index(index)
  487. {
  488. }
  489. bool operator<(const TStructMember& rhs) const {
  490. return Name < rhs.Name;
  491. }
  492. TStringBuf Name;
  493. TType* Type;
  494. ui32* Index;
  495. };
  496. class TStructType : public TType {
  497. friend class TType;
  498. public:
  499. static TStructType* Create(const std::pair<TString, TType*>* members, ui32 membersCount, const TTypeEnvironment& env);
  500. static TStructType* Create(ui32 membersCount, const TStructMember* members, const TTypeEnvironment& env);
  501. using TType::IsSameType;
  502. bool IsSameType(const TStructType& typeToCompare) const;
  503. size_t CalcHash() const;
  504. using TType::IsConvertableTo;
  505. bool IsConvertableTo(const TStructType& typeToCompare, bool ignoreTagged = false) const;
  506. ui32 GetMembersCount() const {
  507. return MembersCount;
  508. }
  509. TStringBuf GetMemberName(ui32 index) const {
  510. Y_DEBUG_ABORT_UNLESS(index < MembersCount);
  511. return Members[index].first.Str();
  512. }
  513. TInternName GetMemberNameStr(ui32 index) const {
  514. Y_DEBUG_ABORT_UNLESS(index < MembersCount);
  515. return Members[index].first;
  516. }
  517. TType* GetMemberType(ui32 index) const {
  518. Y_DEBUG_ABORT_UNLESS(index < MembersCount);
  519. return Members[index].second;
  520. }
  521. ui32 GetMemberIndex(const TStringBuf& name) const;
  522. TMaybe<ui32> FindMemberIndex(const TStringBuf& name) const;
  523. private:
  524. TStructType(ui32 membersCount, std::pair<TInternName, TType*>* members, const TTypeEnvironment& env, bool validate = true);
  525. void DoUpdateLinks(const THashMap<TNode*, TNode*>& links);
  526. TNode* DoCloneOnCallableWrite(const TTypeEnvironment& env) const;
  527. void DoFreeze(const TTypeEnvironment& env);
  528. static bool CalculatePresortSupport(ui32 membersCount, std::pair<TInternName, TType*>* members);
  529. private:
  530. ui32 MembersCount;
  531. std::pair<TInternName, TType*>* Members;
  532. };
  533. class TStructLiteral : public TNode {
  534. friend class TNode;
  535. public:
  536. static TStructLiteral* Create(
  537. ui32 valuesCount, const TRuntimeNode* values, TStructType* type,
  538. const TTypeEnvironment& env, bool useCachedEmptyStruct = true);
  539. TStructType* GetType() const {
  540. return static_cast<TStructType*>(GetGenericType());
  541. }
  542. ui32 GetValuesCount() const {
  543. return GetType()->GetMembersCount();
  544. }
  545. TRuntimeNode GetValue(ui32 index) const {
  546. Y_DEBUG_ABORT_UNLESS(index < GetValuesCount());
  547. return Values[index];
  548. }
  549. private:
  550. TStructLiteral(TRuntimeNode* values, TStructType* type, bool validate = true);
  551. using TNode::Equals;
  552. bool Equals(const TStructLiteral& nodeToCompare) const;
  553. void DoUpdateLinks(const THashMap<TNode*, TNode*>& links);
  554. TNode* DoCloneOnCallableWrite(const TTypeEnvironment& env) const;
  555. void DoFreeze(const TTypeEnvironment& env);
  556. private:
  557. TRuntimeNode* Values;
  558. };
  559. class TListType : public TType {
  560. friend class TType;
  561. public:
  562. static TListType* Create(TType* itemType, const TTypeEnvironment& env);
  563. using TType::IsSameType;
  564. bool IsSameType(const TListType& typeToCompare) const;
  565. size_t CalcHash() const;
  566. using TType::IsConvertableTo;
  567. bool IsConvertableTo(const TListType& typeToCompare, bool ignoreTagged = false) const;
  568. TType* GetItemType() const {
  569. return Data;
  570. }
  571. TDataType* IndexDictKeyType() const {
  572. return IndexDictKey;
  573. }
  574. private:
  575. TListType(TType* itemType, const TTypeEnvironment& env, bool validate = true);
  576. void DoUpdateLinks(const THashMap<TNode*, TNode*>& links);
  577. TNode* DoCloneOnCallableWrite(const TTypeEnvironment& env) const;
  578. void DoFreeze(const TTypeEnvironment& env);
  579. private:
  580. TType* Data;
  581. TDataType* IndexDictKey;
  582. };
  583. class TListLiteral : public TNode {
  584. friend class TNode;
  585. public:
  586. static TListLiteral* Create(TRuntimeNode* items, ui32 count, TListType* type, const TTypeEnvironment& env);
  587. TListType* GetType() const {
  588. return static_cast<TListType*>(GetGenericType());
  589. }
  590. ui32 GetItemsCount() const {
  591. return Count;
  592. }
  593. TRuntimeNode* GetItems() const {
  594. return Items;
  595. }
  596. private:
  597. TListLiteral(TRuntimeNode* items, ui32 count, TListType* type, const TTypeEnvironment& env, bool validate = true);
  598. using TNode::Equals;
  599. bool Equals(const TListLiteral& nodeToCompare) const;
  600. void DoUpdateLinks(const THashMap<TNode*, TNode*>& links);
  601. TNode* DoCloneOnCallableWrite(const TTypeEnvironment& env) const;
  602. void DoFreeze(const TTypeEnvironment& env);
  603. private:
  604. TRuntimeNode* Items;
  605. ui32 Count;
  606. };
  607. class TStreamType : public TType {
  608. friend class TType;
  609. public:
  610. static TStreamType* Create(TType* itemType, const TTypeEnvironment& env);
  611. using TType::IsSameType;
  612. bool IsSameType(const TStreamType& typeToCompare) const;
  613. size_t CalcHash() const;
  614. using TType::IsConvertableTo;
  615. bool IsConvertableTo(const TStreamType& typeToCompare, bool ignoreTagged = false) const;
  616. TType* GetItemType() const {
  617. return Data;
  618. }
  619. private:
  620. TStreamType(TType* itemType, const TTypeEnvironment& env, bool validate = true);
  621. void DoUpdateLinks(const THashMap<TNode*, TNode*>& links);
  622. TNode* DoCloneOnCallableWrite(const TTypeEnvironment& env) const;
  623. void DoFreeze(const TTypeEnvironment& env);
  624. private:
  625. TType* Data;
  626. };
  627. class TFlowType : public TType {
  628. friend class TType;
  629. public:
  630. static TFlowType* Create(TType* itemType, const TTypeEnvironment& env);
  631. using TType::IsSameType;
  632. bool IsSameType(const TFlowType& typeToCompare) const;
  633. size_t CalcHash() const;
  634. using TType::IsConvertableTo;
  635. bool IsConvertableTo(const TFlowType& typeToCompare, bool ignoreTagged = false) const;
  636. TType* GetItemType() const {
  637. return Data;
  638. }
  639. private:
  640. TFlowType(TType* itemType, const TTypeEnvironment& env, bool validate = true);
  641. void DoUpdateLinks(const THashMap<TNode*, TNode*>& links);
  642. TNode* DoCloneOnCallableWrite(const TTypeEnvironment& env) const;
  643. void DoFreeze(const TTypeEnvironment& env);
  644. private:
  645. TType* Data;
  646. };
  647. class TOptionalType : public TType {
  648. friend class TType;
  649. public:
  650. static TOptionalType* Create(TType* itemType, const TTypeEnvironment& env);
  651. using TType::IsSameType;
  652. bool IsSameType(const TOptionalType& typeToCompare) const;
  653. size_t CalcHash() const;
  654. using TType::IsConvertableTo;
  655. bool IsConvertableTo(const TOptionalType& typeToCompare, bool ignoreTagged = false) const;
  656. TType* GetItemType() const {
  657. return Data;
  658. }
  659. private:
  660. TOptionalType(TType* itemType, const TTypeEnvironment& env, bool validate = true);
  661. void DoUpdateLinks(const THashMap<TNode*, TNode*>& links);
  662. TNode* DoCloneOnCallableWrite(const TTypeEnvironment& env) const;
  663. void DoFreeze(const TTypeEnvironment& env);
  664. private:
  665. TType* Data;
  666. };
  667. class TOptionalLiteral : public TNode {
  668. friend class TNode;
  669. public:
  670. static TOptionalLiteral* Create(TRuntimeNode item, TOptionalType* type, const TTypeEnvironment& env);
  671. static TOptionalLiteral* Create(TOptionalType* type, const TTypeEnvironment& env);
  672. TOptionalType* GetType() const {
  673. return static_cast<TOptionalType*>(GetGenericType());
  674. }
  675. bool HasItem() const {
  676. return !!Item.GetNode();
  677. }
  678. TRuntimeNode GetItem() const {
  679. Y_DEBUG_ABORT_UNLESS(Item.GetNode());
  680. return Item;
  681. }
  682. private:
  683. TOptionalLiteral(TRuntimeNode item, TOptionalType* type, bool validate = true);
  684. TOptionalLiteral(TOptionalType* type, bool validate = true);
  685. using TNode::Equals;
  686. bool Equals(const TOptionalLiteral& nodeToCompare) const;
  687. void DoUpdateLinks(const THashMap<TNode*, TNode*>& links);
  688. TNode* DoCloneOnCallableWrite(const TTypeEnvironment& env) const;
  689. void DoFreeze(const TTypeEnvironment& env);
  690. private:
  691. TRuntimeNode Item;
  692. };
  693. class TDictType : public TType {
  694. friend class TType;
  695. public:
  696. static TDictType* Create(TType* keyType, TType* payloadType, const TTypeEnvironment& env);
  697. using TType::IsSameType;
  698. bool IsSameType(const TDictType& typeToCompare) const;
  699. size_t CalcHash() const;
  700. using TType::IsConvertableTo;
  701. bool IsConvertableTo(const TDictType& typeToCompare, bool ignoreTagged = false) const;
  702. TType* GetKeyType() const {
  703. return KeyType;
  704. }
  705. TType* GetPayloadType() const {
  706. return PayloadType;
  707. }
  708. static void EnsureValidDictKey(TType* keyType);
  709. private:
  710. TDictType(TType* keyType, TType* payloadType, const TTypeEnvironment& env, bool validate = true);
  711. void DoUpdateLinks(const THashMap<TNode*, TNode*>& links);
  712. TNode* DoCloneOnCallableWrite(const TTypeEnvironment& env) const;
  713. void DoFreeze(const TTypeEnvironment& env);
  714. private:
  715. TType* KeyType;
  716. TType* PayloadType;
  717. };
  718. class TDictLiteral : public TNode {
  719. friend class TNode;
  720. public:
  721. static TDictLiteral* Create(ui32 itemsCount, const std::pair<TRuntimeNode, TRuntimeNode>* items, TDictType* type, const TTypeEnvironment& env);
  722. TDictType* GetType() const {
  723. return static_cast<TDictType*>(GetGenericType());
  724. }
  725. ui32 GetItemsCount() const {
  726. return ItemsCount;
  727. }
  728. std::pair<TRuntimeNode, TRuntimeNode> GetItem(ui32 index) const {
  729. Y_DEBUG_ABORT_UNLESS(index < ItemsCount);
  730. return Items[index];
  731. }
  732. private:
  733. TDictLiteral(ui32 itemsCount, std::pair<TRuntimeNode, TRuntimeNode>* items, TDictType* type, bool validate = true);
  734. using TNode::Equals;
  735. bool Equals(const TDictLiteral& nodeToCompare) const;
  736. void DoUpdateLinks(const THashMap<TNode*, TNode*>& links);
  737. TNode* DoCloneOnCallableWrite(const TTypeEnvironment& env) const;
  738. void DoFreeze(const TTypeEnvironment& env);
  739. private:
  740. ui32 ItemsCount;
  741. std::pair<TRuntimeNode, TRuntimeNode>* Items;
  742. };
  743. class TCallableType : public TType {
  744. friend class TType;
  745. public:
  746. static TCallableType* Create(const TString& name, TType* returnType, ui32 argumentsCount,
  747. TType** arguments, TNode* payload, const TTypeEnvironment& env);
  748. static TCallableType* Create(TType* returnType, const TStringBuf& name, ui32 argumentsCount,
  749. TType** arguments, TNode* payload, const TTypeEnvironment& env);
  750. void SetOptionalArgumentsCount(ui32 count);
  751. ui32 GetOptionalArgumentsCount() const {
  752. return OptionalArgs;
  753. }
  754. using TType::IsSameType;
  755. bool IsSameType(const TCallableType& typeToCompare) const;
  756. size_t CalcHash() const;
  757. using TType::IsConvertableTo;
  758. bool IsConvertableTo(const TCallableType& typeToCompare, bool ignoreTagged = false) const;
  759. TStringBuf GetName() const {
  760. return Name.Str();
  761. }
  762. TInternName GetNameStr() const {
  763. return Name;
  764. }
  765. TType* GetReturnType() const {
  766. return ReturnType;
  767. }
  768. ui32 GetArgumentsCount() const {
  769. return ArgumentsCount;
  770. }
  771. TType* GetArgumentType(ui32 index) const {
  772. Y_DEBUG_ABORT_UNLESS(index < ArgumentsCount);
  773. return Arguments[index];
  774. }
  775. void DisableMerge() {
  776. IsMergeDisabled0 = true;
  777. }
  778. bool IsMergeDisabled() const {
  779. return IsMergeDisabled0;
  780. }
  781. TNode* GetPayload() const {
  782. return Payload;
  783. }
  784. private:
  785. TCallableType(const TInternName& name, TType* returnType, ui32 argumentsCount, TType** arguments,
  786. TNode* payload, const TTypeEnvironment& env);
  787. void DoUpdateLinks(const THashMap<TNode*, TNode*>& links);
  788. TNode* DoCloneOnCallableWrite(const TTypeEnvironment& env) const;
  789. void DoFreeze(const TTypeEnvironment& env);
  790. private:
  791. bool IsMergeDisabled0;
  792. ui32 ArgumentsCount;
  793. TInternName Name;
  794. TType* ReturnType;
  795. TType** Arguments;
  796. TNode* Payload;
  797. ui32 OptionalArgs;
  798. };
  799. class TCallablePayload : public NUdf::ICallablePayload {
  800. public:
  801. TCallablePayload(NMiniKQL::TNode* node);
  802. NUdf::TStringRef GetPayload() const override {
  803. return Payload_;
  804. }
  805. NUdf::TStringRef GetArgumentName(ui32 index) const override {
  806. return ArgsNames_[index];
  807. }
  808. ui64 GetArgumentFlags(ui32 index) const override {
  809. return ArgsFlags_[index];
  810. }
  811. private:
  812. NUdf::TStringRef Payload_;
  813. TVector<NUdf::TStringRef> ArgsNames_;
  814. TVector<ui64> ArgsFlags_;
  815. };
  816. class TCallable : public TNode {
  817. friend class TNode;
  818. public:
  819. static TCallable* Create(ui32 inputsCount, const TRuntimeNode* inputs, TCallableType* type, const TTypeEnvironment& env);
  820. static TCallable* Create(TRuntimeNode result, TCallableType* type, const TTypeEnvironment& env);
  821. TCallableType* GetType() const {
  822. return static_cast<TCallableType*>(GetGenericType());
  823. }
  824. ui32 GetInputsCount() const {
  825. return InputsCount;
  826. }
  827. TRuntimeNode GetInput(ui32 index) const {
  828. Y_DEBUG_ABORT_UNLESS(index < InputsCount);
  829. return Inputs[index];
  830. }
  831. bool HasResult() const {
  832. return !!Result.GetNode();
  833. }
  834. TRuntimeNode GetResult() const {
  835. Y_DEBUG_ABORT_UNLESS(!!Result.GetNode());
  836. return Result;
  837. }
  838. void SetResult(TRuntimeNode result, const TTypeEnvironment& env);
  839. ui32 GetUniqueId() const {
  840. return UniqueId;
  841. }
  842. void SetUniqueId(ui32 uniqueId) {
  843. UniqueId = uniqueId;
  844. }
  845. private:
  846. TCallable(ui32 inputsCount, TRuntimeNode* inputs, TCallableType* type, bool validate = true);
  847. TCallable(TRuntimeNode result, TCallableType* type, bool validate = true);
  848. using TNode::Equals;
  849. bool Equals(const TCallable& nodeToCompare) const;
  850. void DoUpdateLinks(const THashMap<TNode*, TNode*>& links);
  851. TNode* DoCloneOnCallableWrite(const TTypeEnvironment& env) const;
  852. void DoFreeze(const TTypeEnvironment& env);
  853. private:
  854. ui32 InputsCount;
  855. ui32 UniqueId;
  856. TRuntimeNode* Inputs;
  857. TRuntimeNode Result;
  858. };
  859. inline TTypeBase::TTypeBase(EKind kind, TTypeType* type, bool supportsPresort)
  860. : TNode(type)
  861. , Kind(kind)
  862. , SupportsPresort(supportsPresort)
  863. {
  864. Y_DEBUG_ABORT_UNLESS(kind != EKind::Type);
  865. }
  866. inline TType* TRuntimeNode::GetStaticType() const {
  867. MKQL_ENSURE(GetNode() != nullptr, "Node is a nullptr value");
  868. if (IsImmediate()) {
  869. return GetNode()->GetGenericType();
  870. } else {
  871. MKQL_ENSURE(GetNode()->GetType()->IsCallable(), "Wrong type");
  872. const auto& callable = static_cast<const TCallable&>(*GetNode());
  873. return callable.GetType()->GetReturnType();
  874. }
  875. }
  876. class TAnyType : public TType {
  877. friend class TTypeEnvironment;
  878. friend class TType;
  879. public:
  880. using TType::IsSameType;
  881. bool IsSameType(const TAnyType& typeToCompare) const;
  882. size_t CalcHash() const;
  883. using TType::IsConvertableTo;
  884. bool IsConvertableTo(const TAnyType& typeToCompare, bool ignoreTagged = false) const;
  885. private:
  886. TAnyType(TTypeType* type)
  887. : TType(EKind::Any, type, false)
  888. {}
  889. static TAnyType* Create(TTypeType* type, const TTypeEnvironment& env);
  890. void DoUpdateLinks(const THashMap<TNode*, TNode*>& links);
  891. TNode* DoCloneOnCallableWrite(const TTypeEnvironment& env) const;
  892. void DoFreeze(const TTypeEnvironment& env);
  893. };
  894. class TAny : public TNode {
  895. friend class TNode;
  896. public:
  897. static TAny* Create(const TTypeEnvironment& env);
  898. TAnyType* GetType() const {
  899. return static_cast<TAnyType*>(GetGenericType());
  900. }
  901. bool HasItem() const {
  902. return !!Item.GetNode();
  903. }
  904. TRuntimeNode GetItem() const {
  905. Y_DEBUG_ABORT_UNLESS(Item.GetNode());
  906. return Item;
  907. }
  908. void SetItem(TRuntimeNode newItem);
  909. private:
  910. TAny(TAnyType* type)
  911. : TNode(type)
  912. {}
  913. using TNode::Equals;
  914. bool Equals(const TAny& nodeToCompare) const;
  915. void DoUpdateLinks(const THashMap<TNode*, TNode*>& links);
  916. TNode* DoCloneOnCallableWrite(const TTypeEnvironment& env) const;
  917. void DoFreeze(const TTypeEnvironment& env);
  918. private:
  919. TRuntimeNode Item;
  920. };
  921. template<typename TDerived, TType::EKind DerivedKind>
  922. class TTupleLikeType : public TType {
  923. friend class TType;
  924. using TSelf = TTupleLikeType<TDerived, DerivedKind>;
  925. public:
  926. static TDerived* Create(ui32 elementsCount, TType* const* elements, const TTypeEnvironment& env) {
  927. TType **allocatedElements = nullptr;
  928. if (elementsCount) {
  929. allocatedElements = static_cast<TType **>(env.AllocateBuffer(elementsCount * sizeof(*allocatedElements)));
  930. for (ui32 i = 0; i < elementsCount; ++i) {
  931. allocatedElements[i] = elements[i];
  932. }
  933. }
  934. return ::new (env.Allocate<TDerived>()) TDerived(elementsCount, allocatedElements, env);
  935. }
  936. using TType::IsSameType;
  937. bool IsSameType(const TDerived& typeToCompare) const {
  938. if (this == &typeToCompare) {
  939. return true;
  940. }
  941. if (ElementsCount != typeToCompare.ElementsCount) {
  942. return false;
  943. }
  944. for (size_t index = 0; index < ElementsCount; ++index) {
  945. if (!Elements[index]->IsSameType(*typeToCompare.Elements[index])) {
  946. return false;
  947. }
  948. }
  949. return true;
  950. }
  951. size_t CalcHash() const {
  952. size_t hash = 0;
  953. for (size_t index = 0; index < ElementsCount; ++index) {
  954. hash = CombineHashes(hash, Elements[index]->CalcHash());
  955. }
  956. return hash;
  957. }
  958. using TType::IsConvertableTo;
  959. bool IsConvertableTo(const TDerived& typeToCompare, bool ignoreTagged = false) const {
  960. if (this == &typeToCompare) {
  961. return true;
  962. }
  963. if (ElementsCount != typeToCompare.GetElementsCount()) {
  964. return false;
  965. }
  966. for (size_t index = 0; index < ElementsCount; ++index) {
  967. if (!Elements[index]->IsConvertableTo(*typeToCompare.GetElementType(index), ignoreTagged)) {
  968. return false;
  969. }
  970. }
  971. return true;
  972. }
  973. ui32 GetElementsCount() const {
  974. return ElementsCount;
  975. }
  976. TType* GetElementType(ui32 index) const {
  977. Y_DEBUG_ABORT_UNLESS(index < ElementsCount);
  978. return Elements[index];
  979. }
  980. TArrayRef<TType* const> GetElements() const {
  981. return TArrayRef<TType* const>(Elements, ElementsCount);
  982. }
  983. protected:
  984. TTupleLikeType(ui32 elementsCount, TType** elements, const TTypeEnvironment& env)
  985. : TType(DerivedKind, env.GetTypeOfTypeLazy(), CalculatePresortSupport(elementsCount, elements))
  986. , ElementsCount(elementsCount)
  987. , Elements(elements)
  988. {
  989. }
  990. private:
  991. void DoUpdateLinks(const THashMap<TNode*, TNode*>& links) {
  992. for (ui32 i = 0; i < ElementsCount; ++i) {
  993. auto &element = Elements[i];
  994. auto elementIt = links.find(element);
  995. if (elementIt != links.end()) {
  996. TNode* newNode = elementIt->second;
  997. Y_DEBUG_ABORT_UNLESS(element->Equals(*newNode));
  998. element = static_cast<TType*>(newNode);
  999. }
  1000. }
  1001. }
  1002. TNode* DoCloneOnCallableWrite(const TTypeEnvironment& env) const {
  1003. bool needClone = false;
  1004. for (ui32 i = 0; i < ElementsCount; ++i) {
  1005. if (Elements[i]->GetCookie()) {
  1006. needClone = true;
  1007. break;
  1008. }
  1009. }
  1010. if (!needClone) {
  1011. return const_cast<TSelf*>(this);
  1012. }
  1013. TType** allocatedElements = nullptr;
  1014. if (ElementsCount) {
  1015. allocatedElements = static_cast<TType**>(env.AllocateBuffer(ElementsCount * sizeof(*allocatedElements)));
  1016. for (ui32 i = 0; i < ElementsCount; ++i) {
  1017. allocatedElements[i] = Elements[i];
  1018. auto newNode = (TNode *)Elements[i]->GetCookie();
  1019. if (newNode) {
  1020. allocatedElements[i] = static_cast<TType*>(newNode);
  1021. }
  1022. }
  1023. }
  1024. return ::new (env.Allocate<TDerived>()) TDerived(ElementsCount, allocatedElements, env);
  1025. }
  1026. void DoFreeze(const TTypeEnvironment& env) {
  1027. Y_UNUSED(env);
  1028. }
  1029. static bool CalculatePresortSupport(ui32 elementsCount, TType** elements) {
  1030. for (ui32 i = 0; i < elementsCount; ++i) {
  1031. if (!elements[i]->IsPresortSupported()) {
  1032. return false;
  1033. }
  1034. }
  1035. return true;
  1036. }
  1037. private:
  1038. ui32 ElementsCount;
  1039. TType** Elements;
  1040. };
  1041. class TTupleType : public TTupleLikeType<TTupleType, TType::EKind::Tuple> {
  1042. private:
  1043. friend class TType;
  1044. using TBase = TTupleLikeType<TTupleType, TType::EKind::Tuple>;
  1045. friend TBase;
  1046. TTupleType(ui32 elementsCount, TType** elements, const TTypeEnvironment& env)
  1047. : TBase(elementsCount, elements, env)
  1048. {
  1049. }
  1050. };
  1051. class TMultiType : public TTupleLikeType<TMultiType, TType::EKind::Multi> {
  1052. private:
  1053. friend class TType;
  1054. using TBase = TTupleLikeType<TMultiType, TType::EKind::Multi>;
  1055. friend TBase;
  1056. TMultiType(ui32 elementsCount, TType** elements, const TTypeEnvironment& env)
  1057. : TBase(elementsCount, elements, env)
  1058. {
  1059. }
  1060. };
  1061. class TTupleLiteral : public TNode {
  1062. friend class TNode;
  1063. public:
  1064. static TTupleLiteral* Create(
  1065. ui32 valuesCount, const TRuntimeNode* items, TTupleType* type,
  1066. const TTypeEnvironment& env, bool useCachedEmptyTuple = true);
  1067. TTupleType* GetType() const {
  1068. return static_cast<TTupleType*>(GetGenericType());
  1069. }
  1070. ui32 GetValuesCount() const {
  1071. return GetType()->GetElementsCount();
  1072. }
  1073. TRuntimeNode GetValue(ui32 index) const {
  1074. Y_DEBUG_ABORT_UNLESS(index < GetValuesCount());
  1075. return Values[index];
  1076. }
  1077. private:
  1078. TTupleLiteral(TRuntimeNode* values, TTupleType* type, bool validate = true);
  1079. using TNode::Equals;
  1080. bool Equals(const TTupleLiteral& nodeToCompare) const;
  1081. void DoUpdateLinks(const THashMap<TNode*, TNode*>& links);
  1082. TNode* DoCloneOnCallableWrite(const TTypeEnvironment& env) const;
  1083. void DoFreeze(const TTypeEnvironment& env);
  1084. private:
  1085. TRuntimeNode* Values;
  1086. };
  1087. class TResourceType : public TType {
  1088. friend class TTypeEnvironment;
  1089. friend class TType;
  1090. public:
  1091. using TType::IsSameType;
  1092. bool IsSameType(const TResourceType& typeToCompare) const;
  1093. size_t CalcHash() const;
  1094. using TType::IsConvertableTo;
  1095. bool IsConvertableTo(const TResourceType& typeToCompare, bool ignoreTagged = false) const;
  1096. TStringBuf GetTag() const {
  1097. return Tag.Str();
  1098. }
  1099. TInternName GetTagStr() const {
  1100. return Tag;
  1101. }
  1102. static TResourceType* Create(const TStringBuf& tag, const TTypeEnvironment& env);
  1103. private:
  1104. TResourceType(TTypeType* type, TInternName tag)
  1105. : TType(EKind::Resource, type, false)
  1106. , Tag(tag)
  1107. {}
  1108. void DoUpdateLinks(const THashMap<TNode*, TNode*>& links);
  1109. TNode* DoCloneOnCallableWrite(const TTypeEnvironment& env) const;
  1110. void DoFreeze(const TTypeEnvironment& env);
  1111. private:
  1112. TInternName const Tag;
  1113. };
  1114. class TTaggedType : public TType {
  1115. friend class TType;
  1116. public:
  1117. static TTaggedType* Create(TType* baseType, const TStringBuf& tag, const TTypeEnvironment& env);
  1118. using TType::IsSameType;
  1119. bool IsSameType(const TTaggedType& typeToCompare) const;
  1120. size_t CalcHash() const;
  1121. using TType::IsConvertableTo;
  1122. bool IsConvertableTo(const TTaggedType& typeToCompare, bool ignoreTagged = false) const;
  1123. TType* GetBaseType() const {
  1124. return BaseType;
  1125. }
  1126. TStringBuf GetTag() const {
  1127. return Tag.Str();
  1128. }
  1129. TInternName GetTagStr() const {
  1130. return Tag;
  1131. }
  1132. private:
  1133. TTaggedType(TType* baseType, TInternName tag, const TTypeEnvironment& env);
  1134. void DoUpdateLinks(const THashMap<TNode*, TNode*>& links);
  1135. TNode* DoCloneOnCallableWrite(const TTypeEnvironment& env) const;
  1136. void DoFreeze(const TTypeEnvironment& env);
  1137. private:
  1138. TType* BaseType;
  1139. TInternName const Tag;
  1140. };
  1141. class TVariantType : public TType {
  1142. friend class TType;
  1143. public:
  1144. static TVariantType* Create(TType* underlyingType, const TTypeEnvironment& env);
  1145. using TType::IsSameType;
  1146. bool IsSameType(const TVariantType& typeToCompare) const;
  1147. size_t CalcHash() const;
  1148. using TType::IsConvertableTo;
  1149. bool IsConvertableTo(const TVariantType& typeToCompare, bool ignoreTagged = false) const;
  1150. TType* GetUnderlyingType() const {
  1151. return Data;
  1152. }
  1153. ui32 GetAlternativesCount() const {
  1154. if (Data->IsStruct()) {
  1155. return static_cast<TStructType*>(Data)->GetMembersCount();
  1156. } else {
  1157. return static_cast<TTupleType*>(Data)->GetElementsCount();
  1158. }
  1159. }
  1160. TType* GetAlternativeType(ui32 index) const {
  1161. MKQL_ENSURE(index < GetAlternativesCount(), "Wrong index");
  1162. if (Data->IsStruct()) {
  1163. return static_cast<TStructType*>(Data)->GetMemberType(index);
  1164. } else {
  1165. return static_cast<TTupleType*>(Data)->GetElementType(index);
  1166. }
  1167. }
  1168. private:
  1169. TVariantType(TType* underlyingType, const TTypeEnvironment& env, bool validate = true);
  1170. void DoUpdateLinks(const THashMap<TNode*, TNode*>& links);
  1171. TNode* DoCloneOnCallableWrite(const TTypeEnvironment& env) const;
  1172. void DoFreeze(const TTypeEnvironment& env);
  1173. private:
  1174. TType* Data;
  1175. };
  1176. class TVariantLiteral : public TNode {
  1177. friend class TNode;
  1178. public:
  1179. static TVariantLiteral* Create(TRuntimeNode item, ui32 index, TVariantType* type, const TTypeEnvironment& env);
  1180. TVariantType* GetType() const {
  1181. return static_cast<TVariantType*>(GetGenericType());
  1182. }
  1183. ui32 GetIndex() const {
  1184. return Index;
  1185. }
  1186. TRuntimeNode GetItem() const {
  1187. return Item;
  1188. }
  1189. private:
  1190. TVariantLiteral(TRuntimeNode item, ui32 index, TVariantType* type, bool validate = true);
  1191. using TNode::Equals;
  1192. bool Equals(const TVariantLiteral& nodeToCompare) const;
  1193. void DoUpdateLinks(const THashMap<TNode*, TNode*>& links);
  1194. TNode* DoCloneOnCallableWrite(const TTypeEnvironment& env) const;
  1195. void DoFreeze(const TTypeEnvironment& env);
  1196. private:
  1197. TRuntimeNode Item;
  1198. ui32 Index;
  1199. };
  1200. class TBlockType : public TType {
  1201. friend class TType;
  1202. public:
  1203. enum class EShape: ui8 {
  1204. Scalar = 0,
  1205. Many = 1
  1206. };
  1207. public:
  1208. static TBlockType* Create(TType* itemType, EShape shape, const TTypeEnvironment& env);
  1209. using TType::IsSameType;
  1210. bool IsSameType(const TBlockType& typeToCompare) const;
  1211. size_t CalcHash() const;
  1212. using TType::IsConvertableTo;
  1213. bool IsConvertableTo(const TBlockType& typeToCompare, bool ignoreTagged = false) const;
  1214. inline TType* GetItemType() const noexcept {
  1215. return ItemType;
  1216. }
  1217. inline EShape GetShape() const noexcept {
  1218. return Shape;
  1219. }
  1220. private:
  1221. TBlockType(TType* itemType, EShape shape, const TTypeEnvironment& env);
  1222. void DoUpdateLinks(const THashMap<TNode*, TNode*>& links);
  1223. TNode* DoCloneOnCallableWrite(const TTypeEnvironment& env) const;
  1224. void DoFreeze(const TTypeEnvironment& env);
  1225. private:
  1226. TType* ItemType;
  1227. EShape Shape;
  1228. };
  1229. inline bool TRuntimeNode::operator==(const TRuntimeNode& other) const {
  1230. return IsImmediate() == other.IsImmediate() && GetNode()->Equals(*other.GetNode());
  1231. }
  1232. inline TType* TRuntimeNode::GetRuntimeType() const {
  1233. return GetNode()->GetGenericType();
  1234. }
  1235. bool IsNumericType(NUdf::TDataTypeId typeId);
  1236. bool IsCommonStringType(NUdf::TDataTypeId typeId);
  1237. bool IsDateType(NUdf::TDataTypeId typeId);
  1238. bool IsTzDateType(NUdf::TDataTypeId typeId);
  1239. bool IsIntervalType(NUdf::TDataTypeId typeId);
  1240. enum class EValueRepresentation {
  1241. Embedded = 0,
  1242. String = 1,
  1243. Boxed = 2,
  1244. Any = String | Boxed
  1245. };
  1246. EValueRepresentation GetValueRepresentation(const TType* type);
  1247. EValueRepresentation GetValueRepresentation(NUdf::TDataTypeId typeId);
  1248. TArrayRef<TType* const> GetWideComponents(const TFlowType* type);
  1249. TArrayRef<TType* const> GetWideComponents(const TStreamType* type);
  1250. TArrayRef<TType *const> GetWideComponents(const TType* type);
  1251. inline ui32 GetWideComponentsCount(const TFlowType* type) {
  1252. return (ui32)GetWideComponents(type).size();
  1253. }
  1254. inline ui32 GetWideComponentsCount(const TStreamType* type) {
  1255. return (ui32)GetWideComponents(type).size();
  1256. }
  1257. inline ui32 GetWideComponentsCount(const TType* type) {
  1258. return (ui32)GetWideComponents(type).size();
  1259. }
  1260. template <TType::EKind SingularKind>
  1261. TSingularType<SingularKind>* TSingularType<SingularKind>::Create(TTypeType* type, const TTypeEnvironment& env) {
  1262. return ::new(env.Allocate<TSingularType<SingularKind>>()) TSingularType<SingularKind>(type);
  1263. }
  1264. template <TType::EKind SingularKind>
  1265. bool TSingularType<SingularKind>::IsSameType(const TSingularType<SingularKind>& typeToCompare) const {
  1266. Y_UNUSED(typeToCompare);
  1267. return true;
  1268. }
  1269. template <TType::EKind SingularKind>
  1270. size_t TSingularType<SingularKind>::CalcHash() const {
  1271. return IntHash((size_t)SingularKind);
  1272. }
  1273. template <TType::EKind SingularKind>
  1274. bool TSingularType<SingularKind>::IsConvertableTo(const TSingularType<SingularKind>& typeToCompare, bool ignoreTagged) const {
  1275. Y_UNUSED(ignoreTagged);
  1276. return IsSameType(typeToCompare);
  1277. }
  1278. template <TType::EKind SingularKind>
  1279. void TSingularType<SingularKind>::DoUpdateLinks(const THashMap<TNode*, TNode*>& links) {
  1280. Y_UNUSED(links);
  1281. }
  1282. template <TType::EKind SingularKind>
  1283. TNode* TSingularType<SingularKind>::DoCloneOnCallableWrite(const TTypeEnvironment& env) const {
  1284. Y_UNUSED(env);
  1285. return const_cast<TSingularType<SingularKind>*>(this);
  1286. }
  1287. template <TType::EKind SingularKind>
  1288. void TSingularType<SingularKind>::DoFreeze(const TTypeEnvironment& env) {
  1289. Y_UNUSED(env);
  1290. }
  1291. template <TType::EKind SingularKind>
  1292. TSingular<SingularKind>* TSingular<SingularKind>::Create(const TTypeEnvironment& env) {
  1293. return ::new(env.Allocate<TSingular<SingularKind>>()) TSingular<SingularKind>(env);
  1294. }
  1295. template <TType::EKind SingularKind>
  1296. bool TSingular<SingularKind>::Equals(const TSingular<SingularKind>& nodeToCompare) const {
  1297. Y_UNUSED(nodeToCompare);
  1298. return true;
  1299. }
  1300. template <TType::EKind SingularKind>
  1301. void TSingular<SingularKind>::DoUpdateLinks(const THashMap<TNode*, TNode*>& links) {
  1302. Y_UNUSED(links);
  1303. }
  1304. template <TType::EKind SingularKind>
  1305. TNode* TSingular<SingularKind>::DoCloneOnCallableWrite(const TTypeEnvironment& env) const {
  1306. Y_UNUSED(env);
  1307. return const_cast<TSingular<SingularKind>*>(this);
  1308. }
  1309. template <TType::EKind SingularKind>
  1310. void TSingular<SingularKind>::DoFreeze(const TTypeEnvironment& env) {
  1311. Y_UNUSED(env);
  1312. }
  1313. struct THasherTType {
  1314. inline size_t operator()(const TTypeBase& t) const noexcept {
  1315. return t.CalcHash();
  1316. }
  1317. };
  1318. struct TEqualTType {
  1319. inline bool operator()(const TTypeBase& lhs, const TTypeBase& rhs) const noexcept {
  1320. return lhs.IsSameType(rhs);
  1321. }
  1322. };
  1323. }
  1324. }