summaryrefslogtreecommitdiffstats
path: root/yql/essentials/sql/v1/complete/sql_context.cpp
diff options
context:
space:
mode:
authorvityaman <[email protected]>2025-03-27 23:28:33 +0300
committerrobot-piglet <[email protected]>2025-03-27 23:42:19 +0300
commitb24ce722d5cf848fcbe6c6f9b6fce9698174d3de (patch)
tree5bc1a78180c095f095db112917afd61450f9cf5a /yql/essentials/sql/v1/complete/sql_context.cpp
parent92d7e50254d1edaf2b664e13fba7a34d0dbc161f (diff)
YQL-19747 Split statements
When we run completion engine on multi-statement query, where preceding statements are syntactically incorrect, `antlr4-c3` does not return candidates. Running engine only on a current statement provides a best-effort attempt to provide candidates. - Related to https://github.com/ydb-platform/ydb/issues/9056 - Depends on https://github.com/ytsaurus/ytsaurus/pull/1127 (`ELexerFlavor`) --- Pull Request resolved: https://github.com/ytsaurus/ytsaurus/pull/1144 commit_hash:0ced9443a9712191f5420246531f781ca4bc5f42
Diffstat (limited to 'yql/essentials/sql/v1/complete/sql_context.cpp')
-rw-r--r--yql/essentials/sql/v1/complete/sql_context.cpp41
1 files changed, 37 insertions, 4 deletions
diff --git a/yql/essentials/sql/v1/complete/sql_context.cpp b/yql/essentials/sql/v1/complete/sql_context.cpp
index 4195daa6d83..2bd1a2af987 100644
--- a/yql/essentials/sql/v1/complete/sql_context.cpp
+++ b/yql/essentials/sql/v1/complete/sql_context.cpp
@@ -3,6 +3,7 @@
#include "c3_engine.h"
#include "sql_syntax.h"
+#include <yql/essentials/core/issue/yql_issue.h>
#include <yql/essentials/parser/antlr_ast/gen/v1_antlr4/SQLv1Antlr4Lexer.h>
#include <yql/essentials/parser/antlr_ast/gen/v1_antlr4/SQLv1Antlr4Parser.h>
#include <yql/essentials/parser/antlr_ast/gen/v1_ansi_antlr4/SQLv1Antlr4Lexer.h>
@@ -30,14 +31,19 @@ namespace NSQLComplete {
TDefaultYQLGrammar>;
public:
- TSpecializedSqlContextInference()
+ explicit TSpecializedSqlContextInference(TLexerSupplier lexer)
: Grammar(&GetSqlGrammar(IsAnsiLexer))
+ , Lexer_(lexer(/* ansi = */ IsAnsiLexer))
, C3(ComputeC3Config())
{
}
TCompletionContext Analyze(TCompletionInput input) override {
- auto prefix = input.Text.Head(input.CursorPosition);
+ TStringBuf prefix;
+ if (!GetC3Prefix(input, &prefix)) {
+ return {};
+ }
+
auto tokens = C3.Complete(prefix);
return {
.Keywords = SiftedKeywords(tokens),
@@ -71,6 +77,26 @@ namespace NSQLComplete {
return preferredRules;
}
+ bool GetC3Prefix(TCompletionInput input, TStringBuf* prefix) {
+ *prefix = input.Text.Head(input.CursorPosition);
+
+ TVector<TString> statements;
+ NYql::TIssues issues;
+ if (!NSQLTranslationV1::SplitQueryToStatements(
+ TString(*prefix) + (prefix->EndsWith(';') ? ";" : ""), Lexer_,
+ statements, issues, /* file = */ "",
+ /* areBlankSkipped = */ false)) {
+ return false;
+ }
+
+ if (statements.empty()) {
+ return true;
+ }
+
+ *prefix = prefix->Last(statements.back().size());
+ return true;
+ }
+
TVector<TString> SiftedKeywords(const TVector<TSuggestedToken>& tokens) {
const auto& vocabulary = Grammar->GetVocabulary();
const auto& keywordTokens = Grammar->GetKeywordTokens();
@@ -85,11 +111,18 @@ namespace NSQLComplete {
}
const ISqlGrammar* Grammar;
+ NSQLTranslation::ILexer::TPtr Lexer_;
TC3Engine<G> C3;
};
class TSqlContextInference: public ISqlContextInference {
public:
+ explicit TSqlContextInference(TLexerSupplier lexer)
+ : DefaultEngine(lexer)
+ , AnsiEngine(lexer)
+ {
+ }
+
TCompletionContext Analyze(TCompletionInput input) override {
auto isAnsiLexer = IsAnsiQuery(TString(input.Text));
auto& engine = GetSpecializedEngine(isAnsiLexer);
@@ -108,8 +141,8 @@ namespace NSQLComplete {
TSpecializedSqlContextInference</* IsAnsiLexer = */ true> AnsiEngine;
};
- ISqlContextInference::TPtr MakeSqlContextInference() {
- return TSqlContextInference::TPtr(new TSqlContextInference());
+ ISqlContextInference::TPtr MakeSqlContextInference(TLexerSupplier lexer) {
+ return TSqlContextInference::TPtr(new TSqlContextInference(lexer));
}
} // namespace NSQLComplete