Skip to content

Commit 64d942a

Browse files
vityamanrobot-piglet
authored andcommitted
YQL-19747: Support table completion at CONCAT
--- - Related to `YQL-19747` - Related to vityaman#62 --- Pull Request resolved: ytsaurus/ytsaurus#1323 commit_hash:ebab6c3290ba984174c85bba35eeb066b53af5aa
1 parent a4f3769 commit 64d942a

File tree

11 files changed

+141
-13
lines changed

11 files changed

+141
-13
lines changed
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
#include "function.h"
2+
3+
#include "narrowing_visitor.h"
4+
5+
namespace NSQLComplete {
6+
7+
namespace {
8+
9+
class TVisitor: public TSQLv1NarrowingVisitor {
10+
public:
11+
TVisitor(antlr4::TokenStream* tokens, size_t cursorPosition)
12+
: TSQLv1NarrowingVisitor(tokens, cursorPosition)
13+
{
14+
}
15+
16+
std::any visit(antlr4::tree::ParseTree* tree) override {
17+
if (IsEnclosing(tree)) {
18+
return TSQLv1NarrowingVisitor::visit(tree);
19+
}
20+
return {};
21+
}
22+
23+
std::any visitTable_ref(SQLv1::Table_refContext* ctx) override {
24+
auto* function = ctx->an_id_expr();
25+
auto* lparen = ctx->TOKEN_LPAREN();
26+
if (function == nullptr || lparen == nullptr) {
27+
return {};
28+
}
29+
30+
if (CursorPosition() <= TextInterval(lparen).b) {
31+
return {};
32+
}
33+
34+
return function->getText();
35+
}
36+
};
37+
38+
} // namespace
39+
40+
TMaybe<TString> EnclosingFunction(
41+
SQLv1::Sql_queryContext* ctx,
42+
antlr4::TokenStream* tokens,
43+
size_t cursorPosition) {
44+
std::any result = TVisitor(tokens, cursorPosition).visit(ctx);
45+
if (!result.has_value()) {
46+
return Nothing();
47+
}
48+
return std::any_cast<std::string>(result);
49+
}
50+
51+
} // namespace NSQLComplete
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
#pragma once
2+
3+
#include "parse_tree.h"
4+
5+
#include <util/generic/maybe.h>
6+
#include <util/generic/string.h>
7+
8+
namespace NSQLComplete {
9+
10+
TMaybe<TString> EnclosingFunction(
11+
SQLv1::Sql_queryContext* ctx,
12+
antlr4::TokenStream* tokens,
13+
size_t cursorPosition);
14+
15+
} // namespace NSQLComplete

yql/essentials/sql/v1/complete/analysis/global/global.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
#include "global.h"
22

3+
#include "function.h"
34
#include "named_node.h"
45
#include "parse_tree.h"
56
#include "use.h"
@@ -52,6 +53,7 @@ namespace NSQLComplete {
5253
// TODO(YQL-19747): Add ~ParseContext(Tokens, ParseTree, CursorPosition)
5354
ctx.Use = FindUseStatement(sqlQuery, &Tokens_, input.CursorPosition, env);
5455
ctx.Names = CollectNamedNodes(sqlQuery, &Tokens_, input.CursorPosition);
56+
ctx.EnclosingFunction = EnclosingFunction(sqlQuery, &Tokens_, input.CursorPosition);
5557

5658
return ctx;
5759
}

