Skip to content

Commit b7aa3d6

Browse files
authored
Rework cli workload commands (#4211)
1 parent cb2aea6 commit b7aa3d6

16 files changed

+773
-346
lines changed

ydb/library/workload/workload_query_generator.h

Lines changed: 54 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,14 @@
44
#include <ydb/public/sdk/cpp/client/ydb_query/client.h>
55
#include <ydb/public/sdk/cpp/client/ydb_table/table.h>
66
#include <ydb/public/sdk/cpp/client/ydb_value/value.h>
7+
#include <ydb/library/accessor/accessor.h>
78
#include <library/cpp/getopt/last_getopt.h>
89

910
#include <list>
10-
#include <map>
1111
#include <string>
1212

13+
#define WORKLOAD_QUERY_GENERATOR_INTERFACE_VERSION 2
14+
1315
namespace NYdbWorkload {
1416

1517
struct TQueryInfo {
@@ -25,6 +27,7 @@ struct TQueryInfo {
2527
{}
2628

2729
std::string Query;
30+
std::string ExpectedResult;
2831
NYdb::TParams Params;
2932
bool UseReadRows = false;
3033
TString TablePath;
@@ -42,33 +45,69 @@ class IBulkDataGenerator {
4245
public:
4346
using TPtr = std::shared_ptr<IBulkDataGenerator>;
4447
virtual ~IBulkDataGenerator() = default;
45-
IBulkDataGenerator(const std::string& table)
46-
: Table(table)
48+
IBulkDataGenerator(const std::string& name, ui64 size)
49+
: Name(name)
50+
, Size(size)
4751
{}
4852

49-
std::string GetTable() const {
50-
return Table;
51-
}
53+
struct TDataPortion: public TAtomicRefCount<TDataPortion>, TMoveOnly {
54+
struct TCsv {
55+
TCsv(TString&& data, const TString& formatString = TString())
56+
: Data(std::move(data))
57+
, FormatString(formatString)
58+
{}
59+
TString Data;
60+
TString FormatString;
61+
};
62+
63+
struct TArrow {
64+
TArrow(TString&& data, TString&& schema)
65+
: Data(std::move(data))
66+
, Schema(schema)
67+
{}
68+
TString Data;
69+
TString Schema;
70+
};
71+
72+
template<class T>
73+
TDataPortion(const TString& table, T&& data, ui64 size)
74+
: Table(table)
75+
, Data(std::move(data))
76+
, Size(size)
77+
{}
78+
79+
TString Table;
80+
std::variant<NYdb::TValue, TCsv, TArrow> Data;
81+
ui64 Size;
82+
};
5283

53-
virtual TMaybe<NYdb::TValue> GenerateDataPortion() = 0;
84+
using TDataPortionPtr = TIntrusivePtr<TDataPortion>;
85+
using TDataPortions = TVector<TDataPortionPtr>;
5486

55-
private:
56-
std::string Table;
87+
virtual TDataPortions GenerateDataPortion() = 0;
88+
YDB_READONLY_DEF(std::string, Name);
89+
YDB_READONLY(ui64, Size, 0);
5790
};
5891

5992
using TBulkDataGeneratorList = std::list<std::shared_ptr<IBulkDataGenerator>>;
6093

6194
class IWorkloadQueryGenerator {
6295
public:
6396
struct TWorkloadType {
64-
explicit TWorkloadType(int type, const TString& commandName, const TString& description)
97+
enum class EKind {
98+
Workload,
99+
Benchmark
100+
};
101+
explicit TWorkloadType(int type, const TString& commandName, const TString& description, EKind kind = EKind::Workload)
65102
: Type(type)
66103
, CommandName(commandName)
67104
, Description(description)
105+
, Kind(kind)
68106
{}
69107
int Type = 0;
70108
TString CommandName;
71109
TString Description;
110+
EKind Kind;
72111
};
73112
public:
74113
virtual ~IWorkloadQueryGenerator() = default;
@@ -113,6 +152,11 @@ class TWorkloadQueryGeneratorBase: public IWorkloadQueryGenerator {
113152
TWorkloadQueryGeneratorBase(const TParams* params)
114153
: Params(*params)
115154
{}
155+
156+
const TParams& GetParams() const {
157+
return Params;
158+
}
159+
116160
protected:
117161
const TParams& Params;
118162
};

ydb/public/lib/ydb_cli/commands/benchmark_utils.cpp

Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
#include <util/folder/path.h>
77

88
#include <library/cpp/json/json_writer.h>
9+
#include <library/cpp/string_utils/csv/csv.h>
910

1011
#include <ydb/public/sdk/cpp/client/ydb_table/table.h>
1112
#include <ydb/public/lib/yson_value/ydb_yson_value.h>
@@ -313,4 +314,110 @@ NJson::TJsonValue GetSensorValue(TStringBuf sensor, double value, ui32 queryId)
313314
return sensorValue;
314315
}
315316

317+
template <class T>
318+
bool CompareValueImpl(const T& valResult, TStringBuf vExpected) {
319+
T valExpected;
320+
if (!TryFromString<T>(vExpected, valExpected)) {
321+
Cerr << "cannot parse expected as " << typeid(valResult).name() << "(" << vExpected << ")" << Endl;
322+
return false;
323+
}
324+
return valResult == valExpected;
325+
}
326+
327+
bool CompareValue(const NYdb::TValue& v, TStringBuf vExpected) {
328+
const auto& vp = v.GetProto();
329+
if (vp.has_bool_value()) {
330+
return CompareValueImpl<bool>(vp.bool_value(), vExpected);
331+
}
332+
if (vp.has_int32_value()) {
333+
return CompareValueImpl<i32>(vp.int32_value(), vExpected);
334+
}
335+
if (vp.has_uint32_value()) {
336+
return CompareValueImpl<ui32>(vp.uint32_value(), vExpected);
337+
}
338+
if (vp.has_int64_value()) {
339+
return CompareValueImpl<i64>(vp.int64_value(), vExpected);
340+
}
341+
if (vp.has_uint64_value()) {
342+
return CompareValueImpl<ui64>(vp.uint64_value(), vExpected);
343+
}
344+
if (vp.has_float_value()) {
345+
return CompareValueImpl<float>(vp.float_value(), vExpected);
346+
}
347+
if (vp.has_double_value()) {
348+
return CompareValueImpl<double>(vp.double_value(), vExpected);
349+
}
350+
if (vp.has_text_value()) {
351+
return CompareValueImpl<TString>(TString(vp.text_value().data(), vp.text_value().size()), vExpected);
352+
}
353+
if (vp.has_null_flag_value()) {
354+
return vExpected == "";
355+
}
356+
Cerr << "unexpected type for comparision: " << vp.DebugString() << Endl;
357+
return false;
358+
}
359+
360+
361+
bool TQueryResultInfo::IsExpected(std::string_view expected) const {
362+
if (expected.empty()) {
363+
return true;
364+
}
365+
const auto expectedLines = StringSplitter(expected).Split('\n').SkipEmpty().ToList<TString>();
366+
if (Result.size() + 1 != expectedLines.size()) {
367+
Cerr << "has diff: incorrect lines count (" << Result.size() << " in result, but " << expectedLines.size() << " expected with header)" << Endl;
368+
return false;
369+
}
370+
371+
std::vector<ui32> columnIndexes;
372+
{
373+
const std::map<TString, ui32> columns = GetColumnsRemap();
374+
auto copy = expectedLines.front();
375+
NCsvFormat::CsvSplitter splitter(copy);
376+
while (true) {
377+
auto cName = splitter.Consume();
378+
auto it = columns.find(TString(cName.data(), cName.size()));
379+
if (it == columns.end()) {
380+
columnIndexes.clear();
381+
for (ui32 i = 0; i < columns.size(); ++i) {
382+
columnIndexes.emplace_back(i);
383+
}
384+
break;
385+
}
386+
columnIndexes.emplace_back(it->second);
387+
388+
if (!splitter.Step()) {
389+
break;
390+
}
391+
}
392+
if (columnIndexes.size() != columns.size()) {
393+
Cerr << "there are unexpected columns in result" << Endl;
394+
return false;
395+
}
396+
}
397+
398+
for (ui32 i = 0; i < Result.size(); ++i) {
399+
TString copy = expectedLines[i + 1];
400+
NCsvFormat::CsvSplitter splitter(copy);
401+
bool isCorrectCurrent = true;
402+
for (ui32 cIdx = 0; cIdx < columnIndexes.size(); ++cIdx) {
403+
const NYdb::TValue& resultValue = Result[i][columnIndexes[cIdx]];
404+
if (!isCorrectCurrent) {
405+
Cerr << "has diff: no element in expectation" << Endl;
406+
return false;
407+
}
408+
TStringBuf cItem = splitter.Consume();
409+
if (!CompareValue(resultValue, cItem)) {
410+
Cerr << "has diff: " << resultValue.GetProto().DebugString() << ";EXPECTED:" << cItem << Endl;
411+
return false;
412+
}
413+
isCorrectCurrent = splitter.Step();
414+
}
415+
if (isCorrectCurrent) {
416+
Cerr << "expected more items than have in result" << Endl;
417+
return false;
418+
}
419+
}
420+
return true;
421+
}
422+
316423
} // NYdb::NConsoleClient::BenchmarkUtils

ydb/public/lib/ydb_cli/commands/benchmark_utils.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ class TQueryResultInfo {
4646
const TVector<NYdb::TColumn>& GetColumns() const {
4747
return Columns;
4848
}
49+
bool IsExpected(std::string_view expected) const;
4950
};
5051

5152
class TQueryBenchmarkResult {

ydb/public/lib/ydb_cli/commands/click_bench.cpp

Lines changed: 11 additions & 100 deletions
Original file line numberDiff line numberDiff line change
@@ -63,101 +63,8 @@ class TExternalVariable {
6363

6464
}
6565

66-
bool TClickBenchCommandRun::TQueryFullInfo::CompareValue(const NYdb::TValue& v, const TStringBuf vExpected) const {
67-
const auto& vp = v.GetProto();
68-
if (vp.has_bool_value()) {
69-
return CompareValueImpl<bool>(vp.bool_value(), vExpected);
70-
}
71-
if (vp.has_int32_value()) {
72-
return CompareValueImpl<i32>(vp.int32_value(), vExpected);
73-
}
74-
if (vp.has_uint32_value()) {
75-
return CompareValueImpl<ui32>(vp.uint32_value(), vExpected);
76-
}
77-
if (vp.has_int64_value()) {
78-
return CompareValueImpl<i64>(vp.int64_value(), vExpected);
79-
}
80-
if (vp.has_uint64_value()) {
81-
return CompareValueImpl<ui64>(vp.uint64_value(), vExpected);
82-
}
83-
if (vp.has_float_value()) {
84-
return CompareValueImpl<float>(vp.float_value(), vExpected);
85-
}
86-
if (vp.has_double_value()) {
87-
return CompareValueImpl<double>(vp.double_value(), vExpected);
88-
}
89-
if (vp.has_text_value()) {
90-
return CompareValueImpl<TString>(TString(vp.text_value().data(), vp.text_value().size()), vExpected);
91-
}
92-
if (vp.has_null_flag_value()) {
93-
return vExpected == "";
94-
}
95-
Cerr << "unexpected type for comparision: " << vp.DebugString() << Endl;
96-
return false;
97-
}
98-
9966
bool TClickBenchCommandRun::TQueryFullInfo::IsCorrectResult(const BenchmarkUtils::TQueryResultInfo& resultFull) const {
100-
if (!ExpectedResult) {
101-
return true;
102-
}
103-
const auto expectedLines = StringSplitter(ExpectedResult).Split('\n').SkipEmpty().ToList<TString>();
104-
auto& result = resultFull.GetResult();
105-
if (result.size() + 1 != expectedLines.size()) {
106-
Cerr << "has diff: incorrect lines count (" << result.size() << " in result, but " << expectedLines.size() << " expected with header)" << Endl;
107-
return false;
108-
}
109-
110-
std::vector<ui32> columnIndexes;
111-
{
112-
const std::map<TString, ui32> columns = resultFull.GetColumnsRemap();
113-
auto copy = expectedLines.front();
114-
NCsvFormat::CsvSplitter splitter(copy);
115-
while (true) {
116-
auto cName = splitter.Consume();
117-
auto it = columns.find(TString(cName.data(), cName.size()));
118-
if (it == columns.end()) {
119-
columnIndexes.clear();
120-
for (ui32 i = 0; i < columns.size(); ++i) {
121-
columnIndexes.emplace_back(i);
122-
}
123-
break;
124-
} else {
125-
columnIndexes.emplace_back(it->second);
126-
}
127-
128-
if (!splitter.Step()) {
129-
break;
130-
}
131-
}
132-
if (columnIndexes.size() != columns.size()) {
133-
Cerr << "there are unexpected columns in result" << Endl;
134-
return false;
135-
}
136-
}
137-
138-
for (ui32 i = 0; i < result.size(); ++i) {
139-
TString copy = expectedLines[i + 1];
140-
NCsvFormat::CsvSplitter splitter(copy);
141-
bool isCorrectCurrent = true;
142-
for (ui32 cIdx = 0; cIdx < columnIndexes.size(); ++cIdx) {
143-
const NYdb::TValue& resultValue = result[i][columnIndexes[cIdx]];
144-
if (!isCorrectCurrent) {
145-
Cerr << "has diff: no element in expectation" << Endl;
146-
return false;
147-
}
148-
TStringBuf cItem = splitter.Consume();
149-
if (!CompareValue(resultValue, cItem)) {
150-
Cerr << "has diff: " << resultValue.GetProto().DebugString() << ";EXPECTED:" << cItem << Endl;
151-
return false;
152-
}
153-
isCorrectCurrent = splitter.Step();
154-
}
155-
if (isCorrectCurrent) {
156-
Cerr << "expected more items than have in result" << Endl;
157-
return false;
158-
}
159-
}
160-
return true;
67+
return resultFull.IsExpected(ExpectedResult);
16168
}
16269

16370
TVector<TClickBenchCommandRun::TQueryFullInfo> TClickBenchCommandRun::GetQueries(const TString& fullTablePath) const {
@@ -414,13 +321,13 @@ void TClickBenchCommandInit::Config(TConfig& config) {
414321

415322
int TClickBenchCommandInit::Run(TConfig& config) {
416323
StoreType = to_lower(StoreType);
417-
TString partitionBy = "";
418-
TString storageType = "";
324+
TString partitionBy = "--";
325+
TString storageType = "--";
419326
TString notNull = "";
420327
if (StoreType == "column") {
421328
//partitionBy = "PARTITION BY HASH(CounterID)"; Not enough cardinality in CounterID column @sa KIKIMR-16478
422-
partitionBy = "PARTITION BY HASH(CounterID, EventDate, UserID, EventTime, WatchID)";
423-
storageType = "STORE = COLUMN,";
329+
partitionBy = "PARTITION BY HASH";
330+
storageType = "STORE = COLUMN, --";
424331
notNull = "NOT NULL";
425332
} else if (StoreType != "row") {
426333
throw yexception() << "Incorrect storage type. Available options: \"row\", \"column\"." << Endl;
@@ -431,10 +338,14 @@ int TClickBenchCommandInit::Run(TConfig& config) {
431338
TString createSql = NResource::Find("click_bench_schema.sql");
432339
TTableClient client(driver);
433340

434-
SubstGlobal(createSql, "{table}", FullTablePath(config.Database, Table));
341+
SubstGlobal(createSql, "{path}", FullTablePath(config.Database, Table));
435342
SubstGlobal(createSql, "{notnull}", notNull);
436-
SubstGlobal(createSql, "{partition}", partitionBy);
343+
SubstGlobal(createSql, "{partition_by}", partitionBy);
437344
SubstGlobal(createSql, "{store}", storageType);
345+
SubstGlobal(createSql, "{partitioning}", "AUTO_PARTITIONING_MIN_PARTITIONS_COUNT");
346+
SubstGlobal(createSql, "{primary_key}", ", PRIMARY KEY");
347+
SubstGlobal(createSql, "{external}", "");
348+
SubstGlobal(createSql, "{createExternal}", "");
438349

439350
ThrowOnError(client.RetryOperationSync([createSql](TSession session) {
440351
return session.ExecuteSchemeQuery(createSql).GetValueSync();

ydb/public/lib/ydb_cli/commands/click_bench.h

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -57,17 +57,6 @@ class TClickBenchCommandRun : public NYdb::NConsoleClient::TYdbCommand {
5757
TString Query;
5858
TString ExpectedResult;
5959

60-
template <class T>
61-
bool CompareValueImpl(const T valResult, const TStringBuf vExpected) const {
62-
T valExpected;
63-
if (!TryFromString<T>(vExpected, valExpected)) {
64-
Cerr << "cannot parse expected as " << typeid(valResult).name() << "(" << vExpected << ")" << Endl;
65-
return false;
66-
}
67-
return valResult == valExpected;
68-
}
69-
70-
bool CompareValue(const NYdb::TValue& v, const TStringBuf vExpected) const;
7160
public:
7261
TQueryFullInfo(const TString& query, const TString& expectedResult)
7362
: Query(query)

0 commit comments

Comments
 (0)