Skip to content

Commit a6eb07c

Browse files
authored
Deterministic requests in clickhouse workload (#6678)
1 parent 5a2b13b commit a6eb07c

File tree

5 files changed

+165
-85
lines changed

5 files changed

+165
-85
lines changed
Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
"Minute","PageViews"
2-
"2013-07-15 12:40:00",513
3-
"2013-07-15 12:41:00",457
4-
"2013-07-15 12:42:00",470
5-
"2013-07-15 12:43:00",468
6-
"2013-07-15 12:44:00",453
7-
"2013-07-15 12:45:00",462
8-
"2013-07-15 12:46:00",481
9-
"2013-07-15 12:47:00",458
10-
"2013-07-15 12:48:00",466
11-
"2013-07-15 12:49:00",467
2+
"22898200",513
3+
"22898201",457
4+
"22898202",470
5+
"22898203",468
6+
"22898204",453
7+
"22898205",462
8+
"22898206",481
9+
"22898207",458
10+
"22898208",466
11+
"22898209",467

ydb/library/workload/clickbench/clickbench.cpp

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,8 @@ TQueryInfoList TClickbenchWorkloadGenerator::GetWorkload(int type) {
8282
queries.emplace_back(fInput.ReadAll());
8383
}
8484
} else {
85-
queries = StringSplitter(NResource::Find("click_bench_queries.sql")).Split(';').ToList<TString>();
85+
const auto resourceName = Params.IsCheckCannonical() ? "queries-deterministic.sql" : "click_bench_queries.sql";
86+
queries = StringSplitter(NResource::Find(resourceName)).Split(';').ToList<TString>();
8687
}
8788
auto strVariables = StringSplitter(Params.GetExternalVariablesString()).Split(';').SkipEmpty().ToList<TString>();
8889
TVector<TExternalVariable> vars;
@@ -130,6 +131,14 @@ TMap<ui32, TString> TClickbenchWorkloadGenerator::LoadExternalResults() const {
130131
TFileInput fInput(Params.GetExternalResultsDir() / i);
131132
result.emplace(qId, fInput.ReadAll());
132133
}
134+
} else if (Params.IsCheckCannonical()) {
135+
for(ui32 qId = 0; qId < 43; ++qId) {
136+
const auto key = "click_bench_canonical/q" + ToString(qId) + ".result";
137+
if (!NResource::Has(key)) {
138+
continue;
139+
}
140+
result.emplace(qId, NResource::Find(key));
141+
}
133142
}
134143
return result;
135144
}
@@ -153,6 +162,8 @@ void TClickbenchWorkloadParams::ConfigureOpts(NLastGetopt::TOpts& opts, const EC
153162
opts.AddLongOption('q', "ext-query", "String with external queries. Separated by ';'")
154163
.DefaultValue("")
155164
.StoreResult(&ExternalQueries);
165+
opts.AddLongOption('c', "check-cannonical", "Use deterministic queries and check results with cannonical ones.")
166+
.NoArgument().StoreTrue(&CheckCannonicalFlag);
156167
break;
157168
default:
158169
break;

ydb/library/workload/clickbench/clickbench.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ class TClickbenchWorkloadParams final: public TWorkloadBaseParams {
1818
YDB_READONLY_DEF(TString, ExternalVariablesString);
1919
YDB_READONLY_DEF(TFsPath, ExternalQueriesDir);
2020
YDB_READONLY_DEF(TFsPath, DataFiles);
21+
YDB_READONLY_FLAG(CheckCannonical, false);
2122
};
2223

2324
class TClickbenchWorkloadGenerator final: public TWorkloadGeneratorBase {

ydb/library/workload/clickbench/ya.make

Lines changed: 44 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -8,50 +8,51 @@ SRCS(
88

99
RESOURCE(
1010
click_bench_queries.sql click_bench_queries.sql
11+
${ARCADIA_ROOT}/ydb/tests/functional/clickbench/data/queries-deterministic.sql queries-deterministic.sql
1112
click_bench_schema.sql click_bench_schema.sql
12-
click_bench_canonical/q0.result q0.result
13-
click_bench_canonical/q1.result q1.result
14-
click_bench_canonical/q2.result q2.result
15-
click_bench_canonical/q3.result q3.result
16-
click_bench_canonical/q4.result q4.result
17-
click_bench_canonical/q5.result q5.result
18-
click_bench_canonical/q6.result q6.result
19-
click_bench_canonical/q7.result q7.result
20-
click_bench_canonical/q8.result q8.result
21-
click_bench_canonical/q9.result q9.result
22-
click_bench_canonical/q10.result q10.result
23-
click_bench_canonical/q11.result q11.result
24-
click_bench_canonical/q12.result q12.result
25-
click_bench_canonical/q13.result q13.result
26-
click_bench_canonical/q14.result q14.result
27-
click_bench_canonical/q15.result q15.result
28-
click_bench_canonical/q16.result q16.result
29-
click_bench_canonical/q17.result q17.result
30-
click_bench_canonical/q18.result q18.result
31-
click_bench_canonical/q19.result q19.result
32-
click_bench_canonical/q20.result q20.result
33-
click_bench_canonical/q21.result q21.result
34-
click_bench_canonical/q22.result q22.result
35-
click_bench_canonical/q23.result q23.result
36-
click_bench_canonical/q24.result q24.result
37-
click_bench_canonical/q25.result q25.result
38-
click_bench_canonical/q26.result q26.result
39-
click_bench_canonical/q27.result q27.result
40-
click_bench_canonical/q28.result q28.result
41-
click_bench_canonical/q29.result q29.result
42-
click_bench_canonical/q30.result q30.result
43-
click_bench_canonical/q31.result q31.result
44-
click_bench_canonical/q32.result q32.result
45-
click_bench_canonical/q33.result q33.result
46-
click_bench_canonical/q34.result q34.result
47-
click_bench_canonical/q35.result q35.result
48-
click_bench_canonical/q36.result q36.result
49-
click_bench_canonical/q37.result q37.result
50-
click_bench_canonical/q38.result q38.result
51-
click_bench_canonical/q39.result q39.result
52-
click_bench_canonical/q40.result q40.result
53-
click_bench_canonical/q41.result q41.result
54-
click_bench_canonical/q42.result q42.result
13+
click_bench_canonical/q0.result click_bench_canonical/q0.result
14+
click_bench_canonical/q1.result click_bench_canonical/q1.result
15+
click_bench_canonical/q2.result click_bench_canonical/q2.result
16+
click_bench_canonical/q3.result click_bench_canonical/q3.result
17+
click_bench_canonical/q4.result click_bench_canonical/q4.result
18+
click_bench_canonical/q5.result click_bench_canonical/q5.result
19+
click_bench_canonical/q6.result click_bench_canonical/q6.result
20+
click_bench_canonical/q7.result click_bench_canonical/q7.result
21+
click_bench_canonical/q8.result click_bench_canonical/q8.result
22+
click_bench_canonical/q9.result click_bench_canonical/q9.result
23+
click_bench_canonical/q10.result click_bench_canonical/q10.result
24+
click_bench_canonical/q11.result click_bench_canonical/q11.result
25+
click_bench_canonical/q12.result click_bench_canonical/q12.result
26+
click_bench_canonical/q13.result click_bench_canonical/q13.result
27+
click_bench_canonical/q14.result click_bench_canonical/q14.result
28+
click_bench_canonical/q15.result click_bench_canonical/q15.result
29+
click_bench_canonical/q16.result click_bench_canonical/q16.result
30+
click_bench_canonical/q17.result click_bench_canonical/q17.result
31+
click_bench_canonical/q18.result click_bench_canonical/q18.result
32+
click_bench_canonical/q19.result click_bench_canonical/q19.result
33+
click_bench_canonical/q20.result click_bench_canonical/q20.result
34+
click_bench_canonical/q21.result click_bench_canonical/q21.result
35+
click_bench_canonical/q22.result click_bench_canonical/q22.result
36+
click_bench_canonical/q23.result click_bench_canonical/q23.result
37+
click_bench_canonical/q24.result click_bench_canonical/q24.result
38+
click_bench_canonical/q25.result click_bench_canonical/q25.result
39+
click_bench_canonical/q26.result click_bench_canonical/q26.result
40+
click_bench_canonical/q27.result click_bench_canonical/q27.result
41+
click_bench_canonical/q28.result click_bench_canonical/q28.result
42+
click_bench_canonical/q29.result click_bench_canonical/q29.result
43+
click_bench_canonical/q30.result click_bench_canonical/q30.result
44+
click_bench_canonical/q31.result click_bench_canonical/q31.result
45+
click_bench_canonical/q32.result click_bench_canonical/q32.result
46+
click_bench_canonical/q33.result click_bench_canonical/q33.result
47+
click_bench_canonical/q34.result click_bench_canonical/q34.result
48+
click_bench_canonical/q35.result click_bench_canonical/q35.result
49+
click_bench_canonical/q36.result click_bench_canonical/q36.result
50+
click_bench_canonical/q37.result click_bench_canonical/q37.result
51+
click_bench_canonical/q38.result click_bench_canonical/q38.result
52+
click_bench_canonical/q39.result click_bench_canonical/q39.result
53+
click_bench_canonical/q40.result click_bench_canonical/q40.result
54+
click_bench_canonical/q41.result click_bench_canonical/q41.result
55+
click_bench_canonical/q42.result click_bench_canonical/q42.result
5556
)
5657

5758
PEERDIR(

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

Lines changed: 98 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -129,9 +129,12 @@ void ThrowOnError(const TStatus& status) {
129129
}
130130

131131
bool HasCharsInString(const TString& str) {
132-
for (auto c : str) {
133-
if (std::isalpha(c)) {
134-
return true;
132+
for(TStringBuf q(str), line; q.ReadLine(line);) {
133+
line = line.NextTok("--");
134+
for (auto c: line) {
135+
if (std::isalpha(c)) {
136+
return true;
137+
}
135138
}
136139
}
137140
return false;
@@ -370,41 +373,105 @@ bool CompareValueImpl(const T& valResult, TStringBuf vExpected) {
370373
return valResult == valExpected;
371374
}
372375

373-
bool CompareValue(const NYdb::TValue& v, TStringBuf vExpected) {
374-
const auto& vp = v.GetProto();
375-
if (vp.has_bool_value()) {
376-
return CompareValueImpl<bool>(vp.bool_value(), vExpected);
377-
}
378-
if (vp.has_int32_value()) {
379-
return CompareValueImpl<i32>(vp.int32_value(), vExpected);
380-
}
381-
if (vp.has_uint32_value()) {
382-
return CompareValueImpl<ui32>(vp.uint32_value(), vExpected);
383-
}
384-
if (vp.has_int64_value()) {
385-
return CompareValueImpl<i64>(vp.int64_value(), vExpected);
386-
}
387-
if (vp.has_uint64_value()) {
388-
return CompareValueImpl<ui64>(vp.uint64_value(), vExpected);
389-
}
390-
if (vp.has_float_value()) {
391-
return CompareValueImpl<float>(vp.float_value(), vExpected);
376+
template <class T>
377+
bool CompareValueImplFloat(const T& valResult, TStringBuf vExpected, const double floatPrecesion) {
378+
T valExpected;
379+
if (!TryFromString<T>(vExpected, valExpected)) {
380+
Cerr << "cannot parse expected as " << typeid(valResult).name() << "(" << vExpected << ")" << Endl;
381+
return false;
392382
}
393-
if (vp.has_double_value()) {
394-
return CompareValueImpl<double>(vp.double_value(), vExpected);
383+
return valResult > (1 - floatPrecesion) * valExpected && valResult < (1 + floatPrecesion) * valExpected;
384+
}
385+
386+
bool CompareValueImplDatetime(const TInstant& valResult, TStringBuf vExpected, TDuration unit) {
387+
TInstant expected;
388+
if (!TInstant::TryParseIso8601(vExpected, expected)) {
389+
i64 i;
390+
if (!TryFromString(vExpected, i)) {
391+
Cerr << "cannot parse expected as " << typeid(valResult).name() << "(" << vExpected << ")" << Endl;
392+
return false;
393+
}
394+
expected = TInstant::Zero() + i * unit;
395395
}
396-
if (vp.has_text_value()) {
397-
return CompareValueImpl<TString>(TString(vp.text_value().data(), vp.text_value().size()), vExpected);
396+
return valResult == expected;
397+
}
398+
399+
template<class T>
400+
bool CompareValueImplDatetime64(const T& valResult, TStringBuf vExpected, TDuration unit) {
401+
T valExpected;
402+
if (!TryFromString<T>(vExpected, valExpected)) {
403+
TInstant expected;
404+
if (!TInstant::TryParseIso8601(vExpected, expected)) {
405+
Cerr << "cannot parse expected as " << typeid(valResult).name() << "(" << vExpected << ")" << Endl;
406+
return false;
407+
}
408+
valExpected = expected.GetValue() / unit.GetValue();
398409
}
399-
if (vp.has_null_flag_value()) {
400-
return vExpected == "";
410+
return valResult == valExpected;
411+
}
412+
413+
bool CompareValue(const NYdb::TValue& v, TStringBuf vExpected, double floatPrecession) {
414+
TValueParser vp(v);
415+
TTypeParser tp(v.GetType());
416+
if (tp.GetKind() == TTypeParser::ETypeKind::Optional) {
417+
if (vp.IsNull()) {
418+
return vExpected == "";
419+
}
420+
vp.OpenOptional();
421+
tp.OpenOptional();
422+
}
423+
switch (tp.GetPrimitive()) {
424+
case EPrimitiveType::Bool:
425+
return CompareValueImpl(vp.GetBool(), vExpected);
426+
case EPrimitiveType::Int8:
427+
return CompareValueImpl(vp.GetInt8(), vExpected);
428+
case EPrimitiveType::Uint8:
429+
return CompareValueImpl(vp.GetUint8(), vExpected);
430+
case EPrimitiveType::Int16:
431+
return CompareValueImpl(vp.GetInt16(), vExpected);
432+
case EPrimitiveType::Uint16:
433+
return CompareValueImpl(vp.GetUint16(), vExpected);
434+
case EPrimitiveType::Int32:
435+
return CompareValueImpl(vp.GetInt32(), vExpected);
436+
case EPrimitiveType::Uint32:
437+
return CompareValueImpl(vp.GetUint32(), vExpected);
438+
case EPrimitiveType::Int64:
439+
return CompareValueImpl(vp.GetInt64(), vExpected);
440+
case EPrimitiveType::Uint64:
441+
return CompareValueImpl(vp.GetUint64(), vExpected);
442+
case EPrimitiveType::Float:
443+
return CompareValueImplFloat(vp.GetFloat(), vExpected, floatPrecession);
444+
case EPrimitiveType::Double:
445+
return CompareValueImplFloat(vp.GetDouble(), vExpected, floatPrecession);
446+
case EPrimitiveType::Date:
447+
return CompareValueImplDatetime(vp.GetDate(), vExpected, TDuration::Days(1));
448+
case EPrimitiveType::Datetime:
449+
return CompareValueImplDatetime(vp.GetDatetime(), vExpected, TDuration::Seconds(1));
450+
case EPrimitiveType::Timestamp:
451+
return CompareValueImplDatetime(vp.GetTimestamp(), vExpected, TDuration::MicroSeconds(1));
452+
case EPrimitiveType::Interval:
453+
return CompareValueImpl(vp.GetInterval(), vExpected);
454+
case EPrimitiveType::Date32:
455+
return CompareValueImplDatetime64(vp.GetDate32(), vExpected, TDuration::Days(1));
456+
case EPrimitiveType::Datetime64:
457+
return CompareValueImplDatetime64(vp.GetDatetime64(), vExpected, TDuration::Seconds(1));
458+
case EPrimitiveType::Timestamp64:
459+
return CompareValueImplDatetime64(vp.GetTimestamp64(), vExpected, TDuration::MicroSeconds(1));
460+
case EPrimitiveType::Interval64:
461+
return CompareValueImpl(vp.GetInterval64(), vExpected);
462+
case EPrimitiveType::String:
463+
return CompareValueImpl(vp.GetString(), vExpected);
464+
case EPrimitiveType::Utf8:
465+
return CompareValueImpl(vp.GetUtf8(), vExpected);
466+
default:
467+
Cerr << "unexpected type for comparision: " << v.GetProto().DebugString() << Endl;
468+
return false;
401469
}
402-
Cerr << "unexpected type for comparision: " << vp.DebugString() << Endl;
403-
return false;
404470
}
405471

406472

407473
bool TQueryResultInfo::IsExpected(std::string_view expected) const {
474+
constexpr double floatPrecesion = 0.0001;
408475
if (expected.empty()) {
409476
return true;
410477
}
@@ -452,7 +519,7 @@ bool TQueryResultInfo::IsExpected(std::string_view expected) const {
452519
return false;
453520
}
454521
TStringBuf cItem = splitter.Consume();
455-
if (!CompareValue(resultValue, cItem)) {
522+
if (!CompareValue(resultValue, cItem, floatPrecesion)) {
456523
Cerr << "has diff: " << resultValue.GetProto().DebugString() << ";EXPECTED:" << cItem << Endl;
457524
return false;
458525
}

0 commit comments

Comments
 (0)