mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-09-22 17:50:47 +00:00
clickhouse: fixed count() in some cases [#CONV-2944].
This commit is contained in:
parent
c8cc523ffe
commit
e7f40f25b3
@ -192,6 +192,8 @@ public:
|
||||
std::string getID() const;
|
||||
|
||||
std::string dumpActions() const;
|
||||
|
||||
static std::string getSmallestColumn(const NamesAndTypesList & columns);
|
||||
|
||||
private:
|
||||
NamesAndTypesList input_columns;
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user