summaryrefslogtreecommitdiffstats
path: root/yql/essentials/sql/v1/complete/sql_complete.cpp
diff options
context:
space:
mode:
authorrobot-piglet <[email protected]>2025-02-28 19:58:58 +0300
committerrobot-piglet <[email protected]>2025-02-28 20:15:53 +0300
commit77397379b6394220a2dfd2802f417cdd8c214905 (patch)
tree0921befe1120e354ab5a47cb126df6bc54b7483a /yql/essentials/sql/v1/complete/sql_complete.cpp
parenteae2230242d713b9044f14d0920dd0845d03145c (diff)
Intermediate changes
commit_hash:5fc851d2c72810067fe0d407b66535b17de63129
Diffstat (limited to 'yql/essentials/sql/v1/complete/sql_complete.cpp')
-rw-r--r--yql/essentials/sql/v1/complete/sql_complete.cpp89
1 files changed, 89 insertions, 0 deletions
diff --git a/yql/essentials/sql/v1/complete/sql_complete.cpp b/yql/essentials/sql/v1/complete/sql_complete.cpp
new file mode 100644
index 00000000000..2a16a250e54
--- /dev/null
+++ b/yql/essentials/sql/v1/complete/sql_complete.cpp
@@ -0,0 +1,89 @@
+#include "sql_complete.h"
+
+#include "sql_context.h"
+#include "string_util.h"
+
+#include <util/generic/algorithm.h>
+#include <util/charset/utf8.h>
+
+namespace NSQLComplete {
+
+ class TSqlCompletionEngine: public ISqlCompletionEngine {
+ public:
+ TSqlCompletionEngine()
+ : ContextInference(MakeSqlContextInference())
+ {
+ }
+
+ TCompletion Complete(TCompletionInput input) {
+ auto prefix = input.Text.Head(input.CursorPosition);
+ auto completedToken = GetCompletedToken(prefix);
+
+ auto context = ContextInference->Analyze(input);
+
+ TVector<TCandidate> candidates;
+ EnrichWithKeywords(candidates, context.Keywords);
+
+ FilterByContent(candidates, completedToken.Content);
+
+ RankingSort(candidates);
+
+ return {
+ .CompletedToken = std::move(completedToken),
+ .Candidates = std::move(candidates),
+ };
+ }
+
+ private:
+ TCompletedToken GetCompletedToken(TStringBuf prefix) {
+ return {
+ .Content = LastWord(prefix),
+ .SourcePosition = LastWordIndex(prefix),
+ };
+ }
+
+ void EnrichWithKeywords(TVector<TCandidate>& candidates, TVector<TString> keywords) {
+ for (auto keyword : keywords) {
+ candidates.push_back({
+ .Kind = ECandidateKind::Keyword,
+ .Content = std::move(keyword),
+ });
+ }
+ }
+
+ void FilterByContent(TVector<TCandidate>& candidates, TStringBuf prefix) {
+ const auto lowerPrefix = ToLowerUTF8(prefix);
+ auto removed = std::ranges::remove_if(candidates, [&](const auto& candidate) {
+ return !ToLowerUTF8(candidate.Content).StartsWith(lowerPrefix);
+ });
+ candidates.erase(std::begin(removed), std::end(removed));
+ }
+
+ void RankingSort(TVector<TCandidate>& candidates) {
+ Sort(candidates, [](const TCandidate& lhs, const TCandidate& rhs) {
+ return std::tie(lhs.Kind, lhs.Content) < std::tie(rhs.Kind, rhs.Content);
+ });
+ }
+
+ ISqlContextInference::TPtr ContextInference;
+ };
+
+ ISqlCompletionEngine::TPtr MakeSqlCompletionEngine() {
+ return ISqlCompletionEngine::TPtr(new TSqlCompletionEngine());
+ }
+
+} // namespace NSQLComplete
+
+template <>
+void Out<NSQLComplete::ECandidateKind>(IOutputStream& out, NSQLComplete::ECandidateKind kind) {
+ switch (kind) {
+ case NSQLComplete::ECandidateKind::Keyword:
+ out << "Keyword";
+ break;
+ }
+}
+
+template <>
+void Out<NSQLComplete::TCandidate>(IOutputStream& out, const NSQLComplete::TCandidate& candidate) {
+ out << "(" << candidate.Kind << ": " << candidate.Content << ")";
+}