yql_makecode.cpp 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197
  1. #include "yql_makecode.h"
  2. #include "yql_type_resource.h"
  3. #include "yql_position.h"
  4. #include <yql/essentials/minikql/computation/mkql_computation_node_holders.h>
  5. #include <yql/essentials/minikql/computation/mkql_computation_node_impl.h>
  6. namespace NKikimr {
  7. namespace NMiniKQL {
  8. template <NYql::TExprNode::EType Type>
  9. struct TMakeCodeArgs;
  10. template <>
  11. struct TMakeCodeArgs<NYql::TExprNode::World> {
  12. static constexpr size_t MinValue = 0;
  13. static constexpr size_t MaxValue = 0;
  14. };
  15. template <>
  16. struct TMakeCodeArgs<NYql::TExprNode::Atom> {
  17. static constexpr size_t MinValue = 1;
  18. static constexpr size_t MaxValue = 1;
  19. };
  20. template <>
  21. struct TMakeCodeArgs<NYql::TExprNode::List> {
  22. static constexpr size_t MinValue = 0;
  23. static constexpr size_t MaxValue = Max<size_t>();
  24. };
  25. template <>
  26. struct TMakeCodeArgs<NYql::TExprNode::Callable> {
  27. static constexpr size_t MinValue = 1;
  28. static constexpr size_t MaxValue = Max<size_t>();
  29. };
  30. template <>
  31. struct TMakeCodeArgs<NYql::TExprNode::Lambda> {
  32. static constexpr size_t MinValue = 2;
  33. static constexpr size_t MaxValue = Max<size_t>();
  34. };
  35. template <NYql::TExprNode::EType Type>
  36. class TMakeCodeWrapper : public TMutableComputationNode<TMakeCodeWrapper<Type>> {
  37. typedef TMutableComputationNode<TMakeCodeWrapper<Type>> TBaseComputation;
  38. public:
  39. TMakeCodeWrapper(TComputationMutables& mutables, TVector<IComputationNode*>&& args, ui32 exprCtxMutableIndex, NYql::TPosition pos)
  40. : TBaseComputation(mutables)
  41. , Args_(std::move(args))
  42. , ExprCtxMutableIndex_(exprCtxMutableIndex)
  43. , Pos_(pos)
  44. {}
  45. NUdf::TUnboxedValue DoCalculate(TComputationContext& ctx) const {
  46. auto exprCtxPtr = GetExprContextPtr(ctx, ExprCtxMutableIndex_);
  47. NYql::TExprNode::TPtr retNode;
  48. switch (Type) {
  49. case NYql::TExprNode::Atom: {
  50. auto strValue = Args_[0]->GetValue(ctx);
  51. retNode = exprCtxPtr->NewAtom(Pos_, strValue.AsStringRef());
  52. break;
  53. }
  54. case NYql::TExprNode::List: {
  55. NYql::TExprNode::TListType items;
  56. for (ui32 i = 0; i < Args_.size(); ++i) {
  57. auto argValue = Args_[i]->GetValue(ctx);
  58. auto iter = argValue.GetListIterator();
  59. NUdf::TUnboxedValue codeValue;
  60. while (iter.Next(codeValue)) {
  61. auto code = GetYqlCode(codeValue);
  62. items.push_back(code);
  63. }
  64. }
  65. retNode = exprCtxPtr->NewList(Pos_, std::move(items));
  66. break;
  67. }
  68. case NYql::TExprNode::Callable: {
  69. NYql::TExprNode::TListType items;
  70. auto strValue = Args_[0]->GetValue(ctx);
  71. for (ui32 i = 1; i < Args_.size(); ++i) {
  72. auto argValue = Args_[i]->GetValue(ctx);
  73. auto iter = argValue.GetListIterator();
  74. NUdf::TUnboxedValue codeValue;
  75. while (iter.Next(codeValue)) {
  76. auto code = GetYqlCode(codeValue);
  77. items.push_back(code);
  78. }
  79. }
  80. retNode = exprCtxPtr->NewCallable(Pos_, strValue.AsStringRef(), std::move(items));
  81. break;
  82. }
  83. case NYql::TExprNode::Lambda: {
  84. auto countValue = Args_[0]->GetValue(ctx);
  85. const bool fixedArgs = !countValue;
  86. const ui32 argsCount = fixedArgs ? Args_.size() - 2 : countValue.template Get<ui32>();
  87. NYql::TExprNode::TListType argNodes;
  88. for (ui32 i = 0; i < argsCount; ++i) {
  89. argNodes.push_back(exprCtxPtr->NewArgument(Pos_, "arg" + ToString(i)));
  90. }
  91. auto argsNode = exprCtxPtr->NewArguments(Pos_, std::move(argNodes));
  92. // fill external nodes with arguments
  93. if (fixedArgs) {
  94. for (ui32 i = 0; i < argsCount; ++i) {
  95. auto arg = argsNode->ChildPtr(i);
  96. dynamic_cast<IComputationExternalNode*>(Args_[i + 1])->SetValue(ctx,
  97. NUdf::TUnboxedValuePod(new TYqlCodeResource(exprCtxPtr, arg)));
  98. }
  99. } else {
  100. NUdf::TUnboxedValue* inplace = nullptr;
  101. NUdf::TUnboxedValue array = ctx.HolderFactory.CreateDirectArrayHolder(argsCount, inplace);
  102. for (ui32 i = 0; i < argsCount; ++i) {
  103. auto arg = argsNode->ChildPtr(i);
  104. inplace[i] = NUdf::TUnboxedValuePod(new TYqlCodeResource(exprCtxPtr, arg));
  105. }
  106. dynamic_cast<IComputationExternalNode*>(Args_[1])->SetValue(ctx, std::move(array));
  107. }
  108. // get body of lambda
  109. auto bodyValue = Args_.back()->GetValue(ctx);
  110. retNode = exprCtxPtr->NewLambda(Pos_, std::move(argsNode), GetYqlCode(bodyValue));
  111. break;
  112. }
  113. case NYql::TExprNode::World: {
  114. retNode = exprCtxPtr->NewWorld(Pos_);
  115. break;
  116. }
  117. default:
  118. MKQL_ENSURE(false, "Unsupported type:" << Type);
  119. }
  120. return NUdf::TUnboxedValuePod(new TYqlCodeResource(exprCtxPtr, retNode));
  121. }
  122. void RegisterDependencies() const override {
  123. if (Type == NYql::TExprNode::Lambda) {
  124. this->DependsOn(Args_.front());
  125. for (size_t i = 1; i < Args_.size() - 1; ++i) {
  126. this->Own(dynamic_cast<IComputationExternalNode*>(Args_[i]));
  127. }
  128. this->DependsOn(Args_.back());
  129. } else {
  130. for (auto arg : Args_) {
  131. this->DependsOn(arg);
  132. }
  133. }
  134. }
  135. private:
  136. TVector<IComputationNode*> Args_;
  137. ui32 ExprCtxMutableIndex_;
  138. NYql::TPosition Pos_;
  139. };
  140. template <NYql::TExprNode::EType Type>
  141. IComputationNode* WrapMakeCode(TCallable& callable, const TComputationNodeFactoryContext& ctx, ui32 exprCtxMutableIndex) {
  142. constexpr size_t expectedMinArgsCount = 3 + TMakeCodeArgs<Type>::MinValue;
  143. constexpr size_t expectedMaxArgsCount = TMakeCodeArgs<Type>::MaxValue != Max<size_t>() ?
  144. 3 + TMakeCodeArgs<Type>::MaxValue : Max<size_t>();
  145. MKQL_ENSURE(callable.GetInputsCount() >= expectedMinArgsCount
  146. && callable.GetInputsCount() <= expectedMaxArgsCount, "Expected from " << expectedMinArgsCount << " to "
  147. << expectedMaxArgsCount << " arg(s), but got: " << callable.GetInputsCount());
  148. auto pos = ExtractPosition(callable);
  149. TVector<IComputationNode*> args;
  150. args.reserve(callable.GetInputsCount() - 3);
  151. for (size_t i = 0; i < callable.GetInputsCount() - 3; ++i) {
  152. args.push_back(LocateNode(ctx.NodeLocator, callable, i + 3));
  153. }
  154. return new TMakeCodeWrapper<Type>(ctx.Mutables, std::move(args), exprCtxMutableIndex, pos);
  155. }
  156. template IComputationNode* WrapMakeCode<NYql::TExprNode::World>
  157. (TCallable& callable, const TComputationNodeFactoryContext& ctx, ui32 exprCtxMutableIndex);
  158. template IComputationNode* WrapMakeCode<NYql::TExprNode::Atom>
  159. (TCallable& callable, const TComputationNodeFactoryContext& ctx, ui32 exprCtxMutableIndex);
  160. template IComputationNode* WrapMakeCode<NYql::TExprNode::List>
  161. (TCallable& callable, const TComputationNodeFactoryContext& ctx, ui32 exprCtxMutableIndex);
  162. template IComputationNode* WrapMakeCode<NYql::TExprNode::Callable>
  163. (TCallable& callable, const TComputationNodeFactoryContext& ctx, ui32 exprCtxMutableIndex);
  164. template IComputationNode* WrapMakeCode<NYql::TExprNode::Lambda>
  165. (TCallable& callable, const TComputationNodeFactoryContext& ctx, ui32 exprCtxMutableIndex);
  166. }
  167. }