-
Notifications
You must be signed in to change notification settings - Fork 7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conditional computations. #2272
Conversation
@@ -67,6 +69,10 @@ struct ExpressionAction | |||
std::string result_name; | |||
DataTypePtr result_type; | |||
|
|||
/// For projections |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Плохое имя, т.к. в этом же и смежных классах под проекцией понимается совршенно другая вещь.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Очень не хватает комментариев в коде, без них сложно разобраться в алгоритме.
|
||
void ExpressionAnalyzer::getRootActions(const ASTPtr & ast, bool no_subqueries, bool only_consts, ExpressionActionsPtr & actions) | ||
{ | ||
ScopeStack scopes(actions, settings); | ||
getActionsImpl(ast, no_subqueries, only_consts, scopes); | ||
ProjectionManipulatorPtr projection_manipulator; | ||
if (!isThereArrayJoin(ast) && settings.enable_conditional_computation && !only_consts) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Тут не совсем очевидна мотивация.
По идее если при выполнении arrayJoin делать replicate() виртуальных столбцов с масками, то должно все работать (?).
Еще есть вариант выполнять все arrayJoin'ы после всех обычных функций.
В текущем варианте это усложняет код тем, что приходится поддерживать dummy реализации всего из ProjectionManipulator.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(Это не первочередное проблема)
dbms/src/Columns/ColumnVector.h
Outdated
@@ -231,6 +231,11 @@ class ColumnVector final : public COWPtrHelper<IColumn, ColumnVector<T>> | |||
return UInt64(data[n]); | |||
} | |||
|
|||
UInt8 getUInt8(size_t n) const override | |||
{ | |||
return UInt8(!!data[n]); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
То, что возвращает функция, не соответствует названию.
Для 0.1 getUInt8 вернет 1, а getUInt64 - 0. Возможно, назвать функцию как getBoolRepresentation() или как-то аналогично?
auto col_res = ColumnUInt8::create(); | ||
auto & vec_res = col_res->getData(); | ||
vec_res.resize(data_column->size()); | ||
for (size_t i = 0; i < data_column->size(); ++i) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
{ должна быть на новой строке
auto & vec_res = col_res->getData(); | ||
vec_res.resize(data_column->size()); | ||
for (size_t i = 0; i < data_column->size(); ++i) { | ||
if (data_column->getUInt8(i)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Нужно проверить, что виртуальный вызов на каждую строку не тормозит. Например, добавить typeid_cast для ColumnUInt8 и сравнить на простом запросе. (select sum(number % 3 == 1 and number % 5 == 2) form system.numbers limit 10000000).
|
||
DataTypePtr FunctionProject::getReturnTypeImpl(const DataTypes & arguments) const | ||
{ | ||
return arguments[0]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Должен ли 2-й аргумент иметь тип UInt8? Если да, то нужно добавить проверку.
|
||
DataTypePtr FunctionBuildProjectionComposition::getReturnTypeImpl(const DataTypes & /*arguments*/) const | ||
{ | ||
return std::make_shared<DataTypeUInt8>(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Если оба аргумента имеют тип UInt8, нужно это проверить.
std::vector<size_t> override_indices(arguments.size() - 1, 0); | ||
for (size_t i = 0; i < projection_column->size(); ++i) { | ||
size_t argument_index = projection_column->getUInt8(i) + 1; | ||
col_res->insertFrom(*block.getByPosition(arguments[argument_index]).column, ++override_indices[argument_index]); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Идея микрооптимизации: запоминать последовательности одинаковых индексов и использовать insertRangeFrom
vec_res[i] = second_projection_column->getUInt8(current_reverse_index++); | ||
} | ||
} | ||
block.getByPosition(result).column = std::move(col_res); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Не помешает проверить, что current_reverse_index == second_projection_column->size()
size_t argument_index = projection_column->getUInt8(i) + 1; | ||
col_res->insertFrom(*block.getByPosition(arguments[argument_index]).column, ++override_indices[argument_index]); | ||
} | ||
block.getByPosition(result).column = std::move(col_res); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Проверить, что override_indices совпадает с размером колонок.
@@ -58,6 +58,8 @@ struct ExpressionAction | |||
|
|||
/// Reorder and rename the columns, delete the extra ones. The same column names are allowed in the result. | |||
PROJECT, | |||
|
|||
MEASURE_INPUT_ROWS_COUNT, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Не хватает комментария
@@ -67,6 +69,11 @@ struct ExpressionAction | |||
std::string result_name; | |||
DataTypePtr result_type; | |||
|
|||
/// For conditional projections (projections on subset of rows) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Из комментария не вполне понятно, для чего нужны эти поля и как MEASURE_INPUT_ROWS_COUNT.
По коду смог понять, что output_row_projection_expression используется для результата MEASURE_INPUT_ROWS_COUNT, а input_row_projection_expression и is_row_projection_complementary в методе execute для того, чтобы получить размер колонки для результата add_column и apply_function. Верно ли это? (Комментарий такого стиля был бы полезен)
I hereby agree to the terms of the CLA available at: https://yandex.ru/legal/cla/?lang=en
В этом реквесте содержится правка, которая позволяет вычислять аргументы функции and не везде, а только на определенных подмножествах строк.
Включается эта функциональность опцией клиента enable_conditional_computation. По-дефолту, функциональность выклчена
Пример работы
Особенность реквеста: приходится пробрасывать в execute количество входных строк, из-за кейсов, где аргумент фукнции "and" может не иметь никаких входных параметров и угадать число строк результата невозможно внутри выполнения функции, только подсказать ей снаружи, как в примере
f and emptyArrayUInt8()
В остальном все просто: добавлены функции проекции, восстановления и взятия композиции проекций и построен способ выбора экшенов, который использует эти функции для вычисления результата.