yql_exec.cpp 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. #include "yql_exec.h"
  2. #include <yql/essentials/core/yql_execution.h>
  3. #include <yql/essentials/utils/log/log.h>
  4. #include <yql/essentials/utils/yql_panic.h>
  5. #include <util/string/builder.h>
  6. #include <util/generic/vector.h>
  7. #include <util/generic/string.h>
  8. namespace NYql {
  9. using namespace NNodes;
  10. TExecTransformerBase::TStatusCallbackPair TExecTransformerBase::CallbackTransform(const TExprNode::TPtr& input, TExprNode::TPtr& output, TExprContext& ctx) {
  11. YQL_ENSURE(input->Type() == TExprNode::Callable);
  12. output = input;
  13. if (auto handlerInfo = Handlers.FindPtr(input->Content())) {
  14. auto status = (handlerInfo->Prerequisite)(input);
  15. if (status.Level != TStatus::Ok) {
  16. return SyncStatus(status);
  17. }
  18. TString uniqId = TStringBuilder() << '#' << input->UniqueId();
  19. YQL_LOG_CTX_SCOPE(uniqId);
  20. return (handlerInfo->Handler)(input, output, ctx);
  21. }
  22. ctx.AddError(TIssue(ctx.GetPosition(input->Pos()), TStringBuilder() << "Don't know how to execute node: " << input->Content()));
  23. return SyncError();
  24. }
  25. void TExecTransformerBase::AddHandler(std::initializer_list<TStringBuf> names, TPrerequisite prerequisite, THandler handler) {
  26. THandlerInfo info;
  27. info.Handler = std::move(handler);
  28. info.Prerequisite = std::move(prerequisite);
  29. for (auto name: names) {
  30. YQL_ENSURE(Handlers.emplace(name, info).second, "Duplicate execution handler for " << name);
  31. }
  32. }
  33. TExecTransformerBase::THandler TExecTransformerBase::Pass() {
  34. return [] (const TExprNode::TPtr& input, TExprNode::TPtr& /*output*/, TExprContext& ctx) {
  35. return ExecPass(input, ctx);
  36. };
  37. }
  38. TExecTransformerBase::TStatusCallbackPair TExecTransformerBase::ExecPass(const TExprNode::TPtr& input, TExprContext& ctx) {
  39. input->SetState(TExprNode::EState::ExecutionComplete);
  40. input->SetResult(ctx.NewWorld(input->Pos()));
  41. return SyncOk();
  42. }
  43. TExecTransformerBase::TPrerequisite TExecTransformerBase::RequireAll() {
  44. return [] (const TExprNode::TPtr& input) {
  45. TStatus combinedStatus = TStatus::Ok;
  46. for (size_t i = 0; i < input->ChildrenSize(); ++i) {
  47. combinedStatus = combinedStatus.Combine(RequireChild(*input, (ui32)i));
  48. }
  49. return combinedStatus;
  50. };
  51. }
  52. TExecTransformerBase::TPrerequisite TExecTransformerBase::RequireNone() {
  53. return [] (const TExprNode::TPtr& /*input*/) {
  54. return TStatus::Ok;
  55. };
  56. }
  57. TExecTransformerBase::TPrerequisite TExecTransformerBase::RequireFirst() {
  58. return [] (const TExprNode::TPtr& input) {
  59. return RequireChild(*input, 0);
  60. };
  61. }
  62. TExecTransformerBase::TPrerequisite TExecTransformerBase::RequireAllOf(std::initializer_list<size_t> children) {
  63. return [required = TVector<size_t>(children)] (const TExprNode::TPtr& input) {
  64. TStatus combinedStatus = TStatus::Ok;
  65. for (size_t i: required) {
  66. YQL_ENSURE(i < input->ChildrenSize());
  67. combinedStatus = combinedStatus.Combine(RequireChild(*input, (ui32)i));
  68. }
  69. return combinedStatus;
  70. };
  71. }
  72. TExecTransformerBase::TPrerequisite TExecTransformerBase::RequireSequenceOf(std::initializer_list<size_t> children) {
  73. return [required = TVector<size_t>(children)] (const TExprNode::TPtr& input) -> TStatus {
  74. for (size_t i: required) {
  75. YQL_ENSURE(i < input->ChildrenSize());
  76. auto status = RequireChild(*input, (ui32)i);
  77. if (status.Level != TStatus::Ok) {
  78. return status;
  79. }
  80. }
  81. return TStatus::Ok;
  82. };
  83. }
  84. }