aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoruzhas <uzhas@ydb.tech>2022-09-28 21:05:21 +0300
committeruzhas <uzhas@ydb.tech>2022-09-28 21:05:21 +0300
commitf063daeadff3ceacd9cde94a6b6e1f47d4d77edc (patch)
tree967dc89a4393571562f0d819d9c280eaba10b48c
parentce67eb7f501987256b2d6fa5dd7dfb79fa5f49c8 (diff)
downloadydb-f063daeadff3ceacd9cde94a6b6e1f47d4d77edc.tar.gz
pg binding: move common logic to separate func
-rw-r--r--ydb/library/yql/sql/pg/pg_sql.cpp74
-rw-r--r--ydb/library/yql/sql/settings/partitioning.cpp63
-rw-r--r--ydb/library/yql/sql/settings/partitioning.h12
-rw-r--r--ydb/library/yql/sql/v1/sql.cpp76
4 files changed, 96 insertions, 129 deletions
diff --git a/ydb/library/yql/sql/pg/pg_sql.cpp b/ydb/library/yql/sql/pg/pg_sql.cpp
index 5bec2f4f13e..1766600b424 100644
--- a/ydb/library/yql/sql/pg/pg_sql.cpp
+++ b/ydb/library/yql/sql/pg/pg_sql.cpp
@@ -1253,82 +1253,30 @@ public:
TAstNode* BuildBindingSource(const RangeVar* value) {
const TString binding = value->relname;
- auto pit = Settings.PrivateBindings.find(binding);
- auto sit = Settings.ScopedBindings.find(binding);
-
- if (pit == Settings.PrivateBindings.end() && sit == Settings.ScopedBindings.end()) {
- AddError(TStringBuilder() << "Table binding `" << binding << "` is not defined");
+ NSQLTranslation::TBindingInfo bindingInfo;
+ if (const auto& error = ExtractBindingInfo(Settings, binding, bindingInfo)) {
+ AddError(error);
return nullptr;
}
-
- const auto& bindSettings = (pit != Settings.PrivateBindings.end()) ? pit->second : sit->second;
-
- // ordered map ensures AST stability
- std::map<TString, TString> kvs(bindSettings.Settings.begin(), bindSettings.Settings.end());
- auto pullSettingOrFail = [&](const TString& name, TString& value) -> bool {
- auto it = kvs.find(name);
- if (it == kvs.end()) {
- AddError(TStringBuilder() << name << " is not found for " << binding);
- return false;
- }
- value = it->second;
- kvs.erase(it);
- return true;
- };
-
- TString cluster;
- TString path;
- TString format;
-
- if (!pullSettingOrFail("cluster", cluster) ||
- !pullSettingOrFail("path", path) ||
- !pullSettingOrFail("format", format)) {
- return nullptr;
- }
-
TVector<TAstNode*> hints;
- if (auto it = kvs.find("schema"); it != kvs.end()) {
- auto schema = QA(it->second);
+ if (bindingInfo.Schema) {
+ auto schema = QA(bindingInfo.Schema);
auto type = L(A("SqlTypeFromYson"), schema);
auto columns = L(A("SqlColumnOrderFromYson"), schema);
hints.emplace_back(QL(QA("userschema"), type, columns));
- kvs.erase(it);
}
- if (auto it = kvs.find("partitioned_by"); it != kvs.end()) {
- TVector<TString> columns;
- if (const TString& error = NSQLTranslation::ParsePartitionedByBinding(it->first, it->second, columns)) {
- AddError(error);
- }
+ for (auto& [key, value] : bindingInfo.Attributes) {
TVector<TAstNode*> hintValues;
- hintValues.push_back(QA("partitionedby"));
- for (auto& column : columns) {
- hintValues.push_back(QA(column));
+ hintValues.push_back(QA(key));
+ for (auto& v : value) {
+ hintValues.push_back(QA(v));
}
hints.emplace_back(QVL(hintValues.data(), hintValues.size()));
- kvs.erase(it);
- }
-
- // put format back to hints
- kvs["format"] = format;
-
- for (auto& [key, value] : kvs) {
- if (!key) {
- AddError(TStringBuilder() << "Hint key should not be empty");
- return nullptr;
- }
-
- hints.emplace_back(QL(QA(key), QA(value)));
- }
-
- auto p = Settings.ClusterMapping.FindPtr(cluster);
- if (!p) {
- AddError(TStringBuilder() << "Unknown cluster: " << cluster);
- return nullptr;
}
- auto source = L(A("DataSource"), QAX(*p), QAX(cluster));
+ auto source = L(A("DataSource"), QAX(bindingInfo.ClusterType), QAX(bindingInfo.Cluster));
return L(
A("Read!"),
A("world"),
@@ -1341,7 +1289,7 @@ public:
QA("table"),
L(
A("String"),
- QAX(path)
+ QAX(bindingInfo.Path)
)
)
)
diff --git a/ydb/library/yql/sql/settings/partitioning.cpp b/ydb/library/yql/sql/settings/partitioning.cpp
index 49e84a855fd..adc65973dba 100644
--- a/ydb/library/yql/sql/settings/partitioning.cpp
+++ b/ydb/library/yql/sql/settings/partitioning.cpp
@@ -1,8 +1,11 @@
#include "partitioning.h"
+#include <ydb/library/yql/providers/common/provider/yql_provider_names.h>
#include <library/cpp/json/json_reader.h>
+#include <util/generic/is_in.h>
#include <util/string/builder.h>
namespace NSQLTranslation {
+namespace {
TString ParsePartitionedByBinding(const TString& name, const TString& value, TVector<TString>& columns) {
using namespace NJson;
@@ -32,4 +35,64 @@ TString ParsePartitionedByBinding(const TString& name, const TString& value, TVe
return {};
}
+}
+
+TString ExtractBindingInfo(const TTranslationSettings& settings, const TString& binding, TBindingInfo& result) {
+ auto pit = settings.PrivateBindings.find(binding);
+ auto sit = settings.ScopedBindings.find(binding);
+
+ if (pit == settings.PrivateBindings.end() && sit == settings.ScopedBindings.end()) {
+ return TStringBuilder() << "Table binding `" << binding << "` is not defined";
+ }
+
+ const auto& bindSettings = (pit != settings.PrivateBindings.end()) ? pit->second : sit->second;
+
+ if (!IsIn({NYql::S3ProviderName, NYql::PqProviderName}, bindSettings.ClusterType)) {
+ return TStringBuilder() << "Cluster type " << bindSettings.ClusterType << " is not supported for table bindings";
+ }
+ result.ClusterType = bindSettings.ClusterType;
+
+ // ordered map ensures AST stability
+ TMap<TString, TString> kvs(bindSettings.Settings.begin(), bindSettings.Settings.end());
+ auto pullSettingOrFail = [&](const TString& name, TString& value) -> TString {
+ auto it = kvs.find(name);
+ if (it == kvs.end()) {
+ return TStringBuilder() << name << " is not found for " << binding;
+ }
+ value = it->second;
+ kvs.erase(it);
+ return {};
+ };
+
+ if (const auto& error = pullSettingOrFail("cluster", result.Cluster)) {
+ return error;
+ }
+ if (const auto& error = pullSettingOrFail("path", result.Path)) {
+ return error;
+ }
+
+ if (auto it = kvs.find("schema"); it != kvs.end()) {
+ result.Schema = it->second;
+ kvs.erase(it);
+ }
+
+ if (auto it = kvs.find("partitioned_by"); it != kvs.end()) {
+ TVector<TString> columns;
+ if (const auto& error = ParsePartitionedByBinding(it->first, it->second, columns)) {
+ return error;
+ }
+ result.Attributes.emplace("partitionedby", std::move(columns));
+ kvs.erase(it);
+ }
+
+ for (auto& [key, value] : kvs) {
+ if (key.empty()) {
+ return "Attribute should not be empty";
+ }
+ result.Attributes.emplace(key, TVector<TString>{value});
+ }
+
+ return {};
+}
+
} // namespace NSQLTranslation
diff --git a/ydb/library/yql/sql/settings/partitioning.h b/ydb/library/yql/sql/settings/partitioning.h
index db825aa95ee..082890ae153 100644
--- a/ydb/library/yql/sql/settings/partitioning.h
+++ b/ydb/library/yql/sql/settings/partitioning.h
@@ -1,9 +1,19 @@
#pragma once
+#include "translation_settings.h"
+#include <util/generic/map.h>
#include <util/generic/string.h>
#include <util/generic/vector.h>
namespace NSQLTranslation {
+ struct TBindingInfo {
+ TString ClusterType;
+ TString Cluster;
+ TString Path;
+ TString Schema;
+ TMap<TString, TVector<TString>> Attributes;
+ };
+
// returns error message if any
- TString ParsePartitionedByBinding(const TString& name, const TString& value, TVector<TString>& columns);
+ TString ExtractBindingInfo(const TTranslationSettings& settings, const TString& binding, TBindingInfo& result);
} // namespace NSQLTranslation
diff --git a/ydb/library/yql/sql/v1/sql.cpp b/ydb/library/yql/sql/v1/sql.cpp
index fa36b157203..ad5a388a2bf 100644
--- a/ydb/library/yql/sql/v1/sql.cpp
+++ b/ydb/library/yql/sql/v1/sql.cpp
@@ -1468,88 +1468,34 @@ bool TSqlTranslation::ClusterExpr(const TRule_cluster_expr& node, bool allowWild
bool ExprList(TSqlExpression& sqlExpr, TVector<TNodePtr>& exprNodes, const TRule_expr_list& node);
bool TSqlTranslation::ApplyTableBinding(const TString& binding, TTableRef& tr, TTableHints& hints) {
- const auto& settings = Context().Settings;
- auto pit = settings.PrivateBindings.find(binding);
- auto sit = settings.ScopedBindings.find(binding);
-
- if (pit == settings.PrivateBindings.end() && sit == settings.ScopedBindings.end()) {
- Ctx.Error() << "Table binding `" << binding << "` is not defined";
+ NSQLTranslation::TBindingInfo bindingInfo;
+ if (const auto& error = ExtractBindingInfo(Context().Settings, binding, bindingInfo)) {
+ Ctx.Error() << error;
return false;
}
- if (pit != settings.PrivateBindings.end() && sit != settings.ScopedBindings.end()) {
- // warn
- Ctx.Warning(Ctx.Pos(),
- TIssuesIds::YQL_TABLE_BINDING_DUPLICATE) << "Table binding `" << binding << "` is defined both as private and scoped binding";
- }
-
- const auto& bindSettings = (pit != settings.PrivateBindings.end()) ? pit->second : sit->second;
-
- if (!IsIn({S3ProviderName, PqProviderName}, bindSettings.ClusterType)) {
- Ctx.Error() << "Cluster type " << bindSettings.ClusterType << " is not supported for table bindings";
- return false;
- }
-
- // ordered map ensures AST stability
- TMap<TString, TString> kvs(bindSettings.Settings.begin(), bindSettings.Settings.end());
- auto pullSettingOrFail = [&](const TString& name, TString& value) -> bool {
- auto it = kvs.find(name);
- if (it == kvs.end()) {
- Ctx.Error() << name << " is not found for " << binding;
- return false;
- }
- value = it->second;
- kvs.erase(it);
- return true;
- };
-
- TString cluster;
- TString path;
- TString format;
-
- if (!pullSettingOrFail("cluster", cluster) ||
- !pullSettingOrFail("path", path) ||
- !pullSettingOrFail("format", format))
- {
- return false;
- }
-
- if (auto it = kvs.find("schema"); it != kvs.end()) {
- TNodePtr schema = BuildQuotedAtom(Ctx.Pos(), it->second);
+ if (bindingInfo.Schema) {
+ TNodePtr schema = BuildQuotedAtom(Ctx.Pos(), bindingInfo.Schema);
TNodePtr type = new TCallNodeImpl(Ctx.Pos(), "SqlTypeFromYson", { schema });
TNodePtr columns = new TCallNodeImpl(Ctx.Pos(), "SqlColumnOrderFromYson", { schema });
hints["user_schema"] = { type, columns };
- kvs.erase(it);
}
- if (auto it = kvs.find("partitioned_by"); it != kvs.end()) {
- TVector<TString> columns;
- if (const auto& error = NSQLTranslation::ParsePartitionedByBinding(it->first, it->second, columns)) {
- Ctx.Error() << error;
- return false;
- }
+ for (auto& [key, values] : bindingInfo.Attributes) {
TVector<TNodePtr> hintValue;
- for (auto& column : columns) {
+ for (auto& column : values) {
hintValue.push_back(BuildQuotedAtom(Ctx.Pos(), column));
}
- hints[it->first] = std::move(hintValue);
- kvs.erase(it);
+ hints[key] = std::move(hintValue);
}
- tr.Service = bindSettings.ClusterType;
- tr.Cluster = TDeferredAtom(Ctx.Pos(), cluster);
- // put format back to hints
- kvs["format"] = format;
-
- for (auto& [key, value] : kvs) {
- YQL_ENSURE(!key.empty());
- hints[key] = { BuildQuotedAtom(Ctx.Pos(), value) };
- }
+ tr.Service = bindingInfo.ClusterType;
+ tr.Cluster = TDeferredAtom(Ctx.Pos(), bindingInfo.Cluster);
const TString view = "";
- tr.Keys = BuildTableKey(Ctx.Pos(), tr.Service, tr.Cluster, TDeferredAtom(Ctx.Pos(), path), view);
+ tr.Keys = BuildTableKey(Ctx.Pos(), tr.Service, tr.Cluster, TDeferredAtom(Ctx.Pos(), bindingInfo.Path), view);
return true;
}