aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorvvvv <vvvv@ydb.tech>2023-06-30 13:15:06 +0300
committervvvv <vvvv@ydb.tech>2023-06-30 13:15:06 +0300
commit94e9dfa9f438035e679983171e79340ea85a7f2d (patch)
treebd9a25a554a7e7465e28d98c163a909c5a15e770
parentfc83a97aeeb5f273651b72e2c8973b4e976e6352 (diff)
downloadydb-94e9dfa9f438035e679983171e79340ea85a7f2d.tar.gz
File isolation option for SQL translation (used in view)
в 2 внешних тестах были усеченные результаты в тестах UDF, поэтому в канонизацию попал путь к временной таблице, который поменялся из-за другого паттерна выделения random.
-rw-r--r--ydb/library/yql/core/common_opt/yql_co_simple1.cpp25
-rw-r--r--ydb/library/yql/core/yql_expr_type_annotation.cpp20
-rw-r--r--ydb/library/yql/core/yql_expr_type_annotation.h2
-rw-r--r--ydb/library/yql/providers/common/provider/yql_data_provider_impl.cpp24
-rw-r--r--ydb/library/yql/providers/common/provider/yql_data_provider_impl.h2
-rw-r--r--ydb/library/yql/providers/dq/provider/yql_dq_datasource.cpp46
-rw-r--r--ydb/library/yql/providers/result/provider/yql_result_provider.cpp44
-rw-r--r--ydb/library/yql/sql/settings/translation_settings.h1
-rw-r--r--ydb/library/yql/sql/v1/builtin.cpp41
-rw-r--r--ydb/library/yql/sql/v1/context.cpp6
-rw-r--r--ydb/library/yql/sql/v1/node.cpp18
-rw-r--r--ydb/library/yql/sql/v1/node.h4
-rw-r--r--ydb/library/yql/sql/v1/sql.cpp16
13 files changed, 182 insertions, 67 deletions
diff --git a/ydb/library/yql/core/common_opt/yql_co_simple1.cpp b/ydb/library/yql/core/common_opt/yql_co_simple1.cpp
index f616897514..4fd179f6f2 100644
--- a/ydb/library/yql/core/common_opt/yql_co_simple1.cpp
+++ b/ydb/library/yql/core/common_opt/yql_co_simple1.cpp
@@ -1052,11 +1052,26 @@ TExprNode::TPtr ExtractMember(const TExprNode& node) {
}
template <bool RightOrLeft>
-TExprNode::TPtr OptimizeDirection(const TExprNode::TPtr& node) {
+TExprNode::TPtr OptimizeDirection(const TExprNode::TPtr& node, TExprContext& ctx) {
if (node->Head().IsCallable(ConsName)) {
- YQL_CLOG(DEBUG, Core) << node->Content() << " over " << node->Head().Content();
- return RightOrLeft ? node->Head().TailPtr() : node->Head().HeadPtr();
+ if (!RightOrLeft || node->Head().Head().Type() == TExprNode::World) {
+ YQL_CLOG(DEBUG, Core) << node->Content() << " over " << node->Head().Content();
+ return RightOrLeft ? node->Head().TailPtr() : node->Head().HeadPtr();
+ }
+
+ if (RightOrLeft && node->Head().Tail().IsCallable(RightName)) {
+ YQL_CLOG(DEBUG, Core) << node->Content() << " over " << node->Head().Content();
+ const auto& right = node->Head().Tail();
+ const auto& read = right.Head();
+ auto sync = ctx.NewCallable(node->Pos(), "Sync!", {
+ node->Head().HeadPtr(),
+ read.HeadPtr(),
+ });
+
+ return ctx.ChangeChild(*node, 0, ctx.ChangeChild(read, 0, std::move(sync)));
+ }
}
+
return node;
}
@@ -4777,8 +4792,8 @@ void RegisterCoSimpleCallables1(TCallableOptimizerMap& map) {
return node;
};
- map[LeftName] = std::bind(&OptimizeDirection<false>, _1);
- map[RightName] = std::bind(&OptimizeDirection<true>, _1);
+ map[LeftName] = std::bind(&OptimizeDirection<false>, _1, _2);
+ map[RightName] = std::bind(&OptimizeDirection<true>, _1, _2);
map["Apply"] = [](const TExprNode::TPtr& node, TExprContext& /*ctx*/, TOptimizeContext& /*optCtx*/) {
auto ret = FoldYsonParseAfterSerialize(node);
diff --git a/ydb/library/yql/core/yql_expr_type_annotation.cpp b/ydb/library/yql/core/yql_expr_type_annotation.cpp
index 41f4a7db53..4ca8c7ab1d 100644
--- a/ydb/library/yql/core/yql_expr_type_annotation.cpp
+++ b/ydb/library/yql/core/yql_expr_type_annotation.cpp
@@ -4496,7 +4496,7 @@ EDataSlot GetDateTypeByLevel(ui32 level) {
}
}
-bool IsPureIsolatedLambdaImpl(const TExprNode& lambdaBody, TNodeSet& visited) {
+bool IsPureIsolatedLambdaImpl(const TExprNode& lambdaBody, TNodeSet& visited, TSyncMap* syncList) {
if (!visited.emplace(&lambdaBody).second) {
return true;
}
@@ -4505,12 +4505,24 @@ bool IsPureIsolatedLambdaImpl(const TExprNode& lambdaBody, TNodeSet& visited) {
return true;
}
+ if (syncList) {
+ if (auto right = TMaybeNode<TCoRight>(&lambdaBody)) {
+ auto cons = right.Cast().Input().Maybe<TCoCons>();
+ if (!cons) {
+ return false;
+ }
+
+ syncList->emplace(cons.Cast().World().Ptr(), syncList->size());
+ return IsPureIsolatedLambdaImpl(cons.Cast().Input().Ref(), visited, syncList);
+ }
+ }
+
if (!lambdaBody.GetTypeAnn()->IsComposable()) {
return false;
}
for (auto& child : lambdaBody.Children()) {
- if (!IsPureIsolatedLambdaImpl(*child, visited)) {
+ if (!IsPureIsolatedLambdaImpl(*child, visited, syncList)) {
return false;
}
}
@@ -4518,9 +4530,9 @@ bool IsPureIsolatedLambdaImpl(const TExprNode& lambdaBody, TNodeSet& visited) {
return true;
}
-bool IsPureIsolatedLambda(const TExprNode& lambdaBody) {
+bool IsPureIsolatedLambda(const TExprNode& lambdaBody, TSyncMap* syncList) {
TNodeSet visited;
- return IsPureIsolatedLambdaImpl(lambdaBody, visited);
+ return IsPureIsolatedLambdaImpl(lambdaBody, visited, syncList);
}
TString GetIntegralAtomValue(ui64 value, bool hasSign) {
diff --git a/ydb/library/yql/core/yql_expr_type_annotation.h b/ydb/library/yql/core/yql_expr_type_annotation.h
index c4d560ec48..d3bf851240 100644
--- a/ydb/library/yql/core/yql_expr_type_annotation.h
+++ b/ydb/library/yql/core/yql_expr_type_annotation.h
@@ -266,7 +266,7 @@ ui32 GetNumericDataTypeLevel(EDataSlot dataSlot);
EDataSlot GetNumericDataTypeByLevel(ui32 level);
ui32 GetDateTypeLevel(EDataSlot dataSlot);
EDataSlot GetDateTypeByLevel(ui32 level);
-bool IsPureIsolatedLambda(const TExprNode& lambdaBody);
+bool IsPureIsolatedLambda(const TExprNode& lambdaBody, TSyncMap* syncList = nullptr);
TString GetIntegralAtomValue(ui64 value, bool hasSign);
bool AllowIntegralConversion(NNodes::TCoIntegralCtor node, bool negate, EDataSlot toType,
TString* atomValue = nullptr);
diff --git a/ydb/library/yql/providers/common/provider/yql_data_provider_impl.cpp b/ydb/library/yql/providers/common/provider/yql_data_provider_impl.cpp
index 3ec10080f6..b4e421ffbd 100644
--- a/ydb/library/yql/providers/common/provider/yql_data_provider_impl.cpp
+++ b/ydb/library/yql/providers/common/provider/yql_data_provider_impl.cpp
@@ -1,11 +1,15 @@
#include "yql_data_provider_impl.h"
#include <ydb/library/yql/core/yql_expr_constraint.h>
+#include <ydb/library/yql/core/yql_expr_optimize.h>
+#include <ydb/library/yql/core/expr_nodes/yql_expr_nodes.h>
#include <util/system/compiler.h>
namespace NYql {
+using namespace NNodes;
+
void TPlanFormatterBase::WriteDetails(const TExprNode& node, NYson::TYsonWriter& writer) {
Y_UNUSED(node);
Y_UNUSED(writer);
@@ -239,8 +243,7 @@ void TDataProviderBase::LeaveEvaluation(ui64 id) {
}
TExprNode::TPtr TDataProviderBase::CleanupWorld(const TExprNode::TPtr& node, TExprContext& ctx) {
- Y_UNUSED(ctx);
- return node;
+ return DefaultCleanupWorld(node, ctx);
}
TExprNode::TPtr TDataProviderBase::OptimizePull(const TExprNode::TPtr& source, const TFillSettings& fillSettings,
@@ -313,4 +316,21 @@ IDqIntegration* TDataProviderBase::GetDqIntegration() {
return nullptr;
}
+TExprNode::TPtr DefaultCleanupWorld(const TExprNode::TPtr& node, TExprContext& ctx) {
+ auto root = node;
+ auto status = OptimizeExpr(root, root, [&](const TExprNode::TPtr& node, TExprContext& ctx) -> TExprNode::TPtr {
+ Y_UNUSED(ctx);
+ if (auto right = TMaybeNode<TCoRight>(node)) {
+ auto cons = right.Cast().Input().Maybe<TCoCons>();
+ if (cons) {
+ return cons.Cast().Input().Ptr();
+ }
+ }
+
+ return node;
+ }, ctx, TOptimizeExprSettings(nullptr));
+ YQL_ENSURE(status.Level != IGraphTransformer::TStatus::Error);
+ return root;
+}
+
} // namespace NYql
diff --git a/ydb/library/yql/providers/common/provider/yql_data_provider_impl.h b/ydb/library/yql/providers/common/provider/yql_data_provider_impl.h
index 2dce702afb..d1bfd4b027 100644
--- a/ydb/library/yql/providers/common/provider/yql_data_provider_impl.h
+++ b/ydb/library/yql/providers/common/provider/yql_data_provider_impl.h
@@ -94,4 +94,6 @@ protected:
TTrackableNodeProcessorBase NullTrackableNodeProcessor_;
};
+TExprNode::TPtr DefaultCleanupWorld(const TExprNode::TPtr& node, TExprContext& ctx);
+
} // namespace NYql
diff --git a/ydb/library/yql/providers/dq/provider/yql_dq_datasource.cpp b/ydb/library/yql/providers/dq/provider/yql_dq_datasource.cpp
index 21c0eb85d8..49c97fbf83 100644
--- a/ydb/library/yql/providers/dq/provider/yql_dq_datasource.cpp
+++ b/ydb/library/yql/providers/dq/provider/yql_dq_datasource.cpp
@@ -68,27 +68,45 @@ public:
return *ConfigurationTransformer_;
}
- bool CanBuildResult(const TExprNode& node, TSyncMap& syncList) override {
- if (!node.IsComplete()) {
- return false;
+ bool CanBuildResultImpl(const TExprNode& node, TNodeSet& visited) {
+ if (!visited.emplace(&node).second) {
+ return true;
}
- bool canBuild = true;
- VisitExpr(node, [&canBuild] (const TExprNode& n) {
- if (!canBuild) {
- return false;
- }
- if (TDqConnection::Match(&n) || TDqPhyPrecompute::Match(&n)) {
- // Don't go deeper
+ if (TDqConnection::Match(&node) || TDqPhyPrecompute::Match(&node)) {
+ // Don't go deeper
+ return true;
+ }
+
+ if (auto right = TMaybeNode<TCoRight>(&node)) {
+ auto cons = right.Cast().Input().Maybe<TCoCons>();
+ if (!cons) {
return false;
}
- if (!n.IsComposable()) {
- canBuild = false;
+
+ return CanBuildResultImpl(cons.Cast().Input().Ref(), visited);
+ }
+
+ if (!node.IsComposable()) {
+ return false;
+ }
+
+ for (const auto& child : node.Children()) {
+ if (!CanBuildResultImpl(*child, visited)) {
return false;
}
- return true;
- });
+ }
+
+ return true;
+ }
+
+ bool CanBuildResult(const TExprNode& node, TSyncMap& syncList) override {
+ if (!node.IsComplete()) {
+ return false;
+ }
+ TNodeSet visited;
+ bool canBuild = CanBuildResultImpl(node, visited);
if (canBuild) {
for (const auto& child : node.ChildrenList()) {
VisitExpr(child, [&syncList] (const TExprNode::TPtr& item) {
diff --git a/ydb/library/yql/providers/result/provider/yql_result_provider.cpp b/ydb/library/yql/providers/result/provider/yql_result_provider.cpp
index 4a73bffcfa..42a541f5c5 100644
--- a/ydb/library/yql/providers/result/provider/yql_result_provider.cpp
+++ b/ydb/library/yql/providers/result/provider/yql_result_provider.cpp
@@ -731,12 +731,18 @@ namespace {
data = unordered.Cast().Input();
}
- if (IsPureIsolatedLambda(writeInput.Ref())) {
+ TSyncMap syncList;
+ if (IsPureIsolatedLambda(writeInput.Ref(), &syncList)) {
+ auto cleanup = DefaultCleanupWorld(data.Ptr(), ctx);
+ if (!cleanup) {
+ return nullptr;
+ }
+
ret = Build<TResFill>(ctx, resWrite.Pos())
- .World(resWrite.World())
+ .World(ApplySyncListToWorld(resWrite.World().Ptr(), syncList, ctx))
.DataSink(resWrite.DataSink())
.Key(resWrite.Key())
- .Data(data)
+ .Data(cleanup)
.Settings(resWrite.Settings())
.DelegatedSource()
.Value(Config->Types.GetDefaultDataSource())
@@ -1042,26 +1048,28 @@ namespace {
if (auto right = res.Data().Maybe<TCoRight>()) {
auto source = right.Cast().Input();
- const TIntrusivePtr<IDataProvider>* provider = nullptr;
+ if (!source.Maybe<TCoCons>()) {
+ const TIntrusivePtr<IDataProvider>* provider = nullptr;
+
+ if (source.Ref().Type() == TExprNode::Callable || source.Ref().ChildrenSize() >= 2) {
+ if (source.Ref().Child(1)->IsCallable("DataSource")) {
+ auto name = source.Ref().Child(1)->Child(0)->Content();
+ provider = Config->Types.DataSourceMap.FindPtr(name);
+ Y_ENSURE(provider, "DataSource doesn't exist: " << name);
+ }
- if (source.Ref().Type() == TExprNode::Callable || source.Ref().ChildrenSize() >= 2) {
- if (source.Ref().Child(1)->IsCallable("DataSource")) {
- auto name = source.Ref().Child(1)->Child(0)->Content();
- provider = Config->Types.DataSourceMap.FindPtr(name);
- Y_ENSURE(provider, "DataSource doesn't exist: " << name);
+ if (source.Ref().Child(1)->IsCallable("DataSink")) {
+ auto name = source.Ref().Child(1)->Child(0)->Content();
+ provider = Config->Types.DataSinkMap.FindPtr(name);
+ Y_ENSURE(provider, "DataSink doesn't exist: " << name);
+ }
}
- if (source.Ref().Child(1)->IsCallable("DataSink")) {
- auto name = source.Ref().Child(1)->Child(0)->Content();
- provider = Config->Types.DataSinkMap.FindPtr(name);
- Y_ENSURE(provider, "DataSink doesn't exist: " << name);
+ if (!provider) {
+ ctx.AddError(TIssue(ctx.GetPosition(res.Data().Pos()), "Expected Right! over Datasource or Datasink"));
+ return IGraphTransformer::TStatus::Error;
}
}
-
- if (!provider) {
- ctx.AddError(TIssue(ctx.GetPosition(res.Data().Pos()), "Expected Right! over Datasource or Datasink"));
- return IGraphTransformer::TStatus::Error;
- }
}
if (res.Maybe<TResTransientBase>()) {
diff --git a/ydb/library/yql/sql/settings/translation_settings.h b/ydb/library/yql/sql/settings/translation_settings.h
index ae7560ca65..2ddd6a388a 100644
--- a/ydb/library/yql/sql/settings/translation_settings.h
+++ b/ydb/library/yql/sql/settings/translation_settings.h
@@ -103,6 +103,7 @@ namespace NSQLTranslation {
ISqlFeaturePolicy::TPtr DqDefaultAuto;
bool AssumeYdbOnClusterWithSlash;
TString DynamicClusterProvider;
+ TString FileAliasPrefix;
TVector<ui32> PgParameterTypeOids;
};
diff --git a/ydb/library/yql/sql/v1/builtin.cpp b/ydb/library/yql/sql/v1/builtin.cpp
index 81550d0b4c..41b1646867 100644
--- a/ydb/library/yql/sql/v1/builtin.cpp
+++ b/ydb/library/yql/sql/v1/builtin.cpp
@@ -274,10 +274,11 @@ typedef THolder<TBasicAggrFunc> TAggrFuncPtr;
class TLiteralStringAtom: public INode {
public:
- TLiteralStringAtom(TPosition pos, TNodePtr node, const TString& info)
+ TLiteralStringAtom(TPosition pos, TNodePtr node, const TString& info, const TString& prefix = {})
: INode(pos)
, Node(node)
, Info(info)
+ , Prefix(prefix)
{
}
@@ -292,7 +293,7 @@ public:
return false;
}
- Atom = MakeAtomFromExpression(ctx, Node).Build();
+ Atom = MakeAtomFromExpression(ctx, Node, Prefix).Build();
return true;
}
@@ -326,6 +327,7 @@ private:
TNodePtr Node;
TNodePtr Atom;
TString Info;
+ TString Prefix;
};
class TYqlAsAtom: public TLiteralStringAtom {
@@ -1000,25 +1002,26 @@ public:
}
};
-TNodePtr BuildFileNameArgument(TPosition pos, const TNodePtr& argument) {
- return new TLiteralStringAtom(pos, argument, "FilePath requires string literal as parameter");
+TNodePtr BuildFileNameArgument(TPosition pos, const TNodePtr& argument, const TString& prefix) {
+ return new TLiteralStringAtom(pos, argument, "FilePath requires string literal as parameter", prefix);
}
-class TYqlAtom final: public TCallNode {
+template <typename TDerived, bool IsFile>
+class TYqlAtomBase: public TCallNode {
public:
- TYqlAtom(TPosition pos, const TString& opName, const TVector<TNodePtr>& args)
+ TYqlAtomBase(TPosition pos, const TString& opName, const TVector<TNodePtr>& args)
: TCallNode(pos, opName, 1, 1, args)
{}
bool DoInit(TContext& ctx, ISource* src) override {
if (!Args.empty()) {
- Args[0] = BuildFileNameArgument(ctx.Pos(), Args[0]);
+ Args[0] = BuildFileNameArgument(ctx.Pos(), Args[0], IsFile ? ctx.Settings.FileAliasPrefix : TString());
}
return TCallNode::DoInit(ctx, src);
}
TNodePtr DoClone() const final {
- return new TYqlAtom(Pos, OpName, Args);
+ return new TDerived(Pos, OpName, Args);
}
bool IsLiteral() const override {
@@ -1034,6 +1037,18 @@ public:
}
};
+class TYqlAtom final : public TYqlAtomBase<TYqlAtom, false>
+{
+ using TBase = TYqlAtomBase<TYqlAtom, false>;
+ using TBase::TBase;
+};
+
+class TFileYqlAtom final : public TYqlAtomBase<TFileYqlAtom, true>
+{
+ using TBase = TYqlAtomBase<TFileYqlAtom, true>;
+ using TBase::TBase;
+};
+
class TTryMember final: public TCallNode {
public:
TTryMember(TPosition pos, const TString& opName, const TVector<TNodePtr>& args)
@@ -1225,7 +1240,7 @@ public:
if (!dataTypeStringNode) {
return false;
}
- auto aliasNode = BuildFileNameArgument(Args[1]->GetPos(), Args[1]);
+ auto aliasNode = BuildFileNameArgument(Args[1]->GetPos(), Args[1], ctx.Settings.FileAliasPrefix);
OpName = "Apply";
Args[0] = Y("Udf", Q("File.ByLines"), Y("Void"),
Y("TupleType",
@@ -2999,10 +3014,10 @@ struct TBuiltinFuncData {
{"staticzip", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("StaticZip", 1, -1) },
// File builtins
- {"filepath", BuildNamedBuiltinFactoryCallback<TYqlAtom>("FilePath")},
- {"filecontent", BuildNamedBuiltinFactoryCallback<TYqlAtom>("FileContent")},
- {"folderpath", BuildNamedBuiltinFactoryCallback<TYqlAtom>("FolderPath") },
- {"files", BuildNamedBuiltinFactoryCallback<TYqlAtom>("Files")},
+ {"filepath", BuildNamedBuiltinFactoryCallback<TFileYqlAtom>("FilePath")},
+ {"filecontent", BuildNamedBuiltinFactoryCallback<TFileYqlAtom>("FileContent")},
+ {"folderpath", BuildNamedBuiltinFactoryCallback<TFileYqlAtom>("FolderPath") },
+ {"files", BuildNamedBuiltinFactoryCallback<TFileYqlAtom>("Files")},
{"parsefile", BuildSimpleBuiltinFactoryCallback<TYqlParseFileOp>()},
// Misc builtins
diff --git a/ydb/library/yql/sql/v1/context.cpp b/ydb/library/yql/sql/v1/context.cpp
index e097ce174b..4440080666 100644
--- a/ydb/library/yql/sql/v1/context.cpp
+++ b/ydb/library/yql/sql/v1/context.cpp
@@ -350,7 +350,11 @@ bool TContext::AddExport(TPosition pos, const TString& name) {
TString TContext::AddImport(const TVector<TString>& modulePath) {
YQL_ENSURE(!modulePath.empty());
- const TString path = JoinRange("/", modulePath.cbegin(), modulePath.cend());
+ TString path = JoinRange("/", modulePath.cbegin(), modulePath.cend());
+ if (!path.StartsWith('/')) {
+ path = Settings.FileAliasPrefix + path;
+ }
+
auto iter = ImportModuleAliases.find(path);
if (iter == ImportModuleAliases.end()) {
const TString alias = MakeName(TStringBuilder() << modulePath.back() << "_module");
diff --git a/ydb/library/yql/sql/v1/node.cpp b/ydb/library/yql/sql/v1/node.cpp
index 1e8f97264f..6250406d9d 100644
--- a/ydb/library/yql/sql/v1/node.cpp
+++ b/ydb/library/yql/sql/v1/node.cpp
@@ -3650,27 +3650,35 @@ TSourcePtr TryMakeSourceFromExpression(TContext& ctx, const TString& currService
return BuildTableSource(node->GetPos(), table);
}
-void MakeTableFromExpression(TContext& ctx, TNodePtr node, TDeferredAtom& table) {
+void MakeTableFromExpression(TContext& ctx, TNodePtr node, TDeferredAtom& table, const TString& prefix) {
if (auto literal = node->GetLiteral("String")) {
- table = TDeferredAtom(node->GetPos(), *literal);
+ table = TDeferredAtom(node->GetPos(), prefix + *literal);
return;
}
if (auto access = dynamic_cast<TAccessNode*>(node.Get())) {
auto ret = access->TryMakeTable();
if (ret) {
- table = TDeferredAtom(node->GetPos(), *ret);
+ table = TDeferredAtom(node->GetPos(), prefix + *ret);
return;
}
}
+ if (!prefix.Empty()) {
+ node = node->Y("Concat", node->Y("String", node->Q(prefix)), node);
+ }
+
auto wrappedNode = node->Y("EvaluateAtom", node);
table = TDeferredAtom(wrappedNode, ctx);
}
-TDeferredAtom MakeAtomFromExpression(TContext& ctx, TNodePtr node) {
+TDeferredAtom MakeAtomFromExpression(TContext& ctx, TNodePtr node, const TString& prefix) {
if (auto literal = node->GetLiteral("String")) {
- return TDeferredAtom(node->GetPos(), *literal);
+ return TDeferredAtom(node->GetPos(), prefix + *literal);
+ }
+
+ if (!prefix.Empty()) {
+ node = node->Y("Concat", node->Y("String", node->Q(prefix)), node);
}
auto wrappedNode = node->Y("EvaluateAtom", node);
diff --git a/ydb/library/yql/sql/v1/node.h b/ydb/library/yql/sql/v1/node.h
index f26f12451c..07422f4bc5 100644
--- a/ydb/library/yql/sql/v1/node.h
+++ b/ydb/library/yql/sql/v1/node.h
@@ -1529,7 +1529,7 @@ namespace NSQLTranslationV1 {
TNodePtr GroundWithExpr(const TNodePtr& ground, const TNodePtr& expr);
TSourcePtr TryMakeSourceFromExpression(TContext& ctx, const TString& currService, const TDeferredAtom& currCluster,
TNodePtr node, const TString& view = {});
- void MakeTableFromExpression(TContext& ctx, TNodePtr node, TDeferredAtom& table);
- TDeferredAtom MakeAtomFromExpression(TContext& ctx, TNodePtr node);
+ void MakeTableFromExpression(TContext& ctx, TNodePtr node, TDeferredAtom& table, const TString& prefix = {});
+ TDeferredAtom MakeAtomFromExpression(TContext& ctx, TNodePtr node, const TString& prefix = {});
TString NormalizeTypeString(const TString& str);
} // namespace NSQLTranslationV1
diff --git a/ydb/library/yql/sql/v1/sql.cpp b/ydb/library/yql/sql/v1/sql.cpp
index b5b7596949..65399f2d03 100644
--- a/ydb/library/yql/sql/v1/sql.cpp
+++ b/ydb/library/yql/sql/v1/sql.cpp
@@ -6286,6 +6286,7 @@ bool TSqlTranslation::ImportStatement(const TRule_import_stmt& stmt, TVector<TSt
if (!ModulePath(stmt.GetRule_module_path2(), modulePath)) {
return false;
}
+
TVector<TSymbolNameWithPos> names;
TVector<TSymbolNameWithPos> aliases;
if (!NamedBindList(stmt.GetRule_named_bind_parameter_list4(), names, aliases)) {
@@ -10668,6 +10669,7 @@ TNodePtr TSqlQuery::PragmaStatement(const TRule_pragma_stmt& stmt, bool& success
const bool withConfigure = prefix || normalizedPragma == "file" || normalizedPragma == "folder" || normalizedPragma == "udf";
static const THashSet<TStringBuf> lexicalScopePragmas = {"classicdivision", "strictjoinkeytypes", "disablestrictjoinkeytypes", "checkedops"};
const bool hasLexicalScope = withConfigure || lexicalScopePragmas.contains(normalizedPragma);
+ const bool withFileAlias = normalizedPragma == "file" || normalizedPragma == "folder" || normalizedPragma == "library" || normalizedPragma == "udf";
for (auto pragmaValue : pragmaValues) {
if (pragmaValue->HasAlt_pragma_value3()) {
auto value = Token(pragmaValue->GetAlt_pragma_value3().GetToken1());
@@ -10676,7 +10678,12 @@ TNodePtr TSqlQuery::PragmaStatement(const TRule_pragma_stmt& stmt, bool& success
return {};
}
- values.push_back(TDeferredAtom(Ctx.Pos(), parsed->Content));
+ TString prefix;
+ if (withFileAlias && (values.size() == 0)) {
+ prefix = Ctx.Settings.FileAliasPrefix;
+ }
+
+ values.push_back(TDeferredAtom(Ctx.Pos(), prefix + parsed->Content));
}
else if (pragmaValue->HasAlt_pragma_value2()
&& pragmaValue->GetAlt_pragma_value2().GetRule_id1().HasAlt_id2()
@@ -10694,8 +10701,13 @@ TNodePtr TSqlQuery::PragmaStatement(const TRule_pragma_stmt& stmt, bool& success
return {};
}
+ TString prefix;
+ if (withFileAlias && (values.size() == 0)) {
+ prefix = Ctx.Settings.FileAliasPrefix;
+ }
+
TDeferredAtom atom;
- MakeTableFromExpression(Ctx, namedNode, atom);
+ MakeTableFromExpression(Ctx, namedNode, atom, prefix);
values.push_back(atom);
} else {
Error() << "Expected string" << (withConfigure ? ", named parameter" : "") << " or 'default' keyword as pragma value for pragma: " << pragma;