diff options
author | vitya-smirnov <[email protected]> | 2025-08-13 15:40:52 +0300 |
---|---|---|
committer | vitya-smirnov <[email protected]> | 2025-08-13 16:35:22 +0300 |
commit | 0412ed8db0700d3897e00be3a0cad6b2e8625883 (patch) | |
tree | e120a05f38f60c530dc5a09e9bf70d70dd3705b1 /yql/essentials | |
parent | b72d72afabd4fc56ff5573b6b8118c8cca597205 (diff) |
YQL-20301: Map unsupported object to UnknownName
Before this PR unsupported objects were filtered,
but we would like to show even unsupported object
types as unknown name candidates.
commit_hash:04c64b6e28717c3c19927d49eeedec7515608c22
Diffstat (limited to 'yql/essentials')
9 files changed, 64 insertions, 13 deletions
diff --git a/yql/essentials/sql/v1/complete/analysis/local/local.cpp b/yql/essentials/sql/v1/complete/analysis/local/local.cpp index cf10d3a5e85..aa5c87e6169 100644 --- a/yql/essentials/sql/v1/complete/analysis/local/local.cpp +++ b/yql/essentials/sql/v1/complete/analysis/local/local.cpp @@ -278,6 +278,7 @@ namespace NSQLComplete { if (AnyOf(candidates.Rules, RuleAdapted(IsLikelyObjectRefStack))) { object.Kinds.emplace(EObjectKind::Folder); + object.Kinds.emplace(EObjectKind::Unknown); } if (AnyOf(candidates.Rules, RuleAdapted(IsLikelyExistingTableStack))) { diff --git a/yql/essentials/sql/v1/complete/core/name.h b/yql/essentials/sql/v1/complete/core/name.h index d6d718e19e0..30e33859aeb 100644 --- a/yql/essentials/sql/v1/complete/core/name.h +++ b/yql/essentials/sql/v1/complete/core/name.h @@ -8,6 +8,7 @@ namespace NSQLComplete { enum class EObjectKind { Folder, Table, + Unknown, }; enum class ENodeKind { diff --git a/yql/essentials/sql/v1/complete/name/object/schema.cpp b/yql/essentials/sql/v1/complete/name/object/schema.cpp index ef64e0d371d..86c2a0f36a6 100644 --- a/yql/essentials/sql/v1/complete/name/object/schema.cpp +++ b/yql/essentials/sql/v1/complete/name/object/schema.cpp @@ -1,5 +1,14 @@ #include "schema.h" +namespace NSQLComplete { + + THashSet<TString> TFolderEntry::KnownTypes = { + TFolderEntry::Folder, + TFolderEntry::Table, + }; + +} // namespace NSQLComplete + template <> void Out<NSQLComplete::TFolderEntry>(IOutputStream& out, const NSQLComplete::TFolderEntry& value) { out << "{" << value.Type << ", " << value.Name << "}"; diff --git a/yql/essentials/sql/v1/complete/name/object/schema.h b/yql/essentials/sql/v1/complete/name/object/schema.h index d779b293674..e3af2df024d 100644 --- a/yql/essentials/sql/v1/complete/name/object/schema.h +++ b/yql/essentials/sql/v1/complete/name/object/schema.h @@ -13,6 +13,8 @@ namespace NSQLComplete { static constexpr const char* Folder = "Folder"; static constexpr const char* Table = "Table"; + static THashSet<TString> KnownTypes; + TString Type; TString Name; @@ -21,6 +23,7 @@ namespace NSQLComplete { struct TListFilter { TMaybe<THashSet<TString>> Types; + bool IsUnknownAllowed = false; }; struct TListRequest { diff --git a/yql/essentials/sql/v1/complete/name/object/simple/schema.cpp b/yql/essentials/sql/v1/complete/name/object/simple/schema.cpp index 2806b80eead..e13d1c0cfcb 100644 --- a/yql/essentials/sql/v1/complete/name/object/simple/schema.cpp +++ b/yql/essentials/sql/v1/complete/name/object/simple/schema.cpp @@ -20,11 +20,17 @@ namespace NSQLComplete { }; } - static auto FilterEntriesByTypes(TMaybe<THashSet<TString>> types) { - return [types = std::move(types)](auto f) mutable { + static auto FilterEntriesByTypes(const TListFilter& filter) { + return [filter](auto f) mutable { TVector<TFolderEntry> entries = f.ExtractValue(); - EraseIf(entries, [types = std::move(types)](const TFolderEntry& entry) { - return types && !types->contains(entry.Type); + EraseIf(entries, [filter = std::move(filter)](const TFolderEntry& entry) { + const bool isKnownType = TFolderEntry::KnownTypes.contains(entry.Type); + return ( + (isKnownType && + filter.Types && + !filter.Types->contains(entry.Type)) || + (!isKnownType && + !filter.IsUnknownAllowed)); }); return entries; }; @@ -90,7 +96,7 @@ namespace NSQLComplete { auto [path, name] = Simple_->Split(request.Path); return Simple_->List(request.Cluster, TString(path)) .Apply(FilterEntriesByName(TString(name))) - .Apply(FilterEntriesByTypes(request.Filter.Types)) + .Apply(FilterEntriesByTypes(request.Filter)) .Apply(CropEntries(request.Limit)) .Apply(ToListResponse(name)); } diff --git a/yql/essentials/sql/v1/complete/name/object/simple/static/schema_json.cpp b/yql/essentials/sql/v1/complete/name/object/simple/static/schema_json.cpp index ee253a5ad2c..9e0723e5255 100644 --- a/yql/essentials/sql/v1/complete/name/object/simple/static/schema_json.cpp +++ b/yql/essentials/sql/v1/complete/name/object/simple/static/schema_json.cpp @@ -90,7 +90,11 @@ namespace NSQLComplete { return TFolderEntry::Table; } - ythrow yexception() << "Unexpected type: " << type; + if (!type.IsString()) { + ythrow yexception() << "Unexpected type: " << type; + } + + return type.GetStringSafe(); } } // namespace diff --git a/yql/essentials/sql/v1/complete/name/service/schema/name_service.cpp b/yql/essentials/sql/v1/complete/name/service/schema/name_service.cpp index 2691ca0fadc..dafc1e4113a 100644 --- a/yql/essentials/sql/v1/complete/name/service/schema/name_service.cpp +++ b/yql/essentials/sql/v1/complete/name/service/schema/name_service.cpp @@ -110,9 +110,16 @@ namespace NSQLComplete { } static TListFilter ToListFilter(const TNameConstraints& constraints) { + const auto& kinds = constraints.Object->Kinds; + TListFilter filter; filter.Types = THashSet<TString>(); - for (auto kind : constraints.Object->Kinds) { + filter.IsUnknownAllowed = kinds.contains(EObjectKind::Unknown); + for (EObjectKind kind : kinds) { + if (kind == EObjectKind::Unknown) { + continue; + } + filter.Types->emplace(ToFolderEntry(kind)); } return filter; @@ -124,6 +131,10 @@ namespace NSQLComplete { return TFolderEntry::Folder; case EObjectKind::Table: return TFolderEntry::Table; + case EObjectKind::Unknown: + ythrow yexception() + << "Unknown is a type class and " + << "can not be a folder entry"; } } diff --git a/yql/essentials/sql/v1/complete/sql_complete.cpp b/yql/essentials/sql/v1/complete/sql_complete.cpp index f98f8309f77..23b62f7d0a8 100644 --- a/yql/essentials/sql/v1/complete/sql_complete.cpp +++ b/yql/essentials/sql/v1/complete/sql_complete.cpp @@ -209,21 +209,19 @@ namespace NSQLComplete { name = NormalizeName(name); if (name == "concat") { - object->Kinds.emplace(EObjectKind::Folder); - object->Kinds.emplace(EObjectKind::Table); + object->Kinds = {EObjectKind::Folder, EObjectKind::Table}; } else if ((number == 0) && (name == "range" || name == "like" || name == "regexp" || name == "filter" || name == "folder" || name == "walkfolders")) { - object->Kinds.emplace(EObjectKind::Folder); + object->Kinds = {EObjectKind::Folder}; } else if ((number == 1 || number == 2) && (name == "range")) { if (TMaybe<TString> path = function->Arg0) { object->Path = *path; object->Path.append("/"); } - object->Kinds.emplace(EObjectKind::Folder); - object->Kinds.emplace(EObjectKind::Table); + object->Kinds = {EObjectKind::Folder, EObjectKind::Table}; } return local; diff --git a/yql/essentials/sql/v1/complete/sql_complete_ut.cpp b/yql/essentials/sql/v1/complete/sql_complete_ut.cpp index 9540b012249..2d5e12627e0 100644 --- a/yql/essentials/sql/v1/complete/sql_complete_ut.cpp +++ b/yql/essentials/sql/v1/complete/sql_complete_ut.cpp @@ -55,6 +55,7 @@ Y_UNIT_TEST_SUITE(SqlCompleteTests) { using ECandidateKind::PragmaName; using ECandidateKind::TableName; using ECandidateKind::TypeName; + using ECandidateKind::UnknownName; TLexerSupplier MakePureLexerSupplier() { NSQLTranslationV1::TLexers lexers; @@ -118,7 +119,9 @@ Y_UNIT_TEST_SUITE(SqlCompleteTests) { "room": {}, "time": {} }} - }} + }}, + "link": { "type": "LINK" }, + "topic": { "type": "Topic" } }}, "saurus": { "type": "Folder", "entries": { "maxim": { "type": "Table", "columns": { @@ -842,6 +845,21 @@ Y_UNIT_TEST_SUITE(SqlCompleteTests) { } } + Y_UNIT_TEST(AlterObject) { + auto engine = MakeSqlCompletionEngineUT(); + + TString query = R"sql( + ALTER OBJECT example.`#` + )sql"; + + TVector<TCandidate> expected = { + {FolderName, "yql/"}, + {UnknownName, "link"}, + {UnknownName, "topic"}, + }; + UNIT_ASSERT_VALUES_EQUAL(Complete(engine, query), expected); + } + Y_UNIT_TEST(TypeName) { TVector<TCandidate> expected = { {TypeName, "Callable<>", 1}, |