yql_expr.h 87 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880
  1. #pragma once
  2. #include "yql_ast.h"
  3. #include "yql_expr_types.h"
  4. #include "yql_type_string.h"
  5. #include "yql_expr_builder.h"
  6. #include "yql_gc_nodes.h"
  7. #include "yql_constraint.h"
  8. #include "yql_pos_handle.h"
  9. #include <yql/essentials/core/url_lister/interface/url_lister_manager.h>
  10. #include <yql/essentials/utils/yql_panic.h>
  11. #include <yql/essentials/public/issue/yql_issue_manager.h>
  12. #include <yql/essentials/public/udf/udf_data_type.h>
  13. #include <library/cpp/yson/node/node.h>
  14. #include <library/cpp/string_utils/levenshtein_diff/levenshtein_diff.h>
  15. #include <library/cpp/enumbitset/enumbitset.h>
  16. #include <library/cpp/containers/stack_vector/stack_vec.h>
  17. #include <library/cpp/deprecated/enum_codegen/enum_codegen.h>
  18. #include <util/string/ascii.h>
  19. #include <util/string/builder.h>
  20. #include <util/generic/array_ref.h>
  21. #include <util/generic/deque.h>
  22. #include <util/generic/cast.h>
  23. #include <util/generic/hash.h>
  24. #include <util/generic/maybe.h>
  25. #include <util/generic/set.h>
  26. #include <util/generic/bt_exception.h>
  27. #include <util/generic/algorithm.h>
  28. #include <util/digest/murmur.h>
  29. #include <algorithm>
  30. #include <unordered_set>
  31. #include <unordered_map>
  32. #include <span>
  33. #include <stack>
  34. //#define YQL_CHECK_NODES_CONSISTENCY
  35. #ifdef YQL_CHECK_NODES_CONSISTENCY
  36. #define ENSURE_NOT_DELETED \
  37. YQL_ENSURE(!Dead(), "Access to dead node # " << UniqueId_ << ": " << Type_ << " '" << ContentUnchecked() << "'");
  38. #define ENSURE_NOT_FROZEN \
  39. YQL_ENSURE(!Frozen(), "Change in frozen node # " << UniqueId_ << ": " << Type_ << " '" << ContentUnchecked() << "'");
  40. #define ENSURE_NOT_FROZEN_CTX \
  41. YQL_ENSURE(!Frozen, "Change in frozen expr context.");
  42. #else
  43. #define ENSURE_NOT_DELETED Y_DEBUG_ABORT_UNLESS(!Dead(), "Access to dead node # %lu: %d '%s'", UniqueId_, (int)Type_, TString(ContentUnchecked()).data());
  44. #define ENSURE_NOT_FROZEN Y_DEBUG_ABORT_UNLESS(!Frozen());
  45. #define ENSURE_NOT_FROZEN_CTX Y_DEBUG_ABORT_UNLESS(!Frozen);
  46. #endif
  47. namespace NYql {
  48. using NUdf::EDataSlot;
  49. class TUnitExprType;
  50. class TMultiExprType;
  51. class TTupleExprType;
  52. class TStructExprType;
  53. class TItemExprType;
  54. class TListExprType;
  55. class TStreamExprType;
  56. class TDataExprType;
  57. class TPgExprType;
  58. class TWorldExprType;
  59. class TOptionalExprType;
  60. class TCallableExprType;
  61. class TResourceExprType;
  62. class TTypeExprType;
  63. class TDictExprType;
  64. class TVoidExprType;
  65. class TNullExprType;
  66. class TGenericExprType;
  67. class TTaggedExprType;
  68. class TErrorExprType;
  69. class TVariantExprType;
  70. class TStreamExprType;
  71. class TFlowExprType;
  72. class TEmptyListExprType;
  73. class TEmptyDictExprType;
  74. class TBlockExprType;
  75. class TScalarExprType;
  76. const size_t DefaultMistypeDistance = 3;
  77. const TString YqlVirtualPrefix = "_yql_virtual_";
  78. extern const TStringBuf ZeroString;
  79. struct TTypeAnnotationVisitor {
  80. virtual ~TTypeAnnotationVisitor() = default;
  81. virtual void Visit(const TUnitExprType& type) = 0;
  82. virtual void Visit(const TMultiExprType& type) = 0;
  83. virtual void Visit(const TTupleExprType& type) = 0;
  84. virtual void Visit(const TStructExprType& type) = 0;
  85. virtual void Visit(const TItemExprType& type) = 0;
  86. virtual void Visit(const TListExprType& type) = 0;
  87. virtual void Visit(const TStreamExprType& type) = 0;
  88. virtual void Visit(const TFlowExprType& type) = 0;
  89. virtual void Visit(const TDataExprType& type) = 0;
  90. virtual void Visit(const TPgExprType& type) = 0;
  91. virtual void Visit(const TWorldExprType& type) = 0;
  92. virtual void Visit(const TOptionalExprType& type) = 0;
  93. virtual void Visit(const TCallableExprType& type) = 0;
  94. virtual void Visit(const TResourceExprType& type) = 0;
  95. virtual void Visit(const TTypeExprType& type) = 0;
  96. virtual void Visit(const TDictExprType& type) = 0;
  97. virtual void Visit(const TVoidExprType& type) = 0;
  98. virtual void Visit(const TNullExprType& type) = 0;
  99. virtual void Visit(const TGenericExprType& type) = 0;
  100. virtual void Visit(const TTaggedExprType& type) = 0;
  101. virtual void Visit(const TErrorExprType& type) = 0;
  102. virtual void Visit(const TVariantExprType& type) = 0;
  103. virtual void Visit(const TEmptyListExprType& type) = 0;
  104. virtual void Visit(const TEmptyDictExprType& type) = 0;
  105. virtual void Visit(const TBlockExprType& type) = 0;
  106. virtual void Visit(const TScalarExprType& type) = 0;
  107. };
  108. enum ETypeAnnotationFlags : ui32 {
  109. TypeNonComposable = 0x01,
  110. TypeNonPersistable = 0x02,
  111. TypeNonComputable = 0x04,
  112. TypeNonInspectable = 0x08,
  113. TypeNonHashable = 0x10,
  114. TypeNonEquatable = 0x20,
  115. TypeNonComparable = 0x40,
  116. TypeHasNull = 0x80,
  117. TypeHasOptional = 0x100,
  118. TypeHasManyValues = 0x200,
  119. TypeHasBareYson = 0x400,
  120. TypeHasNestedOptional = 0x800,
  121. TypeNonPresortable = 0x1000,
  122. TypeHasDynamicSize = 0x2000,
  123. TypeNonComparableInternal = 0x4000,
  124. };
  125. const ui64 TypeHashMagic = 0x10000;
  126. inline ui64 StreamHash(const void* buffer, size_t size, ui64 seed) {
  127. return MurmurHash(buffer, size, seed);
  128. }
  129. inline ui64 StreamHash(ui64 value, ui64 seed) {
  130. return MurmurHash(&value, sizeof(value), seed);
  131. }
  132. void ReportError(TExprContext& ctx, const TIssue& issue);
  133. class TTypeAnnotationNode {
  134. protected:
  135. TTypeAnnotationNode(ETypeAnnotationKind kind, ui32 flags, ui64 hash, ui64 usedPgExtensions)
  136. : Kind(kind)
  137. , Flags(flags)
  138. , Hash(hash)
  139. , UsedPgExtensions(usedPgExtensions)
  140. {
  141. }
  142. public:
  143. virtual ~TTypeAnnotationNode() = default;
  144. template <typename T>
  145. const T* Cast() const {
  146. static_assert(std::is_base_of<TTypeAnnotationNode, T>::value,
  147. "Should be derived from TTypeAnnotationNode");
  148. const auto ret = dynamic_cast<const T*>(this);
  149. YQL_ENSURE(ret, "Cannot cast type " << *this << " to " << ETypeAnnotationKind(T::KindValue));
  150. return ret;
  151. }
  152. template <typename T>
  153. const T* UserCast(TPosition pos, TExprContext& ctx) const {
  154. static_assert(std::is_base_of<TTypeAnnotationNode, T>::value,
  155. "Should be derived from TTypeAnnotationNode");
  156. const auto ret = dynamic_cast<const T*>(this);
  157. if (!ret) {
  158. ReportError(ctx, TIssue(pos, TStringBuilder() << "Cannot cast type " << *this << " to " << ETypeAnnotationKind(T::KindValue)));
  159. }
  160. return ret;
  161. }
  162. ETypeAnnotationKind GetKind() const {
  163. return Kind;
  164. }
  165. bool IsComposable() const {
  166. return (GetFlags() & TypeNonComposable) == 0;
  167. }
  168. bool IsPersistable() const {
  169. return (GetFlags() & TypeNonPersistable) == 0;
  170. }
  171. bool IsComputable() const {
  172. return (GetFlags() & TypeNonComputable) == 0;
  173. }
  174. bool IsInspectable() const {
  175. return (GetFlags() & TypeNonInspectable) == 0;
  176. }
  177. bool IsHashable() const {
  178. return IsPersistable() && (GetFlags() & TypeNonHashable) == 0;
  179. }
  180. bool IsEquatable() const {
  181. return IsPersistable() && (GetFlags() & TypeNonEquatable) == 0;
  182. }
  183. bool IsComparable() const {
  184. return IsPersistable() && (GetFlags() & TypeNonComparable) == 0;
  185. }
  186. bool IsComparableInternal() const {
  187. return IsPersistable() && (GetFlags() & TypeNonComparableInternal) == 0;
  188. }
  189. bool HasNull() const {
  190. return (GetFlags() & TypeHasNull) != 0;
  191. }
  192. bool HasOptional() const {
  193. return (GetFlags() & TypeHasOptional) != 0;
  194. }
  195. bool HasNestedOptional() const {
  196. return (GetFlags() & TypeHasNestedOptional) != 0;
  197. }
  198. bool HasOptionalOrNull() const {
  199. return (GetFlags() & (TypeHasOptional | TypeHasNull)) != 0;
  200. }
  201. bool IsOptionalOrNull() const {
  202. auto kind = GetKind();
  203. return kind == ETypeAnnotationKind::Optional || kind == ETypeAnnotationKind::Null || kind == ETypeAnnotationKind::Pg;
  204. }
  205. bool IsBlockOrScalar() const {
  206. return IsBlock() || IsScalar();
  207. }
  208. bool IsBlock() const {
  209. return GetKind() == ETypeAnnotationKind::Block;
  210. }
  211. bool IsScalar() const {
  212. return GetKind() == ETypeAnnotationKind::Scalar;
  213. }
  214. bool HasFixedSizeRepr() const {
  215. return (GetFlags() & (TypeHasDynamicSize | TypeNonPersistable | TypeNonComputable)) == 0;
  216. }
  217. bool IsSingleton() const {
  218. return (GetFlags() & TypeHasManyValues) == 0;
  219. }
  220. bool HasBareYson() const {
  221. return (GetFlags() & TypeHasBareYson) != 0;
  222. }
  223. bool IsPresortSupported() const {
  224. return (GetFlags() & TypeNonPresortable) == 0;
  225. }
  226. ui32 GetFlags() const {
  227. return Flags;
  228. }
  229. ui64 GetHash() const {
  230. return Hash;
  231. }
  232. ui64 GetUsedPgExtensions() const {
  233. return UsedPgExtensions;
  234. }
  235. bool Equals(const TTypeAnnotationNode& node) const;
  236. void Accept(TTypeAnnotationVisitor& visitor) const;
  237. void Out(IOutputStream& out) const {
  238. out << FormatType(this);
  239. }
  240. struct THash {
  241. size_t operator()(const TTypeAnnotationNode* node) const {
  242. return node->GetHash();
  243. }
  244. };
  245. struct TEqual {
  246. bool operator()(const TTypeAnnotationNode* one, const TTypeAnnotationNode* two) const {
  247. return one->Equals(*two);
  248. }
  249. };
  250. typedef std::vector<const TTypeAnnotationNode*> TListType;
  251. typedef std::span<const TTypeAnnotationNode*> TSpanType;
  252. protected:
  253. template <typename T>
  254. static ui32 CombineFlags(const T& items) {
  255. ui32 flags = 0;
  256. for (auto& item : items) {
  257. flags |= item->GetFlags();
  258. }
  259. return flags;
  260. }
  261. template <typename T>
  262. static ui64 CombinePgExtensions(const T& items) {
  263. ui64 mask = 0;
  264. for (auto& item : items) {
  265. mask |= item->GetUsedPgExtensions();
  266. }
  267. return mask;
  268. }
  269. private:
  270. const ETypeAnnotationKind Kind;
  271. const ui32 Flags;
  272. const ui64 Hash;
  273. const ui64 UsedPgExtensions;
  274. };
  275. class TUnitExprType : public TTypeAnnotationNode {
  276. public:
  277. static constexpr ETypeAnnotationKind KindValue = ETypeAnnotationKind::Unit;
  278. TUnitExprType(ui64 hash)
  279. : TTypeAnnotationNode(KindValue,
  280. TypeNonComputable | TypeNonPersistable, hash, 0)
  281. {
  282. }
  283. static ui64 MakeHash() {
  284. return TypeHashMagic | (ui64)ETypeAnnotationKind::Unit;
  285. }
  286. bool operator==(const TUnitExprType& other) const {
  287. Y_UNUSED(other);
  288. return true;
  289. }
  290. };
  291. class TTupleExprType : public TTypeAnnotationNode {
  292. public:
  293. static constexpr ETypeAnnotationKind KindValue = ETypeAnnotationKind::Tuple;
  294. TTupleExprType(ui64 hash, const TTypeAnnotationNode::TListType& items)
  295. : TTypeAnnotationNode(KindValue, CombineFlags(items), hash, CombinePgExtensions(items))
  296. , Items(items)
  297. {
  298. }
  299. static ui64 MakeHash(const TTypeAnnotationNode::TListType& items) {
  300. ui64 hash = TypeHashMagic | (ui64)ETypeAnnotationKind::Tuple;
  301. hash = StreamHash(items.size(), hash);
  302. for (const auto& item : items) {
  303. hash = StreamHash(item->GetHash(), hash);
  304. }
  305. return hash;
  306. }
  307. size_t GetSize() const {
  308. return Items.size();
  309. }
  310. const TTypeAnnotationNode::TListType& GetItems() const {
  311. return Items;
  312. }
  313. bool operator==(const TTupleExprType& other) const {
  314. if (GetSize() != other.GetSize()) {
  315. return false;
  316. }
  317. for (ui32 i = 0, e = GetSize(); i < e; ++i) {
  318. if (GetItems()[i] != other.GetItems()[i]) {
  319. return false;
  320. }
  321. }
  322. return true;
  323. }
  324. bool Validate(TPosition position, TExprContext& ctx) const;
  325. bool Validate(TPositionHandle position, TExprContext& ctx) const;
  326. private:
  327. TTypeAnnotationNode::TListType Items;
  328. };
  329. class TMultiExprType : public TTypeAnnotationNode {
  330. public:
  331. static constexpr ETypeAnnotationKind KindValue = ETypeAnnotationKind::Multi;
  332. TMultiExprType(ui64 hash, const TTypeAnnotationNode::TListType& items)
  333. : TTypeAnnotationNode(KindValue, CombineFlags(items), hash, CombinePgExtensions(items))
  334. , Items(items)
  335. {
  336. }
  337. static ui64 MakeHash(const TTypeAnnotationNode::TListType& items) {
  338. ui64 hash = TypeHashMagic | (ui64)ETypeAnnotationKind::Multi;
  339. hash = StreamHash(items.size(), hash);
  340. for (const auto& item : items) {
  341. hash = StreamHash(item->GetHash(), hash);
  342. }
  343. return hash;
  344. }
  345. size_t GetSize() const {
  346. return Items.size();
  347. }
  348. const TTypeAnnotationNode::TListType& GetItems() const {
  349. return Items;
  350. }
  351. bool operator==(const TMultiExprType& other) const {
  352. if (GetSize() != other.GetSize()) {
  353. return false;
  354. }
  355. for (ui32 i = 0, e = GetSize(); i < e; ++i) {
  356. if (GetItems()[i] != other.GetItems()[i]) {
  357. return false;
  358. }
  359. }
  360. return true;
  361. }
  362. bool Validate(TPosition position, TExprContext& ctx) const;
  363. bool Validate(TPositionHandle position, TExprContext& ctx) const;
  364. private:
  365. TTypeAnnotationNode::TListType Items;
  366. };
  367. struct TExprContext;
  368. bool ValidateName(TPosition position, TStringBuf name, TStringBuf descr, TExprContext& ctx);
  369. bool ValidateName(TPositionHandle position, TStringBuf name, TStringBuf descr, TExprContext& ctx);
  370. class TItemExprType : public TTypeAnnotationNode {
  371. public:
  372. static constexpr ETypeAnnotationKind KindValue = ETypeAnnotationKind::Item;
  373. TItemExprType(ui64 hash, const TStringBuf& name, const TTypeAnnotationNode* itemType)
  374. : TTypeAnnotationNode(KindValue, itemType->GetFlags(), hash, itemType->GetUsedPgExtensions())
  375. , Name(name)
  376. , ItemType(itemType)
  377. {
  378. }
  379. static ui64 MakeHash(const TStringBuf& name, const TTypeAnnotationNode* itemType) {
  380. ui64 hash = TypeHashMagic | (ui64)ETypeAnnotationKind::Item;
  381. hash = StreamHash(name.size(), hash);
  382. hash = StreamHash(name.data(), name.size(), hash);
  383. return StreamHash(itemType->GetHash(), hash);
  384. }
  385. bool Validate(TPosition position, TExprContext& ctx) const;
  386. bool Validate(TPositionHandle position, TExprContext& ctx) const;
  387. const TStringBuf& GetName() const {
  388. return Name;
  389. }
  390. TStringBuf GetCleanName(bool isVirtual) const;
  391. const TTypeAnnotationNode* GetItemType() const {
  392. return ItemType;
  393. }
  394. bool operator==(const TItemExprType& other) const {
  395. return GetName() == other.GetName() && GetItemType() == other.GetItemType();
  396. }
  397. const TItemExprType* GetCleanItem(bool isVirtual, TExprContext& ctx) const;
  398. private:
  399. const TStringBuf Name;
  400. const TTypeAnnotationNode* ItemType;
  401. };
  402. class TStructExprType : public TTypeAnnotationNode {
  403. public:
  404. static constexpr ETypeAnnotationKind KindValue = ETypeAnnotationKind::Struct;
  405. struct TItemLess {
  406. bool operator()(const TItemExprType* x, const TItemExprType* y) const {
  407. return x->GetName() < y->GetName();
  408. };
  409. bool operator()(const TItemExprType* x, const TStringBuf& y) const {
  410. return x->GetName() < y;
  411. };
  412. bool operator()(const TStringBuf& x, const TItemExprType* y) const {
  413. return x < y->GetName();
  414. };
  415. };
  416. TStructExprType(ui64 hash, const TVector<const TItemExprType*>& items)
  417. : TTypeAnnotationNode(KindValue, TypeNonComparable | CombineFlags(items), hash, CombinePgExtensions(items))
  418. , Items(items)
  419. {
  420. }
  421. static ui64 MakeHash(const TVector<const TItemExprType*>& items) {
  422. Y_DEBUG_ABORT_UNLESS(IsSorted(items.begin(), items.end(), TItemLess()));
  423. ui64 hash = TypeHashMagic | (ui64)ETypeAnnotationKind::Struct;
  424. hash = StreamHash(items.size(), hash);
  425. for (const auto& item : items) {
  426. hash = StreamHash(item->GetHash(), hash);
  427. }
  428. return hash;
  429. }
  430. bool Validate(TPosition position, TExprContext& ctx) const;
  431. bool Validate(TPositionHandle position, TExprContext& ctx) const;
  432. size_t GetSize() const {
  433. return Items.size();
  434. }
  435. const TVector<const TItemExprType*>& GetItems() const {
  436. return Items;
  437. }
  438. TMaybe<ui32> FindItem(const TStringBuf& name) const {
  439. auto it = LowerBound(Items.begin(), Items.end(), name, TItemLess());
  440. if (it == Items.end() || (*it)->GetName() != name) {
  441. return TMaybe<ui32>();
  442. }
  443. return it - Items.begin();
  444. }
  445. TMaybe<ui32> FindItemI(const TStringBuf& name, bool* isVirtual) const {
  446. for (ui32 v = 0; v < 2; ++v) {
  447. if (isVirtual) {
  448. *isVirtual = v > 0;
  449. }
  450. auto nameToSearch = (v ? YqlVirtualPrefix : "") + name;
  451. auto strict = FindItem(nameToSearch);
  452. if (strict) {
  453. return strict;
  454. }
  455. TMaybe<ui32> ret;
  456. for (ui32 i = 0; i < Items.size(); ++i) {
  457. if (AsciiEqualsIgnoreCase(nameToSearch, Items[i]->GetName())) {
  458. if (ret) {
  459. return Nothing();
  460. }
  461. ret = i;
  462. }
  463. }
  464. if (ret) {
  465. return ret;
  466. }
  467. }
  468. return Nothing();
  469. }
  470. const TTypeAnnotationNode* FindItemType(const TStringBuf& name) const {
  471. const auto it = LowerBound(Items.begin(), Items.end(), name, TItemLess());
  472. if (it == Items.end() || (*it)->GetName() != name) {
  473. return nullptr;
  474. }
  475. return (*it)->GetItemType();
  476. }
  477. TMaybe<TStringBuf> FindMistype(const TStringBuf& name) const {
  478. for (const auto& item: Items) {
  479. if (NLevenshtein::Distance(name, item->GetName()) < DefaultMistypeDistance) {
  480. return item->GetName();
  481. }
  482. }
  483. return TMaybe<TStringBuf>();
  484. }
  485. bool operator==(const TStructExprType& other) const {
  486. if (GetSize() != other.GetSize()) {
  487. return false;
  488. }
  489. for (ui32 i = 0, e = GetSize(); i < e; ++i) {
  490. if (GetItems()[i] != other.GetItems()[i]) {
  491. return false;
  492. }
  493. }
  494. return true;
  495. }
  496. TString ToString() const {
  497. TStringBuilder sb;
  498. for (std::size_t i = 0; i < Items.size(); i++) {
  499. sb << i << ": " << Items[i]->GetName() << "(" << FormatType(Items[i]->GetItemType()) << ")";
  500. if (i != Items.size() - 1) {
  501. sb << ", ";
  502. }
  503. }
  504. return sb;
  505. }
  506. private:
  507. TVector<const TItemExprType*> Items;
  508. };
  509. class TListExprType : public TTypeAnnotationNode {
  510. public:
  511. static constexpr ETypeAnnotationKind KindValue = ETypeAnnotationKind::List;
  512. TListExprType(ui64 hash, const TTypeAnnotationNode* itemType)
  513. : TTypeAnnotationNode(KindValue, itemType->GetFlags() | TypeHasDynamicSize, hash, itemType->GetUsedPgExtensions())
  514. , ItemType(itemType)
  515. {
  516. }
  517. static ui64 MakeHash(const TTypeAnnotationNode* itemType) {
  518. ui64 hash = TypeHashMagic | (ui64)ETypeAnnotationKind::List;
  519. return StreamHash(itemType->GetHash(), hash);
  520. }
  521. const TTypeAnnotationNode* GetItemType() const {
  522. return ItemType;
  523. }
  524. bool operator==(const TListExprType& other) const {
  525. return GetItemType() == other.GetItemType();
  526. }
  527. private:
  528. const TTypeAnnotationNode* ItemType;
  529. };
  530. class TStreamExprType : public TTypeAnnotationNode {
  531. public:
  532. static constexpr ETypeAnnotationKind KindValue = ETypeAnnotationKind::Stream;
  533. TStreamExprType(ui64 hash, const TTypeAnnotationNode* itemType)
  534. : TTypeAnnotationNode(KindValue, itemType->GetFlags() | TypeNonPersistable, hash, itemType->GetUsedPgExtensions())
  535. , ItemType(itemType)
  536. {
  537. }
  538. static ui64 MakeHash(const TTypeAnnotationNode* itemType) {
  539. ui64 hash = TypeHashMagic | (ui64)ETypeAnnotationKind::Stream;
  540. return StreamHash(itemType->GetHash(), hash);
  541. }
  542. const TTypeAnnotationNode* GetItemType() const {
  543. return ItemType;
  544. }
  545. bool operator==(const TStreamExprType& other) const {
  546. return GetItemType() == other.GetItemType();
  547. }
  548. private:
  549. const TTypeAnnotationNode* ItemType;
  550. };
  551. class TFlowExprType : public TTypeAnnotationNode {
  552. public:
  553. static constexpr ETypeAnnotationKind KindValue = ETypeAnnotationKind::Flow;
  554. TFlowExprType(ui64 hash, const TTypeAnnotationNode* itemType)
  555. : TTypeAnnotationNode(KindValue, itemType->GetFlags() | TypeNonPersistable, hash, itemType->GetUsedPgExtensions())
  556. , ItemType(itemType)
  557. {
  558. }
  559. static ui64 MakeHash(const TTypeAnnotationNode* itemType) {
  560. ui64 hash = TypeHashMagic | (ui64)ETypeAnnotationKind::Flow;
  561. return StreamHash(itemType->GetHash(), hash);
  562. }
  563. const TTypeAnnotationNode* GetItemType() const {
  564. return ItemType;
  565. }
  566. bool operator==(const TFlowExprType& other) const {
  567. return GetItemType() == other.GetItemType();
  568. }
  569. private:
  570. const TTypeAnnotationNode* ItemType;
  571. };
  572. class TBlockExprType : public TTypeAnnotationNode {
  573. public:
  574. static constexpr ETypeAnnotationKind KindValue = ETypeAnnotationKind::Block;
  575. TBlockExprType(ui64 hash, const TTypeAnnotationNode* itemType)
  576. : TTypeAnnotationNode(KindValue, itemType->GetFlags() | TypeNonPersistable, hash, itemType->GetUsedPgExtensions())
  577. , ItemType(itemType)
  578. {
  579. }
  580. static ui64 MakeHash(const TTypeAnnotationNode* itemType) {
  581. ui64 hash = TypeHashMagic | (ui64)ETypeAnnotationKind::Block;
  582. return StreamHash(itemType->GetHash(), hash);
  583. }
  584. const TTypeAnnotationNode* GetItemType() const {
  585. return ItemType;
  586. }
  587. bool operator==(const TBlockExprType& other) const {
  588. return GetItemType() == other.GetItemType();
  589. }
  590. private:
  591. const TTypeAnnotationNode* ItemType;
  592. };
  593. class TScalarExprType : public TTypeAnnotationNode {
  594. public:
  595. static constexpr ETypeAnnotationKind KindValue = ETypeAnnotationKind::Scalar;
  596. TScalarExprType(ui64 hash, const TTypeAnnotationNode* itemType)
  597. : TTypeAnnotationNode(KindValue, itemType->GetFlags() | TypeNonPersistable, hash, itemType->GetUsedPgExtensions())
  598. , ItemType(itemType)
  599. {
  600. }
  601. static ui64 MakeHash(const TTypeAnnotationNode* itemType) {
  602. ui64 hash = TypeHashMagic | (ui64)ETypeAnnotationKind::Scalar;
  603. return StreamHash(itemType->GetHash(), hash);
  604. }
  605. const TTypeAnnotationNode* GetItemType() const {
  606. return ItemType;
  607. }
  608. bool operator==(const TScalarExprType& other) const {
  609. return GetItemType() == other.GetItemType();
  610. }
  611. private:
  612. const TTypeAnnotationNode* ItemType;
  613. };
  614. class TDataExprType : public TTypeAnnotationNode {
  615. public:
  616. static constexpr ETypeAnnotationKind KindValue = ETypeAnnotationKind::Data;
  617. TDataExprType(ui64 hash, EDataSlot slot)
  618. : TTypeAnnotationNode(KindValue, GetFlags(slot), hash, 0)
  619. , Slot(slot)
  620. {
  621. }
  622. static ui32 GetFlags(EDataSlot slot) {
  623. ui32 ret = TypeHasManyValues;
  624. auto props = NUdf::GetDataTypeInfo(slot).Features;
  625. if (!(props & NUdf::CanHash)) {
  626. ret |= TypeNonHashable;
  627. }
  628. if (!(props & NUdf::CanEquate)) {
  629. ret |= TypeNonEquatable;
  630. }
  631. if (!(props & NUdf::CanCompare)) {
  632. ret |= TypeNonComparable;
  633. ret |= TypeNonComparableInternal;
  634. }
  635. if (slot == NUdf::EDataSlot::Yson) {
  636. ret |= TypeHasBareYson;
  637. }
  638. if (props & NUdf::StringType) {
  639. ret |= TypeHasDynamicSize;
  640. }
  641. return ret;
  642. }
  643. static ui64 MakeHash(EDataSlot slot) {
  644. ui64 hash = TypeHashMagic | (ui64)ETypeAnnotationKind::Data;
  645. auto dataType = NUdf::GetDataTypeInfo(slot).Name;
  646. hash = StreamHash(dataType.size(), hash);
  647. return StreamHash(dataType.data(), dataType.size(), hash);
  648. }
  649. EDataSlot GetSlot() const {
  650. return Slot;
  651. }
  652. TStringBuf GetName() const {
  653. return NUdf::GetDataTypeInfo(Slot).Name;
  654. }
  655. bool operator==(const TDataExprType& other) const {
  656. return Slot == other.Slot;
  657. }
  658. private:
  659. EDataSlot Slot;
  660. };
  661. class TDataExprParamsType : public TDataExprType {
  662. public:
  663. TDataExprParamsType(ui64 hash, EDataSlot slot, const TStringBuf& one, const TStringBuf& two)
  664. : TDataExprType(hash, slot), One(one), Two(two)
  665. {}
  666. static ui64 MakeHash(EDataSlot slot, const TStringBuf& one, const TStringBuf& two) {
  667. auto hash = TDataExprType::MakeHash(slot);
  668. hash = StreamHash(one.size(), hash);
  669. hash = StreamHash(one.data(), one.size(), hash);
  670. hash = StreamHash(two.size(), hash);
  671. hash = StreamHash(two.data(), two.size(), hash);
  672. return hash;
  673. }
  674. const TStringBuf& GetParamOne() const {
  675. return One;
  676. }
  677. const TStringBuf& GetParamTwo() const {
  678. return Two;
  679. }
  680. bool operator==(const TDataExprParamsType& other) const {
  681. return GetSlot() == other.GetSlot() && GetParamOne() == other.GetParamOne() && GetParamTwo() == other.GetParamTwo();
  682. }
  683. bool Validate(TPosition position, TExprContext& ctx) const;
  684. bool Validate(TPositionHandle position, TExprContext& ctx) const;
  685. private:
  686. const TStringBuf One, Two;
  687. };
  688. class TPgExprType : public TTypeAnnotationNode {
  689. public:
  690. static constexpr ETypeAnnotationKind KindValue = ETypeAnnotationKind::Pg;
  691. // TODO: TypeHasDynamicSize for Pg types
  692. TPgExprType(ui64 hash, ui32 typeId)
  693. : TTypeAnnotationNode(KindValue, GetFlags(typeId), hash, GetPgExtensionsMask(typeId))
  694. , TypeId(typeId)
  695. {
  696. }
  697. static ui64 MakeHash(ui32 typeId) {
  698. ui64 hash = TypeHashMagic | (ui64)ETypeAnnotationKind::Pg;
  699. return StreamHash(typeId, hash);
  700. }
  701. const TString& GetName() const;
  702. ui32 GetId() const {
  703. return TypeId;
  704. }
  705. bool operator==(const TPgExprType& other) const {
  706. return TypeId == other.TypeId;
  707. }
  708. private:
  709. ui32 GetFlags(ui32 typeId);
  710. ui64 GetPgExtensionsMask(ui32 typeId);
  711. private:
  712. ui32 TypeId;
  713. };
  714. ui64 MakePgExtensionMask(ui32 extensionIndex);
  715. class TWorldExprType : public TTypeAnnotationNode {
  716. public:
  717. static constexpr ETypeAnnotationKind KindValue = ETypeAnnotationKind::World;
  718. TWorldExprType(ui64 hash)
  719. : TTypeAnnotationNode(KindValue,
  720. TypeNonComposable | TypeNonComputable | TypeNonPersistable | TypeNonInspectable, hash, 0)
  721. {
  722. }
  723. static ui64 MakeHash() {
  724. return TypeHashMagic | (ui64)ETypeAnnotationKind::World;
  725. }
  726. bool operator==(const TWorldExprType& other) const {
  727. Y_UNUSED(other);
  728. return true;
  729. }
  730. };
  731. class TOptionalExprType : public TTypeAnnotationNode {
  732. public:
  733. static constexpr ETypeAnnotationKind KindValue = ETypeAnnotationKind::Optional;
  734. TOptionalExprType(ui64 hash, const TTypeAnnotationNode* itemType)
  735. : TTypeAnnotationNode(KindValue, GetFlags(itemType), hash, itemType->GetUsedPgExtensions())
  736. , ItemType(itemType)
  737. {
  738. }
  739. static ui32 GetFlags(const TTypeAnnotationNode* itemType) {
  740. auto ret = TypeHasOptional | itemType->GetFlags();
  741. if (itemType->GetKind() == ETypeAnnotationKind::Data &&
  742. itemType->Cast<TDataExprType>()->GetSlot() == NUdf::EDataSlot::Yson) {
  743. ret = ret & ~TypeHasBareYson;
  744. }
  745. if (itemType->IsOptionalOrNull()) {
  746. ret |= TypeHasNestedOptional;
  747. }
  748. return ret;
  749. }
  750. static ui64 MakeHash(const TTypeAnnotationNode* itemType) {
  751. ui64 hash = TypeHashMagic | (ui64)ETypeAnnotationKind::Optional;
  752. return StreamHash(itemType->GetHash(), hash);
  753. }
  754. const TTypeAnnotationNode* GetItemType() const {
  755. return ItemType;
  756. }
  757. bool operator==(const TOptionalExprType& other) const {
  758. return GetItemType() == other.GetItemType();
  759. }
  760. private:
  761. const TTypeAnnotationNode* ItemType;
  762. };
  763. class TVariantExprType : public TTypeAnnotationNode {
  764. public:
  765. static constexpr ETypeAnnotationKind KindValue = ETypeAnnotationKind::Variant;
  766. TVariantExprType(ui64 hash, const TTypeAnnotationNode* underlyingType)
  767. : TTypeAnnotationNode(KindValue, MakeFlags(underlyingType), hash, underlyingType->GetUsedPgExtensions())
  768. , UnderlyingType(underlyingType)
  769. {
  770. }
  771. static ui64 MakeHash(const TTypeAnnotationNode* underlyingType) {
  772. ui64 hash = TypeHashMagic | (ui64)ETypeAnnotationKind::Variant;
  773. return StreamHash(underlyingType->GetHash(), hash);
  774. }
  775. const TTypeAnnotationNode* GetUnderlyingType() const {
  776. return UnderlyingType;
  777. }
  778. bool operator==(const TVariantExprType& other) const {
  779. return GetUnderlyingType() == other.GetUnderlyingType();
  780. }
  781. bool Validate(TPosition position, TExprContext& ctx) const;
  782. bool Validate(TPositionHandle position, TExprContext& ctx) const;
  783. static ui32 MakeFlags(const TTypeAnnotationNode* underlyingType);
  784. private:
  785. const TTypeAnnotationNode* UnderlyingType;
  786. };
  787. class TTypeExprType : public TTypeAnnotationNode {
  788. public:
  789. static constexpr ETypeAnnotationKind KindValue = ETypeAnnotationKind::Type;
  790. TTypeExprType(ui64 hash, const TTypeAnnotationNode* type)
  791. : TTypeAnnotationNode(KindValue, TypeNonPersistable | TypeNonComputable, hash, 0)
  792. , Type(type)
  793. {
  794. }
  795. static ui64 MakeHash(const TTypeAnnotationNode* type) {
  796. ui64 hash = TypeHashMagic | (ui64)ETypeAnnotationKind::Type;
  797. return StreamHash(type->GetHash(), hash);
  798. }
  799. const TTypeAnnotationNode* GetType() const {
  800. return Type;
  801. }
  802. bool operator==(const TTypeExprType& other) const {
  803. return GetType() == other.GetType();
  804. }
  805. private:
  806. const TTypeAnnotationNode* Type;
  807. };
  808. class TDictExprType : public TTypeAnnotationNode {
  809. public:
  810. static constexpr ETypeAnnotationKind KindValue = ETypeAnnotationKind::Dict;
  811. TDictExprType(ui64 hash, const TTypeAnnotationNode* keyType, const TTypeAnnotationNode* payloadType)
  812. : TTypeAnnotationNode(KindValue, TypeNonComparable | TypeHasDynamicSize |
  813. keyType->GetFlags() | payloadType->GetFlags(), hash,
  814. keyType->GetUsedPgExtensions() | payloadType->GetUsedPgExtensions())
  815. , KeyType(keyType)
  816. , PayloadType(payloadType)
  817. {
  818. }
  819. static ui64 MakeHash(const TTypeAnnotationNode* keyType, const TTypeAnnotationNode* payloadType) {
  820. ui64 hash = TypeHashMagic | (ui64)ETypeAnnotationKind::Dict;
  821. return StreamHash(StreamHash(keyType->GetHash(), hash), payloadType->GetHash());
  822. }
  823. bool Validate(TPosition position, TExprContext& ctx) const;
  824. bool Validate(TPositionHandle position, TExprContext& ctx) const;
  825. const TTypeAnnotationNode* GetKeyType() const {
  826. return KeyType;
  827. }
  828. const TTypeAnnotationNode* GetPayloadType() const {
  829. return PayloadType;
  830. }
  831. bool operator==(const TDictExprType& other) const {
  832. return GetKeyType() == other.GetKeyType() &&
  833. GetPayloadType() == other.GetPayloadType();
  834. }
  835. private:
  836. const TTypeAnnotationNode* KeyType;
  837. const TTypeAnnotationNode* PayloadType;
  838. };
  839. class TVoidExprType : public TTypeAnnotationNode {
  840. public:
  841. static constexpr ETypeAnnotationKind KindValue = ETypeAnnotationKind::Void;
  842. TVoidExprType(ui64 hash)
  843. : TTypeAnnotationNode(KindValue, 0, hash, 0)
  844. {
  845. }
  846. static ui64 MakeHash() {
  847. return TypeHashMagic | (ui64)ETypeAnnotationKind::Void;
  848. }
  849. bool operator==(const TVoidExprType& other) const {
  850. Y_UNUSED(other);
  851. return true;
  852. }
  853. };
  854. class TNullExprType : public TTypeAnnotationNode {
  855. public:
  856. static constexpr ETypeAnnotationKind KindValue = ETypeAnnotationKind::Null;
  857. TNullExprType(ui64 hash)
  858. : TTypeAnnotationNode(KindValue, TypeHasNull, hash, 0)
  859. {
  860. }
  861. static ui64 MakeHash() {
  862. return TypeHashMagic | (ui64)ETypeAnnotationKind::Null;
  863. }
  864. bool operator==(const TNullExprType& other) const {
  865. Y_UNUSED(other);
  866. return true;
  867. }
  868. };
  869. struct TArgumentFlags {
  870. enum {
  871. AutoMap = 0x01,
  872. };
  873. };
  874. class TCallableExprType : public TTypeAnnotationNode {
  875. public:
  876. static constexpr ETypeAnnotationKind KindValue = ETypeAnnotationKind::Callable;
  877. struct TArgumentInfo {
  878. const TTypeAnnotationNode* Type = nullptr;
  879. TStringBuf Name;
  880. ui64 Flags = 0;
  881. bool operator==(const TArgumentInfo& other) const {
  882. return Type == other.Type && Name == other.Name && Flags == other.Flags;
  883. }
  884. bool operator!=(const TArgumentInfo& other) const {
  885. return !(*this == other);
  886. }
  887. };
  888. TCallableExprType(ui64 hash, const TTypeAnnotationNode* returnType, const TVector<TArgumentInfo>& arguments
  889. , size_t optionalArgumentsCount, const TStringBuf& payload)
  890. : TTypeAnnotationNode(KindValue, MakeFlags(returnType), hash, returnType->GetUsedPgExtensions())
  891. , ReturnType(returnType)
  892. , Arguments(arguments)
  893. , OptionalArgumentsCount(optionalArgumentsCount)
  894. , Payload(payload)
  895. {
  896. for (ui32 i = 0; i < Arguments.size(); ++i) {
  897. const auto& arg = Arguments[i];
  898. if (!arg.Name.empty()) {
  899. IndexByName.insert({ arg.Name, i });
  900. }
  901. }
  902. }
  903. static ui64 MakeHash(const TTypeAnnotationNode* returnType, const TVector<TArgumentInfo>& arguments
  904. , size_t optionalArgumentsCount, const TStringBuf& payload) {
  905. ui64 hash = TypeHashMagic | (ui64)ETypeAnnotationKind::Callable;
  906. hash = StreamHash(returnType->GetHash(), hash);
  907. hash = StreamHash(arguments.size(), hash);
  908. for (const auto& arg : arguments) {
  909. hash = StreamHash(arg.Name.size(), hash);
  910. hash = StreamHash(arg.Name.data(), arg.Name.size(), hash);
  911. hash = StreamHash(arg.Flags, hash);
  912. hash = StreamHash(arg.Type->GetHash(), hash);
  913. }
  914. hash = StreamHash(optionalArgumentsCount, hash);
  915. hash = StreamHash(payload.size(), hash);
  916. hash = StreamHash(payload.data(), payload.size(), hash);
  917. return hash;
  918. }
  919. const TTypeAnnotationNode* GetReturnType() const {
  920. return ReturnType;
  921. }
  922. size_t GetOptionalArgumentsCount() const {
  923. return OptionalArgumentsCount;
  924. }
  925. const TStringBuf& GetPayload() const {
  926. return Payload;
  927. }
  928. size_t GetArgumentsSize() const {
  929. return Arguments.size();
  930. }
  931. const TVector<TArgumentInfo>& GetArguments() const {
  932. return Arguments;
  933. }
  934. bool operator==(const TCallableExprType& other) const {
  935. if (GetArgumentsSize() != other.GetArgumentsSize()) {
  936. return false;
  937. }
  938. if (GetOptionalArgumentsCount() != other.GetOptionalArgumentsCount()) {
  939. return false;
  940. }
  941. if (GetReturnType() != other.GetReturnType()) {
  942. return false;
  943. }
  944. for (ui32 i = 0, e = GetArgumentsSize(); i < e; ++i) {
  945. if (GetArguments()[i] != other.GetArguments()[i]) {
  946. return false;
  947. }
  948. }
  949. return true;
  950. }
  951. bool Validate(TPosition position, TExprContext& ctx) const;
  952. bool Validate(TPositionHandle position, TExprContext& ctx) const;
  953. TMaybe<ui32> ArgumentIndexByName(const TStringBuf& name) const {
  954. auto it = IndexByName.find(name);
  955. if (it == IndexByName.end()) {
  956. return {};
  957. }
  958. return it->second;
  959. }
  960. private:
  961. static ui32 MakeFlags(const TTypeAnnotationNode* returnType) {
  962. ui32 flags = TypeNonPersistable;
  963. flags |= returnType->GetFlags();
  964. return flags;
  965. }
  966. private:
  967. const TTypeAnnotationNode* ReturnType;
  968. TVector<TArgumentInfo> Arguments;
  969. const size_t OptionalArgumentsCount;
  970. const TStringBuf Payload;
  971. THashMap<TStringBuf, ui32> IndexByName;
  972. };
  973. class TGenericExprType : public TTypeAnnotationNode {
  974. public:
  975. static constexpr ETypeAnnotationKind KindValue = ETypeAnnotationKind::Generic;
  976. TGenericExprType(ui64 hash)
  977. : TTypeAnnotationNode(KindValue, TypeNonComputable, hash, 0)
  978. {
  979. }
  980. static ui64 MakeHash() {
  981. return TypeHashMagic | (ui64)ETypeAnnotationKind::Generic;
  982. }
  983. bool operator==(const TGenericExprType& other) const {
  984. Y_UNUSED(other);
  985. return true;
  986. }
  987. };
  988. class TResourceExprType : public TTypeAnnotationNode {
  989. public:
  990. static constexpr ETypeAnnotationKind KindValue = ETypeAnnotationKind::Resource;
  991. TResourceExprType(ui64 hash, const TStringBuf& tag)
  992. : TTypeAnnotationNode(KindValue, TypeNonPersistable | TypeHasManyValues, hash, 0)
  993. , Tag(tag)
  994. {}
  995. static ui64 MakeHash(const TStringBuf& tag) {
  996. ui64 hash = TypeHashMagic | (ui64)ETypeAnnotationKind::Resource;
  997. hash = StreamHash(tag.size(), hash);
  998. return StreamHash(tag.data(), tag.size(), hash);
  999. }
  1000. const TStringBuf& GetTag() const {
  1001. return Tag;
  1002. }
  1003. bool operator==(const TResourceExprType& other) const {
  1004. return Tag == other.Tag;
  1005. }
  1006. private:
  1007. const TStringBuf Tag;
  1008. };
  1009. class TTaggedExprType : public TTypeAnnotationNode {
  1010. public:
  1011. static constexpr ETypeAnnotationKind KindValue = ETypeAnnotationKind::Tagged;
  1012. TTaggedExprType(ui64 hash, const TTypeAnnotationNode* baseType, const TStringBuf& tag)
  1013. : TTypeAnnotationNode(KindValue, baseType->GetFlags(), hash, baseType->GetUsedPgExtensions())
  1014. , BaseType(baseType)
  1015. , Tag(tag)
  1016. {}
  1017. static ui64 MakeHash(const TTypeAnnotationNode* baseType, const TStringBuf& tag) {
  1018. ui64 hash = TypeHashMagic | (ui64)ETypeAnnotationKind::Tagged;
  1019. hash = StreamHash(baseType->GetHash(), hash);
  1020. hash = StreamHash(tag.size(), hash);
  1021. return StreamHash(tag.data(), tag.size(), hash);
  1022. }
  1023. const TStringBuf& GetTag() const {
  1024. return Tag;
  1025. }
  1026. const TTypeAnnotationNode* GetBaseType() const {
  1027. return BaseType;
  1028. }
  1029. bool operator==(const TTaggedExprType& other) const {
  1030. return Tag == other.Tag && GetBaseType() == other.GetBaseType();
  1031. }
  1032. bool Validate(TPosition position, TExprContext& ctx) const;
  1033. bool Validate(TPositionHandle position, TExprContext& ctx) const;
  1034. private:
  1035. const TTypeAnnotationNode* BaseType;
  1036. const TStringBuf Tag;
  1037. };
  1038. class TErrorExprType : public TTypeAnnotationNode {
  1039. public:
  1040. static constexpr ETypeAnnotationKind KindValue = ETypeAnnotationKind::Error;
  1041. TErrorExprType(ui64 hash, const TIssue& error)
  1042. : TTypeAnnotationNode(KindValue, 0, hash, 0)
  1043. , Error(error)
  1044. {}
  1045. static ui64 MakeHash(const TIssue& error) {
  1046. return error.Hash();
  1047. }
  1048. const TIssue& GetError() const {
  1049. return Error;
  1050. }
  1051. bool operator==(const TErrorExprType& other) const {
  1052. return Error == other.Error;
  1053. }
  1054. private:
  1055. const TIssue Error;
  1056. };
  1057. class TEmptyListExprType : public TTypeAnnotationNode {
  1058. public:
  1059. static constexpr ETypeAnnotationKind KindValue = ETypeAnnotationKind::EmptyList;
  1060. TEmptyListExprType(ui64 hash)
  1061. : TTypeAnnotationNode(KindValue, 0, hash, 0)
  1062. {
  1063. }
  1064. static ui64 MakeHash() {
  1065. return TypeHashMagic | (ui64)ETypeAnnotationKind::EmptyList;
  1066. }
  1067. bool operator==(const TEmptyListExprType& other) const {
  1068. Y_UNUSED(other);
  1069. return true;
  1070. }
  1071. };
  1072. class TEmptyDictExprType : public TTypeAnnotationNode {
  1073. public:
  1074. static constexpr ETypeAnnotationKind KindValue = ETypeAnnotationKind::EmptyDict;
  1075. TEmptyDictExprType(ui64 hash)
  1076. : TTypeAnnotationNode(KindValue, 0, hash, 0)
  1077. {
  1078. }
  1079. static ui64 MakeHash() {
  1080. return TypeHashMagic | (ui64)ETypeAnnotationKind::EmptyDict;
  1081. }
  1082. bool operator==(const TEmptyDictExprType& other) const {
  1083. Y_UNUSED(other);
  1084. return true;
  1085. }
  1086. };
  1087. inline bool TTypeAnnotationNode::Equals(const TTypeAnnotationNode& node) const {
  1088. if (this == &node) {
  1089. return true;
  1090. }
  1091. if (Hash != node.GetHash()) {
  1092. return false;
  1093. }
  1094. if (Kind != node.GetKind()) {
  1095. return false;
  1096. }
  1097. switch (Kind) {
  1098. case ETypeAnnotationKind::Unit:
  1099. return static_cast<const TUnitExprType&>(*this) == static_cast<const TUnitExprType&>(node);
  1100. case ETypeAnnotationKind::Tuple:
  1101. return static_cast<const TTupleExprType&>(*this) == static_cast<const TTupleExprType&>(node);
  1102. case ETypeAnnotationKind::Struct:
  1103. return static_cast<const TStructExprType&>(*this) == static_cast<const TStructExprType&>(node);
  1104. case ETypeAnnotationKind::Item:
  1105. return static_cast<const TItemExprType&>(*this) == static_cast<const TItemExprType&>(node);
  1106. case ETypeAnnotationKind::List:
  1107. return static_cast<const TListExprType&>(*this) == static_cast<const TListExprType&>(node);
  1108. case ETypeAnnotationKind::Data:
  1109. return static_cast<const TDataExprType&>(*this) == static_cast<const TDataExprType&>(node);
  1110. case ETypeAnnotationKind::Pg:
  1111. return static_cast<const TPgExprType&>(*this) == static_cast<const TPgExprType&>(node);
  1112. case ETypeAnnotationKind::World:
  1113. return static_cast<const TWorldExprType&>(*this) == static_cast<const TWorldExprType&>(node);
  1114. case ETypeAnnotationKind::Optional:
  1115. return static_cast<const TOptionalExprType&>(*this) == static_cast<const TOptionalExprType&>(node);
  1116. case ETypeAnnotationKind::Type:
  1117. return static_cast<const TTypeExprType&>(*this) == static_cast<const TTypeExprType&>(node);
  1118. case ETypeAnnotationKind::Dict:
  1119. return static_cast<const TDictExprType&>(*this) == static_cast<const TDictExprType&>(node);
  1120. case ETypeAnnotationKind::Void:
  1121. return static_cast<const TVoidExprType&>(*this) == static_cast<const TVoidExprType&>(node);
  1122. case ETypeAnnotationKind::Null:
  1123. return static_cast<const TNullExprType&>(*this) == static_cast<const TNullExprType&>(node);
  1124. case ETypeAnnotationKind::Callable:
  1125. return static_cast<const TCallableExprType&>(*this) == static_cast<const TCallableExprType&>(node);
  1126. case ETypeAnnotationKind::Generic:
  1127. return static_cast<const TGenericExprType&>(*this) == static_cast<const TGenericExprType&>(node);
  1128. case ETypeAnnotationKind::Resource:
  1129. return static_cast<const TResourceExprType&>(*this) == static_cast<const TResourceExprType&>(node);
  1130. case ETypeAnnotationKind::Tagged:
  1131. return static_cast<const TTaggedExprType&>(*this) == static_cast<const TTaggedExprType&>(node);
  1132. case ETypeAnnotationKind::Error:
  1133. return static_cast<const TErrorExprType&>(*this) == static_cast<const TErrorExprType&>(node);
  1134. case ETypeAnnotationKind::Variant:
  1135. return static_cast<const TVariantExprType&>(*this) == static_cast<const TVariantExprType&>(node);
  1136. case ETypeAnnotationKind::Stream:
  1137. return static_cast<const TStreamExprType&>(*this) == static_cast<const TStreamExprType&>(node);
  1138. case ETypeAnnotationKind::Flow:
  1139. return static_cast<const TFlowExprType&>(*this) == static_cast<const TFlowExprType&>(node);
  1140. case ETypeAnnotationKind::EmptyList:
  1141. return static_cast<const TEmptyListExprType&>(*this) == static_cast<const TEmptyListExprType&>(node);
  1142. case ETypeAnnotationKind::EmptyDict:
  1143. return static_cast<const TEmptyDictExprType&>(*this) == static_cast<const TEmptyDictExprType&>(node);
  1144. case ETypeAnnotationKind::Multi:
  1145. return static_cast<const TMultiExprType&>(*this) == static_cast<const TMultiExprType&>(node);
  1146. case ETypeAnnotationKind::Block:
  1147. return static_cast<const TBlockExprType&>(*this) == static_cast<const TBlockExprType&>(node);
  1148. case ETypeAnnotationKind::Scalar:
  1149. return static_cast<const TScalarExprType&>(*this) == static_cast<const TScalarExprType&>(node);
  1150. case ETypeAnnotationKind::LastType:
  1151. YQL_ENSURE(false, "Incorrect type");
  1152. }
  1153. return false;
  1154. }
  1155. inline void TTypeAnnotationNode::Accept(TTypeAnnotationVisitor& visitor) const {
  1156. switch (Kind) {
  1157. case ETypeAnnotationKind::Unit:
  1158. return visitor.Visit(static_cast<const TUnitExprType&>(*this));
  1159. case ETypeAnnotationKind::Tuple:
  1160. return visitor.Visit(static_cast<const TTupleExprType&>(*this));
  1161. case ETypeAnnotationKind::Struct:
  1162. return visitor.Visit(static_cast<const TStructExprType&>(*this));
  1163. case ETypeAnnotationKind::Item:
  1164. return visitor.Visit(static_cast<const TItemExprType&>(*this));
  1165. case ETypeAnnotationKind::List:
  1166. return visitor.Visit(static_cast<const TListExprType&>(*this));
  1167. case ETypeAnnotationKind::Data:
  1168. return visitor.Visit(static_cast<const TDataExprType&>(*this));
  1169. case ETypeAnnotationKind::Pg:
  1170. return visitor.Visit(static_cast<const TPgExprType&>(*this));
  1171. case ETypeAnnotationKind::World:
  1172. return visitor.Visit(static_cast<const TWorldExprType&>(*this));
  1173. case ETypeAnnotationKind::Optional:
  1174. return visitor.Visit(static_cast<const TOptionalExprType&>(*this));
  1175. case ETypeAnnotationKind::Type:
  1176. return visitor.Visit(static_cast<const TTypeExprType&>(*this));
  1177. case ETypeAnnotationKind::Dict:
  1178. return visitor.Visit(static_cast<const TDictExprType&>(*this));
  1179. case ETypeAnnotationKind::Void:
  1180. return visitor.Visit(static_cast<const TVoidExprType&>(*this));
  1181. case ETypeAnnotationKind::Null:
  1182. return visitor.Visit(static_cast<const TNullExprType&>(*this));
  1183. case ETypeAnnotationKind::Callable:
  1184. return visitor.Visit(static_cast<const TCallableExprType&>(*this));
  1185. case ETypeAnnotationKind::Generic:
  1186. return visitor.Visit(static_cast<const TGenericExprType&>(*this));
  1187. case ETypeAnnotationKind::Resource:
  1188. return visitor.Visit(static_cast<const TResourceExprType&>(*this));
  1189. case ETypeAnnotationKind::Tagged:
  1190. return visitor.Visit(static_cast<const TTaggedExprType&>(*this));
  1191. case ETypeAnnotationKind::Error:
  1192. return visitor.Visit(static_cast<const TErrorExprType&>(*this));
  1193. case ETypeAnnotationKind::Variant:
  1194. return visitor.Visit(static_cast<const TVariantExprType&>(*this));
  1195. case ETypeAnnotationKind::Stream:
  1196. return visitor.Visit(static_cast<const TStreamExprType&>(*this));
  1197. case ETypeAnnotationKind::Flow:
  1198. return visitor.Visit(static_cast<const TFlowExprType&>(*this));
  1199. case ETypeAnnotationKind::EmptyList:
  1200. return visitor.Visit(static_cast<const TEmptyListExprType&>(*this));
  1201. case ETypeAnnotationKind::EmptyDict:
  1202. return visitor.Visit(static_cast<const TEmptyDictExprType&>(*this));
  1203. case ETypeAnnotationKind::Multi:
  1204. return visitor.Visit(static_cast<const TMultiExprType&>(*this));
  1205. case ETypeAnnotationKind::Block:
  1206. return visitor.Visit(static_cast<const TBlockExprType&>(*this));
  1207. case ETypeAnnotationKind::Scalar:
  1208. return visitor.Visit(static_cast<const TScalarExprType&>(*this));
  1209. case ETypeAnnotationKind::LastType:
  1210. YQL_ENSURE(false, "Incorrect type");
  1211. }
  1212. }
  1213. class TExprNode {
  1214. friend class TExprNodeBuilder;
  1215. friend class TExprNodeReplaceBuilder;
  1216. friend struct TExprContext;
  1217. private:
  1218. struct TExprFlags {
  1219. enum : ui16 {
  1220. Default = 0,
  1221. Dead = 0x01,
  1222. Frozen = 0x02,
  1223. };
  1224. static constexpr ui32 FlagsMask = 0x03; // all flags should fit here
  1225. };
  1226. public:
  1227. typedef TIntrusivePtr<TExprNode> TPtr;
  1228. typedef std::vector<TPtr> TListType;
  1229. typedef TArrayRef<const TPtr> TChildrenType;
  1230. struct TPtrHash : private std::hash<const TExprNode*> {
  1231. size_t operator()(const TPtr& p) const {
  1232. return std::hash<const TExprNode*>::operator()(p.Get());
  1233. }
  1234. };
  1235. #define YQL_EXPR_NODE_TYPE_MAP(xx) \
  1236. xx(List, 0) \
  1237. xx(Atom, 1) \
  1238. xx(Callable, 2) \
  1239. xx(Lambda, 3) \
  1240. xx(Argument, 4) \
  1241. xx(Arguments, 5) \
  1242. xx(World, 7)
  1243. enum EType : ui8 {
  1244. YQL_EXPR_NODE_TYPE_MAP(ENUM_VALUE_GEN)
  1245. };
  1246. static constexpr ui32 TypeMask = 0x07; // all types should fit here
  1247. #define YQL_EXPR_NODE_STATE_MAP(xx) \
  1248. xx(Initial, 0) \
  1249. xx(TypeInProgress, 1) \
  1250. xx(TypePending, 2) \
  1251. xx(TypeComplete, 3) \
  1252. xx(ConstrInProgress, 4) \
  1253. xx(ConstrPending, 5) \
  1254. xx(ConstrComplete, 6) \
  1255. xx(ExecutionRequired, 7) \
  1256. xx(ExecutionInProgress, 8) \
  1257. xx(ExecutionPending, 9) \
  1258. xx(ExecutionComplete, 10) \
  1259. xx(Error, 11) \
  1260. xx(Last, 12)
  1261. enum class EState : ui8 {
  1262. YQL_EXPR_NODE_STATE_MAP(ENUM_VALUE_GEN)
  1263. };
  1264. static TPtr GetResult(const TPtr& node) {
  1265. return node->Type() == Callable ? node->Result : node;
  1266. }
  1267. const TExprNode& GetResult() const {
  1268. ENSURE_NOT_DELETED
  1269. return Type() == Callable ? *Result : *this;
  1270. }
  1271. bool HasResult() const {
  1272. ENSURE_NOT_DELETED
  1273. return Type() != Callable || bool(Result);
  1274. }
  1275. void SetResult(TPtr&& result) {
  1276. ENSURE_NOT_DELETED
  1277. ENSURE_NOT_FROZEN
  1278. Result = std::move(result);
  1279. }
  1280. bool IsCallable(const std::string_view& name) const {
  1281. ENSURE_NOT_DELETED
  1282. return Type() == TExprNode::Callable && Content() == name;
  1283. }
  1284. bool IsCallable(const std::initializer_list<std::string_view>& names) const {
  1285. ENSURE_NOT_DELETED
  1286. return Type() == TExprNode::Callable && names.end() != std::find(names.begin(), names.end(), Content());
  1287. }
  1288. template <class TKey>
  1289. bool IsCallable(const THashSet<TKey>& names) const {
  1290. ENSURE_NOT_DELETED
  1291. return Type() == TExprNode::Callable && names.contains(Content());
  1292. }
  1293. bool IsCallable() const {
  1294. ENSURE_NOT_DELETED
  1295. return Type() == TExprNode::Callable;
  1296. }
  1297. bool IsAtom() const {
  1298. ENSURE_NOT_DELETED
  1299. return Type() == TExprNode::Atom;
  1300. }
  1301. bool IsWorld() const {
  1302. ENSURE_NOT_DELETED
  1303. return Type() == TExprNode::World;
  1304. }
  1305. bool IsAtom(const std::string_view& content) const {
  1306. ENSURE_NOT_DELETED
  1307. return Type() == TExprNode::Atom && Content() == content;
  1308. }
  1309. bool IsAtom(const std::initializer_list<std::string_view>& names) const {
  1310. ENSURE_NOT_DELETED
  1311. return Type() == TExprNode::Atom && names.end() != std::find(names.begin(), names.end(), Content());
  1312. }
  1313. bool IsList() const {
  1314. ENSURE_NOT_DELETED
  1315. return Type() == TExprNode::List;
  1316. }
  1317. bool IsLambda() const {
  1318. ENSURE_NOT_DELETED
  1319. return Type() == TExprNode::Lambda;
  1320. }
  1321. bool IsArgument() const {
  1322. ENSURE_NOT_DELETED
  1323. return Type() == TExprNode::Argument;
  1324. }
  1325. bool IsArguments() const {
  1326. ENSURE_NOT_DELETED
  1327. return Type() == TExprNode::Arguments;
  1328. }
  1329. bool IsComposable() const {
  1330. ENSURE_NOT_DELETED
  1331. return !IsLambda() && TypeAnnotation_->IsComposable();
  1332. }
  1333. bool IsPersistable() const {
  1334. ENSURE_NOT_DELETED
  1335. return !IsLambda() && TypeAnnotation_->IsPersistable();
  1336. }
  1337. bool IsComputable() const {
  1338. ENSURE_NOT_DELETED
  1339. return !IsLambda() && TypeAnnotation_->IsComputable();
  1340. }
  1341. bool IsInspectable() const {
  1342. ENSURE_NOT_DELETED
  1343. return !IsLambda() && TypeAnnotation_->IsInspectable();
  1344. }
  1345. bool ForDisclosing() const {
  1346. ENSURE_NOT_DELETED
  1347. return Type() == TExprNode::List && ShallBeDisclosed;
  1348. }
  1349. void SetDisclosing() {
  1350. ENSURE_NOT_DELETED
  1351. Y_ENSURE(Type() == TExprNode::List, "Must be list.");
  1352. ShallBeDisclosed = true;
  1353. }
  1354. ui32 GetFlagsToCompare() const {
  1355. ENSURE_NOT_DELETED
  1356. ui32 ret = Flags();
  1357. if ((ret & TNodeFlags::BinaryContent) == 0) {
  1358. ret |= TNodeFlags::ArbitraryContent | TNodeFlags::MultilineContent;
  1359. }
  1360. return ret;
  1361. }
  1362. TString Dump() const;
  1363. bool StartsExecution() const {
  1364. ENSURE_NOT_DELETED
  1365. return State == EState::ExecutionComplete
  1366. || State == EState::ExecutionInProgress
  1367. || State == EState::ExecutionRequired
  1368. || State == EState::ExecutionPending;
  1369. }
  1370. bool IsComplete() const {
  1371. YQL_ENSURE(HasLambdaScope);
  1372. return !OuterLambda;
  1373. }
  1374. bool IsLiteralList() const {
  1375. YQL_ENSURE(IsList());
  1376. return LiteralList;
  1377. }
  1378. void SetLiteralList(bool literal) {
  1379. YQL_ENSURE(IsList());
  1380. LiteralList = literal;
  1381. }
  1382. void Ref() {
  1383. ENSURE_NOT_DELETED
  1384. ENSURE_NOT_FROZEN
  1385. Y_ENSURE(RefCount_ < Max<ui32>());
  1386. ++RefCount_;
  1387. }
  1388. void UnRef() {
  1389. ENSURE_NOT_DELETED
  1390. ENSURE_NOT_FROZEN
  1391. if (!--RefCount_) {
  1392. Result.Reset();
  1393. Children_.clear();
  1394. Constraints_.Clear();
  1395. MarkDead();
  1396. }
  1397. }
  1398. ui32 UseCount() const { return RefCount_; }
  1399. bool Unique() const { return 1U == UseCount(); }
  1400. bool Dead() const {
  1401. return ExprFlags_ & TExprFlags::Dead;
  1402. }
  1403. TPositionHandle Pos() const {
  1404. ENSURE_NOT_DELETED
  1405. return Position_;
  1406. }
  1407. TPosition Pos(const TExprContext& ctx) const;
  1408. EType Type() const {
  1409. ENSURE_NOT_DELETED
  1410. return (EType)Type_;
  1411. }
  1412. TListType::size_type ChildrenSize() const {
  1413. ENSURE_NOT_DELETED
  1414. return Children_.size();
  1415. }
  1416. TExprNode* Child(ui32 index) const {
  1417. ENSURE_NOT_DELETED
  1418. Y_ENSURE(index < Children_.size(), "index out of range");
  1419. return Children_[index].Get();
  1420. }
  1421. TPtr ChildPtr(ui32 index) const {
  1422. ENSURE_NOT_DELETED
  1423. Y_ENSURE(index < Children_.size(), "index out of range");
  1424. return Children_[index];
  1425. }
  1426. TPtr& ChildRef(ui32 index) {
  1427. ENSURE_NOT_DELETED
  1428. ENSURE_NOT_FROZEN
  1429. Y_ENSURE(index < Children_.size(), "index out of range");
  1430. return Children_[index];
  1431. }
  1432. const TExprNode& Head() const {
  1433. ENSURE_NOT_DELETED
  1434. Y_ENSURE(!Children_.empty(), "no children");
  1435. return *Children_.front();
  1436. }
  1437. TExprNode& Head() {
  1438. ENSURE_NOT_DELETED
  1439. Y_ENSURE(!Children_.empty(), "no children");
  1440. return *Children_.front();
  1441. }
  1442. TPtr HeadPtr() const {
  1443. ENSURE_NOT_DELETED
  1444. Y_ENSURE(!Children_.empty(), "no children");
  1445. return Children_.front();
  1446. }
  1447. TPtr& HeadRef() {
  1448. ENSURE_NOT_DELETED
  1449. ENSURE_NOT_FROZEN
  1450. Y_ENSURE(!Children_.empty(), "no children");
  1451. return Children_.front();
  1452. }
  1453. const TExprNode& Tail() const {
  1454. ENSURE_NOT_DELETED
  1455. Y_ENSURE(!Children_.empty(), "no children");
  1456. return *Children_.back();
  1457. }
  1458. TExprNode& Tail() {
  1459. ENSURE_NOT_DELETED
  1460. Y_ENSURE(!Children_.empty(), "no children");
  1461. return *Children_.back();
  1462. }
  1463. TPtr TailPtr() const {
  1464. ENSURE_NOT_DELETED
  1465. Y_ENSURE(!Children_.empty(), "no children");
  1466. return Children_.back();
  1467. }
  1468. TPtr& TailRef() {
  1469. ENSURE_NOT_DELETED
  1470. ENSURE_NOT_FROZEN
  1471. Y_ENSURE(!Children_.empty(), "no children");
  1472. return Children_.back();
  1473. }
  1474. TChildrenType Children() const {
  1475. ENSURE_NOT_DELETED
  1476. return TChildrenType(Children_.data(), Children_.size());
  1477. }
  1478. TListType ChildrenList() const {
  1479. ENSURE_NOT_DELETED
  1480. return Children_;
  1481. }
  1482. void ChangeChildrenInplace(TListType&& newChildren) {
  1483. ENSURE_NOT_DELETED
  1484. Children_ = std::move(newChildren);
  1485. }
  1486. template<class F>
  1487. void ForEachChild(const F& visitor) const {
  1488. for (const auto& child : Children_)
  1489. visitor(*child);
  1490. }
  1491. TStringBuf Content() const {
  1492. ENSURE_NOT_DELETED
  1493. return ContentUnchecked();
  1494. }
  1495. ui32 Flags() const {
  1496. ENSURE_NOT_DELETED
  1497. return Flags_;
  1498. }
  1499. void NormalizeAtomFlags(const TExprNode& otherAtom) {
  1500. ENSURE_NOT_DELETED
  1501. ENSURE_NOT_FROZEN
  1502. Y_ENSURE(Type_ == Atom && otherAtom.Type_ == Atom, "Expected atoms");
  1503. Y_ENSURE((Flags_ & TNodeFlags::BinaryContent) ==
  1504. (otherAtom.Flags_ & TNodeFlags::BinaryContent), "Mismatch binary atom flags");
  1505. if (!(Flags_ & TNodeFlags::BinaryContent)) {
  1506. Flags_ = Min(Flags_, otherAtom.Flags_);
  1507. }
  1508. }
  1509. ui64 UniqueId() const {
  1510. ENSURE_NOT_DELETED
  1511. return UniqueId_;
  1512. }
  1513. const TConstraintNode* GetConstraint(TStringBuf name) const {
  1514. ENSURE_NOT_DELETED
  1515. Y_ENSURE(static_cast<EState>(State) >= EState::ConstrComplete);
  1516. return Constraints_.GetConstraint(name);
  1517. }
  1518. template <class TConstraintType>
  1519. const TConstraintType* GetConstraint() const {
  1520. ENSURE_NOT_DELETED
  1521. Y_ENSURE(static_cast<EState>(State) >= EState::ConstrComplete);
  1522. return Constraints_.GetConstraint<TConstraintType>();
  1523. }
  1524. const TConstraintNode::TListType& GetAllConstraints() const {
  1525. ENSURE_NOT_DELETED
  1526. Y_ENSURE(static_cast<EState>(State) >= EState::ConstrComplete);
  1527. return Constraints_.GetAllConstraints();
  1528. }
  1529. const TConstraintSet& GetConstraintSet() const {
  1530. ENSURE_NOT_DELETED
  1531. Y_ENSURE(static_cast<EState>(State) >= EState::ConstrComplete);
  1532. return Constraints_;
  1533. }
  1534. void AddConstraint(const TConstraintNode* node) {
  1535. ENSURE_NOT_DELETED
  1536. ENSURE_NOT_FROZEN
  1537. Y_ENSURE(static_cast<EState>(State) >= EState::TypeComplete);
  1538. Y_ENSURE(!StartsExecution());
  1539. Constraints_.AddConstraint(node);
  1540. State = EState::ConstrComplete;
  1541. }
  1542. void CopyConstraints(const TExprNode& node) {
  1543. ENSURE_NOT_DELETED
  1544. ENSURE_NOT_FROZEN
  1545. Y_ENSURE(static_cast<EState>(State) >= EState::TypeComplete);
  1546. Constraints_ = node.Constraints_;
  1547. State = EState::ConstrComplete;
  1548. }
  1549. void SetConstraints(const TConstraintSet& constraints) {
  1550. ENSURE_NOT_DELETED
  1551. ENSURE_NOT_FROZEN
  1552. Y_ENSURE(static_cast<EState>(State) >= EState::TypeComplete);
  1553. Constraints_ = constraints;
  1554. State = EState::ConstrComplete;
  1555. }
  1556. static TPtr NewAtom(ui64 uniqueId, TPositionHandle pos, const TStringBuf& content, ui32 flags) {
  1557. return Make(pos, Atom, {}, content, flags, uniqueId);
  1558. }
  1559. static TPtr NewArgument(ui64 uniqueId, TPositionHandle pos, const TStringBuf& name) {
  1560. return Make(pos, Argument, {}, name, 0, uniqueId);
  1561. }
  1562. static TPtr NewArguments(ui64 uniqueId, TPositionHandle pos, TListType&& argNodes) {
  1563. return Make(pos, Arguments, std::move(argNodes), ZeroString, 0, uniqueId);
  1564. }
  1565. static TPtr NewLambda(ui64 uniqueId, TPositionHandle pos, TListType&& lambda) {
  1566. return Make(pos, Lambda, std::move(lambda), ZeroString, 0, uniqueId);
  1567. }
  1568. static TPtr NewLambda(ui64 uniqueId, TPositionHandle pos, TPtr&& args, TListType&& body) {
  1569. TListType lambda(body.size() + 1U);
  1570. lambda.front() = std::move(args);
  1571. std::move(body.rbegin(), body.rend(), lambda.rbegin());
  1572. return NewLambda(uniqueId, pos, std::move(lambda));
  1573. }
  1574. static TPtr NewLambda(ui64 uniqueId, TPositionHandle pos, TPtr&& args, TPtr&& body) {
  1575. TListType children(body ? 2 : 1);
  1576. children.front() = std::move(args);
  1577. if (body) {
  1578. children.back() = std::move(body);
  1579. }
  1580. return NewLambda(uniqueId, pos, std::move(children));
  1581. }
  1582. static TPtr NewWorld(ui64 uniqueId, TPositionHandle pos) {
  1583. return Make(pos, World, {}, {}, 0, uniqueId);
  1584. }
  1585. static TPtr NewList(ui64 uniqueId, TPositionHandle pos, TListType&& children) {
  1586. return Make(pos, List, std::move(children), ZeroString, 0, uniqueId);
  1587. }
  1588. static TPtr NewCallable(ui64 uniqueId, TPositionHandle pos, const TStringBuf& name, TListType&& children) {
  1589. return Make(pos, Callable, std::move(children), name, 0, uniqueId);
  1590. }
  1591. TPtr Clone(ui64 newUniqueId) const {
  1592. ENSURE_NOT_DELETED
  1593. return Make(Position_, (EType)Type_, TListType(Children_), Content(), Flags_, newUniqueId);
  1594. }
  1595. TPtr CloneWithPosition(ui64 newUniqueId, TPositionHandle pos) const {
  1596. ENSURE_NOT_DELETED
  1597. return Make(pos, (EType)Type_, TListType(Children_), Content(), Flags_, newUniqueId);
  1598. }
  1599. static TPtr NewNode(TPositionHandle position, EType type, TListType&& children, const TStringBuf& content, ui32 flags, ui64 uniqueId) {
  1600. return Make(position, type, std::move(children), content, flags, uniqueId);
  1601. }
  1602. TPtr ChangeContent(ui64 newUniqueId, const TStringBuf& content) const {
  1603. ENSURE_NOT_DELETED
  1604. return Make(Position_, (EType)Type_, TListType(Children_), content, Flags_, newUniqueId);
  1605. }
  1606. TPtr ChangeChildren(ui64 newUniqueId, TListType&& children) const {
  1607. ENSURE_NOT_DELETED
  1608. return Make(Position_, (EType)Type_, std::move(children), Content(), Flags_, newUniqueId);
  1609. }
  1610. TPtr ChangeChild(ui64 newUniqueId, ui32 index, TPtr&& child) const {
  1611. ENSURE_NOT_DELETED
  1612. Y_ENSURE(index < Children_.size(), "index out of range");
  1613. TListType newChildren(Children_);
  1614. newChildren[index] = std::move(child);
  1615. return Make(Position_, (EType)Type_, std::move(newChildren), Content(), Flags_, newUniqueId);
  1616. }
  1617. void SetTypeAnn(const TTypeAnnotationNode* typeAnn) {
  1618. TypeAnnotation_ = typeAnn;
  1619. State = TypeAnnotation_ ? EState::TypeComplete : EState::Initial;
  1620. }
  1621. const TTypeAnnotationNode* GetTypeAnn() const {
  1622. return TypeAnnotation_;
  1623. }
  1624. EState GetState() const {
  1625. return State;
  1626. }
  1627. void SetState(EState state) {
  1628. State = state;
  1629. }
  1630. ui32 GetArgIndex() const {
  1631. YQL_ENSURE(Type() == EType::Argument);
  1632. return ArgIndex;
  1633. }
  1634. void SetArgIndex(ui32 argIndex) {
  1635. YQL_ENSURE(Type() == EType::Argument);
  1636. YQL_ENSURE(argIndex <= Max<ui16>());
  1637. ArgIndex = (ui16)argIndex;
  1638. }
  1639. ui64 GetHash() const {
  1640. Y_DEBUG_ABORT_UNLESS(HashAbove == HashBelow);
  1641. return HashAbove;
  1642. }
  1643. void SetHash(ui64 hash) {
  1644. HashAbove = HashBelow = hash;
  1645. }
  1646. ui64 GetHashAbove() const {
  1647. return HashAbove;
  1648. }
  1649. void SetHashAbove(ui64 hash) {
  1650. HashAbove = hash;
  1651. }
  1652. ui64 GetHashBelow() const {
  1653. return HashBelow;
  1654. }
  1655. void SetHashBelow(ui64 hash) {
  1656. HashBelow = hash;
  1657. }
  1658. ui64 GetBloom() const {
  1659. return Bloom;
  1660. }
  1661. void SetBloom(ui64 bloom) {
  1662. Bloom = bloom;
  1663. }
  1664. // return pair of outer and inner lambda.
  1665. std::optional<std::pair<const TExprNode*, const TExprNode*>> GetDependencyScope() const {
  1666. if (HasLambdaScope) {
  1667. return std::make_pair(OuterLambda, InnerLambda);
  1668. }
  1669. return std::nullopt;
  1670. }
  1671. void SetDependencyScope(const TExprNode* outerLambda, const TExprNode* innerLambda) {
  1672. Y_DEBUG_ABORT_UNLESS(outerLambda == innerLambda || outerLambda->GetLambdaLevel() < innerLambda->GetLambdaLevel(), "Wrong scope of closures.");
  1673. HasLambdaScope = 1;
  1674. OuterLambda = outerLambda;
  1675. InnerLambda = innerLambda;
  1676. }
  1677. ui16 GetLambdaLevel() const { return LambdaLevel; }
  1678. void SetLambdaLevel(ui16 lambdaLevel) { LambdaLevel = lambdaLevel; }
  1679. bool IsUsedInDependsOn() const {
  1680. YQL_ENSURE(Type() == EType::Argument);
  1681. return UsedInDependsOn;
  1682. }
  1683. void SetUsedInDependsOn() {
  1684. YQL_ENSURE(Type() == EType::Argument);
  1685. UsedInDependsOn = 1;
  1686. }
  1687. void SetUnorderedChildren() {
  1688. YQL_ENSURE(Type() == EType::List || Type() == EType::Callable);
  1689. UnordChildren = 1;
  1690. }
  1691. bool UnorderedChildren() const {
  1692. YQL_ENSURE(Type() == EType::List || Type() == EType::Callable);
  1693. return bool(UnordChildren);
  1694. }
  1695. ~TExprNode() {
  1696. Y_ABORT_UNLESS(Dead(), "Node (id: %lu, type: %s, content: '%s') not dead on destruction.",
  1697. UniqueId_, ToString(Type_).data(), TString(ContentUnchecked()).data());
  1698. Y_ABORT_UNLESS(!UseCount(), "Node (id: %lu, type: %s, content: '%s') has non-zero use count on destruction.",
  1699. UniqueId_, ToString(Type_).data(), TString(ContentUnchecked()).data());
  1700. }
  1701. private:
  1702. static TPtr Make(TPositionHandle position, EType type, TListType&& children, const TStringBuf& content, ui32 flags, ui64 uniqueId) {
  1703. Y_ENSURE(flags <= TNodeFlags::FlagsMask);
  1704. Y_ENSURE(children.size() <= Max<ui32>());
  1705. Y_ENSURE(content.size() <= Max<ui32>());
  1706. for (size_t i = 0; i < children.size(); ++i) {
  1707. Y_ENSURE(children[i], "Unable to create node " << content << ": " << i << "th child is null");
  1708. }
  1709. return TPtr(new TExprNode(position, type, std::move(children), content.data(), ui32(content.size()), flags, uniqueId));
  1710. }
  1711. TExprNode(TPositionHandle position, EType type, TListType&& children,
  1712. const char* content, ui32 contentSize, ui32 flags, ui64 uniqueId)
  1713. : Children_(std::move(children))
  1714. , Content_(content)
  1715. , UniqueId_(uniqueId)
  1716. , Position_(position)
  1717. , ContentSize(contentSize)
  1718. , Type_(type)
  1719. , Flags_(flags)
  1720. , ExprFlags_(TExprFlags::Default)
  1721. , State(EState::Initial)
  1722. , HasLambdaScope(0)
  1723. , UsedInDependsOn(0)
  1724. , UnordChildren(0)
  1725. , ShallBeDisclosed(0)
  1726. , LiteralList(0)
  1727. {}
  1728. TExprNode(const TExprNode&) = delete;
  1729. TExprNode(TExprNode&&) = delete;
  1730. TExprNode& operator=(const TExprNode&) = delete;
  1731. TExprNode& operator=(TExprNode&&) = delete;
  1732. bool Frozen() const {
  1733. return ExprFlags_ & TExprFlags::Frozen;
  1734. }
  1735. void MarkFrozen(bool frozen = true) {
  1736. if (frozen) {
  1737. ExprFlags_ |= TExprFlags::Frozen;
  1738. } else {
  1739. ExprFlags_ &= ~TExprFlags::Frozen;
  1740. }
  1741. }
  1742. void MarkDead() {
  1743. ExprFlags_ |= TExprFlags::Dead;
  1744. }
  1745. TStringBuf ContentUnchecked() const {
  1746. return TStringBuf(Content_, ContentSize);
  1747. }
  1748. TListType Children_;
  1749. TConstraintSet Constraints_;
  1750. const char* Content_ = nullptr;
  1751. const TExprNode* OuterLambda = nullptr;
  1752. const TExprNode* InnerLambda = nullptr;
  1753. TPtr Result;
  1754. ui64 HashAbove = 0ULL;
  1755. ui64 HashBelow = 0ULL;
  1756. ui64 Bloom = 0ULL;
  1757. const ui64 UniqueId_;
  1758. const TTypeAnnotationNode* TypeAnnotation_ = nullptr;
  1759. const TPositionHandle Position_;
  1760. ui32 RefCount_ = 0U;
  1761. const ui32 ContentSize;
  1762. ui16 ArgIndex = ui16(-1);
  1763. ui16 LambdaLevel = 0; // filled together with OuterLambda
  1764. ui16 IntermediateHashesCount = 0;
  1765. static_assert(TypeMask <= 7, "EType wont fit in 3 bits, increase Type_ bitfield size");
  1766. static_assert(TNodeFlags::FlagsMask <= 7, "TNodeFlags wont fit in 3 bits, increase Flags_ bitfield size");
  1767. static_assert(TExprFlags::FlagsMask <= 3, "TExprFlags wont fit in 2 bits, increase ExprFlags_ bitfield size");
  1768. static_assert(int(EState::Last) <= 16, "EState wont fit in 4 bits, increase State bitfield size");
  1769. struct {
  1770. ui8 Type_ : 3;
  1771. ui8 Flags_ : 3;
  1772. ui8 ExprFlags_ : 2;
  1773. EState State : 4;
  1774. ui8 HasLambdaScope : 1;
  1775. ui8 UsedInDependsOn : 1;
  1776. ui8 UnordChildren : 1;
  1777. ui8 ShallBeDisclosed: 1;
  1778. ui8 LiteralList : 1;
  1779. };
  1780. };
  1781. class TExportTable {
  1782. public:
  1783. using TSymbols = THashMap<TString, TExprNode::TPtr>;
  1784. TExportTable() = default;
  1785. TExportTable(TExprContext& ctx, TSymbols&& symbols)
  1786. : Symbols_(std::move(symbols))
  1787. , Ctx_(&ctx)
  1788. {}
  1789. const TSymbols& Symbols() const {
  1790. return Symbols_;
  1791. }
  1792. TSymbols& Symbols(TExprContext& ctx) {
  1793. if (Ctx_) {
  1794. YQL_ENSURE(Ctx_ == &ctx);
  1795. } else {
  1796. Ctx_ = &ctx;
  1797. }
  1798. return Symbols_;
  1799. }
  1800. TExprContext& ExprCtx() const {
  1801. YQL_ENSURE(Ctx_);
  1802. return *Ctx_;
  1803. }
  1804. private:
  1805. TSymbols Symbols_;
  1806. TExprContext* Ctx_ = nullptr;
  1807. };
  1808. using TModulesTable = THashMap<TString, TExportTable>;
  1809. class IModuleResolver {
  1810. public:
  1811. typedef std::shared_ptr<IModuleResolver> TPtr;
  1812. virtual bool AddFromFile(const std::string_view& file, TExprContext& ctx, ui16 syntaxVersion, ui32 packageVersion, TPosition pos = {}) = 0;
  1813. virtual bool AddFromUrl(const std::string_view& file, const std::string_view& url, const std::string_view& tokenName, TExprContext& ctx, ui16 syntaxVersion, ui32 packageVersion, TPosition pos = {}) = 0;
  1814. virtual bool AddFromMemory(const std::string_view& file, const TString& body, TExprContext& ctx, ui16 syntaxVersion, ui32 packageVersion, TPosition pos = {}) = 0;
  1815. virtual bool AddFromMemory(const std::string_view& file, const TString& body, TExprContext& ctx, ui16 syntaxVersion, ui32 packageVersion, TPosition pos, TString& moduleName, std::vector<TString>* exports = nullptr, std::vector<TString>* imports = nullptr) = 0;
  1816. virtual bool Link(TExprContext& ctx) = 0;
  1817. virtual void UpdateNextUniqueId(TExprContext& ctx) const = 0;
  1818. virtual ui64 GetNextUniqueId() const = 0;
  1819. virtual void RegisterPackage(const TString& package) = 0;
  1820. virtual bool SetPackageDefaultVersion(const TString& package, ui32 version) = 0;
  1821. virtual const TExportTable* GetModule(const TString& module) const = 0;
  1822. /*
  1823. Create new resolver which will use already collected modules in readonly manner.
  1824. Parent resolver should be alive while using child due to raw data sharing.
  1825. */
  1826. virtual IModuleResolver::TPtr CreateMutableChild() const = 0;
  1827. virtual void SetFileAliasPrefix(TString&& prefix) = 0;
  1828. virtual TString GetFileAliasPrefix() const = 0;
  1829. virtual ~IModuleResolver() = default;
  1830. };
  1831. struct TExprStep {
  1832. enum ELevel {
  1833. Params,
  1834. ExpandApplyForLambdas,
  1835. ValidateProviders,
  1836. Configure,
  1837. ExprEval,
  1838. DiscoveryIO,
  1839. Epochs,
  1840. Intents,
  1841. LoadTablesMetadata,
  1842. RewriteIO,
  1843. Recapture,
  1844. LastLevel
  1845. };
  1846. TExprStep()
  1847. {
  1848. }
  1849. void Done(ELevel level) {
  1850. Steps_.Set(level);
  1851. }
  1852. void Reset() {
  1853. Steps_.Reset();
  1854. }
  1855. TExprStep& Repeat(ELevel level) {
  1856. Steps_.Reset(level);
  1857. return *this;
  1858. }
  1859. bool IsDone(ELevel level) {
  1860. return Steps_.Test(level);
  1861. }
  1862. private:
  1863. TEnumBitSet<ELevel, Params, LastLevel> Steps_;
  1864. };
  1865. template <typename T>
  1866. struct TMakeTypeImpl;
  1867. template <class T>
  1868. using TNodeMap = std::unordered_map<const TExprNode*, T>;
  1869. using TNodeSet = std::unordered_set<const TExprNode*>;
  1870. using TNodeOnNodeOwnedMap = TNodeMap<TExprNode::TPtr>;
  1871. using TParentsMap = TNodeMap<TNodeSet>;
  1872. using TNodeMultiSet = std::unordered_multiset<const TExprNode*>;
  1873. using TParentsMultiMap = TNodeMap<TNodeMultiSet>;
  1874. template <>
  1875. struct TMakeTypeImpl<TVoidExprType> {
  1876. static const TVoidExprType* Make(TExprContext& ctx);
  1877. };
  1878. template <>
  1879. struct TMakeTypeImpl<TNullExprType> {
  1880. static const TNullExprType* Make(TExprContext& ctx);
  1881. };
  1882. template <>
  1883. struct TMakeTypeImpl<TEmptyListExprType> {
  1884. static const TEmptyListExprType* Make(TExprContext& ctx);
  1885. };
  1886. template <>
  1887. struct TMakeTypeImpl<TEmptyDictExprType> {
  1888. static const TEmptyDictExprType* Make(TExprContext& ctx);
  1889. };
  1890. template <>
  1891. struct TMakeTypeImpl<TUnitExprType> {
  1892. static const TUnitExprType* Make(TExprContext& ctx);
  1893. };
  1894. template <>
  1895. struct TMakeTypeImpl<TWorldExprType> {
  1896. static const TWorldExprType* Make(TExprContext& ctx);
  1897. };
  1898. template <>
  1899. struct TMakeTypeImpl<TGenericExprType> {
  1900. static const TGenericExprType* Make(TExprContext& ctx);
  1901. };
  1902. template <>
  1903. struct TMakeTypeImpl<TItemExprType> {
  1904. static const TItemExprType* Make(TExprContext& ctx, const TStringBuf& name, const TTypeAnnotationNode* itemType);
  1905. };
  1906. template <>
  1907. struct TMakeTypeImpl<TListExprType> {
  1908. static const TListExprType* Make(TExprContext& ctx, const TTypeAnnotationNode* itemType);
  1909. };
  1910. template <>
  1911. struct TMakeTypeImpl<TOptionalExprType> {
  1912. static const TOptionalExprType* Make(TExprContext& ctx, const TTypeAnnotationNode* itemType);
  1913. };
  1914. template <>
  1915. struct TMakeTypeImpl<TVariantExprType> {
  1916. static const TVariantExprType* Make(TExprContext& ctx, const TTypeAnnotationNode* underlyingType);
  1917. };
  1918. template <>
  1919. struct TMakeTypeImpl<TErrorExprType> {
  1920. static const TErrorExprType* Make(TExprContext& ctx, const TIssue& error);
  1921. };
  1922. template <>
  1923. struct TMakeTypeImpl<TDictExprType> {
  1924. static const TDictExprType* Make(TExprContext& ctx, const TTypeAnnotationNode* keyType,
  1925. const TTypeAnnotationNode* payloadType);
  1926. };
  1927. template <>
  1928. struct TMakeTypeImpl<TTypeExprType> {
  1929. static const TTypeExprType* Make(TExprContext& ctx, const TTypeAnnotationNode* baseType);
  1930. };
  1931. template <>
  1932. struct TMakeTypeImpl<TDataExprType> {
  1933. static const TDataExprType* Make(TExprContext& ctx, EDataSlot slot);
  1934. };
  1935. template <>
  1936. struct TMakeTypeImpl<TPgExprType> {
  1937. static const TPgExprType* Make(TExprContext& ctx, ui32 typeId);
  1938. };
  1939. template <>
  1940. struct TMakeTypeImpl<TDataExprParamsType> {
  1941. static const TDataExprParamsType* Make(TExprContext& ctx, EDataSlot slot, const TStringBuf& one, const TStringBuf& two);
  1942. };
  1943. template <>
  1944. struct TMakeTypeImpl<TCallableExprType> {
  1945. static const TCallableExprType* Make(
  1946. TExprContext& ctx, const TTypeAnnotationNode* returnType, const TVector<TCallableExprType::TArgumentInfo>& arguments,
  1947. size_t optionalArgumentsCount, const TStringBuf& payload);
  1948. };
  1949. template <>
  1950. struct TMakeTypeImpl<TResourceExprType> {
  1951. static const TResourceExprType* Make(TExprContext& ctx, const TStringBuf& tag);
  1952. };
  1953. template <>
  1954. struct TMakeTypeImpl<TTaggedExprType> {
  1955. static const TTaggedExprType* Make(TExprContext& ctx, const TTypeAnnotationNode* baseType, const TStringBuf& tag);
  1956. };
  1957. template <>
  1958. struct TMakeTypeImpl<TStructExprType> {
  1959. static const TStructExprType* Make(TExprContext& ctx, const TVector<const TItemExprType*>& items);
  1960. };
  1961. template <>
  1962. struct TMakeTypeImpl<TTupleExprType> {
  1963. static const TTupleExprType* Make(TExprContext& ctx, const TTypeAnnotationNode::TListType& items);
  1964. };
  1965. template <>
  1966. struct TMakeTypeImpl<TMultiExprType> {
  1967. static const TMultiExprType* Make(TExprContext& ctx, const TTypeAnnotationNode::TListType& items);
  1968. };
  1969. template <>
  1970. struct TMakeTypeImpl<TStreamExprType> {
  1971. static const TStreamExprType* Make(TExprContext& ctx, const TTypeAnnotationNode* itemType);
  1972. };
  1973. template <>
  1974. struct TMakeTypeImpl<TFlowExprType> {
  1975. static const TFlowExprType* Make(TExprContext& ctx, const TTypeAnnotationNode* itemType);
  1976. };
  1977. template <>
  1978. struct TMakeTypeImpl<TBlockExprType> {
  1979. static const TBlockExprType* Make(TExprContext& ctx, const TTypeAnnotationNode* itemType);
  1980. };
  1981. template <>
  1982. struct TMakeTypeImpl<TScalarExprType> {
  1983. static const TScalarExprType* Make(TExprContext& ctx, const TTypeAnnotationNode* itemType);
  1984. };
  1985. using TSingletonTypeCache = std::tuple<
  1986. const TVoidExprType*,
  1987. const TNullExprType*,
  1988. const TUnitExprType*,
  1989. const TEmptyListExprType*,
  1990. const TEmptyDictExprType*,
  1991. const TWorldExprType*,
  1992. const TGenericExprType*,
  1993. const TTupleExprType*,
  1994. const TStructExprType*,
  1995. const TMultiExprType*
  1996. >;
  1997. struct TExprContext : private TNonCopyable {
  1998. class TFreezeGuard {
  1999. public:
  2000. TFreezeGuard(const TFreezeGuard&) = delete;
  2001. TFreezeGuard& operator=(const TFreezeGuard&) = delete;
  2002. TFreezeGuard(TExprContext& ctx)
  2003. : Ctx(ctx)
  2004. {
  2005. Ctx.Freeze();
  2006. }
  2007. ~TFreezeGuard() {
  2008. Ctx.UnFreeze();
  2009. }
  2010. private:
  2011. TExprContext& Ctx;
  2012. };
  2013. TIssueManager IssueManager;
  2014. TNodeMap<TIssues> AssociativeIssues;
  2015. TMemoryPool StringPool;
  2016. std::unordered_set<std::string_view> Strings;
  2017. std::unordered_map<ui32, std::string_view> Indexes;
  2018. std::stack<std::unique_ptr<const TTypeAnnotationNode>> TypeNodes;
  2019. std::stack<std::unique_ptr<const TConstraintNode>> ConstraintNodes;
  2020. std::deque<std::unique_ptr<TExprNode>> ExprNodes;
  2021. TSingletonTypeCache SingletonTypeCache;
  2022. std::unordered_set<const TTypeAnnotationNode*, TTypeAnnotationNode::THash, TTypeAnnotationNode::TEqual> TypeSet;
  2023. std::unordered_set<const TConstraintNode*, TConstraintNode::THash, TConstraintNode::TEqual> ConstraintSet;
  2024. std::unordered_map<const TTypeAnnotationNode*, TExprNode::TPtr> TypeAsNodeCache;
  2025. std::unordered_set<TStringBuf, THash<TStringBuf>> DisabledConstraints;
  2026. ui64 NextUniqueId = 0;
  2027. ui64 NodeAllocationCounter = 0;
  2028. ui64 NodesAllocationLimit = 3000000;
  2029. ui64 StringsAllocationLimit = 100000000;
  2030. ui64 RepeatTransformLimit = 1000000;
  2031. ui64 RepeatTransformCounter = 0;
  2032. ui64 TypeAnnNodeRepeatLimit = 1000;
  2033. TGcNodeConfig GcConfig;
  2034. std::unordered_multimap<ui64, TExprNode*> UniqueNodes;
  2035. TExprStep Step;
  2036. bool Frozen;
  2037. explicit TExprContext(ui64 nextUniqueId = 0ULL);
  2038. ~TExprContext();
  2039. ui64 AllocateNextUniqueId() {
  2040. ENSURE_NOT_FROZEN_CTX
  2041. const auto ret = ++NextUniqueId;
  2042. return ret;
  2043. }
  2044. TStringBuf AppendString(const TStringBuf& buf) {
  2045. ENSURE_NOT_FROZEN_CTX
  2046. if (buf.size() == 0) {
  2047. return ZeroString;
  2048. }
  2049. auto it = Strings.find(buf);
  2050. if (it != Strings.end()) {
  2051. return *it;
  2052. }
  2053. auto newBuf = StringPool.AppendString(buf);
  2054. Strings.insert(it, newBuf);
  2055. return newBuf;
  2056. }
  2057. TPositionHandle AppendPosition(const TPosition& pos);
  2058. TPosition GetPosition(TPositionHandle handle) const;
  2059. TExprNodeBuilder Builder(TPositionHandle pos) {
  2060. return TExprNodeBuilder(pos, *this);
  2061. }
  2062. [[nodiscard]]
  2063. TExprNode::TPtr RenameNode(const TExprNode& node, const TStringBuf& name);
  2064. [[nodiscard]]
  2065. TExprNode::TPtr ShallowCopy(const TExprNode& node);
  2066. [[nodiscard]]
  2067. TExprNode::TPtr ShallowCopyWithPosition(const TExprNode& node, TPositionHandle pos);
  2068. [[nodiscard]]
  2069. TExprNode::TPtr ChangeChildren(const TExprNode& node, TExprNode::TListType&& children);
  2070. [[nodiscard]]
  2071. TExprNode::TPtr ChangeChild(const TExprNode& node, ui32 index, TExprNode::TPtr&& child);
  2072. [[nodiscard]]
  2073. TExprNode::TPtr ExactChangeChildren(const TExprNode& node, TExprNode::TListType&& children);
  2074. [[nodiscard]]
  2075. TExprNode::TPtr ExactShallowCopy(const TExprNode& node);
  2076. [[nodiscard]]
  2077. TExprNode::TPtr DeepCopyLambda(const TExprNode& node, TExprNode::TListType&& body);
  2078. [[nodiscard]]
  2079. TExprNode::TPtr DeepCopyLambda(const TExprNode& node, TExprNode::TPtr&& body = TExprNode::TPtr());
  2080. [[nodiscard]]
  2081. TExprNode::TPtr FuseLambdas(const TExprNode& outer, const TExprNode& inner);
  2082. using TCustomDeepCopier = std::function<bool(const TExprNode& node, TExprNode::TListType& newChildren)>;
  2083. [[nodiscard]]
  2084. TExprNode::TPtr DeepCopy(const TExprNode& node, TExprContext& nodeContext, TNodeOnNodeOwnedMap& deepClones,
  2085. bool internStrings, bool copyTypes, bool copyResult = false, TCustomDeepCopier customCopier = {});
  2086. [[nodiscard]]
  2087. TExprNode::TPtr SwapWithHead(const TExprNode& node);
  2088. TExprNode::TPtr ReplaceNode(TExprNode::TPtr&& start, const TExprNode& src, TExprNode::TPtr dst);
  2089. TExprNode::TPtr ReplaceNodes(TExprNode::TPtr&& start, const TNodeOnNodeOwnedMap& replaces);
  2090. template<bool KeepTypeAnns = false>
  2091. TExprNode::TListType ReplaceNodes(TExprNode::TListType&& start, const TNodeOnNodeOwnedMap& replaces);
  2092. TExprNode::TPtr NewAtom(TPositionHandle pos, const TStringBuf& content, ui32 flags = TNodeFlags::ArbitraryContent) {
  2093. ++NodeAllocationCounter;
  2094. const auto node = TExprNode::NewAtom(AllocateNextUniqueId(), pos, AppendString(content), flags);
  2095. ExprNodes.emplace_back(node.Get());
  2096. return node;
  2097. }
  2098. TExprNode::TPtr NewAtom(TPositionHandle pos, ui32 index) {
  2099. ++NodeAllocationCounter;
  2100. const auto node = TExprNode::NewAtom(AllocateNextUniqueId(), pos, GetIndexAsString(index), TNodeFlags::Default);
  2101. ExprNodes.emplace_back(node.Get());
  2102. return node;
  2103. }
  2104. TExprNode::TPtr NewArgument(TPositionHandle pos, const TStringBuf& name) {
  2105. ++NodeAllocationCounter;
  2106. const auto node = TExprNode::NewArgument(AllocateNextUniqueId(), pos, AppendString(name));
  2107. ExprNodes.emplace_back(node.Get());
  2108. return node;
  2109. }
  2110. TExprNode::TPtr NewArguments(TPositionHandle pos, TExprNode::TListType&& argNodes) {
  2111. ++NodeAllocationCounter;
  2112. const auto node = TExprNode::NewArguments(AllocateNextUniqueId(), pos, std::move(argNodes));
  2113. ExprNodes.emplace_back(node.Get());
  2114. return node;
  2115. }
  2116. TExprNode::TPtr NewLambda(TPositionHandle pos, TExprNode::TListType&& lambda) {
  2117. ++NodeAllocationCounter;
  2118. const auto node = TExprNode::NewLambda(AllocateNextUniqueId(), pos, std::move(lambda));
  2119. ExprNodes.emplace_back(node.Get());
  2120. return node;
  2121. }
  2122. TExprNode::TPtr NewLambda(TPositionHandle pos, TExprNode::TPtr&& args, TExprNode::TListType&& body) {
  2123. ++NodeAllocationCounter;
  2124. const auto node = TExprNode::NewLambda(AllocateNextUniqueId(), pos, std::move(args), std::move(body));
  2125. ExprNodes.emplace_back(node.Get());
  2126. return node;
  2127. }
  2128. TExprNode::TPtr NewLambda(TPositionHandle pos, TExprNode::TPtr&& args, TExprNode::TPtr&& body) {
  2129. ++NodeAllocationCounter;
  2130. const auto node = TExprNode::NewLambda(AllocateNextUniqueId(), pos, std::move(args), std::move(body));
  2131. ExprNodes.emplace_back(node.Get());
  2132. return node;
  2133. }
  2134. TExprNode::TPtr NewWorld(TPositionHandle pos) {
  2135. ++NodeAllocationCounter;
  2136. const auto node = TExprNode::NewWorld(AllocateNextUniqueId(), pos);
  2137. ExprNodes.emplace_back(node.Get());
  2138. return node;
  2139. }
  2140. TExprNode::TPtr NewList(TPositionHandle pos, TExprNode::TListType&& children) {
  2141. ++NodeAllocationCounter;
  2142. const auto node = TExprNode::NewList(AllocateNextUniqueId(), pos, std::move(children));
  2143. ExprNodes.emplace_back(node.Get());
  2144. return node;
  2145. }
  2146. TExprNode::TPtr NewCallable(TPositionHandle pos, const TStringBuf& name, TExprNode::TListType&& children) {
  2147. ++NodeAllocationCounter;
  2148. const auto node = TExprNode::NewCallable(AllocateNextUniqueId(), pos, AppendString(name), std::move(children));
  2149. ExprNodes.emplace_back(node.Get());
  2150. return node;
  2151. }
  2152. TExprNode::TPtr NewAtom(TPosition pos, const TStringBuf& content, ui32 flags = TNodeFlags::ArbitraryContent) {
  2153. return NewAtom(AppendPosition(pos), content, flags);
  2154. }
  2155. TExprNode::TPtr NewAtom(TPosition pos, ui32 index) {
  2156. return NewAtom(AppendPosition(pos), index);
  2157. }
  2158. TExprNode::TPtr NewArgument(TPosition pos, const TStringBuf& name) {
  2159. return NewArgument(AppendPosition(pos), name);
  2160. }
  2161. TExprNode::TPtr NewArguments(TPosition pos, TExprNode::TListType&& argNodes) {
  2162. return NewArguments(AppendPosition(pos), std::move(argNodes));
  2163. }
  2164. TExprNode::TPtr NewLambda(TPosition pos, TExprNode::TListType&& lambda) {
  2165. return NewLambda(AppendPosition(pos), std::move(lambda));
  2166. }
  2167. TExprNode::TPtr NewLambda(TPosition pos, TExprNode::TPtr&& args, TExprNode::TListType&& body) {
  2168. return NewLambda(AppendPosition(pos), std::move(args), std::move(body));
  2169. }
  2170. TExprNode::TPtr NewLambda(TPosition pos, TExprNode::TPtr&& args, TExprNode::TPtr&& body) {
  2171. return NewLambda(AppendPosition(pos), std::move(args), std::move(body));
  2172. }
  2173. TExprNode::TPtr NewWorld(TPosition pos) {
  2174. return NewWorld(AppendPosition(pos));
  2175. }
  2176. TExprNode::TPtr NewList(TPosition pos, TExprNode::TListType&& children) {
  2177. return NewList(AppendPosition(pos), std::move(children));
  2178. }
  2179. TExprNode::TPtr NewCallable(TPosition pos, const TStringBuf& name, TExprNode::TListType&& children) {
  2180. return NewCallable(AppendPosition(pos), name, std::move(children));
  2181. }
  2182. TExprNode::TPtr WrapByCallableIf(bool condition, const TStringBuf& callable, TExprNode::TPtr&& node);
  2183. template <typename T, typename... Args>
  2184. const T* MakeType(Args&&... args);
  2185. template <typename T, typename... Args>
  2186. const T* MakeConstraint(Args&&... args);
  2187. TConstraintSet MakeConstraintSet(const NYT::TNode& serializedConstraints);
  2188. void AddError(const TIssue& error) {
  2189. ENSURE_NOT_FROZEN_CTX
  2190. IssueManager.RaiseIssue(error);
  2191. }
  2192. bool AddWarning(const TIssue& warning) {
  2193. ENSURE_NOT_FROZEN_CTX
  2194. return IssueManager.RaiseWarning(warning);
  2195. }
  2196. void Freeze();
  2197. void UnFreeze();
  2198. void Reset();
  2199. template <class TConstraint>
  2200. bool IsConstraintEnabled() const {
  2201. return DisabledConstraints.find(TConstraint::Name()) == DisabledConstraints.end();
  2202. }
  2203. std::string_view GetIndexAsString(ui32 index);
  2204. private:
  2205. using TPositionHandleEqualPred = std::function<bool(TPositionHandle, TPositionHandle)>;
  2206. using TPositionHandleHasher = std::function<size_t(TPositionHandle)>;
  2207. bool IsEqual(TPositionHandle a, TPositionHandle b) const;
  2208. size_t GetHash(TPositionHandle p) const;
  2209. std::unordered_set<TPositionHandle, TPositionHandleHasher, TPositionHandleEqualPred> PositionSet;
  2210. std::deque<TPosition> Positions;
  2211. };
  2212. template <typename T, typename... Args>
  2213. inline const T* TExprContext::MakeConstraint(Args&&... args) {
  2214. ENSURE_NOT_FROZEN_CTX
  2215. if (!IsConstraintEnabled<T>()) {
  2216. return nullptr;
  2217. }
  2218. T sample(*this, std::forward<Args>(args)...);
  2219. const auto it = ConstraintSet.find(&sample);
  2220. if (ConstraintSet.cend() != it) {
  2221. return static_cast<const T*>(*it);
  2222. }
  2223. ConstraintNodes.emplace(new T(std::move(sample)));
  2224. const auto ins = ConstraintSet.emplace(ConstraintNodes.top().get());
  2225. return static_cast<const T*>(*ins.first);
  2226. }
  2227. #undef ENSURE_NOT_DELETED
  2228. #undef ENSURE_NOT_FROZEN
  2229. #undef ENSURE_NOT_FROZEN_CTX
  2230. inline bool IsSameAnnotation(const TTypeAnnotationNode& left, const TTypeAnnotationNode& right) {
  2231. return &left == &right;
  2232. }
  2233. template <typename T, typename... Args>
  2234. const T* TExprContext::MakeType(Args&&... args) {
  2235. return TMakeTypeImpl<T>::Make(*this, std::forward<Args>(args)...);
  2236. }
  2237. struct TExprAnnotationFlags {
  2238. enum {
  2239. None = 0x00,
  2240. Position = 0x01,
  2241. Types = 0x02
  2242. };
  2243. };
  2244. ///////////////////////////////////////////////////////////////////////////////
  2245. // TNodeException
  2246. ///////////////////////////////////////////////////////////////////////////////
  2247. class TNodeException: public yexception {
  2248. public:
  2249. TNodeException();
  2250. explicit TNodeException(const TExprNode& node);
  2251. explicit TNodeException(const TExprNode* node);
  2252. explicit TNodeException(const TPositionHandle& pos);
  2253. inline const TPositionHandle& Pos() const {
  2254. return Pos_;
  2255. }
  2256. private:
  2257. const TPositionHandle Pos_;
  2258. };
  2259. bool CompileExpr(TAstNode& astRoot, TExprNode::TPtr& exprRoot, TExprContext& ctx,
  2260. IModuleResolver* resolver, IUrlListerManager* urlListerManager,
  2261. bool hasAnnotations = false, ui32 typeAnnotationIndex = Max<ui32>(), ui16 syntaxVersion = 0);
  2262. bool CompileExpr(TAstNode& astRoot, TExprNode::TPtr& exprRoot, TExprContext& ctx,
  2263. IModuleResolver* resolver, IUrlListerManager* urlListerManager,
  2264. ui32 annotationFlags, ui16 syntaxVersion = 0);
  2265. struct TLibraryCohesion {
  2266. TExportTable Exports;
  2267. TNodeMap<std::pair<TString, TString>> Imports;
  2268. };
  2269. bool CompileExpr(TAstNode& astRoot, TLibraryCohesion& cohesion, TExprContext& ctx, ui16 syntaxVersion = 0);
  2270. const TTypeAnnotationNode* CompileTypeAnnotation(const TAstNode& node, TExprContext& ctx);
  2271. // validate consistency of arguments and lambdas
  2272. void CheckArguments(const TExprNode& root);
  2273. void CheckCounts(const TExprNode& root);
  2274. // Compare expression trees and return first diffrent nodes.
  2275. bool CompareExprTrees(const TExprNode*& one, const TExprNode*& two);
  2276. bool CompareExprTreeParts(const TExprNode& one, const TExprNode& two, const TNodeMap<ui32>& argsMap);
  2277. TString MakeCacheKey(const TExprNode& root);
  2278. void GatherParents(const TExprNode& node, TParentsMap& parentsMap);
  2279. struct TConvertToAstSettings {
  2280. ui32 AnnotationFlags = 0;
  2281. bool RefAtoms = false;
  2282. std::function<bool(const TExprNode&)> NoInlineFunc;
  2283. bool PrintArguments = false;
  2284. bool AllowFreeArgs = false;
  2285. bool NormalizeAtomFlags = false;
  2286. IAllocator* Allocator = TDefaultAllocator::Instance();
  2287. };
  2288. TAstParseResult ConvertToAst(const TExprNode& root, TExprContext& ctx, const TConvertToAstSettings& settings);
  2289. // refAtoms allows omit copying of atom bodies - they will be referenced from expr graph
  2290. TAstParseResult ConvertToAst(const TExprNode& root, TExprContext& ctx, ui32 annotationFlags, bool refAtoms);
  2291. TExprNode::TListType GetLambdaBody(const TExprNode& lambda);
  2292. TString SubstParameters(const TString& str, const TMaybe<NYT::TNode>& params, TSet<TString>* usedNames);
  2293. const TTypeAnnotationNode* GetSeqItemType(const TTypeAnnotationNode* seq);
  2294. const TTypeAnnotationNode& GetSeqItemType(const TTypeAnnotationNode& seq);
  2295. const TTypeAnnotationNode& RemoveOptionality(const TTypeAnnotationNode& type);
  2296. TMaybe<TIssue> NormalizeName(TPosition position, TString& name);
  2297. TString NormalizeName(const TStringBuf& name);
  2298. } // namespace NYql
  2299. template<>
  2300. inline void Out<NYql::TTypeAnnotationNode>(
  2301. IOutputStream &out, const NYql::TTypeAnnotationNode& type)
  2302. {
  2303. type.Out(out);
  2304. }
  2305. #include "yql_expr_builder.inl"