mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-11-11 18:14:03 +00:00
clickhouse: fixed count() in some cases [#CONV-2944].
This commit is contained in:
parent
c8cc523ffe
commit
e7f40f25b3
@ -193,6 +193,8 @@ public:
|
|||||||
|
|
||||||
std::string dumpActions() const;
|
std::string dumpActions() const;
|
||||||
|
|
||||||
|
static std::string getSmallestColumn(const NamesAndTypesList & columns);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
NamesAndTypesList input_columns;
|
NamesAndTypesList input_columns;
|
||||||
Actions actions;
|
Actions actions;
|
||||||
|
@ -39,7 +39,7 @@ public:
|
|||||||
/// Получить список ключей агрегирования и описаний агрегатных функций, если в запросе есть GROUP BY.
|
/// Получить список ключей агрегирования и описаний агрегатных функций, если в запросе есть GROUP BY.
|
||||||
void getAggregateInfo(Names & key_names, AggregateDescriptions & aggregates);
|
void getAggregateInfo(Names & key_names, AggregateDescriptions & aggregates);
|
||||||
|
|
||||||
/// Получить набор столбцов, которые достаточно прочесть для выичсления выражения.
|
/// Получить набор столбцов, которые достаточно прочесть для вычисления выражения.
|
||||||
Names getRequiredColumns();
|
Names getRequiredColumns();
|
||||||
|
|
||||||
|
|
||||||
@ -214,6 +214,8 @@ private:
|
|||||||
NamesAndTypesList::iterator findColumn(const String & name, NamesAndTypesList & cols);
|
NamesAndTypesList::iterator findColumn(const String & name, NamesAndTypesList & cols);
|
||||||
NamesAndTypesList::iterator findColumn(const String & name) { return findColumn(name, columns); }
|
NamesAndTypesList::iterator findColumn(const String & name) { return findColumn(name, columns); }
|
||||||
|
|
||||||
|
void removeUnusedColumns();
|
||||||
|
|
||||||
/** Создать словарь алиасов.
|
/** Создать словарь алиасов.
|
||||||
*/
|
*/
|
||||||
void createAliasesDict(ASTPtr & ast);
|
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();
|
NamesAndTypesList::const_iterator it = columns.begin();
|
||||||
|
|
||||||
@ -437,7 +437,7 @@ void ExpressionActions::finalize(const Names & output_columns)
|
|||||||
|
|
||||||
/// Не будем оставлять блок пустым, чтобы не потерять количество строк в нем.
|
/// Не будем оставлять блок пустым, чтобы не потерять количество строк в нем.
|
||||||
if (final_columns.empty())
|
if (final_columns.empty())
|
||||||
final_columns.insert(getAnyColumn(input_columns));
|
final_columns.insert(getSmallestColumn(input_columns));
|
||||||
|
|
||||||
/// Какие столбцы нужны, чтобы выполнить действия от текущего до последнего.
|
/// Какие столбцы нужны, чтобы выполнить действия от текущего до последнего.
|
||||||
NameSet needed_columns = final_columns;
|
NameSet needed_columns = final_columns;
|
||||||
|
@ -57,6 +57,8 @@ void ExpressionAnalyzer::init()
|
|||||||
createAliasesDict(ast); /// Если есть агрегатные функции, присвоит has_aggregation=true.
|
createAliasesDict(ast); /// Если есть агрегатные функции, присвоит has_aggregation=true.
|
||||||
normalizeTree();
|
normalizeTree();
|
||||||
|
|
||||||
|
removeUnusedColumns();
|
||||||
|
|
||||||
/// Найдем агрегатные функции.
|
/// Найдем агрегатные функции.
|
||||||
if (select_query && (select_query->group_expression_list || select_query->having_expression))
|
if (select_query && (select_query->group_expression_list || select_query->having_expression))
|
||||||
has_aggregation = true;
|
has_aggregation = true;
|
||||||
@ -1008,12 +1010,30 @@ void ExpressionAnalyzer::getAggregateInfo(Names & key_names, AggregateDescriptio
|
|||||||
aggregates = aggregate_descriptions;
|
aggregates = aggregate_descriptions;
|
||||||
}
|
}
|
||||||
|
|
||||||
Names ExpressionAnalyzer::getRequiredColumns()
|
void ExpressionAnalyzer::removeUnusedColumns()
|
||||||
{
|
{
|
||||||
NamesSet required;
|
NamesSet required;
|
||||||
NamesSet ignored;
|
NamesSet ignored;
|
||||||
getRequiredColumnsImpl(ast, required, 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;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -362,10 +362,6 @@ QueryProcessingStage::Enum InterpreterSelectQuery::executeFetchColumns(BlockInpu
|
|||||||
+ ", maximum: " + Poco::NumberFormatter::format(settings.limits.max_columns_to_read),
|
+ ", maximum: " + Poco::NumberFormatter::format(settings.limits.max_columns_to_read),
|
||||||
ErrorCodes::TOO_MUCH_COLUMNS);
|
ErrorCodes::TOO_MUCH_COLUMNS);
|
||||||
|
|
||||||
/// Если не указан ни один столбец из таблицы, то будем читать первый попавшийся (чтобы хотя бы знать число строк).
|
|
||||||
if (required_columns.empty())
|
|
||||||
required_columns.push_back(getAnyColumn());
|
|
||||||
|
|
||||||
size_t limit_length = 0;
|
size_t limit_length = 0;
|
||||||
size_t limit_offset = 0;
|
size_t limit_offset = 0;
|
||||||
getLimitLengthAndOffset(query, limit_length, limit_offset);
|
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