yql/essentials/sql/v1/complete/analysis/global/global.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ namespace NSQLComplete {
1818
struct TGlobalContext {
1919
TMaybe<TUseContext> Use;
2020
TVector<TString> Names;
21+
TMaybe<TString> EnclosingFunction;
2122
};
2223

2324
class IGlobalAnalysis {

yql/essentials/sql/v1/complete/analysis/global/global_ut.cpp

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,4 +69,33 @@ Y_UNIT_TEST_SUITE(GlobalAnalysisTests) {
6969
UNIT_ASSERT_VALUES_EQUAL(ctx.Names, expected);
7070
}
7171

72+
Y_UNIT_TEST(EnclosingFunctionName) {
73+
IGlobalAnalysis::TPtr global = MakeGlobalAnalysis();
74+
{
75+
TString query = "SELECT * FROM Concat(#)";
76+
TGlobalContext ctx = global->Analyze(SharpedInput(query), {});
77+
UNIT_ASSERT_VALUES_EQUAL(ctx.EnclosingFunction, "Concat");
78+
}
79+
{
80+
TString query = "SELECT * FROM Concat(a, #)";
81+
TGlobalContext ctx = global->Analyze(SharpedInput(query), {});
82+
UNIT_ASSERT_VALUES_EQUAL(ctx.EnclosingFunction, "Concat");
83+
}
84+
{
85+
TString query = "SELECT * FROM Concat(a#)";
86+
TGlobalContext ctx = global->Analyze(SharpedInput(query), {});
87+
UNIT_ASSERT_VALUES_EQUAL(ctx.EnclosingFunction, "Concat");
88+
}
89+
{
90+
TString query = "SELECT * FROM Concat(#";
91+
TGlobalContext ctx = global->Analyze(SharpedInput(query), {});
92+
UNIT_ASSERT_VALUES_EQUAL(ctx.EnclosingFunction, Nothing());
93+
}
94+
{
95+
TString query = "SELECT * FROM (#)";
96+
TGlobalContext ctx = global->Analyze(SharpedInput(query), {});
97+
UNIT_ASSERT_VALUES_EQUAL(ctx.EnclosingFunction, Nothing());
98+
}
99+
}
100+
72101
} // Y_UNIT_TEST_SUITE(GlobalAnalysisTests)

yql/essentials/sql/v1/complete/analysis/global/narrowing_visitor.cpp

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,21 @@ namespace NSQLComplete {
1212
return TextInterval(node).a < static_cast<ssize_t>(CursorPosition_);
1313
}
1414

15+
std::any TSQLv1NarrowingVisitor::aggregateResult(std::any aggregate, std::any nextResult) {
16+
if (nextResult.has_value()) {
17+
return nextResult;
18+
}
19+
return aggregate;
20+
}
21+
1522
bool TSQLv1NarrowingVisitor::IsEnclosing(antlr4::tree::ParseTree* tree) const {
1623
return TextInterval(tree).properlyContains(CursorInterval());
1724
}
1825

26+
ssize_t TSQLv1NarrowingVisitor::CursorPosition() const {
27+
return CursorPosition_;
28+
}
29+
1930
antlr4::misc::Interval TSQLv1NarrowingVisitor::TextInterval(antlr4::tree::ParseTree* tree) const {
2031
auto tokens = tree->getSourceInterval();
2132
if (tokens.b == -1) {
@@ -27,7 +38,8 @@ namespace NSQLComplete {
2738
}
2839

2940
antlr4::misc::Interval TSQLv1NarrowingVisitor::CursorInterval() const {
30-
return antlr4::misc::Interval(CursorPosition_, CursorPosition_);
41+
auto cursor = CursorPosition();
42+
return antlr4::misc::Interval(cursor, cursor);
3143
}
3244

3345
} // namespace NSQLComplete

yql/essentials/sql/v1/complete/analysis/global/narrowing_visitor.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,15 @@ namespace NSQLComplete {
99
TSQLv1NarrowingVisitor(antlr4::TokenStream* tokens, size_t cursorPosition);
1010

1111
protected:
12-
bool IsEnclosing(antlr4::tree::ParseTree* tree) const;
1312
bool shouldVisitNextChild(antlr4::tree::ParseTree* node, const std::any& /*currentResult*/) override;
13+
std::any aggregateResult(std::any aggregate, std::any nextResult) override;
1414

15-
private:
15+
bool IsEnclosing(antlr4::tree::ParseTree* tree) const;
16+
ssize_t CursorPosition() const;
1617
antlr4::misc::Interval TextInterval(antlr4::tree::ParseTree* tree) const;
1718
antlr4::misc::Interval CursorInterval() const;
1819

20+
private:
1921
antlr4::TokenStream* Tokens_;
2022
size_t CursorPosition_;
2123
};

yql/essentials/sql/v1/complete/analysis/global/use.cpp

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -54,13 +54,6 @@ namespace NSQLComplete {
5454
};
5555
}
5656

57-
std::any aggregateResult(std::any aggregate, std::any nextResult) override {
58-
if (nextResult.has_value()) {
59-
return nextResult;
60-
}
61-
return aggregate;
62-
}
63-
6457
private:
6558
TMaybe<TString> GetId(SQLv1::Pure_column_or_namedContext* ctx) const {
6659
if (auto* x = ctx->bind_parameter()) {

yql/essentials/sql/v1/complete/analysis/global/ya.make

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ LIBRARY()
22

33
SRCS(
44
evaluate.cpp
5+
function.cpp
56
global.cpp
67
named_node.cpp
78
narrowing_visitor.cpp

yql/essentials/sql/v1/complete/sql_complete.cpp

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ namespace NSQLComplete {
7979

8080
TNameRequest NameRequestFrom(
8181
TCompletionInput input,
82-
const TLocalSyntaxContext& context,
82+
const TLocalSyntaxContext& context, // TODO(YQL-19747): rename to `local`
8383
const TGlobalContext& global) const {
8484
TNameRequest request = {
8585
.Prefix = TString(GetCompletedToken(input, context.EditRange).Content),
@@ -134,6 +134,14 @@ namespace NSQLComplete {
134134
request.Constraints.Cluster = std::move(constraints);
135135
}
136136

137+
if (auto name = global.EnclosingFunction.Transform(NormalizeName);
138+
name && name == "concat") {
139+
auto& object = request.Constraints.Object;
140+
object = object.Defined() ? object : TObjectNameConstraints();
141+
object->Kinds.emplace(EObjectKind::Folder);
142+
object->Kinds.emplace(EObjectKind::Table);
143+
}
144+
137145
return request;
138146
}
139147

@@ -196,14 +204,14 @@ namespace NSQLComplete {
196204

197205
if constexpr (std::is_base_of_v<TFolderName, T>) {
198206
name.Indentifier.append('/');
199-
if (!context.Object->IsQuoted) {
207+
if (!context.Object || !context.Object->IsQuoted) {
200208
name.Indentifier.prepend('`');
201209
}
202210
return {ECandidateKind::FolderName, std::move(name.Indentifier)};
203211
}
204212

205213
if constexpr (std::is_base_of_v<TTableName, T>) {
206-
if (!context.Object->IsQuoted) {
214+
if (!context.Object || !context.Object->IsQuoted) {
207215
name.Indentifier.prepend('`');
208216
}
209217
return {ECandidateKind::TableName, std::move(name.Indentifier)};

0 commit comments

Comments
 (0)