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

This commit is contained in:
Michael Kolupaev 2013-06-20 13:50:55 +00:00
parent c8cc523ffe
commit e7f40f25b3
5 changed files with 29 additions and 29 deletions

View File

@ -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;

View File

@ -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);

View File

@ -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;

View File

@ -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;
} }

View File

@ -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;
}
} }