dbms: added sample setting to OLAP compability layer [#METR-9464]

This commit is contained in:
Pavel Kartavyy 2014-01-28 19:26:40 +00:00
parent 92d5a9c302
commit 7d01327b0d
4 changed files with 62 additions and 10 deletions

View File

@ -86,7 +86,7 @@ void QueryConverter::OLAPServerQueryToClickhouse(const QueryParseResult & query,
for (size_t i = 0; i < query.aggregates.size(); ++i)
{
const QueryParseResult::Aggregate & aggregate = query.aggregates[i];
std::string s = convertAggregateFunction(aggregate.attribute, aggregate.parameter, aggregate.function);
std::string s = convertAggregateFunction(aggregate.attribute, aggregate.parameter, aggregate.function, query);
if (query.key_attributes.size() + i > 0)
out_query += ", ";
@ -147,6 +147,10 @@ void QueryConverter::OLAPServerQueryToClickhouse(const QueryParseResult & query,
/// Ограничение на количество выводимых строк.
if (query.limit != 0)
out_query += " LIMIT " + toString(query.limit);
/// Добавляем сэмплирование.
if (query.sample != 1)
out_query += " SAMPLE " + toString(query.sample);
}
std::string QueryConverter::convertAttributeFormatted(const std::string & attribute, unsigned parameter)
@ -180,10 +184,20 @@ static bool StartsWith(const std::string & str, const std::string & prefix)
return str.length() >= prefix.length() && str.substr(0, prefix.length()) == prefix;
}
std::string QueryConverter::convertAggregateFunction(const std::string & attribute, unsigned parameter, const std::string & name)
std::string QueryConverter::convertAggregateFunction(const std::string & attribute, unsigned parameter, const std::string & name,
const QueryParseResult & query)
{
bool float_value = false;
/// если включено сэмплирование, то надо умножить агрегатные функции на 1./sample
if (name == "count")
return "sum(Sign)";
if (query.sample != 1)
{
float_value = true;
return "sum(Sign)*" + toString(1./query.sample);
}
else
return "sum(Sign)";
std::string numeric = convertAttributeNumeric(attribute, parameter);
@ -205,10 +219,22 @@ std::string QueryConverter::convertAggregateFunction(const std::string & attribu
return "uniqHLL12State(" + numeric + ")";
if (name == "count_non_zero")
return "sum((" + numeric + ") == 0 ? toInt64(0) : toInt64(Sign))";
if (query.sample != 1)
{
float_value = true;
return "sum((" + numeric + ") == 0 ? toInt64(0) : toInt64(Sign)) * " + toString(1/query.sample);
}
else
return "sum((" + numeric + ") == 0 ? toInt64(0) : toInt64(Sign))";
if (name == "count_non_minus_one")
return "sum((" + numeric + ") == -1 ? toInt64(0) : toInt64(Sign))";
if (query.sample != 1)
{
float_value = true;
return "sum((" + numeric + ") == -1 ? toInt64(0) : toInt64(Sign)) * " + toString(1/query.sample);
}
else
return "sum((" + numeric + ") == -1 ? toInt64(0) : toInt64(Sign))";
bool trivial_format;
std::string format;
@ -224,12 +250,24 @@ std::string QueryConverter::convertAggregateFunction(const std::string & attribu
}
std::string s;
bool float_value = false;
if (name == "sum")
s = "sum((" + numeric + ") * Sign)";
if (query.sample != 1)
{
s = "sum((" + numeric + ") * Sign) * " + toString(1/query.sample);
float_value = true;
}
else
s = "sum((" + numeric + ") * Sign)";
if (name == "sum_non_minus_one")
s = "sum((" + numeric + ") == -1 ? toInt64(0) : toInt64(" + numeric + ") * Sign)";
if (query.sample != 1)
{
s = "sum((" + numeric + ") == -1 ? toInt64(0) : toInt64(" + numeric + ") * Sign) * " + toString(1/query.sample);
float_value = true;
}
else
s = "sum((" + numeric + ") == -1 ? toInt64(0) : toInt64(" + numeric + ") * Sign)";
if (name == "avg")
{
s = "sum((" + numeric + ") * Sign) / sum(Sign)";

View File

@ -26,7 +26,8 @@ private:
std::string convertAttributeNumeric(const std::string & attribute, unsigned parameter);
/// <aggregates><aggregate> => SELECT x
std::string convertAggregateFunction(const std::string & attribute, unsigned parameter, const std::string & function);
std::string convertAggregateFunction(const std::string & attribute, unsigned parameter, const std::string & function,
const QueryParseResult & query);
/// <where><condition><rhs> => SELECT ... where F(A, x)
std::string convertConstant(const std::string & attribute, const std::string & value);
/// <where><condition> => SELECT ... WHERE x

View File

@ -7,6 +7,7 @@
#include <DB/Core/ErrorCodes.h>
#include <DB/Core/Exception.h>
#include <DB/IO/ReadHelpers.h>
#include <DB/IO/WriteHelpers.h>
namespace DB
@ -53,6 +54,8 @@ QueryParseResult QueryParser::parse(std::istream & s)
result.max_result_size = 0;
result.max_execution_time = 0;
result.sample = 1.0;
result.query = parser.parse(&source);
@ -171,6 +174,12 @@ QueryParseResult QueryParser::parse(std::istream & s)
{
result.local = true;
}
else if (settings_child_nodes->item(i)->nodeName() == "sample")
{
result.sample = DB::parse<Float32>(settings_child_nodes->item(i)->innerText());
if (result.sample <= 0 || result.sample > 1.)
throw Exception(std::string("Wrong sample = ") + DB::toString(result.sample) + ". Sampling must be in range (0, 1]");
}
}
}

View File

@ -81,6 +81,10 @@ struct QueryParseResult
/// Использовать таблицу для одного слоя, даже если указан CounterID = 0.
bool local;
/// сэмплинг - по какой доле данных выполнять запрос. принимает значения в диапазоне (0, 1]
/// если равно 1 - то отключен
float sample;
Format format;
OverflowMode overflow_mode;