mkql_builtins_impl.h.txt 92 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761
  1. #pragma once
  2. #include "mkql_builtins_impl_common.h"
  3. #include <mkql_builtins.h>
  4. #include "mkql_builtins_codegen.h"
  5. #include <arrow/array/array_base.h>
  6. #include <arrow/array/util.h>
  7. namespace NKikimr {
  8. namespace NMiniKQL {
  9. struct TUnaryStub {
  10. template<typename TFunc>
  11. static NUdf::TUnboxedValuePod Execute(const NUdf::TUnboxedValuePod* args) {
  12. return TFunc::Execute(*args);
  13. }
  14. #ifndef MKQL_DISABLE_CODEGEN
  15. template<typename TFunc>
  16. static Value* Generate(Value *const * args, const TCodegenContext& ctx, BasicBlock*& block) {
  17. return GenerateUnaryWithoutCheck(*args, ctx, block, &TFunc::Generate);
  18. }
  19. #endif
  20. };
  21. struct TUnaryWrap {
  22. template<typename TFunc>
  23. static NUdf::TUnboxedValuePod Execute(const NUdf::TUnboxedValuePod* args) {
  24. return *args ? TFunc::Execute(*args) : NUdf::TUnboxedValuePod();
  25. }
  26. #ifndef MKQL_DISABLE_CODEGEN
  27. template<typename TFunc>
  28. static Value* Generate(Value *const * args, const TCodegenContext& ctx, BasicBlock*& block) {
  29. return GenerateUnaryWithCheck(*args, ctx, block, &TFunc::Generate);
  30. }
  31. #endif
  32. };
  33. template<bool CheckLeft, bool CheckRight>
  34. struct TBinaryWrap {
  35. template<typename TFunc>
  36. static NUdf::TUnboxedValuePod Execute(const NUdf::TUnboxedValuePod* args) {
  37. if (CheckLeft && !args[0])
  38. return NUdf::TUnboxedValuePod();
  39. if (CheckRight && !args[1])
  40. return NUdf::TUnboxedValuePod();
  41. return TFunc::Execute(args[0], args[1]);
  42. }
  43. #ifndef MKQL_DISABLE_CODEGEN
  44. template<typename TFunc>
  45. static Value* Generate(Value *const * args, const TCodegenContext& ctx, BasicBlock*& block) {
  46. return GenerateBinary<CheckLeft, CheckRight>(args[0], args[1], ctx, block, &TFunc::Generate);
  47. }
  48. #endif
  49. };
  50. struct TAggregateWrap {
  51. template<typename TFunc>
  52. static NUdf::TUnboxedValuePod Execute(const NUdf::TUnboxedValuePod* args) {
  53. if (!args[0])
  54. return args[1];
  55. if (!args[1])
  56. return args[0];
  57. return TFunc::Execute(args[0], args[1]);
  58. }
  59. #ifndef MKQL_DISABLE_CODEGEN
  60. template<typename TFunc>
  61. static Value* Generate(Value *const * args, const TCodegenContext& ctx, BasicBlock*& block) {
  62. return GenerateAggregate(args[0], args[1], ctx, block, &TFunc::Generate);
  63. }
  64. #endif
  65. };
  66. struct TAggrCompareWrap {
  67. template<typename TFunc>
  68. static NUdf::TUnboxedValuePod Execute(const NUdf::TUnboxedValuePod* args) {
  69. const bool a0(args[0]), a1(args[1]);
  70. return (a0 && a1) ?
  71. TFunc::Execute(args[0], args[1]) : NUdf::TUnboxedValuePod(TFunc::Simple(a0, a1));
  72. }
  73. #ifndef MKQL_DISABLE_CODEGEN
  74. template<typename TFunc>
  75. static Value* Generate(Value *const * args, const TCodegenContext& ctx, BasicBlock*& block) {
  76. return GenerateCompareAggregate(args[0], args[1], ctx, block, &TFunc::Generate, TFunc::SimplePredicate);
  77. }
  78. #endif
  79. };
  80. template<bool CheckFirst>
  81. struct TTernaryWrap {
  82. template<typename TFunc>
  83. static NUdf::TUnboxedValuePod Execute(const NUdf::TUnboxedValuePod* args) {
  84. if (CheckFirst && !*args)
  85. return NUdf::TUnboxedValuePod();
  86. return TFunc::Execute(args[0], args[1], args[2]);
  87. }
  88. #ifndef MKQL_DISABLE_CODEGEN
  89. template<typename TFunc>
  90. static Value* Generate(Value *const * args, const TCodegenContext& ctx, BasicBlock*& block) {
  91. return GenerateTernary<CheckFirst>(args[0], args[1], args[2], ctx, block, &TFunc::Generate);
  92. }
  93. #endif
  94. };
  95. template <typename TInput, typename TOutput>
  96. struct TArithmeticConstraintsUnary {
  97. static_assert(std::is_arithmetic<TInput>::value, "Input type must be arithmetic!");
  98. static_assert(std::is_arithmetic<TOutput>::value, "Output type must be arithmetic!");
  99. };
  100. template <typename TInput, typename TOutput>
  101. struct TArithmeticConstraintsSame {
  102. static_assert(std::is_arithmetic<TInput>::value, "Input type must be arithmetic!");
  103. static_assert(std::is_same<TInput, TOutput>::value, "Input and output must be same types!");
  104. };
  105. template <typename TLeft, typename TRight, typename TOutput>
  106. struct TArithmeticConstraintsBinary {
  107. static_assert(std::is_arithmetic<TLeft>::value, "Left type must be arithmetic!");
  108. static_assert(std::is_arithmetic<TRight>::value, "Right type must be arithmetic!");
  109. static_assert(std::is_arithmetic<TOutput>::value, "Output type must be arithmetic!");
  110. };
  111. template <typename TInput, typename TOutput, class TImpl>
  112. struct TSimpleArithmeticUnary : public TArithmeticConstraintsSame<TInput, TOutput> {
  113. static NUdf::TUnboxedValuePod Execute(const NUdf::TUnboxedValuePod& arg) {
  114. return NUdf::TUnboxedValuePod(TImpl::Do(arg.template Get<TInput>()));
  115. }
  116. static void DoPtr(
  117. const typename TPrimitiveDataType<TInput>::TLayout* arg,
  118. typename TPrimitiveDataType<TOutput>::TLayout* res) {
  119. *res = TImpl::Do(*arg);
  120. }
  121. #ifndef MKQL_DISABLE_CODEGEN
  122. static Value* Generate(Value* arg, const TCodegenContext& ctx, BasicBlock*& block)
  123. {
  124. auto& context = ctx.Codegen.GetContext();
  125. const auto val = GetterFor<TInput>(arg, context, block);
  126. const auto res = TImpl::Gen(val, ctx, block);
  127. const auto wide = SetterFor<TOutput>(res, context, block);
  128. return wide;
  129. }
  130. #endif
  131. };
  132. template <class TImpl>
  133. struct TDecimalUnary {
  134. static void DoPtr(
  135. const NYql::NDecimal::TInt128* arg,
  136. NYql::NDecimal::TInt128* res) {
  137. *res = TImpl::Execute(NUdf::TUnboxedValuePod(*arg)).GetInt128();
  138. }
  139. };
  140. template <typename TLeft, typename TRight, typename TOutput, class TImpl, bool CustomCast = false>
  141. struct TSimpleArithmeticBinary : public TArithmeticConstraintsBinary<TLeft, TRight, TOutput> {
  142. static NUdf::TUnboxedValuePod Execute(const NUdf::TUnboxedValuePod& left, const NUdf::TUnboxedValuePod& right) {
  143. return NUdf::TUnboxedValuePod(TImpl::Do(left.template Get<TLeft>(), right.template Get<TRight>()));
  144. }
  145. static void DoPtr(
  146. const typename TPrimitiveDataType<TLeft>::TLayout* left,
  147. const typename TPrimitiveDataType<TRight>::TLayout* right,
  148. typename TPrimitiveDataType<TOutput>::TLayout* res) {
  149. *res = TImpl::Do(*left, *right);
  150. }
  151. #ifndef MKQL_DISABLE_CODEGEN
  152. static Value* Generate(Value* left, Value* right, const TCodegenContext& ctx, BasicBlock*& block)
  153. {
  154. auto& context = ctx.Codegen.GetContext();
  155. auto lhs = GetterFor<TLeft>(left, context, block);
  156. auto rhs = GetterFor<TRight>(right, context, block);
  157. if constexpr (!CustomCast) {
  158. lhs = StaticCast<TLeft, TOutput>(lhs, context, block);
  159. rhs = StaticCast<TRight, TOutput>(rhs, context, block);
  160. }
  161. const auto res = TImpl::Gen(lhs, rhs, ctx, block);
  162. const auto wide = SetterFor<TOutput>(res, context, block);
  163. return wide;
  164. }
  165. #endif
  166. };
  167. template <typename TInput, typename TOutput, class TImpl>
  168. struct TShiftArithmeticBinary : public TArithmeticConstraintsSame<TInput, TOutput> {
  169. static NUdf::TUnboxedValuePod Execute(const NUdf::TUnboxedValuePod& left, const NUdf::TUnboxedValuePod& right) {
  170. return NUdf::TUnboxedValuePod(TImpl::Do(left.template Get<TInput>(), right.Get<ui8>()));
  171. }
  172. #ifndef MKQL_DISABLE_CODEGEN
  173. static Value* Generate(Value* left, Value* right, const TCodegenContext& ctx, BasicBlock*& block)
  174. {
  175. auto& context = ctx.Codegen.GetContext();
  176. const auto lhs = GetterFor<TInput>(left, context, block);
  177. const auto rhs = CastInst::Create(Instruction::Trunc, right, Type::getInt8Ty(context), "bits", block);
  178. const auto res = TImpl::Gen(lhs, rhs, ctx, block);
  179. const auto wide = SetterFor<TOutput>(res, context, block);
  180. return wide;
  181. }
  182. #endif
  183. };
  184. template <typename TInput, typename TOutput>
  185. struct TUnaryArgs {
  186. static const TFunctionParamMetadata Value[3];
  187. };
  188. template <typename TInput, typename TOutput>
  189. const TFunctionParamMetadata TUnaryArgs<TInput, TOutput>::Value[3] = {
  190. { TOutput::Id, 0 },
  191. { TInput::Id, 0 },
  192. { 0, 0 }
  193. };
  194. template <typename TInput, typename TOutput, bool IsOptional>
  195. struct TUnaryArgsOpt {
  196. static const TFunctionParamMetadata Value[3];
  197. };
  198. template <typename TInput, typename TOutput, bool IsOptional>
  199. const TFunctionParamMetadata TUnaryArgsOpt<TInput, TOutput, IsOptional>::Value[3] = {
  200. { TOutput::Id, IsOptional ? TFunctionParamMetadata::FlagIsNullable : 0 },
  201. { TInput::Id, IsOptional ? TFunctionParamMetadata::FlagIsNullable : 0 },
  202. { 0, 0 }
  203. };
  204. template <typename TInput, typename TOutput>
  205. struct TUnaryArgsWithNullableResult {
  206. static const TFunctionParamMetadata Value[3];
  207. };
  208. template <typename TInput, typename TOutput>
  209. const TFunctionParamMetadata TUnaryArgsWithNullableResult<TInput, TOutput>::Value[3] = {
  210. { TOutput::Id, TFunctionParamMetadata::FlagIsNullable },
  211. { TInput::Id, 0 },
  212. { 0, 0 }
  213. };
  214. template <typename TInput, typename TOutput, bool IsOptional>
  215. struct TUnaryArgsWithNullableResultOpt {
  216. static const TFunctionParamMetadata Value[3];
  217. };
  218. template <typename TInput, typename TOutput, bool IsOptional>
  219. const TFunctionParamMetadata TUnaryArgsWithNullableResultOpt<TInput, TOutput, IsOptional>::Value[3] = {
  220. { TOutput::Id, TFunctionParamMetadata::FlagIsNullable },
  221. { TInput::Id, IsOptional ? TFunctionParamMetadata::FlagIsNullable : 0 },
  222. { 0, 0 }
  223. };
  224. template <typename TInput, typename TOutput>
  225. struct TBinaryArgs {
  226. static const TFunctionParamMetadata Value[4];
  227. };
  228. template <typename TInput, typename TOutput>
  229. const TFunctionParamMetadata TBinaryArgs<TInput, TOutput>::Value[4] = {
  230. { TOutput::Id, 0 },
  231. { TInput::Id, 0 },
  232. { TInput::Id, 0 },
  233. { 0, 0 }
  234. };
  235. template <typename TInput1, typename TInput2, typename TOutput, bool IsLeftOptional, bool IsRightOptional>
  236. struct TBinaryArgsOpt {
  237. static const TFunctionParamMetadata Value[4];
  238. };
  239. template <typename TInput1, typename TInput2, typename TOutput, bool IsLeftOptional, bool IsRightOptional>
  240. const TFunctionParamMetadata TBinaryArgsOpt<TInput1, TInput2, TOutput, IsLeftOptional, IsRightOptional>::Value[4] = {
  241. { TOutput::Id, (IsLeftOptional || IsRightOptional) ? TFunctionParamMetadata::FlagIsNullable : 0 },
  242. { TInput1::Id, IsLeftOptional ? TFunctionParamMetadata::FlagIsNullable : 0 },
  243. { TInput2::Id, IsRightOptional ? TFunctionParamMetadata::FlagIsNullable : 0 },
  244. { 0, 0 }
  245. };
  246. template <typename TInput, typename TOutput, bool IsOptional>
  247. struct TBinaryArgsSameOpt {
  248. static const TFunctionParamMetadata Value[4];
  249. };
  250. template <typename TInput, typename TOutput, bool IsOptional>
  251. const TFunctionParamMetadata TBinaryArgsSameOpt<TInput, TOutput, IsOptional>::Value[4] = {
  252. { TOutput::Id, IsOptional ? TFunctionParamMetadata::FlagIsNullable : 0 },
  253. { TInput::Id, IsOptional ? TFunctionParamMetadata::FlagIsNullable : 0 },
  254. { TInput::Id, IsOptional ? TFunctionParamMetadata::FlagIsNullable : 0 },
  255. { 0, 0 }
  256. };
  257. template <typename TInput, typename TOutput, bool IsOptional>
  258. struct TBinaryArgsSameOptArgsWithNullableResult {
  259. static const TFunctionParamMetadata Value[4];
  260. };
  261. template <typename TInput, typename TOutput, bool IsOptional>
  262. const TFunctionParamMetadata TBinaryArgsSameOptArgsWithNullableResult<TInput, TOutput, IsOptional>::Value[4] = {
  263. { TOutput::Id, TFunctionParamMetadata::FlagIsNullable },
  264. { TInput::Id, IsOptional ? TFunctionParamMetadata::FlagIsNullable : 0 },
  265. { TInput::Id, IsOptional ? TFunctionParamMetadata::FlagIsNullable : 0 },
  266. { 0, 0 }
  267. };
  268. template <typename TInput, typename TOutput>
  269. struct TBinaryShiftArgs {
  270. static const TFunctionParamMetadata Value[4];
  271. };
  272. template <typename TInput, typename TOutput>
  273. const TFunctionParamMetadata TBinaryShiftArgs<TInput, TOutput>::Value[4] = {
  274. { TOutput::Id, 0 },
  275. { TInput::Id, 0 },
  276. { NUdf::TDataType<ui8>::Id, 0 },
  277. { 0, 0 }
  278. };
  279. template <typename TInput, typename TOutput, bool IsOptional>
  280. struct TBinaryShiftArgsOpt {
  281. static const TFunctionParamMetadata Value[4];
  282. };
  283. template <typename TInput, typename TOutput, bool IsOptional>
  284. const TFunctionParamMetadata TBinaryShiftArgsOpt<TInput, TOutput, IsOptional>::Value[4] = {
  285. { TOutput::Id, IsOptional ? TFunctionParamMetadata::FlagIsNullable : 0 },
  286. { TInput::Id, IsOptional ? TFunctionParamMetadata::FlagIsNullable : 0 },
  287. { NUdf::TDataType<ui8>::Id, 0 },
  288. { 0, 0 }
  289. };
  290. template <typename TInput, typename TOutput>
  291. struct TBinaryArgsWithNullableResult {
  292. static const TFunctionParamMetadata Value[4];
  293. };
  294. template <typename TInput, typename TOutput>
  295. const TFunctionParamMetadata TBinaryArgsWithNullableResult<TInput, TOutput>::Value[4] = {
  296. { TOutput::Id, TFunctionParamMetadata::FlagIsNullable },
  297. { TInput::Id, 0 },
  298. { TInput::Id, 0 },
  299. { 0, 0 }
  300. };
  301. template <typename TOutput, typename TInput1, typename TInput2, typename TInput3, bool IsFirstOptional, bool IsSecondOptional, bool IsThirdOptional, bool IsResultOptional = IsFirstOptional>
  302. struct TTernaryArgs {
  303. static const TFunctionParamMetadata Value[5];
  304. };
  305. template <typename TOutput, typename TInput1, typename TInput2, typename TInput3, bool IsFirstOptional, bool IsSecondOptional, bool IsThirdOptional, bool IsResultOptional>
  306. const TFunctionParamMetadata TTernaryArgs<TOutput, TInput1, TInput2, TInput3, IsFirstOptional, IsSecondOptional, IsThirdOptional, IsResultOptional>::Value[5] = {
  307. { TOutput::Id, IsResultOptional ? TFunctionParamMetadata::FlagIsNullable : 0},
  308. { TInput1::Id, IsFirstOptional ? TFunctionParamMetadata::FlagIsNullable : 0},
  309. { TInput2::Id, IsSecondOptional ? TFunctionParamMetadata::FlagIsNullable : 0},
  310. { TInput3::Id, IsThirdOptional ? TFunctionParamMetadata::FlagIsNullable : 0},
  311. { 0, 0 }
  312. };
  313. template <typename TInput1, typename TInput2, typename TOutput, bool IsLeftOptional, bool IsRightOptional>
  314. struct TBinaryArgsOptWithNullableResult {
  315. static const TFunctionParamMetadata Value[4];
  316. };
  317. template <typename TInput1, typename TInput2, typename TOutput, bool IsLeftOptional, bool IsRightOptional>
  318. const TFunctionParamMetadata TBinaryArgsOptWithNullableResult<TInput1, TInput2, TOutput, IsLeftOptional, IsRightOptional>::Value[4] = {
  319. { TOutput::Id, TFunctionParamMetadata::FlagIsNullable },
  320. { TInput1::Id, IsLeftOptional ? TFunctionParamMetadata::FlagIsNullable : 0 },
  321. { TInput2::Id, IsRightOptional ? TFunctionParamMetadata::FlagIsNullable : 0 },
  322. { 0, 0 }
  323. };
  324. template <typename TFunc, typename TArgs, typename TWrap>
  325. void RegisterFunctionImpl(IBuiltinFunctionRegistry& registry, const std::string_view& name) {
  326. #ifndef MKQL_DISABLE_CODEGEN
  327. const TFunctionDescriptor description(TArgs::Value, &TWrap::template Execute<TFunc>, reinterpret_cast<void*>(&TWrap::template Generate<TFunc>));
  328. #else
  329. const TFunctionDescriptor description(TArgs::Value, &TWrap::template Execute<TFunc>);
  330. #endif
  331. registry.Register(name, description);
  332. }
  333. template <
  334. typename TInput, typename TOutput,
  335. template<typename, typename> class TFunc,
  336. template<typename, typename> class TArgs
  337. >
  338. void RegisterFunction(IBuiltinFunctionRegistry& registry, const std::string_view& name) {
  339. RegisterFunctionImpl<TFunc<TInput, TOutput>, TArgs<TInput, TOutput>, TUnaryStub>(registry, name);
  340. }
  341. template <
  342. typename TInput, typename TOutput,
  343. class TFunc,
  344. template<typename, typename, bool> class TArgs
  345. >
  346. void RegisterFunctionOpt(IBuiltinFunctionRegistry& registry, const std::string_view& name) {
  347. RegisterFunctionImpl<TFunc, TArgs<TInput, TOutput, false>, TUnaryStub>(registry, name);
  348. RegisterFunctionImpl<TFunc, TArgs<TInput, TOutput, true>, TUnaryWrap>(registry, name);
  349. }
  350. template <
  351. typename TType,
  352. template<NUdf::EDataSlot> class TFunc,
  353. template<typename, typename, bool> class TArgs
  354. >
  355. void RegisterCustomAggregateFunction(IBuiltinFunctionRegistry& registry, const std::string_view& name) {
  356. RegisterFunctionImpl<TFunc<TType::Slot>, TArgs<TType, TType, false>, TBinaryWrap<false, false>>(registry, name);
  357. RegisterFunctionImpl<TFunc<TType::Slot>, TArgs<TType, TType, true>, TAggregateWrap>(registry, name);
  358. }
  359. template <
  360. typename TType,
  361. template<NUdf::EDataSlot> class TFunc,
  362. template<typename, typename, typename, bool, bool> class TArgs
  363. >
  364. void RegisterCustomSameTypesFunction(IBuiltinFunctionRegistry& registry, const std::string_view& name) {
  365. RegisterFunctionImpl<TFunc<TType::Slot>, TArgs<TType, TType, TType, false, false>, TBinaryWrap<false, false>>(registry, name);
  366. RegisterFunctionImpl<TFunc<TType::Slot>, TArgs<TType, TType, TType, true, false>, TBinaryWrap<true, false>>(registry, name);
  367. RegisterFunctionImpl<TFunc<TType::Slot>, TArgs<TType, TType, TType, false, true>, TBinaryWrap<false, true>>(registry, name);
  368. RegisterFunctionImpl<TFunc<TType::Slot>, TArgs<TType, TType, TType, true, true>, TBinaryWrap<true, true>>(registry, name);
  369. }
  370. template <
  371. typename TType,
  372. template<typename> class TFunc,
  373. template<typename, typename, bool> class TArgs
  374. >
  375. void RegisterAggregateFunction(IBuiltinFunctionRegistry& registry, const std::string_view& name) {
  376. RegisterFunctionImpl<TFunc<typename TType::TLayout>, TArgs<TType, TType, false>, TBinaryWrap<false, false>>(registry, name);
  377. RegisterFunctionImpl<TFunc<typename TType::TLayout>, TArgs<TType, TType, true>, TAggregateWrap>(registry, name);
  378. }
  379. template <
  380. typename TType,
  381. template<typename> class TFunc,
  382. template<typename, typename, bool> class TArgs
  383. >
  384. void RegisterAggregateFunctionPoly(IBuiltinFunctionRegistry& registry, const std::string_view& name) {
  385. RegisterFunctionImpl<TFunc<TType>, TArgs<TType, TType, false>, TBinaryWrap<false, false>>(registry, name);
  386. RegisterFunctionImpl<TFunc<TType>, TArgs<TType, TType, true>, TAggregateWrap>(registry, name);
  387. }
  388. template <
  389. typename TType,
  390. template<typename> class TFunc,
  391. template<typename, typename, typename, bool, bool> class TArgs
  392. >
  393. void RegisterSameTypesFunction(IBuiltinFunctionRegistry& registry, const std::string_view& name) {
  394. RegisterFunctionImpl<TFunc<typename TType::TLayout>, TArgs<TType, TType, TType, false, false>, TBinaryWrap<false, false>>(registry, name);
  395. RegisterFunctionImpl<TFunc<typename TType::TLayout>, TArgs<TType, TType, TType, true, false>, TBinaryWrap<true, false>>(registry, name);
  396. RegisterFunctionImpl<TFunc<typename TType::TLayout>, TArgs<TType, TType, TType, false, true>, TBinaryWrap<false, true>>(registry, name);
  397. RegisterFunctionImpl<TFunc<typename TType::TLayout>, TArgs<TType, TType, TType, true, true>, TBinaryWrap<true, true>>(registry, name);
  398. }
  399. template <
  400. typename TInput, typename TOutput,
  401. template<typename, typename> class TFunc,
  402. template<typename, typename, bool> class TArgs
  403. >
  404. void RegisterFunctionUnOpt(IBuiltinFunctionRegistry& registry, const std::string_view& name) {
  405. RegisterFunctionImpl<TFunc<typename TInput::TLayout, typename TOutput::TLayout>, TArgs<TInput, TOutput, false>, TUnaryStub>(registry, name);
  406. RegisterFunctionImpl<TFunc<typename TInput::TLayout, typename TOutput::TLayout>, TArgs<TInput, TOutput, true>, TUnaryWrap>(registry, name);
  407. }
  408. template <
  409. typename TInput1, typename TInput2, typename TOutput,
  410. template<typename, typename, typename> class TFunc,
  411. template<typename, typename, typename, bool, bool> class TArgs
  412. >
  413. void RegisterFunctionBinOpt(IBuiltinFunctionRegistry& registry, const std::string_view& name) {
  414. RegisterFunctionImpl<TFunc<typename TInput1::TLayout, typename TInput2::TLayout, typename TOutput::TLayout>, TArgs<TInput1, TInput2, TOutput, false, false>, TBinaryWrap<false, false>>(registry, name);
  415. RegisterFunctionImpl<TFunc<typename TInput1::TLayout, typename TInput2::TLayout, typename TOutput::TLayout>, TArgs<TInput1, TInput2, TOutput, false, true>, TBinaryWrap<false, true>>(registry, name);
  416. RegisterFunctionImpl<TFunc<typename TInput1::TLayout, typename TInput2::TLayout, typename TOutput::TLayout>, TArgs<TInput1, TInput2, TOutput, true, false>, TBinaryWrap<true, false>>(registry, name);
  417. RegisterFunctionImpl<TFunc<typename TInput1::TLayout, typename TInput2::TLayout, typename TOutput::TLayout>, TArgs<TInput1, TInput2, TOutput, true, true>, TBinaryWrap<true, true>>(registry, name);
  418. }
  419. template <
  420. typename TInput1, typename TInput2, typename TOutput,
  421. template<typename, typename, typename> class TFunc,
  422. template<typename, typename, typename, bool, bool> class TArgs
  423. >
  424. void RegisterFunctionBinPolyOpt(IBuiltinFunctionRegistry& registry, const std::string_view& name) {
  425. RegisterFunctionImpl<TFunc<TInput1, TInput2, TOutput>, TArgs<TInput1, TInput2, TOutput, false, false>, TBinaryWrap<false, false>>(registry, name);
  426. RegisterFunctionImpl<TFunc<TInput1, TInput2, TOutput>, TArgs<TInput1, TInput2, TOutput, false, true>, TBinaryWrap<false, true>>(registry, name);
  427. RegisterFunctionImpl<TFunc<TInput1, TInput2, TOutput>, TArgs<TInput1, TInput2, TOutput, true, false>, TBinaryWrap<true, false>>(registry, name);
  428. RegisterFunctionImpl<TFunc<TInput1, TInput2, TOutput>, TArgs<TInput1, TInput2, TOutput, true, true>, TBinaryWrap<true, true>>(registry, name);
  429. }
  430. template <
  431. template<typename, typename, typename> class TFunc,
  432. template<typename, typename, typename, bool, bool> class TArgs
  433. >
  434. void RegisterBinaryUnsignedFunctionOpt(IBuiltinFunctionRegistry& registry, const std::string_view& name) {
  435. RegisterFunctionBinOpt<NUdf::TDataType<ui8>, NUdf::TDataType<ui8>, NUdf::TDataType<ui8>, TFunc, TArgs>(registry, name);
  436. RegisterFunctionBinOpt<NUdf::TDataType<ui8>, NUdf::TDataType<ui16>, NUdf::TDataType<ui16>, TFunc, TArgs>(registry, name);
  437. RegisterFunctionBinOpt<NUdf::TDataType<ui8>, NUdf::TDataType<ui32>, NUdf::TDataType<ui32>, TFunc, TArgs>(registry, name);
  438. RegisterFunctionBinOpt<NUdf::TDataType<ui8>, NUdf::TDataType<ui64>, NUdf::TDataType<ui64>, TFunc, TArgs>(registry, name);
  439. RegisterFunctionBinOpt<NUdf::TDataType<ui16>, NUdf::TDataType<ui8>, NUdf::TDataType<ui16>, TFunc, TArgs>(registry, name);
  440. RegisterFunctionBinOpt<NUdf::TDataType<ui16>, NUdf::TDataType<ui16>, NUdf::TDataType<ui16>, TFunc, TArgs>(registry, name);
  441. RegisterFunctionBinOpt<NUdf::TDataType<ui16>, NUdf::TDataType<ui32>, NUdf::TDataType<ui32>, TFunc, TArgs>(registry, name);
  442. RegisterFunctionBinOpt<NUdf::TDataType<ui16>, NUdf::TDataType<ui64>, NUdf::TDataType<ui64>, TFunc, TArgs>(registry, name);
  443. RegisterFunctionBinOpt<NUdf::TDataType<ui32>, NUdf::TDataType<ui8>, NUdf::TDataType<ui32>, TFunc, TArgs>(registry, name);
  444. RegisterFunctionBinOpt<NUdf::TDataType<ui32>, NUdf::TDataType<ui16>, NUdf::TDataType<ui32>, TFunc, TArgs>(registry, name);
  445. RegisterFunctionBinOpt<NUdf::TDataType<ui32>, NUdf::TDataType<ui32>, NUdf::TDataType<ui32>, TFunc, TArgs>(registry, name);
  446. RegisterFunctionBinOpt<NUdf::TDataType<ui32>, NUdf::TDataType<ui64>, NUdf::TDataType<ui64>, TFunc, TArgs>(registry, name);
  447. RegisterFunctionBinOpt<NUdf::TDataType<ui64>, NUdf::TDataType<ui8>, NUdf::TDataType<ui64>, TFunc, TArgs>(registry, name);
  448. RegisterFunctionBinOpt<NUdf::TDataType<ui64>, NUdf::TDataType<ui16>, NUdf::TDataType<ui64>, TFunc, TArgs>(registry, name);
  449. RegisterFunctionBinOpt<NUdf::TDataType<ui64>, NUdf::TDataType<ui32>, NUdf::TDataType<ui64>, TFunc, TArgs>(registry, name);
  450. RegisterFunctionBinOpt<NUdf::TDataType<ui64>, NUdf::TDataType<ui64>, NUdf::TDataType<ui64>, TFunc, TArgs>(registry, name);
  451. }
  452. template <
  453. typename TInput, typename TOutput,
  454. template<typename, typename> class TFunc,
  455. template<typename, typename, bool> class TArgs
  456. >
  457. void RegisterShiftFunctionOpt(IBuiltinFunctionRegistry& registry, const std::string_view& name) {
  458. RegisterFunctionImpl<TFunc<typename TInput::TLayout, typename TOutput::TLayout>, TArgs<TInput, TOutput, false>, TBinaryWrap<false, false>>(registry, name);
  459. RegisterFunctionImpl<TFunc<typename TInput::TLayout, typename TOutput::TLayout>, TArgs<TInput, TOutput, true>, TBinaryWrap<true, false>>(registry, name);
  460. }
  461. template <
  462. template<typename, typename> class TFunc,
  463. template<typename, typename, bool> class TArgs
  464. >
  465. void RegisterUnsignedShiftFunctionOpt(IBuiltinFunctionRegistry& registry, const std::string_view& name) {
  466. RegisterShiftFunctionOpt<NUdf::TDataType<ui8>, NUdf::TDataType<ui8>, TFunc, TArgs>(registry, name);
  467. RegisterShiftFunctionOpt<NUdf::TDataType<ui16>, NUdf::TDataType<ui16>, TFunc, TArgs>(registry, name);
  468. RegisterShiftFunctionOpt<NUdf::TDataType<ui32>, NUdf::TDataType<ui32>, TFunc, TArgs>(registry, name);
  469. RegisterShiftFunctionOpt<NUdf::TDataType<ui64>, NUdf::TDataType<ui64>, TFunc, TArgs>(registry, name);
  470. }
  471. template <
  472. template<typename, typename> class TFunc,
  473. template<typename, typename, bool> class TArgs
  474. >
  475. void RegisterUnaryUnsignedFunctionOpt(IBuiltinFunctionRegistry& registry, const std::string_view& name) {
  476. RegisterFunctionUnOpt<NUdf::TDataType<ui8>, NUdf::TDataType<ui8>, TFunc, TArgs>(registry, name);
  477. RegisterFunctionUnOpt<NUdf::TDataType<ui16>, NUdf::TDataType<ui16>, TFunc, TArgs>(registry, name);
  478. RegisterFunctionUnOpt<NUdf::TDataType<ui32>, NUdf::TDataType<ui32>, TFunc, TArgs>(registry, name);
  479. RegisterFunctionUnOpt<NUdf::TDataType<ui64>, NUdf::TDataType<ui64>, TFunc, TArgs>(registry, name);
  480. }
  481. template <
  482. template<typename, typename> class TFunc,
  483. template<typename, typename, bool> class TArgs
  484. >
  485. void RegisterUnaryIntegralFunctionOpt(IBuiltinFunctionRegistry& registry, const std::string_view& name) {
  486. RegisterUnaryUnsignedFunctionOpt<TFunc, TArgs>(registry, name);
  487. RegisterFunctionUnOpt<NUdf::TDataType<i8>, NUdf::TDataType<i8>, TFunc, TArgs>(registry, name);
  488. RegisterFunctionUnOpt<NUdf::TDataType<i16>, NUdf::TDataType<i16>, TFunc, TArgs>(registry, name);
  489. RegisterFunctionUnOpt<NUdf::TDataType<i32>, NUdf::TDataType<i32>, TFunc, TArgs>(registry, name);
  490. RegisterFunctionUnOpt<NUdf::TDataType<i64>, NUdf::TDataType<i64>, TFunc, TArgs>(registry, name);
  491. }
  492. template <
  493. template<typename, typename> class TFunc,
  494. template<typename, typename, bool> class TArgs
  495. >
  496. void RegisterUnaryNumericFunctionOpt(IBuiltinFunctionRegistry& registry, const std::string_view& name) {
  497. RegisterUnaryIntegralFunctionOpt<TFunc, TArgs>(registry, name);
  498. RegisterFunctionUnOpt<NUdf::TDataType<float>, NUdf::TDataType<float>, TFunc, TArgs>(registry, name);
  499. RegisterFunctionUnOpt<NUdf::TDataType<double>, NUdf::TDataType<double>, TFunc, TArgs>(registry, name);
  500. }
  501. template <
  502. template<typename, typename, typename> class TFunc,
  503. template<typename, typename, typename, bool, bool> class TArgs
  504. >
  505. void RegisterBinaryIntegralToUnsignedFunctionOpt(IBuiltinFunctionRegistry& registry, const std::string_view& name) {
  506. RegisterFunctionBinOpt<NUdf::TDataType<i8>, NUdf::TDataType<ui16>, NUdf::TDataType<ui16>, TFunc, TArgs>(registry, name);
  507. RegisterFunctionBinOpt<NUdf::TDataType<i8>, NUdf::TDataType<ui32>, NUdf::TDataType<ui32>, TFunc, TArgs>(registry, name);
  508. RegisterFunctionBinOpt<NUdf::TDataType<i8>, NUdf::TDataType<ui64>, NUdf::TDataType<ui64>, TFunc, TArgs>(registry, name);
  509. RegisterFunctionBinOpt<NUdf::TDataType<ui16>, NUdf::TDataType<i8>, NUdf::TDataType<ui16>, TFunc, TArgs>(registry, name);
  510. RegisterFunctionBinOpt<NUdf::TDataType<i16>, NUdf::TDataType<ui32>, NUdf::TDataType<ui32>, TFunc, TArgs>(registry, name);
  511. RegisterFunctionBinOpt<NUdf::TDataType<i16>, NUdf::TDataType<ui64>, NUdf::TDataType<ui64>, TFunc, TArgs>(registry, name);
  512. RegisterFunctionBinOpt<NUdf::TDataType<ui32>, NUdf::TDataType<i8>, NUdf::TDataType<ui32>, TFunc, TArgs>(registry, name);
  513. RegisterFunctionBinOpt<NUdf::TDataType<ui32>, NUdf::TDataType<i16>, NUdf::TDataType<ui32>, TFunc, TArgs>(registry, name);
  514. RegisterFunctionBinOpt<NUdf::TDataType<i32>, NUdf::TDataType<ui64>, NUdf::TDataType<ui64>, TFunc, TArgs>(registry, name);
  515. RegisterFunctionBinOpt<NUdf::TDataType<ui64>, NUdf::TDataType<i8>, NUdf::TDataType<ui64>, TFunc, TArgs>(registry, name);
  516. RegisterFunctionBinOpt<NUdf::TDataType<ui64>, NUdf::TDataType<i16>, NUdf::TDataType<ui64>, TFunc, TArgs>(registry, name);
  517. RegisterFunctionBinOpt<NUdf::TDataType<ui64>, NUdf::TDataType<i32>, NUdf::TDataType<ui64>, TFunc, TArgs>(registry, name);
  518. }
  519. template <
  520. template<typename, typename, typename> class TFunc,
  521. template<typename, typename, typename, bool, bool> class TArgs
  522. >
  523. void RegisterBinaryIntegralToSignedFunctionOpt(IBuiltinFunctionRegistry& registry, const std::string_view& name) {
  524. RegisterFunctionBinOpt<NUdf::TDataType<ui8>, NUdf::TDataType<i8>, NUdf::TDataType<i8>, TFunc, TArgs>(registry, name);
  525. RegisterFunctionBinOpt<NUdf::TDataType<ui8>, NUdf::TDataType<i16>, NUdf::TDataType<i16>, TFunc, TArgs>(registry, name);
  526. RegisterFunctionBinOpt<NUdf::TDataType<ui8>, NUdf::TDataType<i32>, NUdf::TDataType<i32>, TFunc, TArgs>(registry, name);
  527. RegisterFunctionBinOpt<NUdf::TDataType<ui8>, NUdf::TDataType<i64>, NUdf::TDataType<i64>, TFunc, TArgs>(registry, name);
  528. RegisterFunctionBinOpt<NUdf::TDataType<i8>, NUdf::TDataType<i8>, NUdf::TDataType<i8>, TFunc, TArgs>(registry, name);
  529. RegisterFunctionBinOpt<NUdf::TDataType<i8>, NUdf::TDataType<ui8>, NUdf::TDataType<i8>, TFunc, TArgs>(registry, name);
  530. RegisterFunctionBinOpt<NUdf::TDataType<i8>, NUdf::TDataType<i16>, NUdf::TDataType<i16>, TFunc, TArgs>(registry, name);
  531. RegisterFunctionBinOpt<NUdf::TDataType<i8>, NUdf::TDataType<i32>, NUdf::TDataType<i32>, TFunc, TArgs>(registry, name);
  532. RegisterFunctionBinOpt<NUdf::TDataType<i8>, NUdf::TDataType<i64>, NUdf::TDataType<i64>, TFunc, TArgs>(registry, name);
  533. RegisterFunctionBinOpt<NUdf::TDataType<ui16>, NUdf::TDataType<i16>, NUdf::TDataType<i16>, TFunc, TArgs>(registry, name);
  534. RegisterFunctionBinOpt<NUdf::TDataType<ui16>, NUdf::TDataType<i32>, NUdf::TDataType<i32>, TFunc, TArgs>(registry, name);
  535. RegisterFunctionBinOpt<NUdf::TDataType<ui16>, NUdf::TDataType<i64>, NUdf::TDataType<i64>, TFunc, TArgs>(registry, name);
  536. RegisterFunctionBinOpt<NUdf::TDataType<i16>, NUdf::TDataType<i8>, NUdf::TDataType<i16>, TFunc, TArgs>(registry, name);
  537. RegisterFunctionBinOpt<NUdf::TDataType<i16>, NUdf::TDataType<ui8>, NUdf::TDataType<i16>, TFunc, TArgs>(registry, name);
  538. RegisterFunctionBinOpt<NUdf::TDataType<i16>, NUdf::TDataType<i16>, NUdf::TDataType<i16>, TFunc, TArgs>(registry, name);
  539. RegisterFunctionBinOpt<NUdf::TDataType<i16>, NUdf::TDataType<ui16>, NUdf::TDataType<i16>, TFunc, TArgs>(registry, name);
  540. RegisterFunctionBinOpt<NUdf::TDataType<i16>, NUdf::TDataType<i32>, NUdf::TDataType<i32>, TFunc, TArgs>(registry, name);
  541. RegisterFunctionBinOpt<NUdf::TDataType<i16>, NUdf::TDataType<i64>, NUdf::TDataType<i64>, TFunc, TArgs>(registry, name);
  542. RegisterFunctionBinOpt<NUdf::TDataType<ui32>, NUdf::TDataType<i32>, NUdf::TDataType<i32>, TFunc, TArgs>(registry, name);
  543. RegisterFunctionBinOpt<NUdf::TDataType<ui32>, NUdf::TDataType<i64>, NUdf::TDataType<i64>, TFunc, TArgs>(registry, name);
  544. RegisterFunctionBinOpt<NUdf::TDataType<i32>, NUdf::TDataType<i8>, NUdf::TDataType<i32>, TFunc, TArgs>(registry, name);
  545. RegisterFunctionBinOpt<NUdf::TDataType<i32>, NUdf::TDataType<ui8>, NUdf::TDataType<i32>, TFunc, TArgs>(registry, name);
  546. RegisterFunctionBinOpt<NUdf::TDataType<i32>, NUdf::TDataType<i16>, NUdf::TDataType<i32>, TFunc, TArgs>(registry, name);
  547. RegisterFunctionBinOpt<NUdf::TDataType<i32>, NUdf::TDataType<ui16>, NUdf::TDataType<i32>, TFunc, TArgs>(registry, name);
  548. RegisterFunctionBinOpt<NUdf::TDataType<i32>, NUdf::TDataType<i32>, NUdf::TDataType<i32>, TFunc, TArgs>(registry, name);
  549. RegisterFunctionBinOpt<NUdf::TDataType<i32>, NUdf::TDataType<ui32>, NUdf::TDataType<i32>, TFunc, TArgs>(registry, name);
  550. RegisterFunctionBinOpt<NUdf::TDataType<i32>, NUdf::TDataType<i64>, NUdf::TDataType<i64>, TFunc, TArgs>(registry, name);
  551. RegisterFunctionBinOpt<NUdf::TDataType<ui64>, NUdf::TDataType<i64>, NUdf::TDataType<i64>, TFunc, TArgs>(registry, name);
  552. RegisterFunctionBinOpt<NUdf::TDataType<i64>, NUdf::TDataType<i8>, NUdf::TDataType<i64>, TFunc, TArgs>(registry, name);
  553. RegisterFunctionBinOpt<NUdf::TDataType<i64>, NUdf::TDataType<ui8>, NUdf::TDataType<i64>, TFunc, TArgs>(registry, name);
  554. RegisterFunctionBinOpt<NUdf::TDataType<i64>, NUdf::TDataType<i16>, NUdf::TDataType<i64>, TFunc, TArgs>(registry, name);
  555. RegisterFunctionBinOpt<NUdf::TDataType<i64>, NUdf::TDataType<ui16>, NUdf::TDataType<i64>, TFunc, TArgs>(registry, name);
  556. RegisterFunctionBinOpt<NUdf::TDataType<i64>, NUdf::TDataType<i32>, NUdf::TDataType<i64>, TFunc, TArgs>(registry, name);
  557. RegisterFunctionBinOpt<NUdf::TDataType<i64>, NUdf::TDataType<ui32>, NUdf::TDataType<i64>, TFunc, TArgs>(registry, name);
  558. RegisterFunctionBinOpt<NUdf::TDataType<i64>, NUdf::TDataType<i64>, NUdf::TDataType<i64>, TFunc, TArgs>(registry, name);
  559. RegisterFunctionBinOpt<NUdf::TDataType<i64>, NUdf::TDataType<ui64>, NUdf::TDataType<i64>, TFunc, TArgs>(registry, name);
  560. }
  561. template <
  562. template<typename, typename, typename> class TFunc,
  563. template<typename, typename, typename, bool, bool> class TArgs
  564. >
  565. void RegisterBinaryIntegralFunctionOpt(IBuiltinFunctionRegistry& registry, const std::string_view& name) {
  566. RegisterBinaryUnsignedFunctionOpt<TFunc, TArgs>(registry, name);
  567. RegisterBinaryIntegralToUnsignedFunctionOpt<TFunc, TArgs>(registry, name);
  568. RegisterBinaryIntegralToSignedFunctionOpt<TFunc, TArgs>(registry, name);
  569. }
  570. template <
  571. template<typename, typename, typename> class TFunc,
  572. template<typename, typename, typename, bool, bool> class TArgs
  573. >
  574. void RegisterBinaryRealFunctionOpt(IBuiltinFunctionRegistry& registry, const std::string_view& name) {
  575. RegisterFunctionBinOpt<NUdf::TDataType<i8>, NUdf::TDataType<float>, NUdf::TDataType<float>, TFunc, TArgs>(registry, name);
  576. RegisterFunctionBinOpt<NUdf::TDataType<i8>, NUdf::TDataType<double>, NUdf::TDataType<double>, TFunc, TArgs>(registry, name);
  577. RegisterFunctionBinOpt<NUdf::TDataType<ui8>, NUdf::TDataType<float>, NUdf::TDataType<float>, TFunc, TArgs>(registry, name);
  578. RegisterFunctionBinOpt<NUdf::TDataType<ui8>, NUdf::TDataType<double>, NUdf::TDataType<double>, TFunc, TArgs>(registry, name);
  579. RegisterFunctionBinOpt<NUdf::TDataType<i16>, NUdf::TDataType<float>, NUdf::TDataType<float>, TFunc, TArgs>(registry, name);
  580. RegisterFunctionBinOpt<NUdf::TDataType<i16>, NUdf::TDataType<double>, NUdf::TDataType<double>, TFunc, TArgs>(registry, name);
  581. RegisterFunctionBinOpt<NUdf::TDataType<ui16>, NUdf::TDataType<float>, NUdf::TDataType<float>, TFunc, TArgs>(registry, name);
  582. RegisterFunctionBinOpt<NUdf::TDataType<ui16>, NUdf::TDataType<double>, NUdf::TDataType<double>, TFunc, TArgs>(registry, name);
  583. RegisterFunctionBinOpt<NUdf::TDataType<i32>, NUdf::TDataType<float>, NUdf::TDataType<float>, TFunc, TArgs>(registry, name);
  584. RegisterFunctionBinOpt<NUdf::TDataType<i32>, NUdf::TDataType<double>, NUdf::TDataType<double>, TFunc, TArgs>(registry, name);
  585. RegisterFunctionBinOpt<NUdf::TDataType<ui32>, NUdf::TDataType<float>, NUdf::TDataType<float>, TFunc, TArgs>(registry, name);
  586. RegisterFunctionBinOpt<NUdf::TDataType<ui32>, NUdf::TDataType<double>, NUdf::TDataType<double>, TFunc, TArgs>(registry, name);
  587. RegisterFunctionBinOpt<NUdf::TDataType<i64>, NUdf::TDataType<float>, NUdf::TDataType<float>, TFunc, TArgs>(registry, name);
  588. RegisterFunctionBinOpt<NUdf::TDataType<i64>, NUdf::TDataType<double>, NUdf::TDataType<double>, TFunc, TArgs>(registry, name);
  589. RegisterFunctionBinOpt<NUdf::TDataType<ui64>, NUdf::TDataType<float>, NUdf::TDataType<float>, TFunc, TArgs>(registry, name);
  590. RegisterFunctionBinOpt<NUdf::TDataType<ui64>, NUdf::TDataType<double>, NUdf::TDataType<double>, TFunc, TArgs>(registry, name);
  591. RegisterFunctionBinOpt<NUdf::TDataType<float>, NUdf::TDataType<i8>, NUdf::TDataType<float>, TFunc, TArgs>(registry, name);
  592. RegisterFunctionBinOpt<NUdf::TDataType<float>, NUdf::TDataType<ui8>, NUdf::TDataType<float>, TFunc, TArgs>(registry, name);
  593. RegisterFunctionBinOpt<NUdf::TDataType<float>, NUdf::TDataType<i16>, NUdf::TDataType<float>, TFunc, TArgs>(registry, name);
  594. RegisterFunctionBinOpt<NUdf::TDataType<float>, NUdf::TDataType<ui16>, NUdf::TDataType<float>, TFunc, TArgs>(registry, name);
  595. RegisterFunctionBinOpt<NUdf::TDataType<float>, NUdf::TDataType<i32>, NUdf::TDataType<float>, TFunc, TArgs>(registry, name);
  596. RegisterFunctionBinOpt<NUdf::TDataType<float>, NUdf::TDataType<ui32>, NUdf::TDataType<float>, TFunc, TArgs>(registry, name);
  597. RegisterFunctionBinOpt<NUdf::TDataType<float>, NUdf::TDataType<i64>, NUdf::TDataType<float>, TFunc, TArgs>(registry, name);
  598. RegisterFunctionBinOpt<NUdf::TDataType<float>, NUdf::TDataType<ui64>, NUdf::TDataType<float>, TFunc, TArgs>(registry, name);
  599. RegisterFunctionBinOpt<NUdf::TDataType<float>, NUdf::TDataType<float>, NUdf::TDataType<float>, TFunc, TArgs>(registry, name);
  600. RegisterFunctionBinOpt<NUdf::TDataType<float>, NUdf::TDataType<double>, NUdf::TDataType<double>, TFunc, TArgs>(registry, name);
  601. RegisterFunctionBinOpt<NUdf::TDataType<double>, NUdf::TDataType<i8>, NUdf::TDataType<double>, TFunc, TArgs>(registry, name);
  602. RegisterFunctionBinOpt<NUdf::TDataType<double>, NUdf::TDataType<ui8>, NUdf::TDataType<double>, TFunc, TArgs>(registry, name);
  603. RegisterFunctionBinOpt<NUdf::TDataType<double>, NUdf::TDataType<i16>, NUdf::TDataType<double>, TFunc, TArgs>(registry, name);
  604. RegisterFunctionBinOpt<NUdf::TDataType<double>, NUdf::TDataType<ui16>, NUdf::TDataType<double>, TFunc, TArgs>(registry, name);
  605. RegisterFunctionBinOpt<NUdf::TDataType<double>, NUdf::TDataType<i32>, NUdf::TDataType<double>, TFunc, TArgs>(registry, name);
  606. RegisterFunctionBinOpt<NUdf::TDataType<double>, NUdf::TDataType<ui32>, NUdf::TDataType<double>, TFunc, TArgs>(registry, name);
  607. RegisterFunctionBinOpt<NUdf::TDataType<double>, NUdf::TDataType<i64>, NUdf::TDataType<double>, TFunc, TArgs>(registry, name);
  608. RegisterFunctionBinOpt<NUdf::TDataType<double>, NUdf::TDataType<ui64>, NUdf::TDataType<double>, TFunc, TArgs>(registry, name);
  609. RegisterFunctionBinOpt<NUdf::TDataType<double>, NUdf::TDataType<float>, NUdf::TDataType<double>, TFunc, TArgs>(registry, name);
  610. RegisterFunctionBinOpt<NUdf::TDataType<double>, NUdf::TDataType<double>, NUdf::TDataType<double>, TFunc, TArgs>(registry, name);
  611. }
  612. template <
  613. template<typename, typename, typename> class TFunc,
  614. template<typename, typename, typename, bool, bool> class TArgs
  615. >
  616. void RegisterBinaryNumericFunctionOpt(IBuiltinFunctionRegistry& registry, const std::string_view& name) {
  617. RegisterBinaryIntegralFunctionOpt<TFunc, TArgs>(registry, name);
  618. RegisterBinaryRealFunctionOpt<TFunc, TArgs>(registry, name);
  619. }
  620. template <
  621. template<typename> class TFunc,
  622. template<typename, typename, bool> class TArgs
  623. >
  624. void RegisterNumericAggregateFunction(IBuiltinFunctionRegistry& registry, const std::string_view& name) {
  625. RegisterAggregateFunction<NUdf::TDataType<i8>, TFunc, TArgs>(registry, name);
  626. RegisterAggregateFunction<NUdf::TDataType<ui8>, TFunc, TArgs>(registry, name);
  627. RegisterAggregateFunction<NUdf::TDataType<i16>, TFunc, TArgs>(registry, name);
  628. RegisterAggregateFunction<NUdf::TDataType<ui16>, TFunc, TArgs>(registry, name);
  629. RegisterAggregateFunction<NUdf::TDataType<i32>, TFunc, TArgs>(registry, name);
  630. RegisterAggregateFunction<NUdf::TDataType<ui32>, TFunc, TArgs>(registry, name);
  631. RegisterAggregateFunction<NUdf::TDataType<i64>, TFunc, TArgs>(registry, name);
  632. RegisterAggregateFunction<NUdf::TDataType<ui64>, TFunc, TArgs>(registry, name);
  633. RegisterAggregateFunction<NUdf::TDataType<float>, TFunc, TArgs>(registry, name);
  634. RegisterAggregateFunction<NUdf::TDataType<double>, TFunc, TArgs>(registry, name);
  635. }
  636. template <
  637. template<typename> class TFunc,
  638. template<typename, typename, bool> class TArgs
  639. >
  640. void RegisterDatetimeAggregateFunction(IBuiltinFunctionRegistry& registry, const std::string_view& name) {
  641. RegisterAggregateFunction<NUdf::TDataType<NUdf::TDate>, TFunc, TArgs>(registry, name);
  642. RegisterAggregateFunction<NUdf::TDataType<NUdf::TDatetime>, TFunc, TArgs>(registry, name);
  643. RegisterAggregateFunction<NUdf::TDataType<NUdf::TTimestamp>, TFunc, TArgs>(registry, name);
  644. RegisterAggregateFunction<NUdf::TDataType<NUdf::TInterval>, TFunc, TArgs>(registry, name);
  645. }
  646. template <
  647. template<typename> class TFunc,
  648. template<typename, typename, bool> class TArgs
  649. >
  650. void RegisterBigDateAggregateFunction(IBuiltinFunctionRegistry& registry, const std::string_view& name) {
  651. RegisterAggregateFunction<NUdf::TDataType<NUdf::TDate32>, TFunc, TArgs>(registry, name);
  652. RegisterAggregateFunction<NUdf::TDataType<NUdf::TDatetime64>, TFunc, TArgs>(registry, name);
  653. RegisterAggregateFunction<NUdf::TDataType<NUdf::TTimestamp64>, TFunc, TArgs>(registry, name);
  654. RegisterAggregateFunction<NUdf::TDataType<NUdf::TInterval64>, TFunc, TArgs>(registry, name);
  655. }
  656. template <
  657. template<typename> class TFunc,
  658. template<typename, typename, bool> class TArgs
  659. >
  660. void RegisterTzDatetimeAggregateFunction(IBuiltinFunctionRegistry& registry, const std::string_view& name) {
  661. RegisterAggregateFunction<NUdf::TDataType<NUdf::TTzDate>, TFunc, TArgs>(registry, name);
  662. RegisterAggregateFunction<NUdf::TDataType<NUdf::TTzDatetime>, TFunc, TArgs>(registry, name);
  663. RegisterAggregateFunction<NUdf::TDataType<NUdf::TTzTimestamp>, TFunc, TArgs>(registry, name);
  664. }
  665. template <
  666. template<typename> class TFunc,
  667. template<typename, typename, typename, bool, bool> class TArgs
  668. >
  669. void RegisterDatetimeSameTypesFunction(IBuiltinFunctionRegistry& registry, const std::string_view& name) {
  670. RegisterSameTypesFunction<NUdf::TDataType<NUdf::TDate>, TFunc, TArgs>(registry, name);
  671. RegisterSameTypesFunction<NUdf::TDataType<NUdf::TDatetime>, TFunc, TArgs>(registry, name);
  672. RegisterSameTypesFunction<NUdf::TDataType<NUdf::TTimestamp>, TFunc, TArgs>(registry, name);
  673. RegisterSameTypesFunction<NUdf::TDataType<NUdf::TInterval>, TFunc, TArgs>(registry, name);
  674. }
  675. template <
  676. template<typename> class TFunc,
  677. template<typename, typename, typename, bool, bool> class TArgs
  678. >
  679. void RegisterTzDatetimeSameTypesFunction(IBuiltinFunctionRegistry& registry, const std::string_view& name) {
  680. RegisterSameTypesFunction<NUdf::TDataType<NUdf::TTzDate>, TFunc, TArgs>(registry, name);
  681. RegisterSameTypesFunction<NUdf::TDataType<NUdf::TTzDatetime>, TFunc, TArgs>(registry, name);
  682. RegisterSameTypesFunction<NUdf::TDataType<NUdf::TTzTimestamp>, TFunc, TArgs>(registry, name);
  683. }
  684. template <
  685. template<typename> class TFunc,
  686. template<typename, typename, bool> class TArgs
  687. >
  688. void RegisterBooleanAggregateFunction(IBuiltinFunctionRegistry& registry, const std::string_view& name) {
  689. RegisterAggregateFunction<NUdf::TDataType<bool>, TFunc, TArgs>(registry, name);
  690. }
  691. template <
  692. template<typename> class TFunc,
  693. template<typename, typename, typename, bool, bool> class TArgs
  694. >
  695. void RegisterBooleanSameTypesFunction(IBuiltinFunctionRegistry& registry, const std::string_view& name) {
  696. RegisterSameTypesFunction<NUdf::TDataType<bool>, TFunc, TArgs>(registry, name);
  697. }
  698. template <
  699. template<typename, typename, typename, bool, bool> class TFunc,
  700. template<typename, typename, typename, bool, bool> class TArgs
  701. >
  702. void RegisterBinaryRealFunction(IBuiltinFunctionRegistry& registry, const std::string_view& name) {
  703. RegisterFunctionBinOpt<NUdf::TDataType<float>, NUdf::TDataType<float>, NUdf::TDataType<float>, TFunc, TArgs>(registry, name);
  704. RegisterFunctionBinOpt<NUdf::TDataType<float>, NUdf::TDataType<double>, NUdf::TDataType<double>, TFunc, TArgs>(registry, name);
  705. RegisterFunctionBinOpt<NUdf::TDataType<double>, NUdf::TDataType<float>, NUdf::TDataType<double>, TFunc, TArgs>(registry, name);
  706. RegisterFunctionBinOpt<NUdf::TDataType<double>, NUdf::TDataType<double>, NUdf::TDataType<double>, TFunc, TArgs>(registry, name);
  707. }
  708. void RegisterAdd(IBuiltinFunctionRegistry& registry);
  709. void RegisterAdd(TKernelFamilyMap& kernelFamilyMap);
  710. void RegisterAggrAdd(IBuiltinFunctionRegistry& registry);
  711. void RegisterSub(IBuiltinFunctionRegistry& registry);
  712. void RegisterSub(TKernelFamilyMap& kernelFamilyMap);
  713. void RegisterMul(IBuiltinFunctionRegistry& registry);
  714. void RegisterMul(TKernelFamilyMap& kernelFamilyMap);
  715. void RegisterDiv(IBuiltinFunctionRegistry& registry);
  716. void RegisterDiv(TKernelFamilyMap& kernelFamilyMap);
  717. void RegisterMod(IBuiltinFunctionRegistry& registry);
  718. void RegisterMod(TKernelFamilyMap& kernelFamilyMap);
  719. void RegisterIncrement(IBuiltinFunctionRegistry& registry);
  720. void RegisterDecrement(IBuiltinFunctionRegistry& registry);
  721. void RegisterBitAnd(IBuiltinFunctionRegistry& registry);
  722. void RegisterBitOr(IBuiltinFunctionRegistry& registry);
  723. void RegisterBitXor(IBuiltinFunctionRegistry& registry);
  724. void RegisterShiftLeft(IBuiltinFunctionRegistry& registry);
  725. void RegisterShiftRight(IBuiltinFunctionRegistry& registry);
  726. void RegisterRotLeft(IBuiltinFunctionRegistry& registry);
  727. void RegisterRotRight(IBuiltinFunctionRegistry& registry);
  728. void RegisterPlus(IBuiltinFunctionRegistry& registry);
  729. void RegisterMinus(IBuiltinFunctionRegistry& registry);
  730. void RegisterMinus(TKernelFamilyMap& kernelFamilyMap);
  731. void RegisterBitNot(IBuiltinFunctionRegistry& registry);
  732. void RegisterCountBits(IBuiltinFunctionRegistry& registry);
  733. void RegisterAbs(IBuiltinFunctionRegistry& registry);
  734. void RegisterAbs(TKernelFamilyMap& kernelFamilyMap);
  735. void RegisterConvert(IBuiltinFunctionRegistry& registry);
  736. void RegisterConcat(IBuiltinFunctionRegistry& registry);
  737. void RegisterSubstring(IBuiltinFunctionRegistry& registry);
  738. void RegisterFind(IBuiltinFunctionRegistry& registry);
  739. void RegisterInversePresortString(IBuiltinFunctionRegistry& registry);
  740. void RegisterInverseString(IBuiltinFunctionRegistry& registry);
  741. void RegisterNanvl(IBuiltinFunctionRegistry& registry);
  742. void RegisterByteAt(IBuiltinFunctionRegistry& registry);
  743. void RegisterMax(IBuiltinFunctionRegistry& registry);
  744. void RegisterMin(IBuiltinFunctionRegistry& registry);
  745. void RegisterAggrMax(IBuiltinFunctionRegistry& registry);
  746. void RegisterAggrMin(IBuiltinFunctionRegistry& registry);
  747. void RegisterWith(IBuiltinFunctionRegistry& registry);
  748. enum class EPropagateTz {
  749. None,
  750. FromLeft,
  751. FromRight
  752. };
  753. std::shared_ptr<arrow::DataType> AddTzType(bool addTz, const std::shared_ptr<arrow::DataType>& type);
  754. std::shared_ptr<arrow::DataType> AddTzType(EPropagateTz propagateTz, const std::shared_ptr<arrow::DataType>& type);
  755. template <typename T>
  756. arrow::compute::InputType GetPrimitiveInputArrowType(bool tz = false);
  757. arrow::compute::InputType GetPrimitiveInputArrowType(NUdf::EDataSlot slot);
  758. template <typename T>
  759. arrow::compute::OutputType GetPrimitiveOutputArrowType(bool tz = false);
  760. arrow::compute::OutputType GetPrimitiveOutputArrowType(NUdf::EDataSlot slot);
  761. std::shared_ptr<arrow::Scalar> ExtractTz(bool isTz, const std::shared_ptr<arrow::Scalar>& value);
  762. std::shared_ptr<arrow::ArrayData> ExtractTz(bool isTz, const std::shared_ptr<arrow::ArrayData>& value);
  763. std::shared_ptr<arrow::Scalar> WithTz(bool propagateTz, const std::shared_ptr<arrow::Scalar>& input,
  764. const std::shared_ptr<arrow::Scalar>& value);
  765. std::shared_ptr<arrow::Scalar> WithTz(EPropagateTz propagateTz,
  766. const std::shared_ptr<arrow::Scalar>& input1,
  767. const std::shared_ptr<arrow::Scalar>& input2,
  768. const std::shared_ptr<arrow::Scalar>& value);
  769. std::shared_ptr<arrow::ArrayData> CopyTzImpl(const std::shared_ptr<arrow::ArrayData>& res, bool propagateTz,
  770. const std::shared_ptr<arrow::ArrayData>& input, arrow::MemoryPool* pool,
  771. size_t sizeOf, const std::shared_ptr<arrow::DataType>& outputType);
  772. template <typename TOutput>
  773. inline std::shared_ptr<arrow::ArrayData> CopyTz(const std::shared_ptr<arrow::ArrayData>& res, bool propagateTz,
  774. const std::shared_ptr<arrow::ArrayData>& input, arrow::MemoryPool* pool) {
  775. return CopyTzImpl(res, propagateTz, input, pool, sizeof(TOutput), GetPrimitiveDataType<TOutput>());
  776. }
  777. std::shared_ptr<arrow::ArrayData> CopyTzImpl(const std::shared_ptr<arrow::ArrayData>& res, EPropagateTz propagateTz,
  778. const std::shared_ptr<arrow::ArrayData>& input1,
  779. const std::shared_ptr<arrow::Scalar>& input2,
  780. arrow::MemoryPool* pool,
  781. size_t sizeOf, const std::shared_ptr<arrow::DataType>& outputType);
  782. template <typename TOutput>
  783. inline std::shared_ptr<arrow::ArrayData> CopyTz(const std::shared_ptr<arrow::ArrayData>& res, EPropagateTz propagateTz,
  784. const std::shared_ptr<arrow::ArrayData>& input1,
  785. const std::shared_ptr<arrow::Scalar>& input2,
  786. arrow::MemoryPool* pool) {
  787. return CopyTzImpl(res, propagateTz, input1, input2, pool, sizeof(TOutput), GetPrimitiveDataType<TOutput>());
  788. }
  789. std::shared_ptr<arrow::ArrayData> CopyTzImpl(const std::shared_ptr<arrow::ArrayData>& res, EPropagateTz propagateTz,
  790. const std::shared_ptr<arrow::Scalar>& input1,
  791. const std::shared_ptr<arrow::ArrayData>& input2,
  792. arrow::MemoryPool* pool,
  793. size_t sizeOf, const std::shared_ptr<arrow::DataType>& outputType);
  794. template <typename TOutput>
  795. inline std::shared_ptr<arrow::ArrayData> CopyTz(const std::shared_ptr<arrow::ArrayData>& res, EPropagateTz propagateTz,
  796. const std::shared_ptr<arrow::Scalar>& input1,
  797. const std::shared_ptr<arrow::ArrayData>& input2,
  798. arrow::MemoryPool* pool) {
  799. return CopyTzImpl(res, propagateTz, input1, input2, pool, sizeof(TOutput), GetPrimitiveDataType<TOutput>());
  800. }
  801. std::shared_ptr<arrow::ArrayData> CopyTzImpl(const std::shared_ptr<arrow::ArrayData>& res, EPropagateTz propagateTz,
  802. const std::shared_ptr<arrow::ArrayData>& input1,
  803. const std::shared_ptr<arrow::ArrayData>& input2,
  804. arrow::MemoryPool* pool,
  805. size_t sizeOf, const std::shared_ptr<arrow::DataType>& outputType);
  806. template <typename TOutput>
  807. inline std::shared_ptr<arrow::ArrayData> CopyTz(const std::shared_ptr<arrow::ArrayData>& res, EPropagateTz propagateTz,
  808. const std::shared_ptr<arrow::ArrayData>& input1,
  809. const std::shared_ptr<arrow::ArrayData>& input2,
  810. arrow::MemoryPool* pool) {
  811. return CopyTzImpl(res, propagateTz, input1, input2, pool, sizeof(TOutput), GetPrimitiveDataType<TOutput>());
  812. }
  813. using TPrimitiveDataTypeGetter = std::shared_ptr<arrow::DataType>(*)();
  814. using TPrimitiveDataScalarGetter= arrow::Datum(*)();
  815. using TPrimitiveDataScalarGetterWithMemPool = arrow::Datum(*)(void** result, arrow::MemoryPool*);
  816. using TUntypedBinaryScalarFuncPtr = void(*)(const void*, const void*, void*);
  817. using TUntypedBinaryArrayFuncPtr = void(*)(const void*, const void*, void*, int64_t length, int64_t offset1, int64_t offset2);
  818. using TUntypedBinaryScalarOptFuncPtr = bool(*)(const void*, const void*, void*);
  819. using TUntypedBinaryArrayOptFuncPtr = void(*)(const void*, const ui8*, const void*, const ui8*, void*, ui8*, int64_t length, int64_t offset1, int64_t offset2);
  820. using TUntypedUnaryScalarFuncPtr = void(*)(const void*, void*);
  821. using TUntypedUnaryArrayFuncPtr = void(*)(const void*, void*, int64_t length, int64_t offset);
  822. arrow::Status ExecScalarImpl(const arrow::compute::ExecBatch& batch, arrow::Datum* res,
  823. TPrimitiveDataTypeGetter typeGetter, TPrimitiveDataScalarGetter scalarGetter, TUntypedUnaryScalarFuncPtr func,
  824. bool tz, bool propagateTz);
  825. arrow::Status ExecArrayImpl(arrow::compute::KernelContext* kernelCtx,
  826. const arrow::compute::ExecBatch& batch, arrow::Datum* res,
  827. TUntypedUnaryArrayFuncPtr func, size_t outputSizeOf, TPrimitiveDataTypeGetter outputTypeGetter,
  828. bool tz, bool propagateTz);
  829. arrow::Status ExecUnaryImpl(arrow::compute::KernelContext* kernelCtx,
  830. const arrow::compute::ExecBatch& batch, arrow::Datum* res,
  831. TPrimitiveDataTypeGetter typeGetter, TPrimitiveDataScalarGetter scalarGetter,
  832. bool tz, bool propagateTz, size_t outputSizeOf,
  833. TUntypedUnaryScalarFuncPtr scalarFunc, TUntypedUnaryArrayFuncPtr arrayFunc);
  834. arrow::Status ExecScalarScalarImpl(const arrow::compute::ExecBatch& batch, arrow::Datum* res,
  835. TPrimitiveDataTypeGetter typeGetter, TPrimitiveDataScalarGetter scalarGetter, TUntypedBinaryScalarFuncPtr func,
  836. bool tz1, bool tz2, EPropagateTz propagateTz);
  837. arrow::Status ExecScalarArrayImpl(arrow::compute::KernelContext* kernelCtx,
  838. const arrow::compute::ExecBatch& batch, arrow::Datum* res,
  839. TUntypedBinaryArrayFuncPtr func, size_t outputSizeOf, TPrimitiveDataTypeGetter outputTypeGetter,
  840. bool tz1, bool tz2, EPropagateTz propagateTz);
  841. arrow::Status ExecArrayScalarImpl(arrow::compute::KernelContext* kernelCtx,
  842. const arrow::compute::ExecBatch& batch, arrow::Datum* res,
  843. TUntypedBinaryArrayFuncPtr func, size_t outputSizeOf, TPrimitiveDataTypeGetter outputTypeGetter,
  844. bool tz1, bool tz2, EPropagateTz propagateTz);
  845. arrow::Status ExecArrayArrayImpl(arrow::compute::KernelContext* kernelCtx,
  846. const arrow::compute::ExecBatch& batch, arrow::Datum* res,
  847. TUntypedBinaryArrayFuncPtr func, size_t outputSizeOf, TPrimitiveDataTypeGetter outputTypeGetter,
  848. bool tz1, bool tz2, EPropagateTz propagateTz);
  849. arrow::Status ExecBinaryImpl(arrow::compute::KernelContext* kernelCtx,
  850. const arrow::compute::ExecBatch& batch, arrow::Datum* res,
  851. TPrimitiveDataTypeGetter typeGetter, TPrimitiveDataScalarGetter scalarGetter,
  852. bool tz1, bool tz2, EPropagateTz propagateTz, size_t outputSizeOf,
  853. TUntypedBinaryScalarFuncPtr scalarScalarFunc,
  854. TUntypedBinaryArrayFuncPtr scalarArrayFunc,
  855. TUntypedBinaryArrayFuncPtr arrayScalarFunc,
  856. TUntypedBinaryArrayFuncPtr arrayArrayFunc);
  857. arrow::Status ExecScalarScalarOptImpl(const arrow::compute::ExecBatch& batch, arrow::Datum* res,
  858. TPrimitiveDataTypeGetter typeGetter, TPrimitiveDataScalarGetter scalarGetter, TUntypedBinaryScalarOptFuncPtr func,
  859. bool tz1, bool tz2, EPropagateTz propagateTz);
  860. arrow::Status ExecScalarArrayOptImpl(arrow::compute::KernelContext* kernelCtx,
  861. const arrow::compute::ExecBatch& batch, arrow::Datum* res,
  862. TUntypedBinaryArrayOptFuncPtr func, size_t outputSizeOf, TPrimitiveDataTypeGetter outputTypeGetter,
  863. bool tz1, bool tz2, EPropagateTz propagateTz);
  864. arrow::Status ExecArrayScalarOptImpl(arrow::compute::KernelContext* kernelCtx,
  865. const arrow::compute::ExecBatch& batch, arrow::Datum* res,
  866. TUntypedBinaryArrayOptFuncPtr func, size_t outputSizeOf, TPrimitiveDataTypeGetter outputTypeGetter,
  867. bool tz1, bool tz2, EPropagateTz propagateTz);
  868. arrow::Status ExecArrayArrayOptImpl(arrow::compute::KernelContext* kernelCtx,
  869. const arrow::compute::ExecBatch& batch, arrow::Datum* res,
  870. TUntypedBinaryArrayOptFuncPtr func, size_t outputSizeOf, TPrimitiveDataTypeGetter outputTypeGetter,
  871. bool tz1, bool tz2, EPropagateTz propagateTz);
  872. arrow::Status ExecBinaryOptImpl(arrow::compute::KernelContext* kernelCtx,
  873. const arrow::compute::ExecBatch& batch, arrow::Datum* res,
  874. TPrimitiveDataTypeGetter typeGetter, TPrimitiveDataScalarGetter scalarGetter,
  875. bool tz1, bool tz2, EPropagateTz propagateTz, size_t outputSizeOf,
  876. TUntypedBinaryScalarOptFuncPtr scalarScalarFunc,
  877. TUntypedBinaryArrayOptFuncPtr scalarArrayFunc,
  878. TUntypedBinaryArrayOptFuncPtr arrayScalarFunc,
  879. TUntypedBinaryArrayOptFuncPtr arrayArrayFunc);
  880. arrow::Status ExecDecimalBinaryOptImpl(arrow::compute::KernelContext* kernelCtx,
  881. const arrow::compute::ExecBatch& batch, arrow::Datum* res,
  882. TPrimitiveDataTypeGetter typeGetter, TPrimitiveDataScalarGetterWithMemPool scalarGetter,
  883. size_t outputSizeOf,
  884. TUntypedBinaryScalarOptFuncPtr scalarScalarFunc,
  885. TUntypedBinaryArrayOptFuncPtr scalarArrayFunc,
  886. TUntypedBinaryArrayOptFuncPtr arrayScalarFunc,
  887. TUntypedBinaryArrayOptFuncPtr arrayArrayFunc);
  888. arrow::Status ExecDecimalUnaryImpl(arrow::compute::KernelContext* kernelCtx,
  889. const arrow::compute::ExecBatch& batch, arrow::Datum* res,
  890. TPrimitiveDataTypeGetter typeGetter,
  891. TUntypedUnaryScalarFuncPtr scalarFunc, TUntypedUnaryArrayFuncPtr arrayFunc);
  892. template<typename TInput1, bool Tz1, typename TInput2, bool Tz2, typename TOutput, EPropagateTz PropagateTz,
  893. typename TFuncInstance, TKernel::ENullMode NullMode>
  894. struct TBinaryKernelExecs;
  895. template<typename TInput1, bool Tz1, typename TInput2, bool Tz2, typename TOutput, EPropagateTz PropagateTz,
  896. typename TFuncInstance>
  897. struct TBinaryKernelExecs<TInput1, Tz1, TInput2, Tz2, TOutput, PropagateTz, TFuncInstance, TKernel::ENullMode::Default>
  898. {
  899. using TTypedBinaryScalarFuncPtr = void(*)(
  900. const typename TPrimitiveDataType<TInput1>::TLayout*,
  901. const typename TPrimitiveDataType<TInput2>::TLayout*,
  902. typename TPrimitiveDataType<TOutput>::TLayout*
  903. );
  904. using TTypedBinaryArrayFuncPtr = void(*)(
  905. const typename TPrimitiveDataType<TInput1>::TLayout*,
  906. const typename TPrimitiveDataType<TInput2>::TLayout*,
  907. typename TPrimitiveDataType<TOutput>::TLayout*,
  908. int64_t,
  909. int64_t,
  910. int64_t
  911. );
  912. static void ScalarArrayCore(
  913. const typename TPrimitiveDataType<TInput1>::TLayout* val1Ptr,
  914. const typename TPrimitiveDataType<TInput2>::TLayout* val2Ptr,
  915. typename TPrimitiveDataType<TOutput>::TLayout* resPtr,
  916. int64_t length, int64_t offset1, int64_t offset2) {
  917. TTypedBinaryScalarFuncPtr func = &TFuncInstance::DoPtr;
  918. Y_UNUSED(offset1);
  919. val2Ptr += offset2;
  920. for (int64_t i = 0; i < length; ++i) {
  921. func(val1Ptr, val2Ptr, resPtr);
  922. ++val2Ptr;
  923. ++resPtr;
  924. }
  925. }
  926. static void ArrayScalarCore(
  927. const typename TPrimitiveDataType<TInput1>::TLayout* val1Ptr,
  928. const typename TPrimitiveDataType<TInput2>::TLayout* val2Ptr,
  929. typename TPrimitiveDataType<TOutput>::TLayout* resPtr,
  930. int64_t length, int64_t offset1, int64_t offset2) {
  931. TTypedBinaryScalarFuncPtr func = &TFuncInstance::DoPtr;
  932. Y_UNUSED(offset2);
  933. val1Ptr += offset1;
  934. for (int64_t i = 0; i < length; ++i) {
  935. func(val1Ptr, val2Ptr, resPtr);
  936. ++val1Ptr;
  937. ++resPtr;
  938. }
  939. }
  940. static void ArrayArrayCore(
  941. const typename TPrimitiveDataType<TInput1>::TLayout* val1Ptr,
  942. const typename TPrimitiveDataType<TInput2>::TLayout* val2Ptr,
  943. typename TPrimitiveDataType<TOutput>::TLayout* resPtr,
  944. int64_t length, int64_t offset1, int64_t offset2) {
  945. TTypedBinaryScalarFuncPtr func = &TFuncInstance::DoPtr;
  946. val1Ptr += offset1;
  947. val2Ptr += offset2;
  948. for (int64_t i = 0; i < length; ++i) {
  949. func(val1Ptr, val2Ptr, resPtr);
  950. ++val1Ptr;
  951. ++val2Ptr;
  952. ++resPtr;
  953. }
  954. }
  955. static arrow::Status Exec(arrow::compute::KernelContext* kernelCtx, const arrow::compute::ExecBatch& batch, arrow::Datum* res) {
  956. TTypedBinaryScalarFuncPtr scalarScalarFunc = &TFuncInstance::DoPtr;
  957. TTypedBinaryArrayFuncPtr scalarArrayFunc = &ScalarArrayCore;
  958. TTypedBinaryArrayFuncPtr arrayScalarFunc = &ArrayScalarCore;
  959. TTypedBinaryArrayFuncPtr arrayArrayFunc = &ArrayArrayCore;
  960. return ExecBinaryImpl(kernelCtx, batch, res,
  961. &GetPrimitiveDataType<TOutput>,
  962. &MakeDefaultScalarDatum<TOutput>,
  963. Tz1, Tz2, PropagateTz, sizeof(TOutput),
  964. (TUntypedBinaryScalarFuncPtr)scalarScalarFunc,
  965. (TUntypedBinaryArrayFuncPtr)scalarArrayFunc,
  966. (TUntypedBinaryArrayFuncPtr)arrayScalarFunc,
  967. (TUntypedBinaryArrayFuncPtr)arrayArrayFunc);
  968. }
  969. };
  970. template<typename TInput1, typename TInput2, typename TOutput, typename TFuncInstance>
  971. struct TBinaryKernelOptExecsImpl
  972. {
  973. using TTypedBinaryScalarOptFuncPtr = bool(*)(
  974. const typename TPrimitiveDataType<TInput1>::TLayout* val1Ptr,
  975. const typename TPrimitiveDataType<TInput2>::TLayout* val2Ptr,
  976. typename TPrimitiveDataType<TOutput>::TLayout* resPtr
  977. );
  978. using TTypedBinaryArrayOptFuncPtr = void(*)(
  979. const typename TPrimitiveDataType<TInput1>::TLayout* val1Ptr,
  980. const ui8* valid1,
  981. const typename TPrimitiveDataType<TInput2>::TLayout* val2Ptr,
  982. const ui8* valid2,
  983. typename TPrimitiveDataType<TOutput>::TLayout* resPtr,
  984. ui8* resValid,
  985. int64_t length,
  986. int64_t offset1,
  987. int64_t offset2
  988. );
  989. static bool ScalarScalarCoreOpt(
  990. const typename TPrimitiveDataType<TInput1>::TLayout* val1Ptr,
  991. const typename TPrimitiveDataType<TInput2>::TLayout* val2Ptr,
  992. typename TPrimitiveDataType<TOutput>::TLayout* resPtr) {
  993. auto resPod = TFuncInstance::Execute(NUdf::TUnboxedValuePod(*val1Ptr), NUdf::TUnboxedValuePod(*val2Ptr));
  994. if (!resPod) {
  995. return false;
  996. }
  997. *resPtr = resPod.template Get<typename TPrimitiveDataType<TOutput>::TLayout>();
  998. return true;
  999. }
  1000. static void ScalarArrayCoreOpt(
  1001. const typename TPrimitiveDataType<TInput1>::TLayout* val1Ptr,
  1002. const ui8* valid1,
  1003. const typename TPrimitiveDataType<TInput2>::TLayout* val2Ptr,
  1004. const ui8* valid2,
  1005. typename TPrimitiveDataType<TOutput>::TLayout* resPtr,
  1006. ui8* resValid,
  1007. int64_t length,
  1008. int64_t offset1,
  1009. int64_t offset2) {
  1010. val2Ptr += offset2;
  1011. Y_UNUSED(valid1);
  1012. Y_UNUSED(offset1);
  1013. for (int64_t i = 0; i < length; ++i, ++val2Ptr, ++resPtr) {
  1014. if (!valid2 || arrow::BitUtil::GetBit(valid2, i + offset2)) {
  1015. auto resPod = TFuncInstance::Execute(NUdf::TUnboxedValuePod(*val1Ptr), NUdf::TUnboxedValuePod(*val2Ptr));
  1016. if (resPod) {
  1017. *resPtr = resPod.template Get<typename TPrimitiveDataType<TOutput>::TLayout>();
  1018. arrow::BitUtil::SetBit(resValid, i);
  1019. continue;
  1020. }
  1021. }
  1022. arrow::BitUtil::ClearBit(resValid, i);
  1023. }
  1024. }
  1025. static void ArrayScalarCoreOpt(
  1026. const typename TPrimitiveDataType<TInput1>::TLayout* val1Ptr,
  1027. const ui8* valid1,
  1028. const typename TPrimitiveDataType<TInput2>::TLayout* val2Ptr,
  1029. const ui8* valid2,
  1030. typename TPrimitiveDataType<TOutput>::TLayout* resPtr,
  1031. ui8* resValid,
  1032. int64_t length,
  1033. int64_t offset1,
  1034. int64_t offset2) {
  1035. val1Ptr += offset1;
  1036. Y_UNUSED(valid2);
  1037. Y_UNUSED(offset2);
  1038. for (int64_t i = 0; i < length; ++i, ++val1Ptr, ++resPtr) {
  1039. if (!valid1 || arrow::BitUtil::GetBit(valid1, i + offset1)) {
  1040. auto resPod = TFuncInstance::Execute(NUdf::TUnboxedValuePod(*val1Ptr), NUdf::TUnboxedValuePod(*val2Ptr));
  1041. if (resPod) {
  1042. *resPtr = resPod.template Get<typename TPrimitiveDataType<TOutput>::TLayout>();
  1043. arrow::BitUtil::SetBit(resValid, i);
  1044. continue;
  1045. }
  1046. }
  1047. arrow::BitUtil::ClearBit(resValid, i);
  1048. }
  1049. }
  1050. static void ArrayArrayCoreOpt(
  1051. const typename TPrimitiveDataType<TInput1>::TLayout* val1Ptr,
  1052. const ui8* valid1,
  1053. const typename TPrimitiveDataType<TInput2>::TLayout* val2Ptr,
  1054. const ui8* valid2,
  1055. typename TPrimitiveDataType<TOutput>::TLayout* resPtr,
  1056. ui8* resValid,
  1057. int64_t length,
  1058. int64_t offset1,
  1059. int64_t offset2) {
  1060. val1Ptr += offset1;
  1061. val2Ptr += offset2;
  1062. for (int64_t i = 0; i < length; ++i, ++val1Ptr, ++val2Ptr, ++resPtr) {
  1063. if ((!valid1 || arrow::BitUtil::GetBit(valid1, i + offset1)) &&
  1064. (!valid2 || arrow::BitUtil::GetBit(valid2, i + offset2))) {
  1065. auto resPod = TFuncInstance::Execute(NUdf::TUnboxedValuePod(*val1Ptr), NUdf::TUnboxedValuePod(*val2Ptr));
  1066. if (resPod) {
  1067. *resPtr = resPod.template Get<typename TPrimitiveDataType<TOutput>::TLayout>();
  1068. arrow::BitUtil::SetBit(resValid, i);
  1069. continue;
  1070. }
  1071. }
  1072. arrow::BitUtil::ClearBit(resValid, i);
  1073. }
  1074. }
  1075. };
  1076. template<typename TInput1, bool Tz1, typename TInput2, bool Tz2, typename TOutput, EPropagateTz PropagateTz,
  1077. typename TFuncInstance>
  1078. struct TBinaryKernelExecs<TInput1, Tz1, TInput2, Tz2, TOutput, PropagateTz, TFuncInstance, TKernel::ENullMode::AlwaysNull>
  1079. {
  1080. static arrow::Status Exec(arrow::compute::KernelContext* kernelCtx, const arrow::compute::ExecBatch& batch, arrow::Datum* res) {
  1081. auto scalarScalarFunc = &TBinaryKernelOptExecsImpl<TInput1, TInput2, TOutput, TFuncInstance>::ScalarScalarCoreOpt;
  1082. auto scalarArrayFunc = &TBinaryKernelOptExecsImpl<TInput1, TInput2, TOutput, TFuncInstance>::ScalarArrayCoreOpt;
  1083. auto arrayScalarFunc = &TBinaryKernelOptExecsImpl<TInput1, TInput2, TOutput, TFuncInstance>::ArrayScalarCoreOpt;
  1084. auto arrayArrayFunc = &TBinaryKernelOptExecsImpl<TInput1, TInput2, TOutput, TFuncInstance>::ArrayArrayCoreOpt;
  1085. return ExecBinaryOptImpl(kernelCtx, batch, res,
  1086. &GetPrimitiveDataType<TOutput>,
  1087. &MakeDefaultScalarDatum<TOutput>,
  1088. Tz1, Tz2, PropagateTz, sizeof(TOutput),
  1089. (TUntypedBinaryScalarOptFuncPtr)scalarScalarFunc,
  1090. (TUntypedBinaryArrayOptFuncPtr)scalarArrayFunc,
  1091. (TUntypedBinaryArrayOptFuncPtr)arrayScalarFunc,
  1092. (TUntypedBinaryArrayOptFuncPtr)arrayArrayFunc);
  1093. }
  1094. };
  1095. class TPlainKernel : public TKernel {
  1096. public:
  1097. TPlainKernel(const TKernelFamily& family, const std::vector<NUdf::TDataTypeId>& argTypes,
  1098. NUdf::TDataTypeId returnType, std::unique_ptr<arrow::compute::ScalarKernel>&& arrowKernel,
  1099. TKernel::ENullMode nullMode);
  1100. const arrow::compute::ScalarKernel& GetArrowKernel() const final;
  1101. std::shared_ptr<arrow::compute::ScalarKernel> MakeArrowKernel(const TVector<TType*>& argTypes, TType* resultType) const final;
  1102. bool IsPolymorphic() const final;
  1103. private:
  1104. const std::unique_ptr<arrow::compute::ScalarKernel> ArrowKernel;
  1105. };
  1106. template<typename TInput, bool Tz, typename TOutput, bool PropagateTz, class TFuncInstance>
  1107. struct TUnaryKernelExecs
  1108. {
  1109. using TTypedUnaryScalarFuncPtr = void(*)(
  1110. const typename TPrimitiveDataType<TInput>::TLayout*,
  1111. typename TPrimitiveDataType<TOutput>::TLayout*
  1112. );
  1113. using TTypedUnaryArrayFuncPtr = void(*)(
  1114. const typename TPrimitiveDataType<TInput>::TLayout*,
  1115. typename TPrimitiveDataType<TOutput>::TLayout*,
  1116. int64_t,
  1117. int64_t
  1118. );
  1119. static void ArrayCore(
  1120. const typename TPrimitiveDataType<TInput>::TLayout* valPtr,
  1121. typename TPrimitiveDataType<TOutput>::TLayout* resPtr,
  1122. int64_t length, int64_t offset) {
  1123. TTypedUnaryScalarFuncPtr func = &TFuncInstance::DoPtr;
  1124. valPtr += offset;
  1125. for (int64_t i = 0; i < length; ++i) {
  1126. func(valPtr, resPtr);
  1127. ++valPtr;
  1128. ++resPtr;
  1129. }
  1130. }
  1131. static arrow::Status Exec(arrow::compute::KernelContext* kernelCtx, const arrow::compute::ExecBatch& batch, arrow::Datum* res) {
  1132. TTypedUnaryScalarFuncPtr func = &TFuncInstance::DoPtr;
  1133. TTypedUnaryArrayFuncPtr arrayFunc = &ArrayCore;
  1134. return ExecUnaryImpl(kernelCtx, batch, res,
  1135. &GetPrimitiveDataType<TOutput>,
  1136. &MakeDefaultScalarDatum<TOutput>,
  1137. Tz, PropagateTz, sizeof(TOutput),
  1138. (TUntypedUnaryScalarFuncPtr)func,
  1139. (TUntypedUnaryArrayFuncPtr)arrayFunc);
  1140. }
  1141. };
  1142. template<class TFuncInstance>
  1143. struct TUnaryDecimalKernelExecs
  1144. {
  1145. using TInput = NYql::NDecimal::TInt128;
  1146. using TOutput = NYql::NDecimal::TInt128;
  1147. static arrow::Status Exec(arrow::compute::KernelContext* kernelCtx, const arrow::compute::ExecBatch& batch, arrow::Datum* res) {
  1148. auto func = &TFuncInstance::DoPtr;
  1149. auto arrayFunc = &TUnaryKernelExecs<TInput, false, TOutput, false, TFuncInstance>::ArrayCore;
  1150. return ExecDecimalUnaryImpl(kernelCtx, batch, res,
  1151. &GetPrimitiveDataType<TOutput>,
  1152. (TUntypedUnaryScalarFuncPtr)func,
  1153. (TUntypedUnaryArrayFuncPtr)arrayFunc);
  1154. }
  1155. };
  1156. using TStatelessArrayKernelExec = arrow::Status(*)(arrow::compute::KernelContext*, const arrow::compute::ExecBatch&, arrow::Datum*);
  1157. void AddUnaryKernelImpl(TKernelFamilyBase& owner, NUdf::EDataSlot arg1, NUdf::EDataSlot res,
  1158. TStatelessArrayKernelExec exec, TKernel::ENullMode nullMode);
  1159. template<typename TInput, typename TOutput,
  1160. template<typename, typename> class TFunc>
  1161. void AddUnaryKernel(TKernelFamilyBase& owner) {
  1162. using TInputLayout = typename TInput::TLayout;
  1163. using TOutputLayout = typename TOutput::TLayout;
  1164. static constexpr bool tz = (TInput::Features & NUdf::TzDateType) != 0;
  1165. static constexpr bool propagateTz = (TOutput::Features & NUdf::TzDateType) != 0;
  1166. using TFuncInstance = TFunc<TInputLayout, TOutputLayout>;
  1167. using TExecs = TUnaryKernelExecs<TInputLayout, tz, TOutputLayout, propagateTz, TFuncInstance>;
  1168. AddUnaryKernelImpl(owner, TInput::Slot, TOutput::Slot, &TExecs::Exec, TFuncInstance::NullMode);
  1169. }
  1170. template<class TFunc>
  1171. void AddUnaryDecimalKernels(TKernelFamilyBase& owner) {
  1172. using TExecs = TUnaryDecimalKernelExecs<TFunc>;
  1173. AddUnaryKernelImpl(owner, NUdf::EDataSlot::Decimal, NUdf::EDataSlot::Decimal, &TExecs::Exec, TKernel::ENullMode::Default);
  1174. }
  1175. void AddBinaryKernelImpl(TKernelFamilyBase& owner, NUdf::EDataSlot arg1, NUdf::EDataSlot arg2, NUdf::EDataSlot res,
  1176. TStatelessArrayKernelExec exec, TKernel::ENullMode nullMode);
  1177. template<typename TInput1, typename TInput2, typename TOutput,
  1178. template<typename, typename, typename> class TFunc>
  1179. void AddBinaryKernel(TKernelFamilyBase& owner) {
  1180. using TInput1Layout = typename TInput1::TLayout;
  1181. using TInput2Layout = typename TInput2::TLayout;
  1182. using TOutputLayout = typename TOutput::TLayout;
  1183. static constexpr bool tz1 = (TInput1::Features & NUdf::TzDateType) != 0;
  1184. static constexpr bool tz2 = (TInput2::Features & NUdf::TzDateType) != 0;
  1185. static constexpr EPropagateTz propagateTz = (TOutput::Features & NUdf::TzDateType) ?
  1186. ((TInput1::Features & NUdf::TzDateType) ? EPropagateTz::FromLeft : EPropagateTz::FromRight) :
  1187. EPropagateTz::None;
  1188. using TFuncInstance = TFunc<TInput1Layout, TInput2Layout, TOutputLayout>;
  1189. using TExecs = TBinaryKernelExecs<TInput1Layout, tz1, TInput2Layout, tz2, TOutputLayout, propagateTz, TFuncInstance, TFuncInstance::NullMode>;
  1190. AddBinaryKernelImpl(owner, TInput1::Slot, TInput2::Slot, TOutput::Slot, &TExecs::Exec, TFuncInstance::NullMode);
  1191. }
  1192. template<typename TInput1, typename TInput2, typename TOutput,
  1193. template<typename, typename, typename> class TFunc>
  1194. void AddBinaryKernelPoly(TKernelFamilyBase& owner) {
  1195. using TInput1Layout = typename TInput1::TLayout;
  1196. using TInput2Layout = typename TInput2::TLayout;
  1197. using TOutputLayout = typename TOutput::TLayout;
  1198. static constexpr bool tz1 = (TInput1::Features & NUdf::TzDateType) != 0;
  1199. static constexpr bool tz2 = (TInput2::Features & NUdf::TzDateType) != 0;
  1200. static constexpr EPropagateTz propagateTz = (TOutput::Features & NUdf::TzDateType) ?
  1201. ((TInput1::Features & NUdf::TzDateType) ? EPropagateTz::FromLeft : EPropagateTz::FromRight) :
  1202. EPropagateTz::None;
  1203. using TFuncInstance = TFunc<TInput1, TInput2, TOutput>;
  1204. using TExecs = TBinaryKernelExecs<TInput1Layout, tz1, TInput2Layout, tz2, TOutputLayout, propagateTz, TFuncInstance, TFuncInstance::NullMode>;
  1205. AddBinaryKernelImpl(owner, TInput1::Slot, TInput2::Slot, TOutput::Slot, &TExecs::Exec, TFuncInstance::NullMode);
  1206. }
  1207. template<template<typename, typename> class TFunc>
  1208. void AddUnaryIntegralKernels(TKernelFamilyBase& owner) {
  1209. AddUnaryKernel<NUdf::TDataType<i8>, NUdf::TDataType<i8>, TFunc>(owner);
  1210. AddUnaryKernel<NUdf::TDataType<i16>, NUdf::TDataType<i16>, TFunc>(owner);
  1211. AddUnaryKernel<NUdf::TDataType<i32>, NUdf::TDataType<i32>, TFunc>(owner);
  1212. AddUnaryKernel<NUdf::TDataType<i64>, NUdf::TDataType<i64>, TFunc>(owner);
  1213. AddUnaryKernel<NUdf::TDataType<ui8>, NUdf::TDataType<ui8>, TFunc>(owner);
  1214. AddUnaryKernel<NUdf::TDataType<ui16>, NUdf::TDataType<ui16>, TFunc>(owner);
  1215. AddUnaryKernel<NUdf::TDataType<ui32>, NUdf::TDataType<ui32>, TFunc>(owner);
  1216. AddUnaryKernel<NUdf::TDataType<ui64>, NUdf::TDataType<ui64>, TFunc>(owner);
  1217. }
  1218. template<template<typename, typename> class TFunc>
  1219. void AddUnaryRealKernels(TKernelFamilyBase& owner) {
  1220. AddUnaryKernel<NUdf::TDataType<float>, NUdf::TDataType<float>, TFunc>(owner);
  1221. AddUnaryKernel<NUdf::TDataType<double>, NUdf::TDataType<double>, TFunc>(owner);
  1222. }
  1223. template<template<typename, typename, typename> class TFunc>
  1224. void AddBinaryIntegralKernels(TKernelFamilyBase& owner) {
  1225. AddBinaryKernel<NUdf::TDataType<ui8>, NUdf::TDataType<ui8>, NUdf::TDataType<ui8>, TFunc>(owner);
  1226. AddBinaryKernel<NUdf::TDataType<ui8>, NUdf::TDataType<i8>, NUdf::TDataType<i8>, TFunc>(owner);
  1227. AddBinaryKernel<NUdf::TDataType<ui8>, NUdf::TDataType<ui16>, NUdf::TDataType<ui16>, TFunc>(owner);
  1228. AddBinaryKernel<NUdf::TDataType<ui8>, NUdf::TDataType<i16>, NUdf::TDataType<i16>, TFunc>(owner);
  1229. AddBinaryKernel<NUdf::TDataType<ui8>, NUdf::TDataType<ui32>, NUdf::TDataType<ui32>, TFunc>(owner);
  1230. AddBinaryKernel<NUdf::TDataType<ui8>, NUdf::TDataType<i32>, NUdf::TDataType<i32>, TFunc>(owner);
  1231. AddBinaryKernel<NUdf::TDataType<ui8>, NUdf::TDataType<ui64>, NUdf::TDataType<ui64>, TFunc>(owner);
  1232. AddBinaryKernel<NUdf::TDataType<ui8>, NUdf::TDataType<i64>, NUdf::TDataType<i64>, TFunc>(owner);
  1233. AddBinaryKernel<NUdf::TDataType<i8>, NUdf::TDataType<ui8>, NUdf::TDataType<i8>, TFunc>(owner);
  1234. AddBinaryKernel<NUdf::TDataType<i8>, NUdf::TDataType<i8>, NUdf::TDataType<i8>, TFunc>(owner);
  1235. AddBinaryKernel<NUdf::TDataType<i8>, NUdf::TDataType<ui16>, NUdf::TDataType<ui16>, TFunc>(owner);
  1236. AddBinaryKernel<NUdf::TDataType<i8>, NUdf::TDataType<i16>, NUdf::TDataType<i16>, TFunc>(owner);
  1237. AddBinaryKernel<NUdf::TDataType<i8>, NUdf::TDataType<ui32>, NUdf::TDataType<ui32>, TFunc>(owner);
  1238. AddBinaryKernel<NUdf::TDataType<i8>, NUdf::TDataType<i32>, NUdf::TDataType<i32>, TFunc>(owner);
  1239. AddBinaryKernel<NUdf::TDataType<i8>, NUdf::TDataType<ui64>, NUdf::TDataType<ui64>, TFunc>(owner);
  1240. AddBinaryKernel<NUdf::TDataType<i8>, NUdf::TDataType<i64>, NUdf::TDataType<i64>, TFunc>(owner);
  1241. AddBinaryKernel<NUdf::TDataType<ui16>, NUdf::TDataType<ui8>, NUdf::TDataType<ui16>, TFunc>(owner);
  1242. AddBinaryKernel<NUdf::TDataType<ui16>, NUdf::TDataType<i8>, NUdf::TDataType<ui16>, TFunc>(owner);
  1243. AddBinaryKernel<NUdf::TDataType<ui16>, NUdf::TDataType<ui16>, NUdf::TDataType<ui16>, TFunc>(owner);
  1244. AddBinaryKernel<NUdf::TDataType<ui16>, NUdf::TDataType<i16>, NUdf::TDataType<i16>, TFunc>(owner);
  1245. AddBinaryKernel<NUdf::TDataType<ui16>, NUdf::TDataType<ui32>, NUdf::TDataType<ui32>, TFunc>(owner);
  1246. AddBinaryKernel<NUdf::TDataType<ui16>, NUdf::TDataType<i32>, NUdf::TDataType<i32>, TFunc>(owner);
  1247. AddBinaryKernel<NUdf::TDataType<ui16>, NUdf::TDataType<ui64>, NUdf::TDataType<ui64>, TFunc>(owner);
  1248. AddBinaryKernel<NUdf::TDataType<ui16>, NUdf::TDataType<i64>, NUdf::TDataType<i64>, TFunc>(owner);
  1249. AddBinaryKernel<NUdf::TDataType<i16>, NUdf::TDataType<ui8>, NUdf::TDataType<i16>, TFunc>(owner);
  1250. AddBinaryKernel<NUdf::TDataType<i16>, NUdf::TDataType<i8>, NUdf::TDataType<i16>, TFunc>(owner);
  1251. AddBinaryKernel<NUdf::TDataType<i16>, NUdf::TDataType<ui16>, NUdf::TDataType<i16>, TFunc>(owner);
  1252. AddBinaryKernel<NUdf::TDataType<i16>, NUdf::TDataType<i16>, NUdf::TDataType<i16>, TFunc>(owner);
  1253. AddBinaryKernel<NUdf::TDataType<i16>, NUdf::TDataType<ui32>, NUdf::TDataType<ui32>, TFunc>(owner);
  1254. AddBinaryKernel<NUdf::TDataType<i16>, NUdf::TDataType<i32>, NUdf::TDataType<i32>, TFunc>(owner);
  1255. AddBinaryKernel<NUdf::TDataType<i16>, NUdf::TDataType<ui64>, NUdf::TDataType<ui64>, TFunc>(owner);
  1256. AddBinaryKernel<NUdf::TDataType<i16>, NUdf::TDataType<i64>, NUdf::TDataType<i64>, TFunc>(owner);
  1257. AddBinaryKernel<NUdf::TDataType<ui32>, NUdf::TDataType<ui8>, NUdf::TDataType<ui32>, TFunc>(owner);
  1258. AddBinaryKernel<NUdf::TDataType<ui32>, NUdf::TDataType<i8>, NUdf::TDataType<ui32>, TFunc>(owner);
  1259. AddBinaryKernel<NUdf::TDataType<ui32>, NUdf::TDataType<ui16>, NUdf::TDataType<ui32>, TFunc>(owner);
  1260. AddBinaryKernel<NUdf::TDataType<ui32>, NUdf::TDataType<i16>, NUdf::TDataType<ui32>, TFunc>(owner);
  1261. AddBinaryKernel<NUdf::TDataType<ui32>, NUdf::TDataType<ui32>, NUdf::TDataType<ui32>, TFunc>(owner);
  1262. AddBinaryKernel<NUdf::TDataType<ui32>, NUdf::TDataType<i32>, NUdf::TDataType<i32>, TFunc>(owner);
  1263. AddBinaryKernel<NUdf::TDataType<ui32>, NUdf::TDataType<ui64>, NUdf::TDataType<ui64>, TFunc>(owner);
  1264. AddBinaryKernel<NUdf::TDataType<ui32>, NUdf::TDataType<i64>, NUdf::TDataType<i64>, TFunc>(owner);
  1265. AddBinaryKernel<NUdf::TDataType<i32>, NUdf::TDataType<ui8>, NUdf::TDataType<i32>, TFunc>(owner);
  1266. AddBinaryKernel<NUdf::TDataType<i32>, NUdf::TDataType<i8>, NUdf::TDataType<i32>, TFunc>(owner);
  1267. AddBinaryKernel<NUdf::TDataType<i32>, NUdf::TDataType<ui16>, NUdf::TDataType<i32>, TFunc>(owner);
  1268. AddBinaryKernel<NUdf::TDataType<i32>, NUdf::TDataType<i16>, NUdf::TDataType<i32>, TFunc>(owner);
  1269. AddBinaryKernel<NUdf::TDataType<i32>, NUdf::TDataType<ui32>, NUdf::TDataType<i32>, TFunc>(owner);
  1270. AddBinaryKernel<NUdf::TDataType<i32>, NUdf::TDataType<i32>, NUdf::TDataType<i32>, TFunc>(owner);
  1271. AddBinaryKernel<NUdf::TDataType<i32>, NUdf::TDataType<ui64>, NUdf::TDataType<ui64>, TFunc>(owner);
  1272. AddBinaryKernel<NUdf::TDataType<i32>, NUdf::TDataType<i64>, NUdf::TDataType<i64>, TFunc>(owner);
  1273. AddBinaryKernel<NUdf::TDataType<ui64>, NUdf::TDataType<ui8>, NUdf::TDataType<ui64>, TFunc>(owner);
  1274. AddBinaryKernel<NUdf::TDataType<ui64>, NUdf::TDataType<i8>, NUdf::TDataType<ui64>, TFunc>(owner);
  1275. AddBinaryKernel<NUdf::TDataType<ui64>, NUdf::TDataType<ui16>, NUdf::TDataType<ui64>, TFunc>(owner);
  1276. AddBinaryKernel<NUdf::TDataType<ui64>, NUdf::TDataType<i16>, NUdf::TDataType<ui64>, TFunc>(owner);
  1277. AddBinaryKernel<NUdf::TDataType<ui64>, NUdf::TDataType<ui32>, NUdf::TDataType<ui64>, TFunc>(owner);
  1278. AddBinaryKernel<NUdf::TDataType<ui64>, NUdf::TDataType<i32>, NUdf::TDataType<ui64>, TFunc>(owner);
  1279. AddBinaryKernel<NUdf::TDataType<ui64>, NUdf::TDataType<ui64>, NUdf::TDataType<ui64>, TFunc>(owner);
  1280. AddBinaryKernel<NUdf::TDataType<ui64>, NUdf::TDataType<i64>, NUdf::TDataType<i64>, TFunc>(owner);
  1281. AddBinaryKernel<NUdf::TDataType<i64>, NUdf::TDataType<ui8>, NUdf::TDataType<i64>, TFunc>(owner);
  1282. AddBinaryKernel<NUdf::TDataType<i64>, NUdf::TDataType<i8>, NUdf::TDataType<i64>, TFunc>(owner);
  1283. AddBinaryKernel<NUdf::TDataType<i64>, NUdf::TDataType<ui16>, NUdf::TDataType<i64>, TFunc>(owner);
  1284. AddBinaryKernel<NUdf::TDataType<i64>, NUdf::TDataType<i16>, NUdf::TDataType<i64>, TFunc>(owner);
  1285. AddBinaryKernel<NUdf::TDataType<i64>, NUdf::TDataType<ui32>, NUdf::TDataType<i64>, TFunc>(owner);
  1286. AddBinaryKernel<NUdf::TDataType<i64>, NUdf::TDataType<i32>, NUdf::TDataType<i64>, TFunc>(owner);
  1287. AddBinaryKernel<NUdf::TDataType<i64>, NUdf::TDataType<ui64>, NUdf::TDataType<i64>, TFunc>(owner);
  1288. AddBinaryKernel<NUdf::TDataType<i64>, NUdf::TDataType<i64>, NUdf::TDataType<i64>, TFunc>(owner);
  1289. }
  1290. template<template<typename, typename, typename> class TFunc>
  1291. void AddBinaryRealKernels(TKernelFamilyBase& owner) {
  1292. AddBinaryKernel<NUdf::TDataType<i8>, NUdf::TDataType<float>, NUdf::TDataType<float>, TFunc>(owner);
  1293. AddBinaryKernel<NUdf::TDataType<i8>, NUdf::TDataType<double>, NUdf::TDataType<double>, TFunc>(owner);
  1294. AddBinaryKernel<NUdf::TDataType<float>, NUdf::TDataType<i8>, NUdf::TDataType<float>, TFunc>(owner);
  1295. AddBinaryKernel<NUdf::TDataType<double>, NUdf::TDataType<i8>, NUdf::TDataType<double>, TFunc>(owner);
  1296. AddBinaryKernel<NUdf::TDataType<ui8>, NUdf::TDataType<float>, NUdf::TDataType<float>, TFunc>(owner);
  1297. AddBinaryKernel<NUdf::TDataType<ui8>, NUdf::TDataType<double>, NUdf::TDataType<double>, TFunc>(owner);
  1298. AddBinaryKernel<NUdf::TDataType<float>, NUdf::TDataType<ui8>, NUdf::TDataType<float>, TFunc>(owner);
  1299. AddBinaryKernel<NUdf::TDataType<double>, NUdf::TDataType<ui8>, NUdf::TDataType<double>, TFunc>(owner);
  1300. AddBinaryKernel<NUdf::TDataType<i16>, NUdf::TDataType<float>, NUdf::TDataType<float>, TFunc>(owner);
  1301. AddBinaryKernel<NUdf::TDataType<i16>, NUdf::TDataType<double>, NUdf::TDataType<double>, TFunc>(owner);
  1302. AddBinaryKernel<NUdf::TDataType<float>, NUdf::TDataType<i16>, NUdf::TDataType<float>, TFunc>(owner);
  1303. AddBinaryKernel<NUdf::TDataType<double>, NUdf::TDataType<i16>, NUdf::TDataType<double>, TFunc>(owner);
  1304. AddBinaryKernel<NUdf::TDataType<ui16>, NUdf::TDataType<float>, NUdf::TDataType<float>, TFunc>(owner);
  1305. AddBinaryKernel<NUdf::TDataType<ui16>, NUdf::TDataType<double>, NUdf::TDataType<double>, TFunc>(owner);
  1306. AddBinaryKernel<NUdf::TDataType<float>, NUdf::TDataType<ui16>, NUdf::TDataType<float>, TFunc>(owner);
  1307. AddBinaryKernel<NUdf::TDataType<double>, NUdf::TDataType<ui16>, NUdf::TDataType<double>, TFunc>(owner);
  1308. AddBinaryKernel<NUdf::TDataType<i32>, NUdf::TDataType<float>, NUdf::TDataType<float>, TFunc>(owner);
  1309. AddBinaryKernel<NUdf::TDataType<i32>, NUdf::TDataType<double>, NUdf::TDataType<double>, TFunc>(owner);
  1310. AddBinaryKernel<NUdf::TDataType<float>, NUdf::TDataType<i32>, NUdf::TDataType<float>, TFunc>(owner);
  1311. AddBinaryKernel<NUdf::TDataType<double>, NUdf::TDataType<i32>, NUdf::TDataType<double>, TFunc>(owner);
  1312. AddBinaryKernel<NUdf::TDataType<ui32>, NUdf::TDataType<float>, NUdf::TDataType<float>, TFunc>(owner);
  1313. AddBinaryKernel<NUdf::TDataType<ui32>, NUdf::TDataType<double>, NUdf::TDataType<double>, TFunc>(owner);
  1314. AddBinaryKernel<NUdf::TDataType<float>, NUdf::TDataType<ui32>, NUdf::TDataType<float>, TFunc>(owner);
  1315. AddBinaryKernel<NUdf::TDataType<double>, NUdf::TDataType<ui32>, NUdf::TDataType<double>, TFunc>(owner);
  1316. AddBinaryKernel<NUdf::TDataType<i64>, NUdf::TDataType<float>, NUdf::TDataType<float>, TFunc>(owner);
  1317. AddBinaryKernel<NUdf::TDataType<i64>, NUdf::TDataType<double>, NUdf::TDataType<double>, TFunc>(owner);
  1318. AddBinaryKernel<NUdf::TDataType<float>, NUdf::TDataType<i64>, NUdf::TDataType<float>, TFunc>(owner);
  1319. AddBinaryKernel<NUdf::TDataType<double>, NUdf::TDataType<i64>, NUdf::TDataType<double>, TFunc>(owner);
  1320. AddBinaryKernel<NUdf::TDataType<ui64>, NUdf::TDataType<float>, NUdf::TDataType<float>, TFunc>(owner);
  1321. AddBinaryKernel<NUdf::TDataType<ui64>, NUdf::TDataType<double>, NUdf::TDataType<double>, TFunc>(owner);
  1322. AddBinaryKernel<NUdf::TDataType<float>, NUdf::TDataType<ui64>, NUdf::TDataType<float>, TFunc>(owner);
  1323. AddBinaryKernel<NUdf::TDataType<double>, NUdf::TDataType<ui64>, NUdf::TDataType<double>, TFunc>(owner);
  1324. AddBinaryKernel<NUdf::TDataType<float>, NUdf::TDataType<float>, NUdf::TDataType<float>, TFunc>(owner);
  1325. AddBinaryKernel<NUdf::TDataType<float>, NUdf::TDataType<double>, NUdf::TDataType<double>, TFunc>(owner);
  1326. AddBinaryKernel<NUdf::TDataType<double>, NUdf::TDataType<float>, NUdf::TDataType<double>, TFunc>(owner);
  1327. AddBinaryKernel<NUdf::TDataType<double>, NUdf::TDataType<double>, NUdf::TDataType<double>, TFunc>(owner);
  1328. }
  1329. template<template<typename, typename, typename> class TFuncForIntegral, template<typename, typename, typename> class TFuncForReal>
  1330. class TBinaryNumericKernelFamily : public TKernelFamilyBase {
  1331. public:
  1332. TBinaryNumericKernelFamily()
  1333. {
  1334. AddBinaryIntegralKernels<TFuncForIntegral>(*this);
  1335. AddBinaryRealKernels<TFuncForReal>(*this);
  1336. }
  1337. };
  1338. template<template<typename, typename> class TFunc>
  1339. class TUnaryNumericKernelFamily : public TKernelFamilyBase {
  1340. public:
  1341. TUnaryNumericKernelFamily()
  1342. {
  1343. AddUnaryIntegralKernels<TFunc>(*this);
  1344. AddUnaryRealKernels<TFunc>(*this);
  1345. }
  1346. };
  1347. template<typename TInput1, typename TInput2,
  1348. template<typename, typename, typename> class TFunc>
  1349. void AddBinaryPredicateKernel(TKernelFamilyBase& owner) {
  1350. AddBinaryKernel<TInput1, TInput2, NUdf::TDataType<bool>, TFunc>(owner);
  1351. }
  1352. template<typename TInput1, typename TInput2,
  1353. template<typename, typename, typename> class TFunc>
  1354. void AddBinaryPredicateKernelPoly(TKernelFamilyBase& owner) {
  1355. AddBinaryKernelPoly<TInput1, TInput2, NUdf::TDataType<bool>, TFunc>(owner);
  1356. }
  1357. template<typename TLeft, template<typename, typename, typename> class TPred>
  1358. void AddArithmeticComparisonKernels(TKernelFamilyBase& owner) {
  1359. AddBinaryPredicateKernel<TLeft, NUdf::TDataType<ui8>, TPred>(owner);
  1360. AddBinaryPredicateKernel<TLeft, NUdf::TDataType<i8>, TPred>(owner);
  1361. AddBinaryPredicateKernel<TLeft, NUdf::TDataType<ui16>, TPred>(owner);
  1362. AddBinaryPredicateKernel<TLeft, NUdf::TDataType<i16>, TPred>(owner);
  1363. AddBinaryPredicateKernel<TLeft, NUdf::TDataType<ui32>, TPred>(owner);
  1364. AddBinaryPredicateKernel<TLeft, NUdf::TDataType<i32>, TPred>(owner);
  1365. AddBinaryPredicateKernel<TLeft, NUdf::TDataType<ui64>, TPred>(owner);
  1366. AddBinaryPredicateKernel<TLeft, NUdf::TDataType<i64>, TPred>(owner);
  1367. AddBinaryPredicateKernel<TLeft, NUdf::TDataType<float>, TPred>(owner);
  1368. AddBinaryPredicateKernel<TLeft, NUdf::TDataType<double>, TPred>(owner);
  1369. }
  1370. template<template<typename, typename, typename> class TPred>
  1371. void AddNumericComparisonKernels(TKernelFamilyBase& owner) {
  1372. // arithmetic types (integral and floating points)
  1373. AddArithmeticComparisonKernels<NUdf::TDataType<ui8>, TPred>(owner);
  1374. AddArithmeticComparisonKernels<NUdf::TDataType<i8>, TPred>(owner);
  1375. AddArithmeticComparisonKernels<NUdf::TDataType<ui16>, TPred>(owner);
  1376. AddArithmeticComparisonKernels<NUdf::TDataType<i16>, TPred>(owner);
  1377. AddArithmeticComparisonKernels<NUdf::TDataType<ui32>, TPred>(owner);
  1378. AddArithmeticComparisonKernels<NUdf::TDataType<i32>, TPred>(owner);
  1379. AddArithmeticComparisonKernels<NUdf::TDataType<ui64>, TPred>(owner);
  1380. AddArithmeticComparisonKernels<NUdf::TDataType<i64>, TPred>(owner);
  1381. AddArithmeticComparisonKernels<NUdf::TDataType<float>, TPred>(owner);
  1382. AddArithmeticComparisonKernels<NUdf::TDataType<double>, TPred>(owner);
  1383. // bool can only be compared with itself
  1384. AddBinaryPredicateKernel<NUdf::TDataType<bool>, NUdf::TDataType<bool>, TPred>(owner);
  1385. }
  1386. template<typename TLeft, template<typename, typename, typename> class TPred>
  1387. void AddDateComparisonKernelsForDate(TKernelFamilyBase& owner) {
  1388. AddBinaryPredicateKernelPoly<NUdf::TDataType<TLeft>, NUdf::TDataType<NUdf::TDate>, TPred>(owner);
  1389. AddBinaryPredicateKernelPoly<NUdf::TDataType<TLeft>, NUdf::TDataType<NUdf::TDatetime>, TPred>(owner);
  1390. AddBinaryPredicateKernelPoly<NUdf::TDataType<TLeft>, NUdf::TDataType<NUdf::TTimestamp>, TPred>(owner);
  1391. AddBinaryPredicateKernelPoly<NUdf::TDataType<TLeft>, NUdf::TDataType<NUdf::TTzDate>, TPred>(owner);
  1392. AddBinaryPredicateKernelPoly<NUdf::TDataType<TLeft>, NUdf::TDataType<NUdf::TTzDatetime>, TPred>(owner);
  1393. AddBinaryPredicateKernelPoly<NUdf::TDataType<TLeft>, NUdf::TDataType<NUdf::TTzTimestamp>, TPred>(owner);
  1394. AddBinaryPredicateKernelPoly<NUdf::TDataType<TLeft>, NUdf::TDataType<NUdf::TDate32>, TPred>(owner);
  1395. AddBinaryPredicateKernelPoly<NUdf::TDataType<TLeft>, NUdf::TDataType<NUdf::TDatetime64>, TPred>(owner);
  1396. AddBinaryPredicateKernelPoly<NUdf::TDataType<TLeft>, NUdf::TDataType<NUdf::TTimestamp64>, TPred>(owner);
  1397. AddBinaryPredicateKernelPoly<NUdf::TDataType<TLeft>, NUdf::TDataType<NUdf::TTzDate32>, TPred>(owner);
  1398. AddBinaryPredicateKernelPoly<NUdf::TDataType<TLeft>, NUdf::TDataType<NUdf::TTzDatetime64>, TPred>(owner);
  1399. AddBinaryPredicateKernelPoly<NUdf::TDataType<TLeft>, NUdf::TDataType<NUdf::TTzTimestamp64>, TPred>(owner);
  1400. }
  1401. template<template<typename, typename, typename> class TPred>
  1402. void AddDateComparisonKernels(TKernelFamilyBase& owner) {
  1403. AddDateComparisonKernelsForDate<NUdf::TDate, TPred>(owner);
  1404. AddDateComparisonKernelsForDate<NUdf::TDatetime, TPred>(owner);
  1405. AddDateComparisonKernelsForDate<NUdf::TTimestamp, TPred>(owner);
  1406. AddDateComparisonKernelsForDate<NUdf::TTzDate, TPred>(owner);
  1407. AddDateComparisonKernelsForDate<NUdf::TTzDatetime, TPred>(owner);
  1408. AddDateComparisonKernelsForDate<NUdf::TTzTimestamp, TPred>(owner);
  1409. AddDateComparisonKernelsForDate<NUdf::TDate32, TPred>(owner);
  1410. AddDateComparisonKernelsForDate<NUdf::TDatetime64, TPred>(owner);
  1411. AddDateComparisonKernelsForDate<NUdf::TTimestamp64, TPred>(owner);
  1412. AddDateComparisonKernelsForDate<NUdf::TTzDate32, TPred>(owner);
  1413. AddDateComparisonKernelsForDate<NUdf::TTzDatetime64, TPred>(owner);
  1414. AddDateComparisonKernelsForDate<NUdf::TTzTimestamp64, TPred>(owner);
  1415. // Interval can only be compared with itself
  1416. AddBinaryPredicateKernelPoly<NUdf::TDataType<NUdf::TInterval>, NUdf::TDataType<NUdf::TInterval>, TPred>(owner);
  1417. AddBinaryPredicateKernelPoly<NUdf::TDataType<NUdf::TInterval>, NUdf::TDataType<NUdf::TInterval64>, TPred>(owner);
  1418. AddBinaryPredicateKernelPoly<NUdf::TDataType<NUdf::TInterval64>, NUdf::TDataType<NUdf::TInterval>, TPred>(owner);
  1419. AddBinaryPredicateKernelPoly<NUdf::TDataType<NUdf::TInterval64>, NUdf::TDataType<NUdf::TInterval64>, TPred>(owner);
  1420. }
  1421. class TDecimalKernel : public TKernel {
  1422. public:
  1423. struct TKernelState : arrow::compute::KernelState {
  1424. ui8 Precision;
  1425. };
  1426. TDecimalKernel(const TKernelFamily& family, const std::vector<NUdf::TDataTypeId>& argTypes,
  1427. NUdf::TDataTypeId returnType, TStatelessArrayKernelExec exec,
  1428. TKernel::ENullMode nullMode);
  1429. const arrow::compute::ScalarKernel& GetArrowKernel() const final;
  1430. std::shared_ptr<arrow::compute::ScalarKernel> MakeArrowKernel(const TVector<TType*>& argTypes, TType* resultType) const final;
  1431. bool IsPolymorphic() const final;
  1432. private:
  1433. TStatelessArrayKernelExec Exec;
  1434. };
  1435. template<template<ui8> class TFuncInstance>
  1436. struct TDecimalKernelExecs
  1437. {
  1438. using TInput1 = NYql::NDecimal::TInt128;
  1439. using TInput2 = NYql::NDecimal::TInt128;
  1440. using TOutput = NYql::NDecimal::TInt128;
  1441. static arrow::Datum ScalarGetter(void** result, arrow::MemoryPool* memory_pool) {
  1442. std::shared_ptr<arrow::Buffer> buffer(ARROW_RESULT(arrow::AllocateBuffer(16, memory_pool)));
  1443. *result = buffer->mutable_data();
  1444. return arrow::Datum(std::make_shared<TPrimitiveDataType<NYql::NDecimal::TInt128>::TScalarResult>(buffer));
  1445. }
  1446. template<ui8 precision>
  1447. static arrow::Status ExecImpl(arrow::compute::KernelContext* kernelCtx, const arrow::compute::ExecBatch& batch, arrow::Datum* res) {
  1448. auto scalarScalarFunc = &TBinaryKernelOptExecsImpl<TInput1, TInput2, TOutput, TFuncInstance<precision>>::ScalarScalarCoreOpt;
  1449. auto scalarArrayFunc = &TBinaryKernelOptExecsImpl<TInput1, TInput2, TOutput, TFuncInstance<precision>>::ScalarArrayCoreOpt;
  1450. auto arrayScalarFunc = &TBinaryKernelOptExecsImpl<TInput1, TInput2, TOutput, TFuncInstance<precision>>::ArrayScalarCoreOpt;
  1451. auto arrayArrayFunc = &TBinaryKernelOptExecsImpl<TInput1, TInput2, TOutput, TFuncInstance<precision>>::ArrayArrayCoreOpt;
  1452. return ExecDecimalBinaryOptImpl(kernelCtx, batch, res,
  1453. &GetPrimitiveDataType<TOutput>, &ScalarGetter,
  1454. sizeof(TOutput),
  1455. (TUntypedBinaryScalarOptFuncPtr)scalarScalarFunc,
  1456. (TUntypedBinaryArrayOptFuncPtr)scalarArrayFunc,
  1457. (TUntypedBinaryArrayOptFuncPtr)arrayScalarFunc,
  1458. (TUntypedBinaryArrayOptFuncPtr)arrayArrayFunc);
  1459. }
  1460. using ExecFunc = arrow::Status(*)(arrow::compute::KernelContext* kernelCtx, const arrow::compute::ExecBatch& batch, arrow::Datum* res) ;
  1461. template <size_t... Is>
  1462. static constexpr auto GenerateTable(std::index_sequence<Is...>) {
  1463. return std::array<ExecFunc, sizeof...(Is)>{ExecImpl<Is+1>...};
  1464. }
  1465. static arrow::Status Exec(arrow::compute::KernelContext* kernelCtx, const arrow::compute::ExecBatch& batch, arrow::Datum* res) {
  1466. ui8 precision = static_cast<TDecimalKernel::TKernelState*>(kernelCtx->state())->Precision;
  1467. Y_DEBUG_ABORT_UNLESS(precision >= 1&& precision <= 35);
  1468. static constexpr auto jumpTable = GenerateTable(std::make_index_sequence<35>{});
  1469. return jumpTable[precision-1](kernelCtx, batch, res);
  1470. }
  1471. };
  1472. template<template<ui8> class TFunc>
  1473. void AddBinaryDecimalKernels(TKernelFamilyBase& owner) {
  1474. auto type1 = NUdf::GetDataTypeInfo(NUdf::EDataSlot::Decimal).TypeId;
  1475. auto type2 = type1;
  1476. auto returnType = type1;
  1477. std::vector<NUdf::TDataTypeId> argTypes({ type1, type2 });
  1478. using Execs = TDecimalKernelExecs<TFunc>;
  1479. auto kernel = std::make_unique<TDecimalKernel>(owner, argTypes, returnType, &Execs::Exec, TKernel::ENullMode::Default);
  1480. owner.Adopt(argTypes, returnType, std::move(kernel));
  1481. }
  1482. template<class TFuncInstance>
  1483. struct TDecimalComparisonKernelExecs
  1484. {
  1485. using TInput1 = NYql::NDecimal::TInt128;
  1486. using TInput2 = NYql::NDecimal::TInt128;
  1487. using TOutput = bool;
  1488. static arrow::Datum ScalarGetter(void** resMem, arrow::MemoryPool*) {
  1489. auto result = MakeDefaultScalarDatum<TOutput>();
  1490. *resMem = GetPrimitiveScalarValueMutablePtr(*result.scalar());
  1491. return result;
  1492. }
  1493. static arrow::Status Exec(arrow::compute::KernelContext* kernelCtx, const arrow::compute::ExecBatch& batch, arrow::Datum* res) {
  1494. auto scalarScalarFunc = &TBinaryKernelOptExecsImpl<TInput1, TInput2, TOutput, TFuncInstance>::ScalarScalarCoreOpt;
  1495. auto scalarArrayFunc = &TBinaryKernelOptExecsImpl<TInput1, TInput2, TOutput, TFuncInstance>::ScalarArrayCoreOpt;
  1496. auto arrayScalarFunc = &TBinaryKernelOptExecsImpl<TInput1, TInput2, TOutput, TFuncInstance>::ArrayScalarCoreOpt;
  1497. auto arrayArrayFunc = &TBinaryKernelOptExecsImpl<TInput1, TInput2, TOutput, TFuncInstance>::ArrayArrayCoreOpt;
  1498. return ExecDecimalBinaryOptImpl(kernelCtx, batch, res,
  1499. &GetPrimitiveDataType<TOutput>, &ScalarGetter,
  1500. sizeof(TOutput),
  1501. (TUntypedBinaryScalarOptFuncPtr)scalarScalarFunc,
  1502. (TUntypedBinaryArrayOptFuncPtr)scalarArrayFunc,
  1503. (TUntypedBinaryArrayOptFuncPtr)arrayScalarFunc,
  1504. (TUntypedBinaryArrayOptFuncPtr)arrayArrayFunc);
  1505. }
  1506. };
  1507. template<class TFunc>
  1508. void AddDecimalComparisonKernels(TKernelFamilyBase& owner) {
  1509. auto type1 = NUdf::GetDataTypeInfo(NUdf::EDataSlot::Decimal).TypeId;
  1510. auto type2 = type1;
  1511. auto returnType = NUdf::GetDataTypeInfo(NUdf::EDataSlot::Bool).TypeId;
  1512. std::vector<NUdf::TDataTypeId> argTypes({ type1, type2 });
  1513. using Execs = TDecimalComparisonKernelExecs<TFunc>;
  1514. auto kernel = std::make_unique<TDecimalKernel>(owner, argTypes, returnType, &Execs::Exec, TKernel::ENullMode::Default);
  1515. owner.Adopt(argTypes, returnType, std::move(kernel));
  1516. }
  1517. }
  1518. }