dispatch_traits.h 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237
  1. #pragma once
  2. #include <yql/essentials/public/udf/udf_type_inspection.h>
  3. #include <yql/essentials/public/udf/udf_value_builder.h>
  4. #include <arrow/type.h>
  5. namespace NYql {
  6. namespace NUdf {
  7. template <typename TTraits, typename... TArgs>
  8. std::unique_ptr<typename TTraits::TResult> MakeTupleArrowTraitsImpl(bool isOptional, TVector<std::unique_ptr<typename TTraits::TResult>>&& children, const TType* type, TArgs&&... args) {
  9. if (isOptional) {
  10. if constexpr (TTraits::PassType) {
  11. return std::make_unique<typename TTraits::template TTuple<true>>(std::move(children), type, std::forward<TArgs>(args)...);
  12. } else {
  13. return std::make_unique<typename TTraits::template TTuple<true>>(std::move(children), std::forward<TArgs>(args)...);
  14. }
  15. } else {
  16. if constexpr (TTraits::PassType) {
  17. return std::make_unique<typename TTraits::template TTuple<false>>(std::move(children), type, std::forward<TArgs>(args)...);
  18. } else {
  19. return std::make_unique<typename TTraits::template TTuple<false>>(std::move(children), std::forward<TArgs>(args)...);
  20. }
  21. }
  22. }
  23. template <typename TTraits, typename T, typename... TArgs>
  24. std::unique_ptr<typename TTraits::TResult> MakeFixedSizeArrowTraitsImpl(bool isOptional, const TType* type, TArgs&&... args) {
  25. if (isOptional) {
  26. if constexpr (TTraits::PassType) {
  27. return std::make_unique<typename TTraits::template TFixedSize<T, true>>(type, std::forward<TArgs>(args)...);
  28. } else {
  29. return std::make_unique<typename TTraits::template TFixedSize<T, true>>(std::forward<TArgs>(args)...);
  30. }
  31. } else {
  32. if constexpr (TTraits::PassType) {
  33. return std::make_unique<typename TTraits::template TFixedSize<T, false>>(type, std::forward<TArgs>(args)...);
  34. } else {
  35. return std::make_unique<typename TTraits::template TFixedSize<T, false>>(std::forward<TArgs>(args)...);
  36. }
  37. }
  38. }
  39. template <typename TTraits, typename T, NKikimr::NUdf::EDataSlot TOriginal, typename... TArgs>
  40. std::unique_ptr<typename TTraits::TResult> MakeStringArrowTraitsImpl(bool isOptional, const TType* type, TArgs&&... args) {
  41. if (isOptional) {
  42. if constexpr (TTraits::PassType) {
  43. return std::make_unique<typename TTraits::template TStrings<T, true, TOriginal>>(type, std::forward<TArgs>(args)...);
  44. } else {
  45. return std::make_unique<typename TTraits::template TStrings<T, true, TOriginal>>(std::forward<TArgs>(args)...);
  46. }
  47. } else {
  48. if constexpr (TTraits::PassType) {
  49. return std::make_unique<typename TTraits::template TStrings<T, false, TOriginal>>(type, std::forward<TArgs>(args)...);
  50. } else {
  51. return std::make_unique<typename TTraits::template TStrings<T, false, TOriginal>>(std::forward<TArgs>(args)...);
  52. }
  53. }
  54. }
  55. template <typename TTraits, typename TTzDate, typename... TArgs>
  56. std::unique_ptr<typename TTraits::TResult> MakeTzDateArrowTraitsImpl(bool isOptional, const TType* type, TArgs&&... args) {
  57. if constexpr (TTraits::PassType) {
  58. return TTraits::template MakeTzDate<TTzDate>(isOptional, type, std::forward<TArgs>(args)...);
  59. } else {
  60. return TTraits::template MakeTzDate<TTzDate>(isOptional, std::forward<TArgs>(args)...);
  61. }
  62. }
  63. template<typename TTraits>
  64. concept CanInstantiateArrowTraitsForDecimal = requires {
  65. typename TTraits::template TFixedSize<NYql::NDecimal::TInt128, true>;
  66. };
  67. template <typename TTraits, typename... TArgs>
  68. std::unique_ptr<typename TTraits::TResult> DispatchByArrowTraits(const ITypeInfoHelper& typeInfoHelper, const TType* type, const IPgBuilder* pgBuilder, TArgs&&... args) {
  69. const TType* unpacked = type;
  70. TOptionalTypeInspector typeOpt(typeInfoHelper, type);
  71. bool isOptional = false;
  72. if (typeOpt) {
  73. unpacked = typeOpt.GetItemType();
  74. isOptional = true;
  75. }
  76. TOptionalTypeInspector unpackedOpt(typeInfoHelper, unpacked);
  77. TPgTypeInspector unpackedPg(typeInfoHelper, unpacked);
  78. if (unpackedOpt || typeOpt && unpackedPg) {
  79. // at least 2 levels of optionals
  80. ui32 nestLevel = 0;
  81. auto currentType = type;
  82. auto previousType = type;
  83. TVector<const TType*> types;
  84. for (;;) {
  85. ++nestLevel;
  86. previousType = currentType;
  87. types.push_back(currentType);
  88. TOptionalTypeInspector currentOpt(typeInfoHelper, currentType);
  89. currentType = currentOpt.GetItemType();
  90. TOptionalTypeInspector nexOpt(typeInfoHelper, currentType);
  91. if (!nexOpt) {
  92. break;
  93. }
  94. }
  95. if (TPgTypeInspector(typeInfoHelper, currentType)) {
  96. previousType = currentType;
  97. ++nestLevel;
  98. }
  99. auto reader = DispatchByArrowTraits<TTraits>(typeInfoHelper, previousType, pgBuilder, std::forward<TArgs>(args)...);
  100. for (ui32 i = 1; i < nestLevel; ++i) {
  101. if constexpr (TTraits::PassType) {
  102. reader = std::make_unique<typename TTraits::TExtOptional>(std::move(reader), types[nestLevel - 1 - i], std::forward<TArgs>(args)...);
  103. } else {
  104. reader = std::make_unique<typename TTraits::TExtOptional>(std::move(reader), std::forward<TArgs>(args)...);
  105. }
  106. }
  107. return reader;
  108. }
  109. else {
  110. type = unpacked;
  111. }
  112. TStructTypeInspector typeStruct(typeInfoHelper, type);
  113. if (typeStruct) {
  114. TVector<std::unique_ptr<typename TTraits::TResult>> members;
  115. for (ui32 i = 0; i < typeStruct.GetMembersCount(); i++) {
  116. members.emplace_back(DispatchByArrowTraits<TTraits>(typeInfoHelper, typeStruct.GetMemberType(i), pgBuilder, std::forward<TArgs>(args)...));
  117. }
  118. // XXX: Use Tuple block reader for Struct.
  119. return MakeTupleArrowTraitsImpl<TTraits>(isOptional, std::move(members), type, std::forward<TArgs>(args)...);
  120. }
  121. TTupleTypeInspector typeTuple(typeInfoHelper, type);
  122. if (typeTuple) {
  123. TVector<std::unique_ptr<typename TTraits::TResult>> children;
  124. for (ui32 i = 0; i < typeTuple.GetElementsCount(); ++i) {
  125. children.emplace_back(DispatchByArrowTraits<TTraits>(typeInfoHelper, typeTuple.GetElementType(i), pgBuilder, std::forward<TArgs>(args)...));
  126. }
  127. return MakeTupleArrowTraitsImpl<TTraits>(isOptional, std::move(children), type, std::forward<TArgs>(args)...);
  128. }
  129. TDataTypeInspector typeData(typeInfoHelper, type);
  130. if (typeData) {
  131. auto typeId = typeData.GetTypeId();
  132. switch (GetDataSlot(typeId)) {
  133. case NUdf::EDataSlot::Int8:
  134. return MakeFixedSizeArrowTraitsImpl<TTraits, i8>(isOptional, type, std::forward<TArgs>(args)...);
  135. case NUdf::EDataSlot::Bool:
  136. case NUdf::EDataSlot::Uint8:
  137. return MakeFixedSizeArrowTraitsImpl<TTraits, ui8>(isOptional, type, std::forward<TArgs>(args)...);
  138. case NUdf::EDataSlot::Int16:
  139. return MakeFixedSizeArrowTraitsImpl<TTraits, i16>(isOptional, type, std::forward<TArgs>(args)...);
  140. case NUdf::EDataSlot::Uint16:
  141. case NUdf::EDataSlot::Date:
  142. return MakeFixedSizeArrowTraitsImpl<TTraits, ui16>(isOptional, type, std::forward<TArgs>(args)...);
  143. case NUdf::EDataSlot::Int32:
  144. case NUdf::EDataSlot::Date32:
  145. return MakeFixedSizeArrowTraitsImpl<TTraits, i32>(isOptional, type, std::forward<TArgs>(args)...);
  146. case NUdf::EDataSlot::Uint32:
  147. case NUdf::EDataSlot::Datetime:
  148. return MakeFixedSizeArrowTraitsImpl<TTraits, ui32>(isOptional, type, std::forward<TArgs>(args)...);
  149. case NUdf::EDataSlot::Int64:
  150. case NUdf::EDataSlot::Interval:
  151. case NUdf::EDataSlot::Interval64:
  152. case NUdf::EDataSlot::Datetime64:
  153. case NUdf::EDataSlot::Timestamp64:
  154. return MakeFixedSizeArrowTraitsImpl<TTraits, i64>(isOptional, type, std::forward<TArgs>(args)...);
  155. case NUdf::EDataSlot::Uint64:
  156. case NUdf::EDataSlot::Timestamp:
  157. return MakeFixedSizeArrowTraitsImpl<TTraits, ui64>(isOptional, type, std::forward<TArgs>(args)...);
  158. case NUdf::EDataSlot::Float:
  159. return MakeFixedSizeArrowTraitsImpl<TTraits, float>(isOptional, type, std::forward<TArgs>(args)...);
  160. case NUdf::EDataSlot::Double:
  161. return MakeFixedSizeArrowTraitsImpl<TTraits, double>(isOptional, type, std::forward<TArgs>(args)...);
  162. case NUdf::EDataSlot::String:
  163. return MakeStringArrowTraitsImpl<TTraits, arrow::BinaryType, NUdf::EDataSlot::String>(isOptional, type, std::forward<TArgs>(args)...);
  164. case NUdf::EDataSlot::Yson:
  165. return MakeStringArrowTraitsImpl<TTraits, arrow::BinaryType, NUdf::EDataSlot::Yson>(isOptional, type, std::forward<TArgs>(args)...);
  166. case NUdf::EDataSlot::JsonDocument:
  167. return MakeStringArrowTraitsImpl<TTraits, arrow::BinaryType, NUdf::EDataSlot::JsonDocument>(isOptional, type, std::forward<TArgs>(args)...);
  168. case NUdf::EDataSlot::Utf8:
  169. return MakeStringArrowTraitsImpl<TTraits, arrow::StringType, NUdf::EDataSlot::Utf8>(isOptional, type, std::forward<TArgs>(args)...);
  170. case NUdf::EDataSlot::Json:
  171. return MakeStringArrowTraitsImpl<TTraits, arrow::StringType, NUdf::EDataSlot::Json>(isOptional, type, std::forward<TArgs>(args)...);
  172. case NUdf::EDataSlot::TzDate:
  173. return MakeTzDateArrowTraitsImpl<TTraits, TTzDate>(isOptional, type, std::forward<TArgs>(args)...);
  174. case NUdf::EDataSlot::TzDatetime:
  175. return MakeTzDateArrowTraitsImpl<TTraits, TTzDatetime>(isOptional, type, std::forward<TArgs>(args)...);
  176. case NUdf::EDataSlot::TzTimestamp:
  177. return MakeTzDateArrowTraitsImpl<TTraits, TTzTimestamp>(isOptional, type, std::forward<TArgs>(args)...);
  178. case NUdf::EDataSlot::TzDate32:
  179. return MakeTzDateArrowTraitsImpl<TTraits, TTzDate32>(isOptional, type, std::forward<TArgs>(args)...);
  180. case NUdf::EDataSlot::TzDatetime64:
  181. return MakeTzDateArrowTraitsImpl<TTraits, TTzDatetime64>(isOptional, type, std::forward<TArgs>(args)...);
  182. case NUdf::EDataSlot::TzTimestamp64:
  183. return MakeTzDateArrowTraitsImpl<TTraits, TTzTimestamp64>(isOptional, type, std::forward<TArgs>(args)...);
  184. case NUdf::EDataSlot::Decimal: {
  185. if constexpr (CanInstantiateArrowTraitsForDecimal<TTraits>) {
  186. return MakeFixedSizeArrowTraitsImpl<TTraits, NYql::NDecimal::TInt128>(isOptional, type, std::forward<TArgs>(args)...);
  187. } else {
  188. Y_ENSURE(false, "Unsupported data slot");
  189. }
  190. }
  191. case NUdf::EDataSlot::Uuid:
  192. case NUdf::EDataSlot::DyNumber:
  193. Y_ENSURE(false, "Unsupported data slot");
  194. }
  195. }
  196. TResourceTypeInspector resource(typeInfoHelper, type);
  197. if (resource) {
  198. if constexpr (TTraits::PassType) {
  199. return TTraits::MakeResource(isOptional, type, std::forward<TArgs>(args)...);
  200. } else {
  201. return TTraits::MakeResource(isOptional, std::forward<TArgs>(args)...);
  202. }
  203. }
  204. TPgTypeInspector typePg(typeInfoHelper, type);
  205. if (typePg) {
  206. auto desc = typeInfoHelper.FindPgTypeDescription(typePg.GetTypeId());
  207. if constexpr (TTraits::PassType) {
  208. return TTraits::MakePg(*desc, pgBuilder, type, std::forward<TArgs>(args)...);
  209. } else {
  210. return TTraits::MakePg(*desc, pgBuilder, std::forward<TArgs>(args)...);
  211. }
  212. }
  213. Y_ENSURE(false, "Unsupported type");
  214. }
  215. }
  216. }