Skip to content

Commit 1ce6fd4

Browse files
author
dgolear
committed
YT: Switch TQueryBuilder to std::string
commit_hash:b9ba9e739dc3af4d562ef56bd81774e2c8919eed
1 parent 8a4ae19 commit 1ce6fd4

File tree

5 files changed

+139
-77
lines changed

5 files changed

+139
-77
lines changed

yt/yt/client/query_client/query_builder.cpp

Lines changed: 52 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -9,26 +9,25 @@ namespace NYT::NQueryClient {
99

1010
////////////////////////////////////////////////////////////////////////////////
1111

12-
static std::vector<TString> Parenthesize(std::vector<TString> strings)
12+
static void Parenthesize(TStringBuilderBase* builder, const std::string& str)
1313
{
14-
for (auto& string : strings) {
15-
string.prepend('(').append(')');
16-
}
17-
return strings;
14+
builder->AppendChar('(');
15+
builder->AppendString(str);
16+
builder->AppendChar(')');
1817
}
1918

20-
void TQueryBuilder::SetSource(TString source)
19+
void TQueryBuilder::SetSource(std::string source)
2120
{
2221
Source_ = std::move(source);
2322
}
2423

25-
void TQueryBuilder::SetSource(TString source, TString alias)
24+
void TQueryBuilder::SetSource(std::string source, std::string alias)
2625
{
2726
Source_ = std::move(source);
2827
SourceAlias_ = std::move(alias);
2928
}
3029

31-
int TQueryBuilder::AddSelectExpression(TString expression)
30+
int TQueryBuilder::AddSelectExpression(std::string expression)
3231
{
3332
SelectEntries_.push_back(TEntryWithAlias{
3433
std::move(expression),
@@ -37,7 +36,7 @@ int TQueryBuilder::AddSelectExpression(TString expression)
3736
return SelectEntries_.size() - 1;
3837
}
3938

40-
int TQueryBuilder::AddSelectExpression(TString expression, TString alias)
39+
int TQueryBuilder::AddSelectExpression(std::string expression, std::string alias)
4140
{
4241
SelectEntries_.push_back(TEntryWithAlias{
4342
std::move(expression),
@@ -46,20 +45,20 @@ int TQueryBuilder::AddSelectExpression(TString expression, TString alias)
4645
return SelectEntries_.size() - 1;
4746
}
4847

49-
void TQueryBuilder::AddWhereConjunct(TString expression)
48+
void TQueryBuilder::AddWhereConjunct(std::string expression)
5049
{
5150
WhereConjuncts_.push_back(std::move(expression));
5251
}
5352

54-
void TQueryBuilder::AddGroupByExpression(TString expression)
53+
void TQueryBuilder::AddGroupByExpression(std::string expression)
5554
{
5655
GroupByEntries_.push_back(TEntryWithAlias{
5756
std::move(expression),
5857
std::nullopt
5958
});
6059
}
6160

62-
void TQueryBuilder::AddGroupByExpression(TString expression, TString alias)
61+
void TQueryBuilder::AddGroupByExpression(std::string expression, std::string alias)
6362
{
6463
GroupByEntries_.push_back(TEntryWithAlias{
6564
std::move(expression),
@@ -72,33 +71,33 @@ void TQueryBuilder::SetWithTotals(EWithTotalsMode withTotalsMode)
7271
WithTotalsMode_ = withTotalsMode;
7372
}
7473

75-
void TQueryBuilder::AddHavingConjunct(TString expression)
74+
void TQueryBuilder::AddHavingConjunct(std::string expression)
7675
{
7776
HavingConjuncts_.push_back(std::move(expression));
7877
}
7978

80-
void TQueryBuilder::AddOrderByExpression(TString expression)
79+
void TQueryBuilder::AddOrderByExpression(std::string expression)
8180
{
8281
OrderByEntries_.push_back(TOrderByEntry{
8382
std::move(expression),
8483
std::nullopt,
8584
});
8685
}
8786

88-
void TQueryBuilder::AddOrderByExpression(TString expression, std::optional<EOrderByDirection> direction)
87+
void TQueryBuilder::AddOrderByExpression(std::string expression, std::optional<EOrderByDirection> direction)
8988
{
9089
OrderByEntries_.push_back(TOrderByEntry{
9190
std::move(expression),
9291
direction,
9392
});
9493
}
9594

96-
void TQueryBuilder::AddOrderByAscendingExpression(TString expression)
95+
void TQueryBuilder::AddOrderByAscendingExpression(std::string expression)
9796
{
9897
AddOrderByExpression(std::move(expression), EOrderByDirection::Ascending);
9998
}
10099

101-
void TQueryBuilder::AddOrderByDescendingExpression(TString expression)
100+
void TQueryBuilder::AddOrderByDescendingExpression(std::string expression)
102101
{
103102
AddOrderByExpression(std::move(expression), EOrderByDirection::Descending);
104103
}
@@ -114,9 +113,9 @@ void TQueryBuilder::SetLimit(i64 limit)
114113
}
115114

116115
void TQueryBuilder::AddJoinExpression(
117-
TString table,
118-
TString alias,
119-
TString onExpression,
116+
std::string table,
117+
std::string alias,
118+
std::string onExpression,
120119
ETableJoinType type)
121120
{
122121
JoinEntries_.push_back(TJoinEntry{
@@ -127,94 +126,98 @@ void TQueryBuilder::AddJoinExpression(
127126
});
128127
}
129128

130-
TString TQueryBuilder::Build()
129+
std::string TQueryBuilder::Build()
131130
{
132-
std::vector<TString> parts;
133-
parts.reserve(8);
131+
TStringBuilder builder;
132+
TDelimitedStringBuilderWrapper wrapper(&builder, " ");
134133

135134
if (SelectEntries_.empty()) {
136135
THROW_ERROR_EXCEPTION("Query must have at least one SELECT expression");
137136
}
138-
parts.push_back(JoinSeq(", ", SelectEntries_));
137+
JoinToString(&wrapper, SelectEntries_.begin(), SelectEntries_.end(), &FormatEntryWithAlias);
139138

140139
if (!Source_) {
141140
THROW_ERROR_EXCEPTION("Source must be specified in query");
142141
}
143142
if (!SourceAlias_) {
144-
parts.push_back(Format("FROM [%v]", *Source_));
143+
wrapper->AppendFormat("FROM [%v]", *Source_);
145144
} else {
146-
parts.push_back(Format("FROM [%v] AS %v", *Source_, *SourceAlias_));
145+
wrapper->AppendFormat("FROM [%v] AS %v", *Source_, *SourceAlias_);
147146
}
148147

149148
for (const auto& join : JoinEntries_) {
150149
TStringBuf joinType = join.Type == ETableJoinType::Inner ? "JOIN" : "LEFT JOIN";
151-
parts.push_back(Format("%v [%v] AS [%v] ON %v", joinType, join.Table, join.Alias, join.OnExpression));
150+
wrapper->AppendFormat("%v [%v] AS [%v] ON %v", joinType, join.Table, join.Alias, join.OnExpression);
152151
}
153152

154153
if (!WhereConjuncts_.empty()) {
155-
parts.push_back("WHERE");
156-
parts.push_back(JoinSeq(" AND ", Parenthesize(WhereConjuncts_)));
154+
wrapper->AppendFormat("WHERE");
155+
JoinToString(&wrapper, WhereConjuncts_.begin(), WhereConjuncts_.end(), &Parenthesize, " AND ");
157156
}
158157

159158
if (!GroupByEntries_.empty()) {
160-
parts.push_back("GROUP BY");
161-
parts.push_back(JoinSeq(", ", GroupByEntries_));
159+
wrapper->AppendString("GROUP BY");
160+
JoinToString(&wrapper, GroupByEntries_.begin(), GroupByEntries_.end(), &FormatEntryWithAlias);
162161
}
163162

164163
if (WithTotalsMode_ == EWithTotalsMode::BeforeHaving) {
165-
parts.push_back("WITH TOTALS");
164+
wrapper->AppendString("WITH TOTALS");
166165
}
167166

168167
if (!HavingConjuncts_.empty()) {
169168
if (GroupByEntries_.empty()) {
170169
THROW_ERROR_EXCEPTION("Having without group by is not valid");
171170
}
172-
parts.push_back("HAVING");
173-
parts.push_back(JoinSeq(" AND ", Parenthesize(HavingConjuncts_)));
171+
wrapper->AppendString("HAVING");
172+
JoinToString(&wrapper, HavingConjuncts_.begin(), HavingConjuncts_.end(), &Parenthesize, " AND ");
174173
}
175174

176175
if (WithTotalsMode_ == EWithTotalsMode::AfterHaving) {
177-
parts.push_back("WITH TOTALS");
176+
wrapper->AppendString("WITH TOTALS");
178177
}
179178

180179
if (!OrderByEntries_.empty()) {
181-
parts.push_back("ORDER BY");
182-
parts.push_back(JoinSeq(", ", OrderByEntries_));
180+
wrapper->AppendString("ORDER BY");
181+
JoinToString(&wrapper, OrderByEntries_.begin(), OrderByEntries_.end(), &FormatOrderByEntry);
183182
}
184183

185184
if (Offset_) {
186-
parts.push_back(Format("OFFSET %v", *Offset_));
185+
wrapper->AppendFormat("OFFSET %v", *Offset_);
187186
}
188187

189188
if (Limit_) {
190-
parts.push_back(Format("LIMIT %v", *Limit_));
189+
wrapper->AppendFormat("LIMIT %v", *Limit_);
191190
}
192191

193-
return JoinSeq(" ", parts);
192+
return builder.Flush();
194193
}
195194

196-
void AppendToString(TString& dst, const TQueryBuilder::TEntryWithAlias& entry)
195+
void TQueryBuilder::FormatEntryWithAlias(TStringBuilderBase* builder, const TQueryBuilder::TEntryWithAlias& entry)
197196
{
198-
TStringOutput output(dst);
199197
if (entry.Expression == "*") {
200-
output << "*";
198+
builder->AppendChar('*');
201199
return;
202200
}
203-
output << '(' << entry.Expression << ')';
201+
builder->AppendChar('(');
202+
builder->AppendString(entry.Expression);
203+
builder->AppendChar(')');
204204
if (entry.Alias) {
205-
output << " AS " << *entry.Alias;
205+
builder->AppendString(" AS ");
206+
builder->AppendString(*entry.Alias);
206207
}
207208
}
208209

209-
void AppendToString(TString& dst, const TQueryBuilder::TOrderByEntry& entry)
210+
void TQueryBuilder::FormatOrderByEntry(TStringBuilderBase* builder, const TQueryBuilder::TOrderByEntry& entry)
210211
{
211-
TStringOutput output(dst);
212-
output << '(' << entry.Expression << ')';
212+
builder->AppendChar('(');
213+
builder->AppendString(entry.Expression);
214+
builder->AppendChar(')');
213215
if (entry.Direction) {
214216
TStringBuf directionString = (*entry.Direction == EOrderByDirection::Ascending)
215217
? "ASC"
216218
: "DESC";
217-
output << ' ' << directionString;
219+
builder->AppendChar(' ');
220+
builder->AppendString(directionString);
218221
}
219222
}
220223

yt/yt/client/query_client/query_builder.h

Lines changed: 26 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -29,72 +29,70 @@ DEFINE_ENUM(EWithTotalsMode,
2929
class TQueryBuilder
3030
{
3131
public:
32-
void SetSource(TString source);
33-
void SetSource(TString source, TString alias);
32+
void SetSource(std::string source);
33+
void SetSource(std::string source, std::string alias);
3434

35-
int AddSelectExpression(TString expression);
36-
int AddSelectExpression(TString expression, TString alias);
35+
int AddSelectExpression(std::string expression);
36+
int AddSelectExpression(std::string expression, std::string alias);
3737

38-
void AddWhereConjunct(TString expression);
38+
void AddWhereConjunct(std::string expression);
3939

40-
void AddGroupByExpression(TString expression);
41-
void AddGroupByExpression(TString expression, TString alias);
40+
void AddGroupByExpression(std::string expression);
41+
void AddGroupByExpression(std::string expression, std::string alias);
4242

4343
void SetWithTotals(EWithTotalsMode withTotalsMode);
4444

45-
void AddHavingConjunct(TString expression);
45+
void AddHavingConjunct(std::string expression);
4646

47-
void AddOrderByExpression(TString expression);
48-
void AddOrderByExpression(TString expression, std::optional<EOrderByDirection> direction);
47+
void AddOrderByExpression(std::string expression);
48+
void AddOrderByExpression(std::string expression, std::optional<EOrderByDirection> direction);
4949

50-
void AddOrderByAscendingExpression(TString expression);
51-
void AddOrderByDescendingExpression(TString expression);
50+
void AddOrderByAscendingExpression(std::string expression);
51+
void AddOrderByDescendingExpression(std::string expression);
5252

53-
void AddJoinExpression(TString table, TString alias, TString onExpression, ETableJoinType type);
53+
void AddJoinExpression(std::string table, std::string alias, std::string onExpression, ETableJoinType type);
5454

5555
void SetOffset(i64 offset);
5656
void SetLimit(i64 limit);
5757

58-
TString Build();
58+
std::string Build();
5959

6060
private:
6161
struct TEntryWithAlias
6262
{
63-
TString Expression;
64-
std::optional<TString> Alias;
63+
std::string Expression;
64+
std::optional<std::string> Alias;
6565
};
6666

6767
struct TOrderByEntry
6868
{
69-
TString Expression;
69+
std::string Expression;
7070
std::optional<EOrderByDirection> Direction;
7171
};
7272

7373
struct TJoinEntry
7474
{
75-
TString Table;
76-
TString Alias;
77-
TString OnExpression;
75+
std::string Table;
76+
std::string Alias;
77+
std::string OnExpression;
7878
ETableJoinType Type;
7979
};
8080

8181
private:
82-
std::optional<TString> Source_;
83-
std::optional<TString> SourceAlias_;
82+
std::optional<std::string> Source_;
83+
std::optional<std::string> SourceAlias_;
8484
std::vector<TEntryWithAlias> SelectEntries_;
85-
std::vector<TString> WhereConjuncts_;
85+
std::vector<std::string> WhereConjuncts_;
8686
std::vector<TOrderByEntry> OrderByEntries_;
8787
std::vector<TEntryWithAlias> GroupByEntries_;
8888
EWithTotalsMode WithTotalsMode_ = EWithTotalsMode::None;
89-
std::vector<TString> HavingConjuncts_;
89+
std::vector<std::string> HavingConjuncts_;
9090
std::vector<TJoinEntry> JoinEntries_;
9191
std::optional<i64> Offset_;
9292
std::optional<i64> Limit_;
9393

94-
private:
95-
// We overload this functions to allow the corresponding JoinSeq().
96-
friend void AppendToString(TString& dst, const TEntryWithAlias& entry);
97-
friend void AppendToString(TString& dst, const TOrderByEntry& entry);
94+
static void FormatEntryWithAlias(TStringBuilderBase* builder, const TEntryWithAlias& entry);
95+
static void FormatOrderByEntry(TStringBuilderBase* builder, const TOrderByEntry& entry);
9896
};
9997

10098
////////////////////////////////////////////////////////////////////////////////
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
#include <yt/yt/client/query_client/query_builder.h>
2+
3+
#include <yt/yt/core/test_framework/framework.h>
4+
5+
#include <gtest/gtest.h>
6+
7+
namespace NYT::NQueryClient {
8+
namespace {
9+
10+
////////////////////////////////////////////////////////////////////////////////
11+
12+
TEST(TQueryBuilderTest, Build)
13+
{
14+
TQueryBuilder builder;
15+
16+
builder.SetLimit(10);
17+
builder.SetOffset(15);
18+
builder.SetSource("fooTable");
19+
20+
builder.AddWhereConjunct("[id] = 42");
21+
builder.AddWhereConjunct("[some_other_field] < 15");
22+
23+
builder.AddSelectExpression("[some_field] * [some_other_field]", "res");
24+
builder.AddOrderByExpression("[res]", EOrderByDirection::Descending);
25+
builder.AddOrderByExpression("[some_field]", EOrderByDirection::Ascending);
26+
27+
builder.AddJoinExpression("barTable", "bar", "fooTable.[id] = barTable.[id]", ETableJoinType::Left);
28+
29+
auto source = builder.Build();
30+
31+
EXPECT_NE(source.find("FROM [fooTable]"), source.npos);
32+
EXPECT_NE(source.find("LIMIT 10"), source.npos);
33+
EXPECT_NE(source.find("OFFSET 15"), source.npos);
34+
EXPECT_NE(source.find("ORDER BY ([res]) DESC, ([some_field]) ASC"), source.npos);
35+
EXPECT_NE(source.find("WHERE ([id] = 42) AND ([some_other_field] < 15)"), source.npos);
36+
EXPECT_NE(source.find("([some_field] * [some_other_field]) AS res"), source.npos);
37+
EXPECT_NE(source.find("LEFT JOIN [barTable] AS [bar] ON fooTable.[id] = barTable.[id]"), source.npos);
38+
};
39+
40+
////////////////////////////////////////////////////////////////////////////////
41+
42+
} // namespace
43+
} // namespace NYT::NQueryClient

0 commit comments

Comments
 (0)