提交 e7f40f25 编写于 作者: M Michael Kolupaev

clickhouse: fixed count() in some cases [#CONV-2944].

上级 c8cc523f
......@@ -193,6 +193,8 @@ public:
std::string dumpActions() const;
static std::string getSmallestColumn(const NamesAndTypesList & columns);
private:
NamesAndTypesList input_columns;
Actions actions;
......
......@@ -39,7 +39,7 @@ public:
/// Получить список ключей агрегирования и описаний агрегатных функций, если в запросе есть GROUP BY.
void getAggregateInfo(Names & key_names, AggregateDescriptions & aggregates);
/// Получить набор столбцов, которые достаточно прочесть для выичсления выражения.
/// Получить набор столбцов, которые достаточно прочесть для вычисления выражения.
Names getRequiredColumns();
......@@ -214,6 +214,8 @@ private:
NamesAndTypesList::iterator findColumn(const String & name, NamesAndTypesList & cols);
NamesAndTypesList::iterator findColumn(const String & name) { return findColumn(name, columns); }
void removeUnusedColumns();
/** Создать словарь алиасов.
*/
void createAliasesDict(ASTPtr & ast);
......
......@@ -404,7 +404,7 @@ void ExpressionActions::execute(Block & block) const
}
}
static std::string getAnyColumn(const NamesAndTypesList & columns)
std::string ExpressionActions::getSmallestColumn(const NamesAndTypesList & columns)
{
NamesAndTypesList::const_iterator it = columns.begin();
......@@ -437,7 +437,7 @@ void ExpressionActions::finalize(const Names & output_columns)
/// Не будем оставлять блок пустым, чтобы не потерять количество строк в нем.
if (final_columns.empty())
final_columns.insert(getAnyColumn(input_columns));
final_columns.insert(getSmallestColumn(input_columns));
/// Какие столбцы нужны, чтобы выполнить действия от текущего до последнего.
NameSet needed_columns = final_columns;
......
......@@ -57,6 +57,8 @@ void ExpressionAnalyzer::init()
createAliasesDict(ast); /// Если есть агрегатные функции, присвоит has_aggregation=true.
normalizeTree();
removeUnusedColumns();
/// Найдем агрегатные функции.
if (select_query && (select_query->group_expression_list || select_query->having_expression))
has_aggregation = true;
......@@ -1008,12 +1010,30 @@ void ExpressionAnalyzer::getAggregateInfo(Names & key_names, AggregateDescriptio
aggregates = aggregate_descriptions;
}
Names ExpressionAnalyzer::getRequiredColumns()
void ExpressionAnalyzer::removeUnusedColumns()
{
NamesSet required;
NamesSet ignored;
getRequiredColumnsImpl(ast, required, ignored);
Names res(required.begin(), required.end());
/// Нужно прочитать хоть один столбец, чтобы узнать количество строк.
if (required.empty())
required.insert(ExpressionActions::getSmallestColumn(columns));
for (NamesAndTypesList::iterator it = columns.begin(); it != columns.end();)
{
NamesAndTypesList::iterator it0 = it;
++it;
if (!required.count(it0->first))
columns.erase(it0);
}
}
Names ExpressionAnalyzer::getRequiredColumns()
{
Names res;
for (NamesAndTypesList::iterator it = columns.begin(); it != columns.end(); ++it)
res.push_back(it->first);
return res;
}
......
......@@ -362,10 +362,6 @@ QueryProcessingStage::Enum InterpreterSelectQuery::executeFetchColumns(BlockInpu
+ ", maximum: " + Poco::NumberFormatter::format(settings.limits.max_columns_to_read),
ErrorCodes::TOO_MUCH_COLUMNS);
/// Если не указан ни один столбец из таблицы, то будем читать первый попавшийся (чтобы хотя бы знать число строк).
if (required_columns.empty())
required_columns.push_back(getAnyColumn());
size_t limit_length = 0;
size_t limit_offset = 0;
getLimitLengthAndOffset(query, limit_length, limit_offset);
......@@ -645,24 +641,4 @@ BlockInputStreamPtr InterpreterSelectQuery::executeAndFormat(WriteBuffer & buf)
}
String InterpreterSelectQuery::getAnyColumn()
{
NamesAndTypesList::const_iterator it = context.getColumns().begin();
size_t min_size = it->second->isNumeric() ? it->second->getSizeOfField() : 100;
String res = it->first;
for (; it != context.getColumns().end(); ++it)
{
size_t current_size = it->second->isNumeric() ? it->second->getSizeOfField() : 100;
if (current_size < min_size)
{
min_size = current_size;
res = it->first;
}
}
return res;
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册