summaryrefslogtreecommitdiffstats
path: root/yql/essentials/sql/v1/complete/sql_complete.cpp
diff options
context:
space:
mode:
authorvityaman <[email protected]>2025-05-06 15:49:02 +0300
committerrobot-piglet <[email protected]>2025-05-06 16:04:08 +0300
commit9c3fdca51d8ae892c5ad8f6ef92df73fafc09e28 (patch)
tree561c599fae4ea29b537a6958b65e1b052548edf2 /yql/essentials/sql/v1/complete/sql_complete.cpp
parentc131e959456f9f9a4adada5623ce3bae4097a8c1 (diff)
YQL-19747 Complete folder, table and cluster names
--- - Related to `YQL-19747` - On top of https://github.com/ytsaurus/ytsaurus/pull/1253 - Related to https://github.com/ydb-platform/ydb/issues/9056 - Related to https://github.com/vityaman/ydb/issues/14 - Related to https://github.com/vityaman/ydb/issues/35 - Related to https://github.com/vityaman/ydb/issues/40 --- Pull Request resolved: https://github.com/ytsaurus/ytsaurus/pull/1257 commit_hash:0b842abb27184c88b8177beeea29fb1ea86b7a04
Diffstat (limited to 'yql/essentials/sql/v1/complete/sql_complete.cpp')
-rw-r--r--yql/essentials/sql/v1/complete/sql_complete.cpp178
1 files changed, 127 insertions, 51 deletions
diff --git a/yql/essentials/sql/v1/complete/sql_complete.cpp b/yql/essentials/sql/v1/complete/sql_complete.cpp
index 0ec34e212db..d3941661e44 100644
--- a/yql/essentials/sql/v1/complete/sql_complete.cpp
+++ b/yql/essentials/sql/v1/complete/sql_complete.cpp
@@ -16,9 +16,9 @@ namespace NSQLComplete {
TLexerSupplier lexer,
INameService::TPtr names,
ISqlCompletionEngine::TConfiguration configuration)
- : Configuration(std::move(configuration))
- , SyntaxAnalysis(MakeLocalSyntaxAnalysis(lexer))
- , Names(std::move(names))
+ : Configuration_(std::move(configuration))
+ , SyntaxAnalysis_(MakeLocalSyntaxAnalysis(lexer))
+ , Names_(std::move(names))
{
}
@@ -36,32 +36,35 @@ namespace NSQLComplete {
<< " for input size " << input.Text.size();
}
- TLocalSyntaxContext context = SyntaxAnalysis->Analyze(input);
+ TLocalSyntaxContext context = SyntaxAnalysis_->Analyze(input);
+ auto keywords = context.Keywords;
- TStringBuf prefix = input.Text.Head(input.CursorPosition);
- TCompletedToken completedToken = GetCompletedToken(prefix);
+ TNameRequest request = NameRequestFrom(input, context);
+ if (request.IsEmpty()) {
+ return NThreading::MakeFuture<TCompletion>({
+ .CompletedToken = GetCompletedToken(input, context.EditRange),
+ .Candidates = {},
+ });
+ }
- return GetCandidates(std::move(context), completedToken)
- .Apply([completedToken](NThreading::TFuture<TVector<TCandidate>> f) {
- return TCompletion{
- .CompletedToken = std::move(completedToken),
- .Candidates = f.ExtractValue(),
- };
+ return Names_->Lookup(std::move(request))
+ .Apply([this, input, context = std::move(context)](auto f) {
+ return ToCompletion(input, context, f.ExtractValue());
});
}
private:
- TCompletedToken GetCompletedToken(TStringBuf prefix) const {
+ TCompletedToken GetCompletedToken(TCompletionInput input, TEditRange editRange) const {
return {
- .Content = LastWord(prefix),
- .SourcePosition = LastWordIndex(prefix),
+ .Content = input.Text.SubStr(editRange.Begin, editRange.Length),
+ .SourcePosition = editRange.Begin,
};
}
- NThreading::TFuture<TVector<TCandidate>> GetCandidates(TLocalSyntaxContext context, const TCompletedToken& prefix) const {
+ TNameRequest NameRequestFrom(TCompletionInput input, const TLocalSyntaxContext& context) const {
TNameRequest request = {
- .Prefix = TString(prefix.Content),
- .Limit = Configuration.Limit,
+ .Prefix = TString(GetCompletedToken(input, context.EditRange).Content),
+ .Limit = Configuration_.Limit,
};
for (const auto& [first, _] : context.Keywords) {
@@ -74,7 +77,7 @@ namespace NSQLComplete {
request.Constraints.Pragma = std::move(constraints);
}
- if (context.IsTypeName) {
+ if (context.Type) {
request.Constraints.Type = TTypeName::TConstraints();
}
@@ -90,48 +93,109 @@ namespace NSQLComplete {
request.Constraints.Hint = std::move(constraints);
}
- if (request.IsEmpty()) {
- return NThreading::MakeFuture<TVector<TCandidate>>({});
+ if (context.Object) {
+ request.Constraints.Object = TObjectNameConstraints{
+ .Provider = context.Object->Provider,
+ .Cluster = context.Object->Cluster,
+ .Kinds = context.Object->Kinds,
+ };
+ request.Prefix = context.Object->Path;
}
- return Names->Lookup(std::move(request))
- .Apply([keywords = std::move(context.Keywords)](NThreading::TFuture<TNameResponse> f) {
- TNameResponse response = f.ExtractValue();
- return Convert(std::move(response.RankedNames), std::move(keywords));
- });
+ if (context.Cluster) {
+ TClusterName::TConstraints constraints;
+ constraints.Namespace = context.Cluster->Provider;
+ request.Constraints.Cluster = std::move(constraints);
+ }
+
+ return request;
}
- static TVector<TCandidate> Convert(TVector<TGenericName> names, TLocalSyntaxContext::TKeywords keywords) {
+ TCompletion ToCompletion(
+ TCompletionInput input,
+ TLocalSyntaxContext context,
+ TNameResponse response) const {
+ TCompletion completion = {
+ .CompletedToken = GetCompletedToken(input, context.EditRange),
+ .Candidates = Convert(std::move(response.RankedNames), std::move(context)),
+ };
+
+ if (response.NameHintLength) {
+ const auto length = *response.NameHintLength;
+ TEditRange editRange = {
+ .Begin = input.CursorPosition - length,
+ .Length = length,
+ };
+ completion.CompletedToken = GetCompletedToken(input, editRange);
+ }
+
+ return completion;
+ }
+
+ static TVector<TCandidate> Convert(TVector<TGenericName> names, TLocalSyntaxContext context) {
TVector<TCandidate> candidates;
+ candidates.reserve(names.size());
for (auto& name : names) {
- candidates.emplace_back(std::visit([&](auto&& name) -> TCandidate {
- using T = std::decay_t<decltype(name)>;
- if constexpr (std::is_base_of_v<TKeyword, T>) {
- TVector<TString>& seq = keywords[name.Content];
- seq.insert(std::begin(seq), name.Content);
- return {ECandidateKind::Keyword, FormatKeywords(seq)};
- }
- if constexpr (std::is_base_of_v<TPragmaName, T>) {
- return {ECandidateKind::PragmaName, std::move(name.Indentifier)};
- }
- if constexpr (std::is_base_of_v<TTypeName, T>) {
- return {ECandidateKind::TypeName, std::move(name.Indentifier)};
- }
- if constexpr (std::is_base_of_v<TFunctionName, T>) {
- name.Indentifier += "(";
- return {ECandidateKind::FunctionName, std::move(name.Indentifier)};
- }
- if constexpr (std::is_base_of_v<THintName, T>) {
- return {ECandidateKind::HintName, std::move(name.Indentifier)};
- }
- }, std::move(name)));
+ candidates.emplace_back(Convert(std::move(name), context));
}
return candidates;
}
- TConfiguration Configuration;
- ILocalSyntaxAnalysis::TPtr SyntaxAnalysis;
- INameService::TPtr Names;
+ static TCandidate Convert(TGenericName name, TLocalSyntaxContext& context) {
+ return std::visit([&](auto&& name) -> TCandidate {
+ using T = std::decay_t<decltype(name)>;
+
+ if constexpr (std::is_base_of_v<TKeyword, T>) {
+ TVector<TString>& seq = context.Keywords[name.Content];
+ seq.insert(std::begin(seq), name.Content);
+ return {ECandidateKind::Keyword, FormatKeywords(seq)};
+ }
+
+ if constexpr (std::is_base_of_v<TPragmaName, T>) {
+ return {ECandidateKind::PragmaName, std::move(name.Indentifier)};
+ }
+
+ if constexpr (std::is_base_of_v<TTypeName, T>) {
+ return {ECandidateKind::TypeName, std::move(name.Indentifier)};
+ }
+
+ if constexpr (std::is_base_of_v<TFunctionName, T>) {
+ name.Indentifier += "(";
+ return {ECandidateKind::FunctionName, std::move(name.Indentifier)};
+ }
+
+ if constexpr (std::is_base_of_v<THintName, T>) {
+ return {ECandidateKind::HintName, std::move(name.Indentifier)};
+ }
+
+ if constexpr (std::is_base_of_v<TFolderName, T>) {
+ name.Indentifier.append('/');
+ if (!context.Object->IsEnclosed) {
+ name.Indentifier = Quoted(std::move(name.Indentifier));
+ }
+ return {ECandidateKind::FolderName, std::move(name.Indentifier)};
+ }
+
+ if constexpr (std::is_base_of_v<TTableName, T>) {
+ if (!context.Object->IsEnclosed) {
+ name.Indentifier = Quoted(std::move(name.Indentifier));
+ }
+ return {ECandidateKind::TableName, std::move(name.Indentifier)};
+ }
+
+ if constexpr (std::is_base_of_v<TClusterName, T>) {
+ return {ECandidateKind::ClusterName, std::move(name.Indentifier)};
+ }
+
+ if constexpr (std::is_base_of_v<TUnkownName, T>) {
+ return {ECandidateKind::UnknownName, std::move(name.Content)};
+ }
+ }, std::move(name));
+ }
+
+ TConfiguration Configuration_;
+ ILocalSyntaxAnalysis::TPtr SyntaxAnalysis_;
+ INameService::TPtr Names_;
};
ISqlCompletionEngine::TPtr MakeSqlCompletionEngine(
@@ -162,6 +226,18 @@ void Out<NSQLComplete::ECandidateKind>(IOutputStream& out, NSQLComplete::ECandid
case NSQLComplete::ECandidateKind::HintName:
out << "HintName";
break;
+ case NSQLComplete::ECandidateKind::FolderName:
+ out << "FolderName";
+ break;
+ case NSQLComplete::ECandidateKind::TableName:
+ out << "TableName";
+ break;
+ case NSQLComplete::ECandidateKind::ClusterName:
+ out << "ClusterName";
+ break;
+ case NSQLComplete::ECandidateKind::UnknownName:
+ out << "UnknownName";
+ break;
}
}