diff --git a/dbms/include/DB/AggregateFunctions/AggregateFunctionUniqUpTo.h b/dbms/include/DB/AggregateFunctions/AggregateFunctionUniqUpTo.h index 52605ce7dcc..d182eec0a9b 100644 --- a/dbms/include/DB/AggregateFunctions/AggregateFunctionUniqUpTo.h +++ b/dbms/include/DB/AggregateFunctions/AggregateFunctionUniqUpTo.h @@ -202,6 +202,11 @@ private: UInt8 threshold = 5; /// Значение по-умолчанию, если параметр не указан. public: + size_t sizeOfData() const + { + return sizeof(AggregateFunctionUniqUpToData) + sizeof(UInt64) * threshold; + } + String getName() const { return "uniqUpTo"; } DataTypePtr getReturnType() const diff --git a/dbms/src/Interpreters/Aggregator.cpp b/dbms/src/Interpreters/Aggregator.cpp index bb7bff6f616..096f1c92151 100644 --- a/dbms/src/Interpreters/Aggregator.cpp +++ b/dbms/src/Interpreters/Aggregator.cpp @@ -1356,11 +1356,15 @@ void NO_INLINE Aggregator::mergeSingleLevelDataImpl( mergeDataImpl( getDataVariant(*res).data, getDataVariant(current).data); - else + else if (res->without_key) mergeDataNoMoreKeysImpl( getDataVariant(*res).data, res->without_key, getDataVariant(current).data); + else + mergeDataOnlyExistingKeysImpl( + getDataVariant(*res).data, + getDataVariant(current).data); /// current не будет уничтожать состояния агрегатных функций в деструкторе current.aggregator = nullptr; diff --git a/dbms/tests/queries/0_stateless/00263_merge_aggregates_and_overflow.reference b/dbms/tests/queries/0_stateless/00263_merge_aggregates_and_overflow.reference new file mode 100644 index 00000000000..d05b1f927f4 --- /dev/null +++ b/dbms/tests/queries/0_stateless/00263_merge_aggregates_and_overflow.reference @@ -0,0 +1 @@ +0 0 diff --git a/dbms/tests/queries/0_stateless/00263_merge_aggregates_and_overflow.sql b/dbms/tests/queries/0_stateless/00263_merge_aggregates_and_overflow.sql new file mode 100644 index 00000000000..604d89cca1d --- /dev/null +++ b/dbms/tests/queries/0_stateless/00263_merge_aggregates_and_overflow.sql @@ -0,0 +1,12 @@ +DROP TABLE IF EXISTS test.numbers_10k_log; + +SET max_block_size = 1000; + +CREATE TABLE test.numbers_10k_log ENGINE = Log AS SELECT number FROM system.numbers LIMIT 10000; + +SET max_threads = 4; +SET max_rows_to_group_by = 3000, group_by_overflow_mode = 'any'; + +SELECT ignore(rand() AS k), ignore(max(toString(number))) FROM test.numbers_10k_log GROUP BY k LIMIT 1; + +DROP TABLE test.numbers_10k_log; diff --git a/dbms/tests/queries/0_stateless/00264_uniq_many_args.reference b/dbms/tests/queries/0_stateless/00264_uniq_many_args.reference new file mode 100644 index 00000000000..758b4d6b8e2 --- /dev/null +++ b/dbms/tests/queries/0_stateless/00264_uniq_many_args.reference @@ -0,0 +1,11 @@ +10 10 100 100 1000 1000 10 10 100 100 1000 1000 10 10 101 101 1006 1006 10 10 100 100 1000 1000 6 6 6 6 6 6 +17 10 10 100 100 610 610 10 10 100 100 610 610 10 10 101 101 616 616 10 10 100 100 610 610 6 6 6 6 6 6 766 +52 10 10 100 100 608 608 10 10 100 100 608 608 10 10 101 101 611 611 10 10 100 100 608 608 6 6 6 6 6 6 766 +5 10 10 100 100 609 609 10 10 100 100 609 609 10 10 101 101 608 608 10 10 100 100 609 609 6 6 6 6 6 6 765 +9 10 10 100 100 608 608 10 10 100 100 608 608 10 10 101 101 618 618 10 10 100 100 608 608 6 6 6 6 6 6 765 +13 10 10 100 100 607 607 10 10 100 100 607 607 10 10 101 101 610 610 10 10 100 100 607 607 6 6 6 6 6 6 765 +46 10 10 100 100 607 607 10 10 100 100 607 607 10 10 101 101 611 611 10 10 100 100 607 607 6 6 6 6 6 6 765 +48 10 10 100 100 609 609 10 10 100 100 609 609 10 10 101 101 617 617 10 10 100 100 609 609 6 6 6 6 6 6 765 +50 10 10 100 100 608 608 10 10 100 100 608 608 10 10 101 101 614 614 10 10 100 100 608 608 6 6 6 6 6 6 765 +54 10 10 100 100 609 609 10 10 100 100 609 609 10 10 101 101 615 615 10 10 100 100 609 609 6 6 6 6 6 6 765 +56 10 10 100 100 608 608 10 10 100 100 608 608 10 10 101 101 614 614 10 10 100 100 608 608 6 6 6 6 6 6 765 diff --git a/dbms/tests/queries/0_stateless/00264_uniq_many_args.sql b/dbms/tests/queries/0_stateless/00264_uniq_many_args.sql new file mode 100644 index 00000000000..2b24e68910c --- /dev/null +++ b/dbms/tests/queries/0_stateless/00264_uniq_many_args.sql @@ -0,0 +1,35 @@ +SELECT + uniq(x), uniq((x)), uniq(x, y), uniq((x, y)), uniq(x, y, z), uniq((x, y, z)), + uniqCombined(x), uniqCombined((x)), uniqCombined(x, y), uniqCombined((x, y)), uniqCombined(x, y, z), uniqCombined((x, y, z)), + uniqHLL12(x), uniqHLL12((x)), uniqHLL12(x, y), uniqHLL12((x, y)), uniqHLL12(x, y, z), uniqHLL12((x, y, z)), + uniqExact(x), uniqExact((x)), uniqExact(x, y), uniqExact((x, y)), uniqExact(x, y, z), uniqExact((x, y, z)), + uniqUpTo(5)(x), uniqUpTo(5)((x)), uniqUpTo(5)(x, y), uniqUpTo(5)((x, y)), uniqUpTo(5)(x, y, z), uniqUpTo(5)((x, y, z)) +FROM +( + SELECT + number % 10 AS x, + intDiv(number, 10) % 10 AS y, + toString(intDiv(number, 100) % 10) AS z + FROM system.numbers LIMIT 1000 +); + + +SELECT k, + uniq(x), uniq((x)), uniq(x, y), uniq((x, y)), uniq(x, y, z), uniq((x, y, z)), + uniqCombined(x), uniqCombined((x)), uniqCombined(x, y), uniqCombined((x, y)), uniqCombined(x, y, z), uniqCombined((x, y, z)), + uniqHLL12(x), uniqHLL12((x)), uniqHLL12(x, y), uniqHLL12((x, y)), uniqHLL12(x, y, z), uniqHLL12((x, y, z)), + uniqExact(x), uniqExact((x)), uniqExact(x, y), uniqExact((x, y)), uniqExact(x, y, z), uniqExact((x, y, z)), + uniqUpTo(5)(x), uniqUpTo(5)((x)), uniqUpTo(5)(x, y), uniqUpTo(5)((x, y)), uniqUpTo(5)(x, y, z), uniqUpTo(5)((x, y, z)), + count() AS c +FROM +( + SELECT + (number + 0x8ffcbd8257219a26) * 0x66bb3430c06d2353 % 131 AS k, + number % 10 AS x, + intDiv(number, 10) % 10 AS y, + toString(intDiv(number, 100) % 10) AS z + FROM system.numbers LIMIT 100000 +) +GROUP BY k +ORDER BY c DESC, k ASC +LIMIT 10;