yql_configuration_transformer.cpp 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164
  1. #include "yql_configuration_transformer.h"
  2. #include <yql/essentials/core/yql_graph_transformer.h>
  3. #include <yql/essentials/core/yql_expr_optimize.h>
  4. #include <yql/essentials/core/yql_expr_type_annotation.h>
  5. #include <yql/essentials/core/expr_nodes/yql_expr_nodes.h>
  6. #include <util/generic/maybe.h>
  7. #include <util/string/vector.h>
  8. namespace NYql {
  9. namespace NCommon {
  10. using namespace NNodes;
  11. TProviderConfigurationTransformer::TProviderConfigurationTransformer(TSettingDispatcher::TPtr dispatcher,
  12. const TTypeAnnotationContext& types, const TString& provider, const THashSet<TStringBuf>& configureCallables)
  13. : Dispatcher(dispatcher)
  14. , Types(types)
  15. , Provider(provider)
  16. , ConfigureCallables(configureCallables)
  17. {
  18. if (ConfigureCallables.empty()) {
  19. ConfigureCallables.insert(TCoConfigure::CallableName());
  20. }
  21. }
  22. IGraphTransformer::TStatus TProviderConfigurationTransformer::DoTransform(TExprNode::TPtr input,
  23. TExprNode::TPtr& output, TExprContext& ctx)
  24. {
  25. output = input;
  26. if (ctx.Step.IsDone(TExprStep::Configure)) {
  27. return TStatus::Ok;
  28. }
  29. TOptimizeExprSettings settings(nullptr);
  30. settings.VisitChanges = true;
  31. auto status = OptimizeExpr(input, output, [&](const TExprNode::TPtr& node, TExprContext& ctx) -> TExprNode::TPtr {
  32. if (node->IsCallable(ConfigureCallables)) {
  33. if (!EnsureMinArgsCount(*node, 2, ctx)) {
  34. return nullptr;
  35. }
  36. if (!TCoDataSource::Match(node->Child(TCoConfigure::idx_DataSource))) {
  37. return node;
  38. }
  39. auto ds = node->Child(TCoConfigure::idx_DataSource);
  40. if (ds->Child(TCoDataSource::idx_Category)->Content() != Provider) {
  41. return node;
  42. }
  43. if (!EnsureMinArgsCount(*ds, 2, ctx)) {
  44. return nullptr;
  45. }
  46. if (!EnsureAtom(*ds->Child(1), ctx)) {
  47. return nullptr;
  48. }
  49. auto clusterName = TString(ds->Child(1)->Content());
  50. if (!EnsureMinArgsCount(*node, 3, ctx)) {
  51. return nullptr;
  52. }
  53. if (!EnsureAtom(*node->Child(2), ctx)) {
  54. return nullptr;
  55. }
  56. auto atom = node->Child(2)->Content();
  57. if (atom == TStringBuf("Attr")) {
  58. if (!EnsureMinArgsCount(*node, 4, ctx)) {
  59. return nullptr;
  60. }
  61. if (!EnsureMaxArgsCount(*node, 5, ctx)) {
  62. return nullptr;
  63. }
  64. if (!EnsureAtom(*node->Child(3), ctx)) {
  65. return nullptr;
  66. }
  67. auto name = TString(node->Child(3)->Content());
  68. if (name.StartsWith('_')) {
  69. ctx.AddError(TIssue(ctx.GetPosition(node->Child(3)->Pos()),
  70. TStringBuilder() << "Failed to override system setting: " << name));
  71. return nullptr;
  72. }
  73. TMaybe<TString> value;
  74. if (node->ChildrenSize() == 5) {
  75. if (node->Child(4)->IsCallable("EvaluateAtom")) {
  76. return node;
  77. }
  78. if (!EnsureAtom(*node->Child(4), ctx)) {
  79. return nullptr;
  80. }
  81. value = TString(node->Child(4)->Content());
  82. }
  83. if (!HandleAttr(node->Child(3)->Pos(), clusterName, name, value, ctx)) {
  84. return nullptr;
  85. }
  86. } else if (atom == TStringBuf("Auth")) {
  87. if (!EnsureArgsCount(*node, 4, ctx)) {
  88. return nullptr;
  89. }
  90. if (!EnsureAtom(*node->Child(3), ctx)) {
  91. return nullptr;
  92. }
  93. auto credAlias = TString(node->Child(3)->Content());
  94. if (!HandleAuth(node->Child(3)->Pos(), clusterName, credAlias, ctx)) {
  95. return nullptr;
  96. }
  97. } else {
  98. ctx.AddError(TIssue(ctx.GetPosition(node->Child(2)->Pos()), TStringBuilder()
  99. << "Unsupported configuration option: " << atom));
  100. return nullptr;
  101. }
  102. }
  103. return node;
  104. }, ctx, settings);
  105. return status;
  106. }
  107. bool TProviderConfigurationTransformer::HandleAttr(TPositionHandle pos, const TString& cluster, const TString& name,
  108. const TMaybe<TString>& value, TExprContext& ctx)
  109. {
  110. Y_UNUSED(pos);
  111. Y_UNUSED(ctx);
  112. return Dispatcher->Dispatch(cluster, name, value, TSettingDispatcher::EStage::STATIC, TSettingDispatcher::GetErrorCallback(pos, ctx));
  113. }
  114. bool TProviderConfigurationTransformer::HandleAuth(TPositionHandle pos, const TString& cluster, const TString& alias,
  115. TExprContext& ctx)
  116. {
  117. auto cred = Types.Credentials->FindCredential(alias);
  118. if (!cred) {
  119. ctx.AddError(TIssue(ctx.GetPosition(pos), TStringBuilder() << "Unknown credential: " << alias));
  120. return false;
  121. }
  122. if (cred->Category != Provider) {
  123. ctx.AddError(TIssue(ctx.GetPosition(pos), TStringBuilder()
  124. << "Mismatch credential category, expected: "
  125. << Provider << ", but found: " << cred->Category));
  126. return false;
  127. }
  128. return Dispatcher->Dispatch(cluster, "Auth", cred->Content, TSettingDispatcher::EStage::STATIC, TSettingDispatcher::GetErrorCallback(pos, ctx));
  129. }
  130. THolder<IGraphTransformer> CreateProviderConfigurationTransformer(
  131. TSettingDispatcher::TPtr dispatcher,
  132. const TTypeAnnotationContext& types,
  133. const TString& provider) {
  134. return THolder(new TProviderConfigurationTransformer(dispatcher, types, provider));
  135. }
  136. } // namespace NCommon
  137. } // namespace NYql