aboutsummaryrefslogtreecommitdiffstats
path: root/yql/essentials/sql/v1/complete
diff options
context:
space:
mode:
authorvitya-smirnov <vitya-smirnov@yandex-team.com>2025-06-26 16:37:42 +0300
committervitya-smirnov <vitya-smirnov@yandex-team.com>2025-06-26 17:24:30 +0300
commit633c9e434ac33037ba01b36a8f2937034903fe9f (patch)
treee620cfd34faf4354d3d25d05b564def09445118a /yql/essentials/sql/v1/complete
parente99c3783c2970a70b35b1c67ba177fe940936aae (diff)
downloadydb-633c9e434ac33037ba01b36a8f2937034903fe9f.tar.gz
YQL-19747: Refactor SQL completion engine
Some refactorings to compact the code: - YQL-19747: Pass TParsedInput to visitor - YQL-19747: Add TParsedInput - YQL-19747: Cosmetics - YQL-19747: Refactor configuration - YQL-19747: Refactor name to candidate mapping commit_hash:44dfe7dc7bcc627ef9c20696077f2d962a3014f6
Diffstat (limited to 'yql/essentials/sql/v1/complete')
-rw-r--r--yql/essentials/sql/v1/complete/analysis/global/column.cpp11
-rw-r--r--yql/essentials/sql/v1/complete/analysis/global/column.h7
-rw-r--r--yql/essentials/sql/v1/complete/analysis/global/function.cpp11
-rw-r--r--yql/essentials/sql/v1/complete/analysis/global/function.h7
-rw-r--r--yql/essentials/sql/v1/complete/analysis/global/global.cpp35
-rw-r--r--yql/essentials/sql/v1/complete/analysis/global/input.cpp1
-rw-r--r--yql/essentials/sql/v1/complete/analysis/global/input.h16
-rw-r--r--yql/essentials/sql/v1/complete/analysis/global/named_node.cpp14
-rw-r--r--yql/essentials/sql/v1/complete/analysis/global/named_node.h7
-rw-r--r--yql/essentials/sql/v1/complete/analysis/global/narrowing_visitor.cpp6
-rw-r--r--yql/essentials/sql/v1/complete/analysis/global/narrowing_visitor.h4
-rw-r--r--yql/essentials/sql/v1/complete/analysis/global/use.cpp16
-rw-r--r--yql/essentials/sql/v1/complete/analysis/global/use.h8
-rw-r--r--yql/essentials/sql/v1/complete/analysis/global/ya.make1
-rw-r--r--yql/essentials/sql/v1/complete/configuration.cpp62
-rw-r--r--yql/essentials/sql/v1/complete/configuration.h28
-rw-r--r--yql/essentials/sql/v1/complete/name/service/name_service.h4
-rw-r--r--yql/essentials/sql/v1/complete/name/service/ranking/ranking.cpp2
-rw-r--r--yql/essentials/sql/v1/complete/name/service/schema/name_service.cpp2
-rw-r--r--yql/essentials/sql/v1/complete/name_mapping.cpp147
-rw-r--r--yql/essentials/sql/v1/complete/name_mapping.h14
-rw-r--r--yql/essentials/sql/v1/complete/sql_complete.cpp204
-rw-r--r--yql/essentials/sql/v1/complete/sql_complete.h24
-rw-r--r--yql/essentials/sql/v1/complete/ya.make2
24 files changed, 336 insertions, 297 deletions
diff --git a/yql/essentials/sql/v1/complete/analysis/global/column.cpp b/yql/essentials/sql/v1/complete/analysis/global/column.cpp
index 9a9fd7f18a2..5cecb40fb13 100644
--- a/yql/essentials/sql/v1/complete/analysis/global/column.cpp
+++ b/yql/essentials/sql/v1/complete/analysis/global/column.cpp
@@ -220,8 +220,8 @@ namespace NSQLComplete {
class TVisitor: public TSQLv1NarrowingVisitor {
public:
- TVisitor(antlr4::TokenStream* tokens, size_t cursorPosition)
- : TSQLv1NarrowingVisitor(tokens, cursorPosition)
+ TVisitor(const TParsedInput& input)
+ : TSQLv1NarrowingVisitor(input)
{
}
@@ -247,12 +247,9 @@ namespace NSQLComplete {
} // namespace
- TMaybe<TColumnContext> InferColumnContext(
- SQLv1::Sql_queryContext* ctx,
- antlr4::TokenStream* tokens,
- size_t cursorPosition) {
+ TMaybe<TColumnContext> InferColumnContext(TParsedInput input) {
// TODO: add utility `auto ToMaybe<T>(std::any any) -> TMaybe<T>`
- std::any result = TVisitor(tokens, cursorPosition).visit(ctx);
+ std::any result = TVisitor(input).visit(input.SqlQuery);
if (!result.has_value()) {
return Nothing();
}
diff --git a/yql/essentials/sql/v1/complete/analysis/global/column.h b/yql/essentials/sql/v1/complete/analysis/global/column.h
index 790dbee1d15..306626ba061 100644
--- a/yql/essentials/sql/v1/complete/analysis/global/column.h
+++ b/yql/essentials/sql/v1/complete/analysis/global/column.h
@@ -1,13 +1,10 @@
#pragma once
#include "global.h"
-#include "parse_tree.h"
+#include "input.h"
namespace NSQLComplete {
- TMaybe<TColumnContext> InferColumnContext(
- SQLv1::Sql_queryContext* ctx,
- antlr4::TokenStream* tokens,
- size_t cursorPosition);
+ TMaybe<TColumnContext> InferColumnContext(TParsedInput input);
} // namespace NSQLComplete
diff --git a/yql/essentials/sql/v1/complete/analysis/global/function.cpp b/yql/essentials/sql/v1/complete/analysis/global/function.cpp
index 16140bc614e..0bd9740796a 100644
--- a/yql/essentials/sql/v1/complete/analysis/global/function.cpp
+++ b/yql/essentials/sql/v1/complete/analysis/global/function.cpp
@@ -8,8 +8,8 @@ namespace NSQLComplete {
class TVisitor: public TSQLv1NarrowingVisitor {
public:
- TVisitor(antlr4::TokenStream* tokens, size_t cursorPosition)
- : TSQLv1NarrowingVisitor(tokens, cursorPosition)
+ TVisitor(const TParsedInput& input)
+ : TSQLv1NarrowingVisitor(input)
{
}
@@ -37,11 +37,8 @@ namespace NSQLComplete {
} // namespace
- TMaybe<TString> EnclosingFunction(
- SQLv1::Sql_queryContext* ctx,
- antlr4::TokenStream* tokens,
- size_t cursorPosition) {
- std::any result = TVisitor(tokens, cursorPosition).visit(ctx);
+ TMaybe<TString> EnclosingFunction(TParsedInput input) {
+ std::any result = TVisitor(input).visit(input.SqlQuery);
if (!result.has_value()) {
return Nothing();
}
diff --git a/yql/essentials/sql/v1/complete/analysis/global/function.h b/yql/essentials/sql/v1/complete/analysis/global/function.h
index bb94e71318e..77f1478c5cc 100644
--- a/yql/essentials/sql/v1/complete/analysis/global/function.h
+++ b/yql/essentials/sql/v1/complete/analysis/global/function.h
@@ -1,15 +1,12 @@
#pragma once
-#include "parse_tree.h"
+#include "input.h"
#include <util/generic/maybe.h>
#include <util/generic/string.h>
namespace NSQLComplete {
- TMaybe<TString> EnclosingFunction(
- SQLv1::Sql_queryContext* ctx,
- antlr4::TokenStream* tokens,
- size_t cursorPosition);
+ TMaybe<TString> EnclosingFunction(TParsedInput input);
} // namespace NSQLComplete
diff --git a/yql/essentials/sql/v1/complete/analysis/global/global.cpp b/yql/essentials/sql/v1/complete/analysis/global/global.cpp
index f11447c1f12..5bdba0714b3 100644
--- a/yql/essentials/sql/v1/complete/analysis/global/global.cpp
+++ b/yql/essentials/sql/v1/complete/analysis/global/global.cpp
@@ -2,6 +2,7 @@
#include "column.h"
#include "function.h"
+#include "input.h"
#include "named_node.h"
#include "parse_tree.h"
#include "use.h"
@@ -87,18 +88,10 @@ namespace NSQLComplete {
template <bool IsAnsiLexer>
class TSpecializedGlobalAnalysis: public IGlobalAnalysis {
public:
- using TDefaultYQLGrammar = TAntlrGrammar<
- NALADefaultAntlr4::SQLv1Antlr4Lexer,
- NALADefaultAntlr4::SQLv1Antlr4Parser>;
-
- using TAnsiYQLGrammar = TAntlrGrammar<
- NALAAnsiAntlr4::SQLv1Antlr4Lexer,
- NALAAnsiAntlr4::SQLv1Antlr4Parser>;
-
- using G = std::conditional_t<
+ using TLexer = std::conditional_t<
IsAnsiLexer,
- TAnsiYQLGrammar,
- TDefaultYQLGrammar>;
+ NALAAnsiAntlr4::SQLv1Antlr4Lexer,
+ NALADefaultAntlr4::SQLv1Antlr4Lexer>;
TSpecializedGlobalAnalysis()
: Chars_()
@@ -128,11 +121,17 @@ namespace NSQLComplete {
TGlobalContext ctx;
- // TODO(YQL-19747): Add ~ParseContext(Tokens, ParseTree, CursorPosition)
- ctx.Use = FindUseStatement(sqlQuery, &Tokens_, input.CursorPosition, env);
- ctx.Names = CollectNamedNodes(sqlQuery, &Tokens_, input.CursorPosition);
- ctx.EnclosingFunction = EnclosingFunction(sqlQuery, &Tokens_, input.CursorPosition);
- ctx.Column = InferColumnContext(sqlQuery, &Tokens_, input.CursorPosition);
+ TParsedInput parsed = {
+ .Original = input,
+ .Tokens = &Tokens_,
+ .Parser = &Parser_,
+ .SqlQuery = sqlQuery,
+ };
+
+ ctx.Use = FindUseStatement(parsed, env);
+ ctx.Names = CollectNamedNodes(parsed);
+ ctx.EnclosingFunction = EnclosingFunction(parsed);
+ ctx.Column = InferColumnContext(parsed);
if (ctx.Use && ctx.Column) {
EnrichTableClusters(*ctx.Column, *ctx.Use);
@@ -176,9 +175,9 @@ namespace NSQLComplete {
}
antlr4::ANTLRInputStream Chars_;
- G::TLexer Lexer_;
+ TLexer Lexer_;
antlr4::CommonTokenStream Tokens_;
- TDefaultYQLGrammar::TParser Parser_;
+ SQLv1 Parser_;
};
class TGlobalAnalysis: public IGlobalAnalysis {
diff --git a/yql/essentials/sql/v1/complete/analysis/global/input.cpp b/yql/essentials/sql/v1/complete/analysis/global/input.cpp
new file mode 100644
index 00000000000..018d9c796f3
--- /dev/null
+++ b/yql/essentials/sql/v1/complete/analysis/global/input.cpp
@@ -0,0 +1 @@
+#include "input.h"
diff --git a/yql/essentials/sql/v1/complete/analysis/global/input.h b/yql/essentials/sql/v1/complete/analysis/global/input.h
new file mode 100644
index 00000000000..3f40ec1f31d
--- /dev/null
+++ b/yql/essentials/sql/v1/complete/analysis/global/input.h
@@ -0,0 +1,16 @@
+#pragma once
+
+#include "parse_tree.h"
+
+#include <yql/essentials/sql/v1/complete/core/input.h>
+
+namespace NSQLComplete {
+
+ struct TParsedInput {
+ TCompletionInput Original;
+ antlr4::CommonTokenStream* Tokens;
+ SQLv1* Parser;
+ SQLv1::Sql_queryContext* SqlQuery;
+ };
+
+} // namespace NSQLComplete
diff --git a/yql/essentials/sql/v1/complete/analysis/global/named_node.cpp b/yql/essentials/sql/v1/complete/analysis/global/named_node.cpp
index 0896b508432..57223e73405 100644
--- a/yql/essentials/sql/v1/complete/analysis/global/named_node.cpp
+++ b/yql/essentials/sql/v1/complete/analysis/global/named_node.cpp
@@ -14,11 +14,8 @@ namespace NSQLComplete {
class TVisitor: public TSQLv1NarrowingVisitor {
public:
- TVisitor(
- antlr4::TokenStream* tokens,
- size_t cursorPosition,
- THashSet<TString>* names)
- : TSQLv1NarrowingVisitor(tokens, cursorPosition)
+ TVisitor(const TParsedInput& input, THashSet<TString>* names)
+ : TSQLv1NarrowingVisitor(input)
, Names_(names)
{
}
@@ -110,12 +107,9 @@ namespace NSQLComplete {
} // namespace
- TVector<TString> CollectNamedNodes(
- SQLv1::Sql_queryContext* ctx,
- antlr4::TokenStream* tokens,
- size_t cursorPosition) {
+ TVector<TString> CollectNamedNodes(TParsedInput input) {
THashSet<TString> names;
- TVisitor(tokens, cursorPosition, &names).visit(ctx);
+ TVisitor(input, &names).visit(input.SqlQuery);
return TVector<TString>(begin(names), end(names));
}
diff --git a/yql/essentials/sql/v1/complete/analysis/global/named_node.h b/yql/essentials/sql/v1/complete/analysis/global/named_node.h
index 119fbc4d5f6..55466765013 100644
--- a/yql/essentials/sql/v1/complete/analysis/global/named_node.h
+++ b/yql/essentials/sql/v1/complete/analysis/global/named_node.h
@@ -1,15 +1,12 @@
#pragma once
-#include "parse_tree.h"
+#include "input.h"
#include <util/generic/string.h>
#include <util/generic/vector.h>
namespace NSQLComplete {
- TVector<TString> CollectNamedNodes(
- SQLv1::Sql_queryContext* ctx,
- antlr4::TokenStream* tokens,
- size_t cursorPosition);
+ TVector<TString> CollectNamedNodes(TParsedInput input);
} // namespace NSQLComplete
diff --git a/yql/essentials/sql/v1/complete/analysis/global/narrowing_visitor.cpp b/yql/essentials/sql/v1/complete/analysis/global/narrowing_visitor.cpp
index f1cd303062c..95f5e1c13bd 100644
--- a/yql/essentials/sql/v1/complete/analysis/global/narrowing_visitor.cpp
+++ b/yql/essentials/sql/v1/complete/analysis/global/narrowing_visitor.cpp
@@ -2,9 +2,9 @@
namespace NSQLComplete {
- TSQLv1NarrowingVisitor::TSQLv1NarrowingVisitor(antlr4::TokenStream* tokens, size_t cursorPosition)
- : Tokens_(tokens)
- , CursorPosition_(cursorPosition)
+ TSQLv1NarrowingVisitor::TSQLv1NarrowingVisitor(const TParsedInput& input)
+ : Tokens_(input.Tokens)
+ , CursorPosition_(input.Original.CursorPosition)
{
}
diff --git a/yql/essentials/sql/v1/complete/analysis/global/narrowing_visitor.h b/yql/essentials/sql/v1/complete/analysis/global/narrowing_visitor.h
index 1ad4bbe2274..759ad5bd37c 100644
--- a/yql/essentials/sql/v1/complete/analysis/global/narrowing_visitor.h
+++ b/yql/essentials/sql/v1/complete/analysis/global/narrowing_visitor.h
@@ -1,13 +1,13 @@
#pragma once
#include "base_visitor.h"
-#include "parse_tree.h"
+#include "input.h"
namespace NSQLComplete {
class TSQLv1NarrowingVisitor: public TSQLv1BaseVisitor {
public:
- TSQLv1NarrowingVisitor(antlr4::TokenStream* tokens, size_t cursorPosition);
+ TSQLv1NarrowingVisitor(const TParsedInput& input);
protected:
bool shouldVisitNextChild(antlr4::tree::ParseTree* node, const std::any& /*currentResult*/) override;
diff --git a/yql/essentials/sql/v1/complete/analysis/global/use.cpp b/yql/essentials/sql/v1/complete/analysis/global/use.cpp
index d9a430ec12b..ce592b724c3 100644
--- a/yql/essentials/sql/v1/complete/analysis/global/use.cpp
+++ b/yql/essentials/sql/v1/complete/analysis/global/use.cpp
@@ -9,11 +9,8 @@ namespace NSQLComplete {
class TVisitor: public TSQLv1NarrowingVisitor {
public:
- TVisitor(
- antlr4::TokenStream* tokens,
- size_t cursorPosition,
- const TEnvironment* env)
- : TSQLv1NarrowingVisitor(tokens, cursorPosition)
+ TVisitor(const TParsedInput& input, const TEnvironment* env)
+ : TSQLv1NarrowingVisitor(input)
, Env_(env)
{
}
@@ -78,12 +75,9 @@ namespace NSQLComplete {
} // namespace
- TMaybe<TUseContext> FindUseStatement(
- SQLv1::Sql_queryContext* ctx,
- antlr4::TokenStream* tokens,
- size_t cursorPosition,
- const TEnvironment& env) {
- std::any result = TVisitor(tokens, cursorPosition, &env).visit(ctx);
+ // TODO(YQL-19747): Use any to maybe conversion function
+ TMaybe<TUseContext> FindUseStatement(TParsedInput input, const TEnvironment& env) {
+ std::any result = TVisitor(input, &env).visit(input.SqlQuery);
if (!result.has_value()) {
return Nothing();
}
diff --git a/yql/essentials/sql/v1/complete/analysis/global/use.h b/yql/essentials/sql/v1/complete/analysis/global/use.h
index 0cdb9b15469..964519e4e99 100644
--- a/yql/essentials/sql/v1/complete/analysis/global/use.h
+++ b/yql/essentials/sql/v1/complete/analysis/global/use.h
@@ -1,7 +1,7 @@
#pragma once
#include "global.h"
-#include "parse_tree.h"
+#include "input.h"
#include <util/generic/ptr.h>
#include <util/generic/maybe.h>
@@ -9,10 +9,6 @@
namespace NSQLComplete {
- TMaybe<TUseContext> FindUseStatement(
- SQLv1::Sql_queryContext* ctx,
- antlr4::TokenStream* tokens,
- size_t cursorPosition,
- const TEnvironment& env);
+ TMaybe<TUseContext> FindUseStatement(TParsedInput input, const TEnvironment& env);
} // namespace NSQLComplete
diff --git a/yql/essentials/sql/v1/complete/analysis/global/ya.make b/yql/essentials/sql/v1/complete/analysis/global/ya.make
index b67f290a3be..25c83108230 100644
--- a/yql/essentials/sql/v1/complete/analysis/global/ya.make
+++ b/yql/essentials/sql/v1/complete/analysis/global/ya.make
@@ -6,6 +6,7 @@ SRCS(
evaluate.cpp
function.cpp
global.cpp
+ input.cpp
named_node.cpp
narrowing_visitor.cpp
parse_tree.cpp
diff --git a/yql/essentials/sql/v1/complete/configuration.cpp b/yql/essentials/sql/v1/complete/configuration.cpp
new file mode 100644
index 00000000000..9dbba885b2c
--- /dev/null
+++ b/yql/essentials/sql/v1/complete/configuration.cpp
@@ -0,0 +1,62 @@
+#include "configuration.h"
+
+#include <yql/essentials/sql/v1/complete/syntax/grammar.h>
+
+namespace NSQLComplete {
+
+ TConfiguration MakeConfiguration(THashSet<TString> allowedStmts) {
+ allowedStmts.emplace("sql_stmt");
+
+ TConfiguration config;
+ for (const std::string& name : GetSqlGrammar().GetAllRules()) {
+ if (name.ends_with("_stmt") && !allowedStmts.contains(name)) {
+ config.IgnoredRules_.emplace(name);
+ }
+ }
+ return config;
+ }
+
+ TConfiguration MakeYDBConfiguration() {
+ TConfiguration config;
+ config.IgnoredRules_ = {
+ "use_stmt",
+ "import_stmt",
+ "export_stmt",
+ };
+ return config;
+ }
+
+ TConfiguration MakeYQLConfiguration() {
+ auto config = MakeConfiguration(/* allowedStmts = */ {
+ "lambda_stmt",
+ "pragma_stmt",
+ "select_stmt",
+ "named_nodes_stmt",
+ "drop_table_stmt",
+ "use_stmt",
+ "into_table_stmt",
+ "commit_stmt",
+ "declare_stmt",
+ "import_stmt",
+ "export_stmt",
+ "do_stmt",
+ "define_action_or_subquery_stmt",
+ "if_stmt",
+ "for_stmt",
+ "values_stmt",
+ });
+
+ config.DisabledPreviousByToken_ = {};
+
+ config.ForcedPreviousByToken_ = {
+ {"PARALLEL", {}},
+ {"TABLESTORE", {}},
+ {"FOR", {"EVALUATE"}},
+ {"IF", {"EVALUATE"}},
+ {"EXTERNAL", {"USING"}},
+ };
+
+ return config;
+ }
+
+} // namespace NSQLComplete
diff --git a/yql/essentials/sql/v1/complete/configuration.h b/yql/essentials/sql/v1/complete/configuration.h
new file mode 100644
index 00000000000..620207bfcf2
--- /dev/null
+++ b/yql/essentials/sql/v1/complete/configuration.h
@@ -0,0 +1,28 @@
+#pragma once
+
+#include <util/generic/string.h>
+#include <util/generic/hash.h>
+#include <util/generic/hash_set.h>
+
+namespace NSQLComplete {
+
+ struct TConfiguration {
+ friend class TSqlCompletionEngine;
+ friend TConfiguration MakeYDBConfiguration();
+ friend TConfiguration MakeYQLConfiguration();
+ friend TConfiguration MakeConfiguration(THashSet<TString> allowedStmts);
+
+ public:
+ size_t Limit = 256;
+
+ private:
+ THashSet<TString> IgnoredRules_;
+ THashMap<TString, THashSet<TString>> DisabledPreviousByToken_;
+ THashMap<TString, THashSet<TString>> ForcedPreviousByToken_;
+ };
+
+ TConfiguration MakeYDBConfiguration();
+
+ TConfiguration MakeYQLConfiguration();
+
+} // namespace NSQLComplete
diff --git a/yql/essentials/sql/v1/complete/name/service/name_service.h b/yql/essentials/sql/v1/complete/name/service/name_service.h
index e4971b86250..a5d793835ee 100644
--- a/yql/essentials/sql/v1/complete/name/service/name_service.h
+++ b/yql/essentials/sql/v1/complete/name/service/name_service.h
@@ -78,7 +78,7 @@ namespace NSQLComplete {
struct TBindingName: TIndentifier {
};
- struct TUnkownName {
+ struct TUnknownName {
TString Content;
TString Type;
};
@@ -94,7 +94,7 @@ namespace NSQLComplete {
TClusterName,
TColumnName,
TBindingName,
- TUnkownName>;
+ TUnknownName>;
struct TNameConstraints {
TMaybe<TPragmaName::TConstraints> Pragma;
diff --git a/yql/essentials/sql/v1/complete/name/service/ranking/ranking.cpp b/yql/essentials/sql/v1/complete/name/service/ranking/ranking.cpp
index d8e0e0ff1bb..09edce52123 100644
--- a/yql/essentials/sql/v1/complete/name/service/ranking/ranking.cpp
+++ b/yql/essentials/sql/v1/complete/name/service/ranking/ranking.cpp
@@ -118,7 +118,7 @@ namespace NSQLComplete {
if constexpr (std::is_base_of_v<TIndentifier, T>) {
return name.Indentifier;
}
- if constexpr (std::is_base_of_v<TUnkownName, T>) {
+ if constexpr (std::is_base_of_v<TUnknownName, T>) {
return name.Content;
}
}, name);
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 736f7c3090e..3b13ec93784 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
@@ -130,7 +130,7 @@ namespace NSQLComplete {
local.Indentifier = std::move(entry.Name);
name = std::move(local);
} else {
- TUnkownName local;
+ TUnknownName local;
local.Content = std::move(entry.Name);
local.Type = std::move(entry.Type);
name = std::move(local);
diff --git a/yql/essentials/sql/v1/complete/name_mapping.cpp b/yql/essentials/sql/v1/complete/name_mapping.cpp
new file mode 100644
index 00000000000..541188ea8c8
--- /dev/null
+++ b/yql/essentials/sql/v1/complete/name_mapping.cpp
@@ -0,0 +1,147 @@
+#include "name_mapping.h"
+
+#include <yql/essentials/sql/v1/complete/syntax/format.h>
+
+namespace NSQLComplete {
+
+ TCandidate ToCandidate(TKeyword name, TLocalSyntaxContext& context) {
+ TVector<TString>& seq = context.Keywords[name.Content];
+ seq.insert(std::begin(seq), name.Content);
+
+ TCandidate candidate = {
+ .Kind = ECandidateKind::Keyword,
+ .Content = FormatKeywords(seq),
+ };
+
+ if (candidate.Content.EndsWith('(')) {
+ candidate.Content += ')';
+ candidate.CursorShift = 1;
+ }
+
+ return candidate;
+ }
+
+ TCandidate ToCandidate(TPragmaName name) {
+ return {ECandidateKind::PragmaName, std::move(name.Indentifier)};
+ }
+
+ TCandidate ToCandidate(TTypeName name) {
+ TCandidate candidate = {
+ .Kind = ECandidateKind::TypeName,
+ .Content = std::move(name.Indentifier),
+ };
+
+ switch (name.Kind) {
+ case TTypeName::EKind::Simple: {
+ } break;
+ case TTypeName::EKind::Container: {
+ candidate.Content += "<>";
+ candidate.CursorShift = 1;
+ } break;
+ case TTypeName::EKind::Parameterized: {
+ candidate.Content += "()";
+ candidate.CursorShift = 1;
+ } break;
+ }
+
+ return candidate;
+ }
+
+ TCandidate ToCandidate(TFunctionName name) {
+ TCandidate candidate = {
+ .Kind = ECandidateKind::FunctionName,
+ .Content = std::move(name.Indentifier),
+ };
+
+ candidate.Content += "()";
+ candidate.CursorShift = 1;
+
+ return candidate;
+ }
+
+ TCandidate ToCandidate(THintName name) {
+ return {ECandidateKind::HintName, std::move(name.Indentifier)};
+ }
+
+ TCandidate ToCandidate(TFolderName name, TLocalSyntaxContext& context) {
+ TCandidate candidate = {
+ .Kind = ECandidateKind::FolderName,
+ .Content = std::move(name.Indentifier),
+ };
+
+ if (!context.IsQuoted.AtLhs) {
+ candidate.Content.prepend('`');
+ }
+
+ candidate.Content.append('/');
+
+ if (!context.IsQuoted.AtRhs) {
+ candidate.Content.append('`');
+ candidate.CursorShift = 1;
+ }
+
+ return candidate;
+ }
+
+ TCandidate ToCandidate(TTableName name, TLocalSyntaxContext& context) {
+ if (!context.IsQuoted.AtLhs) {
+ name.Indentifier.prepend('`');
+ }
+ if (!context.IsQuoted.AtRhs) {
+ name.Indentifier.append('`');
+ }
+ return {ECandidateKind::TableName, std::move(name.Indentifier)};
+ }
+
+ TCandidate ToCandidate(TClusterName name) {
+ return {ECandidateKind::ClusterName, std::move(name.Indentifier)};
+ }
+
+ TCandidate ToCandidate(TColumnName name, TLocalSyntaxContext& context) {
+ if (context.Column->Table.empty() && !name.TableAlias.empty()) {
+ name.Indentifier.prepend('.');
+ name.Indentifier.prepend(name.TableAlias);
+ }
+
+ return {ECandidateKind::ColumnName, std::move(name.Indentifier)};
+ }
+
+ TCandidate ToCandidate(TBindingName name, TLocalSyntaxContext& context) {
+ if (!context.Binding) {
+ name.Indentifier.prepend('$');
+ }
+ return {ECandidateKind::BindingName, std::move(name.Indentifier)};
+ }
+
+ TCandidate ToCandidate(TUnknownName name) {
+ return {ECandidateKind::UnknownName, std::move(name.Content)};
+ }
+
+ TCandidate ToCandidate(TGenericName generic, TLocalSyntaxContext& context) {
+ return std::visit([&](auto&& name) -> TCandidate {
+ using T = std::decay_t<decltype(name)>;
+ constexpr bool IsContextSensitive =
+ std::is_same_v<T, TKeyword> ||
+ std::is_same_v<T, TFolderName> ||
+ std::is_same_v<T, TTableName> ||
+ std::is_same_v<T, TColumnName> ||
+ std::is_same_v<T, TBindingName>;
+
+ if constexpr (IsContextSensitive) {
+ return ToCandidate(std::move(name), context);
+ } else {
+ return ToCandidate(std::move(name));
+ }
+ }, std::move(generic));
+ }
+
+ TVector<TCandidate> ToCandidate(TVector<TGenericName> names, TLocalSyntaxContext context) {
+ TVector<TCandidate> candidates;
+ candidates.reserve(names.size());
+ for (auto& name : names) {
+ candidates.emplace_back(ToCandidate(std::move(name), context));
+ }
+ return candidates;
+ }
+
+} // namespace NSQLComplete
diff --git a/yql/essentials/sql/v1/complete/name_mapping.h b/yql/essentials/sql/v1/complete/name_mapping.h
new file mode 100644
index 00000000000..0bde9ffd6dc
--- /dev/null
+++ b/yql/essentials/sql/v1/complete/name_mapping.h
@@ -0,0 +1,14 @@
+#pragma once
+
+#include "sql_complete.h"
+
+#include <yql/essentials/sql/v1/complete/analysis/local/local.h>
+#include <yql/essentials/sql/v1/complete/name/service/name_service.h>
+
+namespace NSQLComplete {
+
+ TCandidate ToCandidate(TGenericName name, TLocalSyntaxContext& context);
+
+ TVector<TCandidate> ToCandidate(TVector<TGenericName> names, TLocalSyntaxContext context);
+
+} // namespace NSQLComplete
diff --git a/yql/essentials/sql/v1/complete/sql_complete.cpp b/yql/essentials/sql/v1/complete/sql_complete.cpp
index 59cbeba1385..307bc432518 100644
--- a/yql/essentials/sql/v1/complete/sql_complete.cpp
+++ b/yql/essentials/sql/v1/complete/sql_complete.cpp
@@ -1,5 +1,7 @@
#include "sql_complete.h"
+#include "name_mapping.h"
+
#include <yql/essentials/sql/v1/complete/syntax/grammar.h>
#include <yql/essentials/sql/v1/complete/text/word.h>
#include <yql/essentials/sql/v1/complete/name/object/simple/static/schema.h>
@@ -23,7 +25,7 @@ namespace NSQLComplete {
TSqlCompletionEngine(
TLexerSupplier lexer,
INameService::TPtr names,
- ISqlCompletionEngine::TConfiguration configuration)
+ TConfiguration configuration)
: Configuration_(std::move(configuration))
, SyntaxAnalysis_(MakeLocalSyntaxAnalysis(
lexer,
@@ -41,10 +43,9 @@ namespace NSQLComplete {
}
NThreading::TFuture<TCompletion> CompleteAsync(TCompletionInput input, TEnvironment env) override {
- if (
- input.CursorPosition < input.Text.length() &&
- IsUTF8ContinuationByte(input.Text.at(input.CursorPosition)) ||
- input.Text.length() < input.CursorPosition) {
+ if ((input.CursorPosition < input.Text.length() &&
+ IsUTF8ContinuationByte(input.Text.at(input.CursorPosition))) ||
+ (input.Text.length() < input.CursorPosition)) {
ythrow yexception()
<< "invalid cursor position " << input.CursorPosition
<< " for input size " << input.Text.size();
@@ -167,13 +168,10 @@ namespace NSQLComplete {
return request;
}
- TCompletion ToCompletion(
- TCompletionInput input,
- TLocalSyntaxContext context,
- TNameResponse response) const {
+ 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)),
+ .Candidates = ToCandidate(std::move(response.RankedNames), std::move(context)),
};
if (response.NameHintLength) {
@@ -188,200 +186,16 @@ namespace NSQLComplete {
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(Convert(std::move(name), context));
- }
- return candidates;
- }
-
- // TODO(YQL-19747): extract to a separate file
- 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);
-
- TCandidate candidate = {
- .Kind = ECandidateKind::Keyword,
- .Content = FormatKeywords(seq),
- };
-
- if (candidate.Content.EndsWith('(')) {
- candidate.Content += ')';
- candidate.CursorShift = 1;
- }
-
- return candidate;
- }
-
- 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>) {
- TCandidate candidate = {
- .Kind = ECandidateKind::TypeName,
- .Content = std::move(name.Indentifier),
- };
-
- switch (name.Kind) {
- case TTypeName::EKind::Simple: {
- } break;
- case TTypeName::EKind::Container: {
- candidate.Content += "<>";
- candidate.CursorShift = 1;
- } break;
- case TTypeName::EKind::Parameterized: {
- candidate.Content += "()";
- candidate.CursorShift = 1;
- } break;
- }
-
- return candidate;
- }
-
- if constexpr (std::is_base_of_v<TFunctionName, T>) {
- TCandidate candidate = {
- .Kind = ECandidateKind::FunctionName,
- .Content = std::move(name.Indentifier),
- };
-
- candidate.Content += "()";
- candidate.CursorShift = 1;
-
- return candidate;
- }
-
- 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>) {
- TCandidate candidate = {
- .Kind = ECandidateKind::FolderName,
- .Content = std::move(name.Indentifier),
- };
-
- if (!context.IsQuoted.AtLhs) {
- candidate.Content.prepend('`');
- }
-
- candidate.Content.append('/');
-
- if (!context.IsQuoted.AtRhs) {
- candidate.Content.append('`');
- candidate.CursorShift = 1;
- }
-
- return candidate;
- }
-
- if constexpr (std::is_base_of_v<TTableName, T>) {
- if (!context.IsQuoted.AtLhs) {
- name.Indentifier.prepend('`');
- }
- if (!context.IsQuoted.AtRhs) {
- name.Indentifier.append('`');
- }
- 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<TColumnName, T>) {
- if (context.Column->Table.empty() && !name.TableAlias.empty()) {
- name.Indentifier.prepend('.');
- name.Indentifier.prepend(name.TableAlias);
- }
-
- return {ECandidateKind::ColumnName, std::move(name.Indentifier)};
- }
-
- if constexpr (std::is_base_of_v<TBindingName, T>) {
- if (!context.Binding) {
- name.Indentifier.prepend('$');
- }
- return {ECandidateKind::BindingName, 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_;
IGlobalAnalysis::TPtr GlobalAnalysis_;
INameService::TPtr Names_;
};
- ISqlCompletionEngine::TConfiguration MakeConfiguration(THashSet<TString> allowedStmts) {
- allowedStmts.emplace("sql_stmt");
-
- ISqlCompletionEngine::TConfiguration config;
- for (const std::string& name : GetSqlGrammar().GetAllRules()) {
- if (name.ends_with("_stmt") && !allowedStmts.contains(name)) {
- config.IgnoredRules_.emplace(name);
- }
- }
- return config;
- }
-
- ISqlCompletionEngine::TConfiguration MakeYDBConfiguration() {
- ISqlCompletionEngine::TConfiguration config;
- config.IgnoredRules_ = {
- "use_stmt",
- "import_stmt",
- "export_stmt",
- };
- return config;
- }
-
- ISqlCompletionEngine::TConfiguration MakeYQLConfiguration() {
- auto config = MakeConfiguration(/* allowedStmts = */ {
- "lambda_stmt",
- "pragma_stmt",
- "select_stmt",
- "named_nodes_stmt",
- "drop_table_stmt",
- "use_stmt",
- "into_table_stmt",
- "commit_stmt",
- "declare_stmt",
- "import_stmt",
- "export_stmt",
- "do_stmt",
- "define_action_or_subquery_stmt",
- "if_stmt",
- "for_stmt",
- "values_stmt",
- });
-
- config.DisabledPreviousByToken_ = {};
-
- config.ForcedPreviousByToken_ = {
- {"PARALLEL", {}},
- {"TABLESTORE", {}},
- {"FOR", {"EVALUATE"}},
- {"IF", {"EVALUATE"}},
- {"EXTERNAL", {"USING"}},
- };
-
- return config;
- }
-
ISqlCompletionEngine::TPtr MakeSqlCompletionEngine(
TLexerSupplier lexer,
INameService::TPtr names,
- ISqlCompletionEngine::TConfiguration configuration) {
+ TConfiguration configuration) {
return MakeHolder<TSqlCompletionEngine>(
lexer, std::move(names), std::move(configuration));
}
diff --git a/yql/essentials/sql/v1/complete/sql_complete.h b/yql/essentials/sql/v1/complete/sql_complete.h
index ce8a7c5296f..3387019e25f 100644
--- a/yql/essentials/sql/v1/complete/sql_complete.h
+++ b/yql/essentials/sql/v1/complete/sql_complete.h
@@ -1,5 +1,7 @@
#pragma once
+#include "configuration.h"
+
#include <yql/essentials/sql/v1/complete/core/input.h>
#include <yql/essentials/sql/v1/complete/core/environment.h>
#include <yql/essentials/sql/v1/complete/name/service/name_service.h>
@@ -51,20 +53,8 @@ namespace NSQLComplete {
public:
using TPtr = THolder<ISqlCompletionEngine>;
- struct TConfiguration {
- friend class TSqlCompletionEngine;
- friend ISqlCompletionEngine::TConfiguration MakeYDBConfiguration();
- friend ISqlCompletionEngine::TConfiguration MakeYQLConfiguration();
- friend ISqlCompletionEngine::TConfiguration MakeConfiguration(THashSet<TString> allowedStmts);
-
- public:
- size_t Limit = 256;
-
- private:
- THashSet<TString> IgnoredRules_;
- THashMap<TString, THashSet<TString>> DisabledPreviousByToken_;
- THashMap<TString, THashSet<TString>> ForcedPreviousByToken_;
- };
+ // TODO(YQL-19747): Deprecated, Migrate YDB CLI to `TConfiguration`
+ using TConfiguration = NSQLComplete::TConfiguration;
virtual ~ISqlCompletionEngine() = default;
@@ -77,13 +67,9 @@ namespace NSQLComplete {
using TLexerSupplier = std::function<NSQLTranslation::ILexer::TPtr(bool ansi)>;
- ISqlCompletionEngine::TConfiguration MakeYDBConfiguration();
-
- ISqlCompletionEngine::TConfiguration MakeYQLConfiguration();
-
ISqlCompletionEngine::TPtr MakeSqlCompletionEngine(
TLexerSupplier lexer,
INameService::TPtr names,
- ISqlCompletionEngine::TConfiguration configuration = {});
+ TConfiguration configuration = {});
} // namespace NSQLComplete
diff --git a/yql/essentials/sql/v1/complete/ya.make b/yql/essentials/sql/v1/complete/ya.make
index e85ba90b524..b0b5ee4be21 100644
--- a/yql/essentials/sql/v1/complete/ya.make
+++ b/yql/essentials/sql/v1/complete/ya.make
@@ -1,6 +1,8 @@
LIBRARY()
SRCS(
+ configuration.cpp
+ name_mapping.cpp
sql_complete.cpp
)