aboutsummaryrefslogtreecommitdiffstats
path: root/yql/essentials/core
diff options
context:
space:
mode:
authorudovichenko-r <udovichenko-r@yandex-team.com>2024-11-12 22:07:02 +0300
committerudovichenko-r <udovichenko-r@yandex-team.com>2024-11-12 22:21:07 +0300
commitfa5655229271d7a09cce8033d1097f1b03daf94e (patch)
tree5922c2db17789e411b6cc46069c66188e834f28b /yql/essentials/core
parent77c13da33ae29c033359e516ac2eb55a6c3d5e9e (diff)
downloadydb-fa5655229271d7a09cce8033d1097f1b03daf94e.tar.gz
Apply GH commits
Apply GH: Extract prefix and entries in backup-related sql (#10807) Apply GH: Fix syntax for Column Family (#10781) Apply GH: Case-insensitive mode for searching modules and functions (#10842) Apply GH: Fixed i/o for pg_proc (#10914) Apply GH: An option to render SQL transalation with Seq! (#11015) commit_hash:d2d2fcdef2bbd0434236aef325aa071c7e39c526
Diffstat (limited to 'yql/essentials/core')
-rw-r--r--yql/essentials/core/qplayer/udf_resolver/yql_qplayer_udf_resolver.cpp7
-rw-r--r--yql/essentials/core/type_ann/type_ann_core.cpp9
-rw-r--r--yql/essentials/core/ut/yql_udf_index_ut.cpp109
-rw-r--r--yql/essentials/core/yql_type_annotation.h1
-rw-r--r--yql/essentials/core/yql_udf_index.cpp127
-rw-r--r--yql/essentials/core/yql_udf_index.h19
-rw-r--r--yql/essentials/core/yql_udf_resolver.h1
7 files changed, 228 insertions, 45 deletions
diff --git a/yql/essentials/core/qplayer/udf_resolver/yql_qplayer_udf_resolver.cpp b/yql/essentials/core/qplayer/udf_resolver/yql_qplayer_udf_resolver.cpp
index 2980c808d0..15cc73400a 100644
--- a/yql/essentials/core/qplayer/udf_resolver/yql_qplayer_udf_resolver.cpp
+++ b/yql/essentials/core/qplayer/udf_resolver/yql_qplayer_udf_resolver.cpp
@@ -109,6 +109,7 @@ private:
TString SaveValue(const TFunction* f) const {
auto node = NYT::TNode()
+ ("NormalizedName", f->NormalizedName)
("CallableType", TypeToYsonNode(f->CallableType));
if (f->NormalizedUserType && f->NormalizedUserType->GetKind() != ETypeAnnotationKind::Void) {
node("NormalizedUserType", TypeToYsonNode(f->NormalizedUserType));
@@ -131,6 +132,12 @@ private:
void LoadValue(TFunction* f, const TString& value, TExprContext& ctx) const {
auto node = NYT::NodeFromYsonString(value);
+ if (node.HasKey("NormalizedName")) {
+ f->NormalizedName = node["NormalizedName"].AsString();
+ } else {
+ f->NormalizedName = f->Name;
+ }
+
f->CallableType = ParseTypeFromYson(node["CallableType"], ctx);
if (node.HasKey("NormalizedUserType")) {
f->NormalizedUserType = ParseTypeFromYson(node["NormalizedUserType"], ctx);
diff --git a/yql/essentials/core/type_ann/type_ann_core.cpp b/yql/essentials/core/type_ann/type_ann_core.cpp
index d301430e29..ea068f3f4a 100644
--- a/yql/essentials/core/type_ann/type_ann_core.cpp
+++ b/yql/essentials/core/type_ann/type_ann_core.cpp
@@ -2115,7 +2115,7 @@ namespace NTypeAnnImpl {
}
}
- const auto commonItemType = CommonTypeForChildren(*input, ctx.Expr);
+ const auto commonItemType = CommonTypeForChildren(*input, ctx.Expr);
if (!commonItemType) {
return IGraphTransformer::TStatus::Error;
}
@@ -7590,11 +7590,16 @@ template <NKikimr::NUdf::EDataSlot DataSlot>
return IGraphTransformer::TStatus::Error;
}
+ cached.NormalizedName = description.NormalizedName;
cached.FunctionType = description.CallableType;
cached.RunConfigType = description.RunConfigType ? description.RunConfigType : ctx.Expr.MakeType<TVoidExprType>();
cached.NormalizedUserType = description.NormalizedUserType ? description.NormalizedUserType : ctx.Expr.MakeType<TVoidExprType>();
cached.SupportsBlocks = description.SupportsBlocks;
cached.IsStrict = description.IsStrict;
+
+ if (name != cached.NormalizedName) {
+ ctx.Types.UdfTypeCache[std::make_tuple(cached.NormalizedName, TString(typeConfig), userType)] = cached;
+ }
}
TStringBuf typeConfig = "";
@@ -7623,7 +7628,7 @@ template <NKikimr::NUdf::EDataSlot DataSlot>
TStringBuf fileAlias = udfInfo ? udfInfo->FileAlias : ""_sb;
auto ret = ctx.Expr.Builder(input->Pos())
.Callable("Udf")
- .Add(0, input->HeadPtr())
+ .Atom(0, cached.NormalizedName)
.Add(1, runConfigValue)
.Add(2, ExpandType(input->Pos(), *cached.NormalizedUserType, ctx.Expr))
.Atom(3, typeConfig)
diff --git a/yql/essentials/core/ut/yql_udf_index_ut.cpp b/yql/essentials/core/ut/yql_udf_index_ut.cpp
index 5ff58e1267..3ac395ac18 100644
--- a/yql/essentials/core/ut/yql_udf_index_ut.cpp
+++ b/yql/essentials/core/ut/yql_udf_index_ut.cpp
@@ -43,7 +43,7 @@ void EnsureLinksEqual(const TDownloadLink& link1, const TDownloadLink& link2) {
void EnsureContainsFunction(TUdfIndex::TPtr index, TString module, const TFunctionInfo& f) {
TFunctionInfo existingFunc;
- UNIT_ASSERT(index->FindFunction(module, f.Name, existingFunc));
+ UNIT_ASSERT(index->FindFunction(module, f.Name, existingFunc) == TUdfIndex::EStatus::Found);
EnsureFunctionsEqual(f, existingFunc);
}
}
@@ -52,15 +52,15 @@ Y_UNIT_TEST_SUITE(TUdfIndexTests) {
Y_UNIT_TEST(Empty) {
auto index1 = MakeIntrusive<TUdfIndex>();
- UNIT_ASSERT(!index1->ContainsModule("M1"));
+ UNIT_ASSERT_EQUAL(index1->ContainsModule("M1"), TUdfIndex::EStatus::NotFound);
UNIT_ASSERT(index1->FindResourceByModule("M1") == nullptr);
TFunctionInfo f1;
- UNIT_ASSERT(!index1->FindFunction("M1", "M1.F1", f1));
+ UNIT_ASSERT_EQUAL(index1->FindFunction("M1", "M1.F1", f1), TUdfIndex::EStatus::NotFound);
auto index2 = index1->Clone();
- UNIT_ASSERT(!index2->ContainsModule("M1"));
+ UNIT_ASSERT_EQUAL(index2->ContainsModule("M1"), TUdfIndex::EStatus::NotFound);
UNIT_ASSERT(index2->FindResourceByModule("M1") == nullptr);
- UNIT_ASSERT(!index2->FindFunction("M1", "M1.F1", f1));
+ UNIT_ASSERT_EQUAL(index2->FindFunction("M1", "M1.F1", f1), TUdfIndex::EStatus::NotFound);
}
Y_UNIT_TEST(SingleModuleAndFunction) {
@@ -72,8 +72,8 @@ Y_UNIT_TEST_SUITE(TUdfIndexTests) {
b.AddFunction(func1);
index1->RegisterResource(b.Build(), TUdfIndex::EOverrideMode::RaiseError);
- UNIT_ASSERT(index1->ContainsModule("M1"));
- UNIT_ASSERT(!index1->ContainsModule("M2"));
+ UNIT_ASSERT_EQUAL(index1->ContainsModule("M1"), TUdfIndex::EStatus::Found);
+ UNIT_ASSERT_EQUAL(index1->ContainsModule("M2"), TUdfIndex::EStatus::NotFound);
UNIT_ASSERT(index1->FindResourceByModule("M2") == nullptr);
auto resource1 = index1->FindResourceByModule("M1");
@@ -81,19 +81,19 @@ Y_UNIT_TEST_SUITE(TUdfIndexTests) {
EnsureLinksEqual(resource1->Link, link1);
TFunctionInfo f1;
- UNIT_ASSERT(!index1->FindFunction("M2", "M2.F1", f1));
+ UNIT_ASSERT_EQUAL(index1->FindFunction("M2", "M2.F1", f1), TUdfIndex::EStatus::NotFound);
- UNIT_ASSERT(index1->FindFunction("M1", "M1.F1", f1));
+ UNIT_ASSERT_EQUAL(index1->FindFunction("M1", "M1.F1", f1), TUdfIndex::EStatus::Found);
EnsureFunctionsEqual(f1, func1);
// ensure both indexes contain the same info
auto index2 = index1->Clone();
- UNIT_ASSERT(index1->ContainsModule("M1"));
- UNIT_ASSERT(index2->ContainsModule("M1"));
+ UNIT_ASSERT_EQUAL(index1->ContainsModule("M1"), TUdfIndex::EStatus::Found);
+ UNIT_ASSERT_EQUAL(index2->ContainsModule("M1"), TUdfIndex::EStatus::Found);
TFunctionInfo f2;
- UNIT_ASSERT(index2->FindFunction("M1", "M1.F1", f2));
+ UNIT_ASSERT_EQUAL(index2->FindFunction("M1", "M1.F1", f2), TUdfIndex::EStatus::Found);
EnsureFunctionsEqual(f1, f2);
auto resource2 = index2->FindResourceByModule("M1");
@@ -140,11 +140,11 @@ Y_UNIT_TEST_SUITE(TUdfIndexTests) {
EnsureLinksEqual(r22->Link, link2);
// check modules
- UNIT_ASSERT(index1->ContainsModule("M1"));
- UNIT_ASSERT(index1->ContainsModule("M2"));
- UNIT_ASSERT(index1->ContainsModule("M3"));
- UNIT_ASSERT(index1->ContainsModule("M4"));
- UNIT_ASSERT(!index1->ContainsModule("M5"));
+ UNIT_ASSERT_EQUAL(index1->ContainsModule("M1"), TUdfIndex::EStatus::Found);
+ UNIT_ASSERT_EQUAL(index1->ContainsModule("M2"), TUdfIndex::EStatus::Found);
+ UNIT_ASSERT_EQUAL(index1->ContainsModule("M3"), TUdfIndex::EStatus::Found);
+ UNIT_ASSERT_EQUAL(index1->ContainsModule("M4"), TUdfIndex::EStatus::Found);
+ UNIT_ASSERT_EQUAL(index1->ContainsModule("M5"), TUdfIndex::EStatus::NotFound);
EnsureContainsFunction(index1, "M1", func11);
EnsureContainsFunction(index1, "M1", func12);
@@ -157,8 +157,8 @@ Y_UNIT_TEST_SUITE(TUdfIndexTests) {
TFunctionInfo f;
// known func, but non-existent module
- UNIT_ASSERT(!index1->FindFunction("M5", "M1.F1", f));
- UNIT_ASSERT(!index1->FindFunction("M2", "M3.F1", f));
+ UNIT_ASSERT_EQUAL(index1->FindFunction("M5", "M1.F1", f), TUdfIndex::EStatus::NotFound);
+ UNIT_ASSERT_EQUAL(index1->FindFunction("M2", "M3.F1", f), TUdfIndex::EStatus::NotFound);
}
Y_UNIT_TEST(ConflictRaiseError) {
@@ -199,7 +199,7 @@ Y_UNIT_TEST_SUITE(TUdfIndexTests) {
EnsureContainsFunction(index1, "M2", func13);
TFunctionInfo f;
- UNIT_ASSERT(!index1->FindFunction("M3", "M3.F1", f));
+ UNIT_ASSERT_EQUAL(index1->FindFunction("M3", "M3.F1", f), TUdfIndex::EStatus::NotFound);
}
Y_UNIT_TEST(ConflictPreserveExisting) {
@@ -240,7 +240,7 @@ Y_UNIT_TEST_SUITE(TUdfIndexTests) {
EnsureContainsFunction(index1, "M2", func13);
TFunctionInfo f;
- UNIT_ASSERT(!index1->FindFunction("M3", "M3.F1", f));
+ UNIT_ASSERT_EQUAL(index1->FindFunction("M3", "M3.F1", f), TUdfIndex::EStatus::NotFound);
}
Y_UNIT_TEST(ConflictReplace1WithNew) {
@@ -299,9 +299,9 @@ Y_UNIT_TEST_SUITE(TUdfIndexTests) {
// not here anymore
TFunctionInfo f;
- UNIT_ASSERT(!index1->FindFunction("M1", "M1.F1", f));
- UNIT_ASSERT(!index1->FindFunction("M1", "M1.F2", f));
- UNIT_ASSERT(!index1->FindFunction("M2", "M2.F1", f));
+ UNIT_ASSERT_EQUAL(index1->FindFunction("M1", "M1.F1", f), TUdfIndex::EStatus::NotFound);
+ UNIT_ASSERT_EQUAL(index1->FindFunction("M1", "M1.F2", f), TUdfIndex::EStatus::NotFound);
+ UNIT_ASSERT_EQUAL(index1->FindFunction("M2", "M2.F1", f), TUdfIndex::EStatus::NotFound);
}
Y_UNIT_TEST(ConflictReplace2WithNew) {
@@ -359,10 +359,63 @@ Y_UNIT_TEST_SUITE(TUdfIndexTests) {
// not here anymore
TFunctionInfo f;
- UNIT_ASSERT(!index1->FindFunction("M1", "M1.F2", f));
- UNIT_ASSERT(!index1->FindFunction("M2", "M2.F1", f));
+ UNIT_ASSERT_EQUAL(index1->FindFunction("M1", "M1.F2", f), TUdfIndex::EStatus::NotFound);
+ UNIT_ASSERT_EQUAL(index1->FindFunction("M2", "M2.F1", f), TUdfIndex::EStatus::NotFound);
- UNIT_ASSERT(!index1->FindFunction("M3", "M3.F3", f));
- UNIT_ASSERT(!index1->FindFunction("M4", "M4.F4", f));
+ UNIT_ASSERT_EQUAL(index1->FindFunction("M3", "M3.F3", f), TUdfIndex::EStatus::NotFound);
+ UNIT_ASSERT_EQUAL(index1->FindFunction("M4", "M4.F4", f), TUdfIndex::EStatus::NotFound);
+ }
+
+ Y_UNIT_TEST(SetInsensitiveSearch) {
+ auto index1 = MakeIntrusive<TUdfIndex>();
+ index1->SetCaseSentiveSearch(false);
+ auto func1 = BuildFunctionInfo("M1.FA", 1);
+ auto func2 = BuildFunctionInfo("M1.fa", 1);
+ auto func3 = BuildFunctionInfo("M1.g", 1);
+ auto func4 = BuildFunctionInfo("mx.h", 1);
+ auto func5 = BuildFunctionInfo("MX.g", 1);
+ auto link1 = TDownloadLink::File("file1");
+
+ TResourceBuilder b(link1);
+ b.AddFunction(func1);
+ b.AddFunction(func2);
+ b.AddFunction(func3);
+ b.AddFunction(func4);
+ b.AddFunction(func5);
+
+ index1->RegisterResource(b.Build(), TUdfIndex::EOverrideMode::RaiseError);
+
+ auto checkIndex = [&](auto index) {
+ UNIT_ASSERT_EQUAL(index->ContainsModule("M1"), TUdfIndex::EStatus::Found);
+ UNIT_ASSERT_EQUAL(index->ContainsModule("m1"), TUdfIndex::EStatus::Found);
+ UNIT_ASSERT_EQUAL(index->ContainsModule("mx"), TUdfIndex::EStatus::Found);
+ UNIT_ASSERT_EQUAL(index->ContainsModule("MX"), TUdfIndex::EStatus::Found);
+ UNIT_ASSERT_EQUAL(index->ContainsModule("mX"), TUdfIndex::EStatus::Ambigious);
+ UNIT_ASSERT_EQUAL(index->ContainsModule("M3"), TUdfIndex::EStatus::NotFound);
+
+ UNIT_ASSERT(index->FindResourceByModule("M3") == nullptr);
+ auto resource1 = index->FindResourceByModule("m1");
+ UNIT_ASSERT(resource1 != nullptr);
+ EnsureLinksEqual(resource1->Link, link1);
+
+ TFunctionInfo f;
+ UNIT_ASSERT_EQUAL(index->FindFunction("m1", "M1.FA", f), TUdfIndex::EStatus::Found);
+ EnsureFunctionsEqual(f, func1);
+ UNIT_ASSERT_EQUAL(index->FindFunction("m1", "m1.Fa", f), TUdfIndex::EStatus::Ambigious);
+ UNIT_ASSERT_EQUAL(index->FindFunction("m1", "M1.fa", f), TUdfIndex::EStatus::Found);
+ EnsureFunctionsEqual(f, func2);
+ UNIT_ASSERT_EQUAL(index->FindFunction("m1", "m1.g", f), TUdfIndex::EStatus::Found);
+ EnsureFunctionsEqual(f, func3);
+ UNIT_ASSERT_EQUAL(index->FindFunction("Mx", "mx.h", f), TUdfIndex::EStatus::Ambigious);
+ UNIT_ASSERT_EQUAL(index->FindFunction("mx", "mx.H", f), TUdfIndex::EStatus::Found);
+ EnsureFunctionsEqual(f, func4);
+ UNIT_ASSERT_EQUAL(index->FindFunction("MX", "mx.g", f), TUdfIndex::EStatus::Found);
+ EnsureFunctionsEqual(f, func5);
+ };
+
+ checkIndex(index1);
+ // ensure both indexes contain the same info
+ auto index2 = index1->Clone();
+ checkIndex(index2);
}
}
diff --git a/yql/essentials/core/yql_type_annotation.h b/yql/essentials/core/yql_type_annotation.h
index 1473b9deb0..7275801c6c 100644
--- a/yql/essentials/core/yql_type_annotation.h
+++ b/yql/essentials/core/yql_type_annotation.h
@@ -273,6 +273,7 @@ enum class EBlockEngineMode {
};
struct TUdfCachedInfo {
+ TString NormalizedName;
const TTypeAnnotationNode* FunctionType = nullptr;
const TTypeAnnotationNode* RunConfigType = nullptr;
const TTypeAnnotationNode* NormalizedUserType = nullptr;
diff --git a/yql/essentials/core/yql_udf_index.cpp b/yql/essentials/core/yql_udf_index.cpp
index 5c936dda68..7f2053693e 100644
--- a/yql/essentials/core/yql_udf_index.cpp
+++ b/yql/essentials/core/yql_udf_index.cpp
@@ -80,40 +80,137 @@ void AddResolveResultToRegistry(const TResolveResult& resolveResult, const TMap<
TUdfIndex::TUdfIndex() {
}
-TUdfIndex::TUdfIndex(const TMap<TString, TResourceInfo::TPtr>& resources)
+void TUdfIndex::SetCaseSentiveSearch(bool caseSensitive) {
+ CaseSensitive_ = caseSensitive;
+}
+
+TUdfIndex::TUdfIndex(const TMap<TString, TResourceInfo::TPtr>& resources, bool caseSensitive)
: Resources_(resources)
+ , CaseSensitive_(caseSensitive)
{
-
+ for (const auto& x : Resources_) {
+ ICaseModules_[to_lower(x.first)].insert(x.first);
+ }
}
-bool TUdfIndex::ContainsModule(const TString& moduleName) const {
+bool TUdfIndex::ContainsModuleStrict(const TString& moduleName) const {
return Resources_.contains(moduleName);
}
+bool TUdfIndex::CanonizeModule(TString& moduleName) const {
+ if (Resources_.contains(moduleName)) {
+ return true;
+ }
+
+ if (CaseSensitive_) {
+ return false;
+ }
+
+ auto p = ICaseModules_.FindPtr(to_lower(moduleName));
+ if (!p) {
+ return false;
+ }
+
+ Y_ENSURE(p->size() > 0);
+ if (p->size() > 1) {
+ return false;
+ }
+
+ moduleName = *p->begin();
+ return true;
+}
+
+TUdfIndex::EStatus TUdfIndex::ContainsModule(const TString& moduleName) const {
+ if (Resources_.contains(moduleName)) {
+ return EStatus::Found;
+ }
+
+ if (CaseSensitive_) {
+ return EStatus::NotFound;
+ }
+
+ auto p = ICaseModules_.FindPtr(to_lower(moduleName));
+ if (!p) {
+ return EStatus::NotFound;
+ }
+
+ Y_ENSURE(p->size() > 0);
+ return p->size() > 1 ? EStatus::Ambigious : EStatus::Found;
+}
+
bool TUdfIndex::ContainsAnyModule(const TSet<TString>& modules) const {
return AnyOf(modules, [this](auto& m) {
- return this->ContainsModule(m);
+ return Resources_.contains(m);
});
}
-bool TUdfIndex::FindFunction(const TString& moduleName, const TString& functionName, TFunctionInfo& function) const {
- auto r = FindResourceByModule(moduleName);
+TUdfIndex::EStatus TUdfIndex::FindFunction(const TString& moduleName, const TString& functionName, TFunctionInfo& function) const {
+ auto r = Resources_.FindPtr(moduleName);
if (!r) {
- return false;
+ if (CaseSensitive_) {
+ return EStatus::NotFound;
+ }
+
+ auto p = ICaseModules_.FindPtr(to_lower(moduleName));
+ if (!p) {
+ return EStatus::NotFound;
+ }
+
+ Y_ENSURE(p->size() > 0);
+ if (p->size() > 1) {
+ return EStatus::Ambigious;
+ }
+
+ r = Resources_.FindPtr(*p->begin());
+ Y_ENSURE(r);
}
- auto f = r->Functions.FindPtr(functionName);
+ auto f = (*r)->Functions.FindPtr(functionName);
if (!f) {
- return false;
+ if (CaseSensitive_) {
+ return EStatus::NotFound;
+ }
+
+ auto p = (*r)->ICaseFuncNames.FindPtr(to_lower(functionName));
+ if (!p) {
+ return EStatus::NotFound;
+ }
+
+ Y_ENSURE(p->size() > 0);
+ if (p->size() > 1) {
+ return EStatus::Ambigious;
+ }
+
+ f = (*r)->Functions.FindPtr(*p->begin());
+ Y_ENSURE(f);
}
function = *f;
- return true;
+ return EStatus::Found;
}
TResourceInfo::TPtr TUdfIndex::FindResourceByModule(const TString& moduleName) const {
auto p = Resources_.FindPtr(moduleName);
- return p ? *p : nullptr;
+ if (!p) {
+ if (CaseSensitive_) {
+ return nullptr;
+ }
+
+ auto n = ICaseModules_.FindPtr(to_lower(moduleName));
+ if (!n) {
+ return nullptr;
+ }
+
+ Y_ENSURE(n->size() > 0);
+ if (n->size() > 1) {
+ return nullptr;
+ }
+
+ p = Resources_.FindPtr(*n->begin());
+ Y_ENSURE(p);
+ }
+
+ return *p;
}
TSet<TResourceInfo::TPtr> TUdfIndex::FindResourcesByModules(const TSet<TString>& modules) const {
@@ -130,6 +227,11 @@ TSet<TResourceInfo::TPtr> TUdfIndex::FindResourcesByModules(const TSet<TString>&
void TUdfIndex::UnregisterResource(TResourceInfo::TPtr resource) {
for (auto& m : resource->Modules) {
Resources_.erase(m);
+ auto& names = ICaseModules_[to_lower(m)];
+ names.erase(m);
+ if (names.empty()) {
+ ICaseModules_.erase(to_lower(m));
+ }
}
// resource pointer should be alive here to avoid problems with erase
}
@@ -170,11 +272,12 @@ void TUdfIndex::RegisterResource(const TResourceInfo::TPtr& resource, EOverrideM
for (auto& m : resource->Modules) {
Resources_.emplace(m, resource);
+ ICaseModules_[to_lower(m)].insert(m);
}
}
TIntrusivePtr<TUdfIndex> TUdfIndex::Clone() const {
- return new TUdfIndex(Resources_);
+ return new TUdfIndex(Resources_, CaseSensitive_);
}
void TUdfIndex::RegisterResources(const TVector<TResourceInfo::TPtr>& resources, EOverrideMode mode) {
diff --git a/yql/essentials/core/yql_udf_index.h b/yql/essentials/core/yql_udf_index.h
index 41896d191d..1ac882bd81 100644
--- a/yql/essentials/core/yql_udf_index.h
+++ b/yql/essentials/core/yql_udf_index.h
@@ -72,10 +72,12 @@ struct TResourceInfo : public TThrRefBase {
TDownloadLink Link;
TSet<TString> Modules;
TMap<TString, TFunctionInfo> Functions;
+ TMap<TString, TSet<TString>> ICaseFuncNames;
void SetFunctions(const TVector<TFunctionInfo>& functions) {
for (auto& f : functions) {
Functions.emplace(f.Name, f);
+ ICaseFuncNames[to_lower(f.Name)].insert(f.Name);
}
}
};
@@ -96,12 +98,21 @@ public:
RaiseError
};
+ enum class EStatus {
+ Found,
+ NotFound,
+ Ambigious
+ };
+
public:
TUdfIndex();
- bool ContainsModule(const TString& moduleName) const;
- bool FindFunction(const TString& moduleName, const TString& functionName, TFunctionInfo& function) const;
+ void SetCaseSentiveSearch(bool caseSensitive);
+ bool CanonizeModule(TString& moduleName) const;
+ EStatus ContainsModule(const TString& moduleName) const;
+ EStatus FindFunction(const TString& moduleName, const TString& functionName, TFunctionInfo& function) const;
TResourceInfo::TPtr FindResourceByModule(const TString& moduleName) const;
+ bool ContainsModuleStrict(const TString& moduleName) const;
/*
New resource can contain already registered module.
In this case 'mode' will be used to resolve conflicts.
@@ -114,7 +125,7 @@ public:
TIntrusivePtr<TUdfIndex> Clone() const;
private:
- explicit TUdfIndex(const TMap<TString, TResourceInfo::TPtr>& resources);
+ explicit TUdfIndex(const TMap<TString, TResourceInfo::TPtr>& resources, bool caseSensitive);
bool ContainsAnyModule(const TSet<TString>& modules) const;
TSet<TResourceInfo::TPtr> FindResourcesByModules(const TSet<TString>& modules) const;
@@ -123,6 +134,8 @@ private:
private:
// module => Resource
TMap<TString, TResourceInfo::TPtr> Resources_;
+ bool CaseSensitive_ = true;
+ TMap<TString, TSet<TString>> ICaseModules_;
};
void LoadRichMetadataToUdfIndex(const IUdfResolver& resolver, const TVector<TString>& paths, bool isTrusted, TUdfIndex::EOverrideMode mode, TUdfIndex& registry);
diff --git a/yql/essentials/core/yql_udf_resolver.h b/yql/essentials/core/yql_udf_resolver.h
index 5dfb6744ed..9b6bf4f8ee 100644
--- a/yql/essentials/core/yql_udf_resolver.h
+++ b/yql/essentials/core/yql_udf_resolver.h
@@ -42,6 +42,7 @@ public:
THashMap<TString, TString> SecureParams;
// output
+ TString NormalizedName;
const TTypeAnnotationNode* NormalizedUserType = nullptr;
const TTypeAnnotationNode* RunConfigType = nullptr;
const TTypeAnnotationNode* CallableType = nullptr;