dummylog_udf.cpp 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193
  1. #include <yql/essentials/public/udf/udf_value.h>
  2. #include <yql/essentials/public/udf/udf_value_builder.h>
  3. #include <yql/essentials/public/udf/udf_type_builder.h>
  4. #include <yql/essentials/public/udf/udf_registrator.h>
  5. #include <util/generic/yexception.h>
  6. using namespace NKikimr;
  7. using namespace NUdf;
  8. namespace {
  9. struct TRecordInfo
  10. {
  11. ui32 Key;
  12. ui32 Subkey;
  13. ui32 Value;
  14. static constexpr ui32 FieldsCount = 3U;
  15. };
  16. //////////////////////////////////////////////////////////////////////////////
  17. // TDummyLog
  18. //////////////////////////////////////////////////////////////////////////////
  19. class TDummyLog: public TBoxedValue
  20. {
  21. public:
  22. explicit TDummyLog(
  23. const TRecordInfo& fieldIndexes)
  24. : RecordInfo_(fieldIndexes)
  25. {
  26. }
  27. private:
  28. TUnboxedValue Run(
  29. const IValueBuilder* valueBuilder,
  30. const TUnboxedValuePod* args) const override
  31. {
  32. auto keyData = args[0].GetElement(RecordInfo_.Key);
  33. auto subkeyData = args[0].GetElement(RecordInfo_.Subkey);
  34. auto valueData = args[0].GetElement(RecordInfo_.Value);
  35. TString key = TString("Key: ") + keyData.AsStringRef();
  36. TString subkey = TString("Subkey: ") + subkeyData.AsStringRef();
  37. TString value = TString("Value: ") + valueData.AsStringRef();
  38. TUnboxedValue* items = nullptr;
  39. auto res = valueBuilder->NewArray(RecordInfo_.FieldsCount, items);
  40. items[RecordInfo_.Key] = valueBuilder->NewString(key);
  41. items[RecordInfo_.Subkey] = valueBuilder->NewString(subkey);
  42. items[RecordInfo_.Value] = valueBuilder->NewString(value);
  43. return res;
  44. }
  45. const TRecordInfo RecordInfo_;
  46. };
  47. class TDummyLog2 : public TBoxedValue
  48. {
  49. public:
  50. class TFactory : public TBoxedValue {
  51. public:
  52. TFactory(const TRecordInfo& inputInfo, const TRecordInfo& outputInfo)
  53. : InputInfo_(inputInfo)
  54. , OutputInfo_(outputInfo)
  55. {}
  56. private:
  57. TUnboxedValue Run(
  58. const IValueBuilder* valueBuilder,
  59. const TUnboxedValuePod* args) const override
  60. {
  61. Y_UNUSED(valueBuilder);
  62. return TUnboxedValuePod(new TDummyLog2(args[0], InputInfo_, OutputInfo_));
  63. }
  64. const TRecordInfo InputInfo_;
  65. const TRecordInfo OutputInfo_;
  66. };
  67. explicit TDummyLog2(
  68. const TUnboxedValuePod& runConfig,
  69. const TRecordInfo& inputInfo,
  70. const TRecordInfo& outputInfo
  71. )
  72. : Prefix_(runConfig.AsStringRef())
  73. , InputInfo_(inputInfo)
  74. , OutputInfo_(outputInfo)
  75. {
  76. }
  77. private:
  78. TUnboxedValue Run(
  79. const IValueBuilder* valueBuilder,
  80. const TUnboxedValuePod* args) const override
  81. {
  82. auto keyData = args[0].GetElement(InputInfo_.Key);
  83. auto valueData = args[0].GetElement(InputInfo_.Value);
  84. TString key = Prefix_ + TString("Key: ") + keyData.AsStringRef();
  85. TString value = Prefix_ + TString("Value: ") + valueData.AsStringRef();
  86. TUnboxedValue* items = nullptr;
  87. auto res = valueBuilder->NewArray(2U, items);
  88. items[OutputInfo_.Key] = valueBuilder->NewString(key);
  89. items[OutputInfo_.Value] = valueBuilder->NewString(value);
  90. return res;
  91. }
  92. const TString Prefix_;
  93. const TRecordInfo InputInfo_;
  94. const TRecordInfo OutputInfo_;
  95. };
  96. //////////////////////////////////////////////////////////////////////////////
  97. // TDummyLogModule
  98. //////////////////////////////////////////////////////////////////////////////
  99. class TDummyLogModule: public IUdfModule
  100. {
  101. public:
  102. TStringRef Name() const {
  103. return TStringRef::Of("DummyLog");
  104. }
  105. void CleanupOnTerminate() const final {}
  106. void GetAllFunctions(IFunctionsSink& sink) const final {
  107. sink.Add(TStringRef::Of("ReadRecord"));
  108. sink.Add(TStringRef::Of("ReadRecord2"))->SetTypeAwareness();
  109. }
  110. void BuildFunctionTypeInfo(
  111. const TStringRef& name,
  112. TType* userType,
  113. const TStringRef& typeConfig,
  114. ui32 flags,
  115. IFunctionTypeInfoBuilder& builder) const final
  116. {
  117. try {
  118. Y_UNUSED(userType);
  119. Y_UNUSED(typeConfig);
  120. bool typesOnly = (flags & TFlags::TypesOnly);
  121. if (TStringRef::Of("ReadRecord") == name) {
  122. TRecordInfo recordInfo;
  123. auto recordType = builder.Struct(recordInfo.FieldsCount)->
  124. AddField<char*>("key", &recordInfo.Key)
  125. .AddField<char*>("subkey", &recordInfo.Subkey)
  126. .AddField<char*>("value", &recordInfo.Value)
  127. .Build();
  128. builder.Returns(recordType).Args()->Add(recordType).Done();
  129. if (!typesOnly) {
  130. builder.Implementation(new TDummyLog(recordInfo));
  131. }
  132. }
  133. if (TStringRef::Of("ReadRecord2") == name) {
  134. if (TStringBuf(typeConfig) != TStringBuf("AAA")) {
  135. builder.SetError(TStringRef::Of("Only AAA is valid type config"));
  136. }
  137. TRecordInfo inputInfo;
  138. auto inputType = builder.Struct(inputInfo.FieldsCount)->
  139. AddField<char*>("key", &inputInfo.Key)
  140. .AddField<char*>("subkey", &inputInfo.Subkey)
  141. .AddField<char*>("value", &inputInfo.Value)
  142. .Build();
  143. TRecordInfo outputInfo;
  144. auto outputType = builder.Struct(2U)->
  145. AddField<char*>("key", &outputInfo.Key)
  146. .AddField<char*>("value", &outputInfo.Value)
  147. .Build();
  148. builder.Returns(outputType).Args()->Add(inputType).Done();
  149. builder.RunConfig<char*>();
  150. if (!typesOnly) {
  151. builder.Implementation(new TDummyLog2::TFactory(inputInfo, outputInfo));
  152. }
  153. }
  154. } catch (const std::exception& e) {
  155. builder.SetError(CurrentExceptionMessage());
  156. }
  157. }
  158. };
  159. } // namespace
  160. REGISTER_MODULES(TDummyLogModule)