dbms: fixed error with WITH TOTALS and group_by_overflow_mode [#METR-14604].

This commit is contained in:
Alexey Milovidov 2015-01-15 22:29:37 +03:00
parent 715f5bf8d1
commit 819f13801d
4 changed files with 47 additions and 3 deletions

View File

@ -520,6 +520,24 @@ struct AggregatedDataVariants : private boost::noncopyable
} }
} }
/// Размер без учёта строчки, в которую записываются данные для расчёта TOTALS.
size_t sizeWithoutOverflowRow() const
{
switch (type)
{
case Type::EMPTY: return 0;
case Type::without_key: return 1;
#define M(NAME, IS_TWO_LEVEL) \
case Type::NAME: return NAME->data.size();
APPLY_FOR_AGGREGATED_VARIANTS(M)
#undef M
default:
throw Exception("Unknown aggregated data variant.", ErrorCodes::UNKNOWN_AGGREGATED_DATA_VARIANT);
}
}
const char * getMethodName() const const char * getMethodName() const
{ {
switch (type) switch (type)

View File

@ -637,7 +637,7 @@ bool Aggregator::executeOnBlock(Block & block, AggregatedDataVariants & result,
} }
} }
size_t result_size = result.size(); size_t result_size = result.sizeWithoutOverflowRow();
/// Если результат уже достаточно большой, и его можно сконвертировать в двухуровневую хэш-таблицу. /// Если результат уже достаточно большой, и его можно сконвертировать в двухуровневую хэш-таблицу.
constexpr auto TWO_LEVEL_HASH_TABLE_THRESHOLD = 30000; constexpr auto TWO_LEVEL_HASH_TABLE_THRESHOLD = 30000;
@ -889,7 +889,7 @@ BlocksList Aggregator::prepareBlocksAndFillWithoutKey(AggregatedDataVariants & d
BlocksList Aggregator::prepareBlocksAndFillSingleLevel(AggregatedDataVariants & data_variants, bool final) const BlocksList Aggregator::prepareBlocksAndFillSingleLevel(AggregatedDataVariants & data_variants, bool final) const
{ {
size_t rows = data_variants.size(); size_t rows = data_variants.sizeWithoutOverflowRow();
auto filler = [&data_variants, this]( auto filler = [&data_variants, this](
ColumnPlainPtrs & key_columns, ColumnPlainPtrs & key_columns,
@ -1039,7 +1039,7 @@ BlocksList Aggregator::convertToBlocks(AggregatedDataVariants & data_variants, b
return blocks; return blocks;
std::unique_ptr<boost::threadpool::pool> thread_pool; std::unique_ptr<boost::threadpool::pool> thread_pool;
if (max_threads > 1 && data_variants.size() > 100000 /// TODO Сделать настраиваемый порог. if (max_threads > 1 && data_variants.sizeWithoutOverflowRow() > 100000 /// TODO Сделать настраиваемый порог.
&& data_variants.isTwoLevel()) /// TODO Использовать общий тред-пул с функцией merge. && data_variants.isTwoLevel()) /// TODO Использовать общий тред-пул с функцией merge.
thread_pool.reset(new boost::threadpool::pool(max_threads)); thread_pool.reset(new boost::threadpool::pool(max_threads));

View File

@ -0,0 +1,12 @@
0 1
0 1
0 1
0 1
0 1
0 1
0 1
0 1

View File

@ -0,0 +1,14 @@
SET max_rows_to_group_by = 100000;
SET group_by_overflow_mode = 'any';
SET totals_mode = 'after_having_auto';
SELECT dummy, count() GROUP BY dummy WITH TOTALS;
SET totals_mode = 'after_having_inclusive';
SELECT dummy, count() GROUP BY dummy WITH TOTALS;
SET totals_mode = 'after_having_exclusive';
SELECT dummy, count() GROUP BY dummy WITH TOTALS;
SET totals_mode = 'before_having';
SELECT dummy, count() GROUP BY dummy WITH TOTALS;