From 819f13801d589f51054f665b3cc6b36fe797f901 Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Thu, 15 Jan 2015 22:29:37 +0300 Subject: [PATCH] dbms: fixed error with WITH TOTALS and group_by_overflow_mode [#METR-14604]. --- dbms/include/DB/Interpreters/Aggregator.h | 18 ++++++++++++++++++ dbms/src/Interpreters/Aggregator.cpp | 6 +++--- .../00106_totals_after_having.reference | 12 ++++++++++++ .../0_stateless/00106_totals_after_having.sql | 14 ++++++++++++++ 4 files changed, 47 insertions(+), 3 deletions(-) create mode 100644 dbms/tests/queries/0_stateless/00106_totals_after_having.reference create mode 100644 dbms/tests/queries/0_stateless/00106_totals_after_having.sql diff --git a/dbms/include/DB/Interpreters/Aggregator.h b/dbms/include/DB/Interpreters/Aggregator.h index 67606bde4a0..74901974da1 100644 --- a/dbms/include/DB/Interpreters/Aggregator.h +++ b/dbms/include/DB/Interpreters/Aggregator.h @@ -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 { switch (type) diff --git a/dbms/src/Interpreters/Aggregator.cpp b/dbms/src/Interpreters/Aggregator.cpp index ecd2e9ee20c..a5087345fe4 100644 --- a/dbms/src/Interpreters/Aggregator.cpp +++ b/dbms/src/Interpreters/Aggregator.cpp @@ -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; @@ -889,7 +889,7 @@ BlocksList Aggregator::prepareBlocksAndFillWithoutKey(AggregatedDataVariants & d 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]( ColumnPlainPtrs & key_columns, @@ -1039,7 +1039,7 @@ BlocksList Aggregator::convertToBlocks(AggregatedDataVariants & data_variants, b return blocks; std::unique_ptr 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. thread_pool.reset(new boost::threadpool::pool(max_threads)); diff --git a/dbms/tests/queries/0_stateless/00106_totals_after_having.reference b/dbms/tests/queries/0_stateless/00106_totals_after_having.reference new file mode 100644 index 00000000000..405337762d5 --- /dev/null +++ b/dbms/tests/queries/0_stateless/00106_totals_after_having.reference @@ -0,0 +1,12 @@ +0 1 + +0 1 +0 1 + +0 1 +0 1 + +0 1 +0 1 + +0 1 diff --git a/dbms/tests/queries/0_stateless/00106_totals_after_having.sql b/dbms/tests/queries/0_stateless/00106_totals_after_having.sql new file mode 100644 index 00000000000..5ec2bbb9d02 --- /dev/null +++ b/dbms/tests/queries/0_stateless/00106_totals_after_having.sql @@ -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;