yql_expr_schema.cpp 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446
  1. #include "yql_expr_schema.h"
  2. #include <yql/essentials/providers/common/schema/parser/yql_type_parser.h>
  3. #include <yql/essentials/ast/yql_expr_types.h>
  4. #include <yql/essentials/ast/yql_expr.h>
  5. #include <yql/essentials/utils/yql_panic.h>
  6. #include <yql/essentials/public/udf/udf_data_type.h>
  7. #include <yql/essentials/parser/pg_catalog/catalog.h>
  8. #include <library/cpp/yson/node/node_io.h>
  9. #include <library/cpp/yson/node/node_builder.h>
  10. #include <library/cpp/yson/writer.h>
  11. #include <util/generic/map.h>
  12. #include <util/stream/str.h>
  13. namespace NYql {
  14. namespace NCommon {
  15. template <template<typename> class TSaver>
  16. class TExprTypeSaver: public TSaver<TExprTypeSaver<TSaver>> {
  17. typedef TSaver<TExprTypeSaver<TSaver>> TBase;
  18. struct TStructAdaptor {
  19. const TStructExprType* Type;
  20. TStructAdaptor(const TStructExprType* type)
  21. : Type(type)
  22. {
  23. }
  24. ui32 GetMembersCount() const {
  25. return Type->GetItems().size();
  26. }
  27. const TStringBuf& GetMemberName(ui32 idx) const {
  28. return Type->GetItems()[idx]->GetName();
  29. }
  30. const TTypeAnnotationNode* GetMemberType(ui32 idx) const {
  31. return Type->GetItems()[idx]->GetItemType();
  32. }
  33. };
  34. struct TMappingOrderedStructAdaptor {
  35. TVector<std::pair<TStringBuf, const TTypeAnnotationNode*>> Members;
  36. TMappingOrderedStructAdaptor(const TStructMemberMapper& mapper, const TMaybe<TColumnOrder>& columns, const TStructExprType* type, bool writePhysical = true)
  37. {
  38. TMap<TStringBuf, const TTypeAnnotationNode*> members;
  39. for (auto& item: type->GetItems()) {
  40. TMaybe<TStringBuf> name = mapper ? mapper(item->GetName()) : item->GetName();
  41. if (!name) {
  42. continue;
  43. }
  44. members[*name] = item->GetItemType();
  45. }
  46. if (columns) {
  47. for (auto& [column, gen_column] : *columns) {
  48. auto it = members.find(gen_column);
  49. if (it != members.end()) {
  50. Members.emplace_back(writePhysical ? gen_column : column, it->second);
  51. }
  52. }
  53. } else {
  54. Members.insert(Members.end(), members.begin(), members.end());
  55. }
  56. }
  57. ui32 GetMembersCount() const {
  58. return Members.size();
  59. }
  60. const TStringBuf& GetMemberName(ui32 idx) const {
  61. return Members[idx].first;
  62. }
  63. const TTypeAnnotationNode* GetMemberType(ui32 idx) const {
  64. return Members[idx].second;
  65. }
  66. };
  67. struct TTupleAdaptor {
  68. const TTupleExprType* Type;
  69. TTupleAdaptor(const TTupleExprType* type)
  70. : Type(type)
  71. {
  72. }
  73. ui32 GetElementsCount() const {
  74. return Type->GetItems().size();
  75. }
  76. const TTypeAnnotationNode* GetElementType(ui32 idx) const {
  77. return Type->GetItems()[idx];
  78. }
  79. };
  80. struct TCallableAdaptor {
  81. const TCallableExprType* Type;
  82. TCallableAdaptor(const TCallableExprType* type)
  83. : Type(type)
  84. {
  85. }
  86. size_t GetOptionalArgsCount() const {
  87. return Type->GetOptionalArgumentsCount();
  88. }
  89. TStringBuf GetPayload() const {
  90. return Type->GetPayload();
  91. }
  92. const TTypeAnnotationNode* GetReturnType() const {
  93. return Type->GetReturnType();
  94. }
  95. size_t GetArgumentsCount() const {
  96. return Type->GetArgumentsSize();
  97. }
  98. TStringBuf GetArgumentName(size_t i) const {
  99. return Type->GetArguments().at(i).Name;
  100. }
  101. ui64 GetArgumentFlags(size_t i) const {
  102. return Type->GetArguments().at(i).Flags;
  103. }
  104. const TTypeAnnotationNode* GetArgumentType(size_t i) const {
  105. return Type->GetArguments().at(i).Type;
  106. }
  107. };
  108. void SaveErrorType(const TErrorExprType& errorType) {
  109. TBase::SaveTypeHeader("ErrorType");
  110. auto err = errorType.GetError();
  111. TBase::Writer.OnListItem();
  112. TBase::Writer.OnInt64Scalar(err.Position.Row);
  113. TBase::Writer.OnListItem();
  114. TBase::Writer.OnInt64Scalar(err.Position.Column);
  115. TBase::Writer.OnListItem();
  116. TBase::Writer.OnStringScalar(err.Position.File);
  117. TBase::Writer.OnListItem();
  118. TBase::Writer.OnStringScalar(err.GetMessage());
  119. TBase::Writer.OnEndList();
  120. }
  121. public:
  122. TExprTypeSaver(typename TBase::TConsumer& consumer, bool extendedForm)
  123. : TBase(consumer, extendedForm)
  124. {
  125. }
  126. void Save(const TTypeAnnotationNode* type) {
  127. switch (type->GetKind()) {
  128. case ETypeAnnotationKind::Data: {
  129. const auto dataType = type->Cast<TDataExprType>();
  130. if (const auto dataParamsType = dynamic_cast<const TDataExprParamsType*>(dataType)) {
  131. TBase::SaveDataTypeParams(dataType->GetName(), dataParamsType->GetParamOne(), dataParamsType->GetParamTwo());
  132. } else {
  133. TBase::SaveDataType(dataType->GetName());
  134. }
  135. break;
  136. }
  137. case ETypeAnnotationKind::Pg:
  138. TBase::SavePgType(type->Cast<TPgExprType>()->GetName());
  139. break;
  140. case ETypeAnnotationKind::Struct:
  141. TBase::SaveStructType(TStructAdaptor(type->Cast<TStructExprType>()));
  142. break;
  143. case ETypeAnnotationKind::List:
  144. TBase::SaveListType(*type->Cast<TListExprType>());
  145. break;
  146. case ETypeAnnotationKind::Optional:
  147. TBase::SaveOptionalType(*type->Cast<TOptionalExprType>());
  148. break;
  149. case ETypeAnnotationKind::Tuple:
  150. TBase::SaveTupleType(TTupleAdaptor(type->Cast<TTupleExprType>()));
  151. break;
  152. case ETypeAnnotationKind::Dict:
  153. TBase::SaveDictType(*type->Cast<TDictExprType>());
  154. break;
  155. case ETypeAnnotationKind::Type:
  156. TBase::SaveType();
  157. break;
  158. case ETypeAnnotationKind::Generic:
  159. TBase::SaveGenericType();
  160. break;
  161. case ETypeAnnotationKind::Void:
  162. TBase::SaveVoidType();
  163. break;
  164. case ETypeAnnotationKind::Null:
  165. TBase::SaveNullType();
  166. break;
  167. case ETypeAnnotationKind::Unit:
  168. TBase::SaveUnitType();
  169. break;
  170. case ETypeAnnotationKind::EmptyList:
  171. TBase::SaveEmptyListType();
  172. break;
  173. case ETypeAnnotationKind::EmptyDict:
  174. TBase::SaveEmptyDictType();
  175. break;
  176. case ETypeAnnotationKind::Resource:
  177. TBase::SaveResourceType(type->Cast<TResourceExprType>()->GetTag());
  178. break;
  179. case ETypeAnnotationKind::Tagged:
  180. TBase::SaveTaggedType(*type->Cast<TTaggedExprType>());
  181. break;
  182. case ETypeAnnotationKind::Error:
  183. SaveErrorType(*type->Cast<TErrorExprType>());
  184. break;
  185. case ETypeAnnotationKind::Callable:
  186. TBase::SaveCallableType(TCallableAdaptor(type->Cast<TCallableExprType>()));
  187. break;
  188. case ETypeAnnotationKind::Variant:
  189. TBase::SaveVariantType(*type->Cast<TVariantExprType>());
  190. break;
  191. case ETypeAnnotationKind::Stream:
  192. TBase::SaveStreamType(*type->Cast<TStreamExprType>());
  193. break;
  194. default:
  195. YQL_ENSURE(false, "Unsupported type annotation kind: " << type->GetKind());
  196. }
  197. }
  198. void SaveStructType(const TStructExprType* type, const TMaybe<TColumnOrder>& columns, const TStructMemberMapper& mapper, bool physical = true) {
  199. if (mapper || columns) {
  200. TBase::SaveStructType(TMappingOrderedStructAdaptor(mapper, columns, type, physical));
  201. } else {
  202. Save(type);
  203. }
  204. }
  205. };
  206. void SaveStructTypeToYson(NYson::TYsonConsumerBase& writer, const TStructExprType* type, const TMaybe<TColumnOrder>& columns, const TStructMemberMapper& mapper, bool extendedForm) {
  207. TExprTypeSaver<TYqlTypeYsonSaverImpl> saver(writer, extendedForm);
  208. saver.SaveStructType(type, columns, mapper, true);
  209. }
  210. void SaveStructTypeToYsonWithLogicalNames(NYson::TYsonConsumerBase& writer, const TStructExprType* type, const TMaybe<TColumnOrder>& columns, const TStructMemberMapper& mapper, bool extendedForm) {
  211. TExprTypeSaver<TYqlTypeYsonSaverImpl> saver(writer, extendedForm);
  212. saver.SaveStructType(type, columns, mapper, false);
  213. }
  214. void WriteTypeToYson(NYson::TYsonConsumerBase& writer, const TTypeAnnotationNode* type, bool extendedForm) {
  215. TExprTypeSaver<TYqlTypeYsonSaverImpl> saver(writer, extendedForm);
  216. saver.Save(type);
  217. }
  218. NYT::TNode TypeToYsonNode(const TTypeAnnotationNode* type, bool extendedForm) {
  219. NYT::TNode res;
  220. NYT::TNodeBuilder builder(&res);
  221. WriteTypeToYson(builder, type, extendedForm);
  222. return res;
  223. }
  224. TString WriteTypeToYson(const TTypeAnnotationNode* type, NYson::EYsonFormat format, bool extendedForm) {
  225. TStringStream stream;
  226. NYson::TYsonWriter writer(&stream, format);
  227. WriteTypeToYson(writer, type, extendedForm);
  228. return stream.Str();
  229. }
  230. struct TExprTypeLoader {
  231. typedef const TTypeAnnotationNode* TType;
  232. TExprContext& Ctx;
  233. TPosition Pos;
  234. TExprTypeLoader(TExprContext& ctx, const TPosition& pos = TPosition())
  235. : Ctx(ctx)
  236. , Pos(pos)
  237. {
  238. }
  239. TMaybe<TType> LoadVoidType(ui32 /*level*/) {
  240. return Ctx.MakeType<TVoidExprType>();
  241. }
  242. TMaybe<TType> LoadNullType(ui32 /*level*/) {
  243. return Ctx.MakeType<TNullExprType>();
  244. }
  245. TMaybe<TType> LoadUnitType(ui32 /*level*/) {
  246. return Ctx.MakeType<TUnitExprType>();
  247. }
  248. TMaybe<TType> LoadGenericType(ui32 /*level*/) {
  249. return Ctx.MakeType<TGenericExprType>();
  250. }
  251. TMaybe<TType> LoadEmptyListType(ui32 /*level*/) {
  252. return Ctx.MakeType<TEmptyListExprType>();
  253. }
  254. TMaybe<TType> LoadEmptyDictType(ui32 /*level*/) {
  255. return Ctx.MakeType<TEmptyDictExprType>();
  256. }
  257. TMaybe<TType> LoadDataType(const TString& dataType, ui32 /*level*/) {
  258. return Ctx.MakeType<TDataExprType>(NYql::NUdf::GetDataSlot(dataType));
  259. }
  260. TMaybe<TType> LoadPgType(const TString& name, ui32 /*level*/) {
  261. return Ctx.MakeType<TPgExprType>(NYql::NPg::LookupType(name).TypeId);
  262. }
  263. TMaybe<TType> LoadDataTypeParams(const TString& dataType, const TString& paramOne, const TString& paramTwo, ui32 /*level*/) {
  264. auto ret = Ctx.MakeType<TDataExprParamsType>(NYql::NUdf::GetDataSlot(dataType), paramOne, paramTwo);
  265. YQL_ENSURE(ret->Validate(TPosition(), Ctx));
  266. return ret;
  267. }
  268. TMaybe<TType> LoadResourceType(const TString& tag, ui32 /*level*/) {
  269. return Ctx.MakeType<TResourceExprType>(tag);
  270. }
  271. TMaybe<TType> LoadTaggedType(TType baseType, const TString& tag, ui32 /*level*/) {
  272. auto ret = Ctx.MakeType<TTaggedExprType>(baseType, tag);
  273. YQL_ENSURE(ret->Validate(TPosition(), Ctx));
  274. return ret;
  275. }
  276. TMaybe<TType> LoadErrorType(ui32 row, ui32 column, const TString& file, const TString& msg, ui32 /*level*/) {
  277. return Ctx.MakeType<TErrorExprType>(TIssue(TPosition(column, row, file), msg));
  278. }
  279. TMaybe<TType> LoadStructType(const TVector<std::pair<TString, TType>>& members, ui32 /*level*/) {
  280. TVector<const TItemExprType*> items;
  281. TColumnOrder order;
  282. for (auto& member: members) {
  283. items.push_back(Ctx.MakeType<TItemExprType>(order.AddColumn(member.first), member.second));
  284. }
  285. auto ret = Ctx.MakeType<TStructExprType>(items);
  286. YQL_ENSURE(ret->Validate(TPosition(), Ctx));
  287. return ret;
  288. }
  289. TMaybe<TType> LoadListType(TType itemType, ui32 /*level*/) {
  290. return Ctx.MakeType<TListExprType>(itemType);
  291. }
  292. TMaybe<TType> LoadStreamType(TType itemType, ui32 /*level*/) {
  293. return Ctx.MakeType<TStreamExprType>(itemType);
  294. }
  295. TMaybe<TType> LoadOptionalType(TType itemType, ui32 /*level*/) {
  296. return Ctx.MakeType<TOptionalExprType>(itemType);
  297. }
  298. TMaybe<TType> LoadTupleType(const TVector<TType>& elements, ui32 /*level*/) {
  299. auto ret = Ctx.MakeType<TTupleExprType>(elements);
  300. YQL_ENSURE(ret->Validate(TPosition(), Ctx));
  301. return ret;
  302. }
  303. TMaybe<TType> LoadDictType(TType keyType, TType valType, ui32 /*level*/) {
  304. auto ret = Ctx.MakeType<TDictExprType>(keyType, valType);
  305. YQL_ENSURE(ret->Validate(TPosition(), Ctx));
  306. return ret;
  307. }
  308. TMaybe<TType> LoadCallableType(TType returnType, const TVector<TType>& argTypes, const TVector<TString>& argNames,
  309. const TVector<ui64>& argFlags, size_t optionalCount, const TString& payload, ui32 /*level*/) {
  310. YQL_ENSURE(argTypes.size() == argNames.size() && argTypes.size() == argFlags.size());
  311. TVector<TCallableExprType::TArgumentInfo> args;
  312. for (size_t i = 0; i < argTypes.size(); ++i) {
  313. args.emplace_back();
  314. args.back().Type = argTypes[i];
  315. args.back().Name = Ctx.AppendString(argNames[i]);
  316. args.back().Flags = argFlags[i];
  317. }
  318. auto ret = Ctx.MakeType<TCallableExprType>(returnType, args, optionalCount, Ctx.AppendString(payload));
  319. YQL_ENSURE(ret->Validate(TPosition(), Ctx));
  320. return ret;
  321. }
  322. TMaybe<TType> LoadVariantType(TType underlyingType, ui32 /*level*/) {
  323. auto ret = Ctx.MakeType<TVariantExprType>(underlyingType);
  324. YQL_ENSURE(ret->Validate(TPosition(), Ctx));
  325. return ret;
  326. }
  327. void Error(const TString& info) {
  328. Ctx.AddError(TIssue(Pos, info));
  329. }
  330. };
  331. const TTypeAnnotationNode* ParseTypeFromYson(const TStringBuf yson, TExprContext& ctx, const TPosition& pos) {
  332. NYT::TNode node;
  333. TStringStream err;
  334. if (!ParseYson(node, yson, err)) {
  335. ctx.AddError(TIssue(pos, err.Str()));
  336. return nullptr;
  337. }
  338. return ParseTypeFromYson(node, ctx, pos);
  339. }
  340. const TTypeAnnotationNode* ParseOrderAwareTypeFromYson(const TStringBuf yson, TColumnOrder& topLevelColumns, TExprContext& ctx, const TPosition& pos) {
  341. NYT::TNode node;
  342. TStringStream err;
  343. if (!ParseYson(node, yson, err)) {
  344. ctx.AddError(TIssue(pos, err.Str()));
  345. return nullptr;
  346. }
  347. return ParseOrderAwareTypeFromYson(node, topLevelColumns, ctx, pos);
  348. }
  349. const TTypeAnnotationNode* ParseTypeFromYson(const NYT::TNode& node, TExprContext& ctx, const TPosition& pos) {
  350. TExprTypeLoader loader(ctx, pos);
  351. return DoLoadTypeFromYson(loader, node, 0).GetOrElse(nullptr);
  352. }
  353. struct TOrderAwareExprTypeLoader: public TExprTypeLoader {
  354. typedef const TTypeAnnotationNode* TType;
  355. TColumnOrder& TopLevelColumns;
  356. TOrderAwareExprTypeLoader(TExprContext& ctx, const TPosition& pos, TColumnOrder& topLevelColumns)
  357. : TExprTypeLoader(ctx, pos)
  358. , TopLevelColumns(topLevelColumns)
  359. {
  360. TopLevelColumns.Clear();
  361. }
  362. TMaybe<TType> LoadStructType(const TVector<std::pair<TString, TType>>& members, ui32 level) {
  363. if (level == 0) {
  364. YQL_ENSURE(TopLevelColumns.Size() == 0);
  365. for (auto& [column, type] : members) {
  366. TopLevelColumns.AddColumn(column);
  367. }
  368. }
  369. return TExprTypeLoader::LoadStructType(members, level);
  370. }
  371. };
  372. const TTypeAnnotationNode* ParseOrderAwareTypeFromYson(const NYT::TNode& node, TColumnOrder& topLevelColumns, TExprContext& ctx, const TPosition& pos) {
  373. TOrderAwareExprTypeLoader loader(ctx, pos, topLevelColumns);
  374. return DoLoadTypeFromYson(loader, node, 0).GetOrElse(nullptr);
  375. }
  376. void WriteResOrPullType(NYson::TYsonConsumerBase& writer, const TTypeAnnotationNode* type, const TColumnOrder& columns) {
  377. if (columns.Size() == 0 ||
  378. type->GetKind() != ETypeAnnotationKind::List ||
  379. type->Cast<TListExprType>()->GetItemType()->GetKind() != ETypeAnnotationKind::Struct) {
  380. WriteTypeToYson(writer, type, true);
  381. } else {
  382. writer.OnBeginList();
  383. writer.OnListItem();
  384. writer.OnStringScalar("ListType");
  385. writer.OnListItem();
  386. SaveStructTypeToYsonWithLogicalNames(writer, type->Cast<TListExprType>()->GetItemType()->Cast<TStructExprType>(), columns, {}, true);
  387. writer.OnEndList();
  388. }
  389. }
  390. } // namespace NCommon
  391. } // namespace NYql