1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
|
#include "archive.h"
#include "percentile.h"
#include <util/generic/vector.h>
#include <util/generic/xrange.h>
#include <util/string/cast.h>
#include <util/string/join.h>
#include <util/string/split.h>
#include <utility>
namespace NKikimr {
static constexpr TStringBuf kResultTablePath = ".load_test_archive";
namespace {
using TColumnDescription = TVector<std::pair<TString, TString>>;
const TColumnDescription BuildTableColumns() {
TColumnDescription columns;
columns.emplace_back("id", "String");
for (const auto& name : {"start", "finish"}) {
columns.emplace_back(name, "Datetime");
}
columns.emplace_back("total_nodes", "Uint32");
columns.emplace_back("success_nodes", "Uint32");
auto addStatsColumn = [&columns](const TString& name, const TString& typeName) {
for (const auto& suffix : {"_min", "_avg", "_max"}) {
columns.emplace_back(name + suffix, typeName);
}
};
addStatsColumn("transactions", "Uint64");
addStatsColumn("transactions_per_sec", "Double");
addStatsColumn("errors_per_sec", "Double");
for (ui32 level : xrange(EPL_COUNT_NUM)) {
addStatsColumn("p" + ToString(static_cast<EPercentileLevel>(level)) + "_ms", "Double");
}
columns.emplace_back("config", "String");
return columns;
}
const TColumnDescription& GetTableColumns() {
static const TColumnDescription kColumns = BuildTableColumns();
return kColumns;
}
const TVector<TString> BuildTableColumnNames() {
TVector<TString> names;
for (const auto& [name, _] : GetTableColumns()) {
names.push_back(name);
}
return names;
}
const TVector<TString> GetTableColumnNames() {
static const TVector<TString> kNames = BuildTableColumnNames();
return kNames;
}
TString DatetimeFromInstant(TInstant instant) {
return instant.FormatGmTime("Datetime(\"%Y-%m-%dT%H:%M:%SZ\")");
}
TString EscapeQuotes(const TString& rawValue) {
TVector<TString> parts;
Split(rawValue, "\"", parts);
return JoinSeq("\\\"", parts);
}
} // anonymous namespace
TString MakeTableCreationYql() {
TVector<TString> schemaParts;
for (const auto& [name, typeName] : GetTableColumns()) {
schemaParts.push_back(name + " " + typeName);
};
schemaParts.push_back("PRIMARY KEY(id)");
TStringStream ss;
ss << "--!syntax_v1\n";
ss << "CREATE TABLE `" << kResultTablePath << "` ";
ss << "(" << JoinSeq(", ", schemaParts) << ")";
return ss.Str();
}
TString MakeRecordInsertionYql(const TVector<TAggregatedResult>& items) {
TStringStream ss;
ss << "--!syntax_v1\n";
ss << "INSERT INTO `" << kResultTablePath << "` ";
ss << "(" << JoinSeq(", ", GetTableColumnNames()) << ") ";
ss << "VALUES ";
bool first = true;
for (const auto& item : items) {
if (first) {
first = false;
} else {
ss << ", ";
}
ss << "(\"" << item.Uuid << "\", " <<
DatetimeFromInstant(item.Start) << ", " <<
DatetimeFromInstant(item.Finish) << ", " <<
item.Stats.TotalNodes << ", " <<
item.Stats.SuccessNodes << ", " <<
item.Stats.Transactions << ", " <<
item.Stats.TransactionsPerSecond << ", " <<
item.Stats.ErrorsPerSecond << ", ";
for (ui32 level : xrange(EPL_COUNT_NUM)) {
ss << item.Stats.Percentiles[level] << ", ";
}
ss << "\"" << EscapeQuotes(item.Config) << "\")";
}
ss << ";";
return ss.Str();
}
TString MakeRecordSelectionYql(ui32 offset, ui32 limit) {
TStringStream ss;
ss << "--!syntax_v1\n";
ss << "SELECT * FROM `" << kResultTablePath << "` ";
ss << "ORDER BY `start` DESC ";
ss << "LIMIT " << limit << " OFFSET " << offset << ";";
return ss.Str();
}
} // namespace NKikimr
|