callables_udf.cpp 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224
  1. #include <yql/essentials/public/udf/udf_value.h>
  2. #include <yql/essentials/public/udf/udf_type_builder.h>
  3. #include <yql/essentials/public/udf/udf_registrator.h>
  4. #include <util/generic/yexception.h>
  5. #include <util/string/cast.h>
  6. using namespace NKikimr;
  7. using namespace NUdf;
  8. namespace {
  9. //////////////////////////////////////////////////////////////////////////////
  10. // TFromString
  11. //////////////////////////////////////////////////////////////////////////////
  12. class TFromString: public TBoxedValue
  13. {
  14. public:
  15. static TStringRef Name() {
  16. static auto name = TStringRef::Of("FromString");
  17. return name;
  18. }
  19. private:
  20. TUnboxedValue Run(
  21. const IValueBuilder* valueBuilder,
  22. const TUnboxedValuePod* args) const override
  23. {
  24. Y_UNUSED(valueBuilder);
  25. auto str = args[0].AsStringRef();
  26. int val = FromString<int>(str);
  27. return TUnboxedValuePod(val);
  28. }
  29. };
  30. //////////////////////////////////////////////////////////////////////////////
  31. // TSum
  32. //////////////////////////////////////////////////////////////////////////////
  33. class TSum: public TBoxedValue
  34. {
  35. public:
  36. static TStringRef Name() {
  37. static auto name = TStringRef::Of("Sum");
  38. return name;
  39. }
  40. private:
  41. TUnboxedValue Run(
  42. const IValueBuilder* valueBuilder,
  43. const TUnboxedValuePod* args) const override
  44. {
  45. int sum = 0;
  46. auto it = args[0].GetListIterator();
  47. for (TUnboxedValue arg; it.Next(arg);) {
  48. auto value = args[1].Run(valueBuilder, &arg);
  49. sum += value.Get<int>();
  50. }
  51. return TUnboxedValuePod(sum);
  52. }
  53. };
  54. //////////////////////////////////////////////////////////////////////////////
  55. // TMul
  56. //////////////////////////////////////////////////////////////////////////////
  57. class TMul: public TBoxedValue
  58. {
  59. public:
  60. static TStringRef Name() {
  61. static auto name = TStringRef::Of("Mul");
  62. return name;
  63. }
  64. private:
  65. TUnboxedValue Run(
  66. const IValueBuilder* valueBuilder,
  67. const TUnboxedValuePod* args) const override
  68. {
  69. int mul = 1;
  70. const auto it = args[0].GetListIterator();
  71. for (TUnboxedValue arg; it.Next(arg);) {
  72. auto value = args[1].Run(valueBuilder, &arg);
  73. mul *= value.Get<int>();
  74. }
  75. return TUnboxedValuePod(mul);
  76. }
  77. };
  78. extern const char A[] = "a";
  79. using TNamedA = TNamedArg<i32, A>;
  80. //////////////////////////////////////////////////////////////////////////////
  81. // TNamedArgUdf
  82. //////////////////////////////////////////////////////////////////////////////
  83. class TNamedArgUdf: public TBoxedValue {
  84. public:
  85. static TStringRef Name() {
  86. static auto name = TStringRef::Of("NamedArgUdf");
  87. return name;
  88. }
  89. private:
  90. TUnboxedValue Run(
  91. const IValueBuilder* valueBuilder,
  92. const TUnboxedValuePod* args) const override
  93. {
  94. Y_UNUSED(valueBuilder);
  95. auto res = args[0] ? args[0].Get<i32>() : 123;
  96. return TUnboxedValuePod(res + 1);
  97. }
  98. };
  99. //////////////////////////////////////////////////////////////////////////////
  100. // TReturnNamedArgCallable
  101. //////////////////////////////////////////////////////////////////////////////
  102. class TReturnNamedArgCallable: public TBoxedValue {
  103. public:
  104. static TStringRef Name() {
  105. static auto name = TStringRef::Of("ReturnNamedArgCallable");
  106. return name;
  107. }
  108. TUnboxedValue Run(
  109. const IValueBuilder* valueBuilder,
  110. const TUnboxedValuePod* args) const override
  111. {
  112. Y_UNUSED(valueBuilder);
  113. Y_UNUSED(args);
  114. return TUnboxedValuePod(new TNamedArgUdf());
  115. }
  116. };
  117. //////////////////////////////////////////////////////////////////////////////
  118. // TCallablesModule
  119. //////////////////////////////////////////////////////////////////////////////
  120. class TCallablesModule: public IUdfModule
  121. {
  122. public:
  123. TStringRef Name() const {
  124. return TStringRef::Of("Callables");
  125. }
  126. void CleanupOnTerminate() const final {}
  127. void GetAllFunctions(IFunctionsSink& sink) const final {
  128. sink.Add(TFromString::Name());
  129. sink.Add(TSum::Name());
  130. sink.Add(TMul::Name());
  131. }
  132. void BuildFunctionTypeInfo(
  133. const TStringRef& name,
  134. TType* userType,
  135. const TStringRef& typeConfig,
  136. ui32 flags,
  137. IFunctionTypeInfoBuilder& builder) const final
  138. {
  139. try {
  140. Y_UNUSED(userType);
  141. Y_UNUSED(typeConfig);
  142. bool typesOnly = (flags & TFlags::TypesOnly);
  143. if (TFromString::Name() == name) {
  144. // function signature:
  145. // int (String)
  146. // run config: void
  147. builder.SimpleSignature<int(char*)>();
  148. if (!typesOnly) {
  149. builder.Implementation(new TFromString);
  150. }
  151. }
  152. else if (TSum::Name() == name) {
  153. // function signature:
  154. // int (ListOf(String), int(*)(String))
  155. // run config: void
  156. builder.Returns<int>().Args()->
  157. Add(builder.List()->Item<char*>())
  158. .Add(builder.Callable()->Returns<int>().Arg<char*>())
  159. .Done();
  160. if (!typesOnly) {
  161. builder.Implementation(new TSum);
  162. }
  163. }
  164. else if (TMul::Name() == name) {
  165. // function signature:
  166. // int (ListOf(String), int(*)(String))
  167. // run config: void
  168. using TFuncType = int(*)(char*);
  169. builder.SimpleSignature<int(TListType<char*>, TFuncType)>();
  170. if (!typesOnly) {
  171. builder.Implementation(new TMul);
  172. }
  173. } else if (TNamedArgUdf::Name() == name) {
  174. builder.SimpleSignature<int(TNamedA)>();
  175. if (!typesOnly) {
  176. builder.Implementation(new TNamedArgUdf());
  177. }
  178. } else if (TReturnNamedArgCallable::Name() == name) {
  179. builder.Returns(builder.Callable()->Returns<int>().Arg<int>().Name(A));
  180. if (!typesOnly) {
  181. builder.Implementation(new TReturnNamedArgCallable());
  182. }
  183. }
  184. } catch (const std::exception& e) {
  185. builder.SetError(CurrentExceptionMessage());
  186. }
  187. }
  188. };
  189. } // namespace
  190. REGISTER_MODULES(TCallablesModule)