From 12e00411b4a240387aedb99dc67f3bb0c8616d23 Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Fri, 10 Jul 2020 06:08:15 +0300 Subject: [PATCH] Fix TOTALS/ROLLUP/CUBE for aggregate functions with -State and Nullable arguments #12163 --- .../AggregateFunctionNull.cpp | 14 ++++ src/Functions/FunctionsBitmap.cpp | 3 +- .../01380_nullable_state.reference | 64 +++++++++++++++++++ .../0_stateless/01380_nullable_state.sql | 26 ++++++++ 4 files changed, 105 insertions(+), 2 deletions(-) create mode 100644 tests/queries/0_stateless/01380_nullable_state.reference create mode 100644 tests/queries/0_stateless/01380_nullable_state.sql diff --git a/src/AggregateFunctions/AggregateFunctionNull.cpp b/src/AggregateFunctions/AggregateFunctionNull.cpp index b8fbad53350..cd77cf9f2c8 100644 --- a/src/AggregateFunctions/AggregateFunctionNull.cpp +++ b/src/AggregateFunctions/AggregateFunctionNull.cpp @@ -2,6 +2,7 @@ #include #include #include +#include #include #include "registerAggregateFunctions.h" @@ -36,6 +37,19 @@ public: const DataTypes & arguments, const Array & params) const override { + /// If applied to aggregate function with -State combinator, we apply -Null combinator to it's nested_function instead of itself. + /// Because Nullable AggregateFunctionState does not make sense and ruins the logic of managing aggregate function states. + + if (const AggregateFunctionState * function_state = typeid_cast(nested_function.get())) + { + auto transformed_nested_function = transformAggregateFunction(function_state->getNestedFunction(), properties, arguments, params); + + return std::make_shared( + transformed_nested_function, + transformed_nested_function->getArgumentTypes(), + transformed_nested_function->getParameters()); + } + bool has_nullable_types = false; bool has_null_types = false; for (const auto & arg_type : arguments) diff --git a/src/Functions/FunctionsBitmap.cpp b/src/Functions/FunctionsBitmap.cpp index c94566b04b0..72652288872 100644 --- a/src/Functions/FunctionsBitmap.cpp +++ b/src/Functions/FunctionsBitmap.cpp @@ -1,7 +1,6 @@ #include -// TODO include this last because of a broken roaring header. See the comment -// inside. +// TODO include this last because of a broken roaring header. See the comment inside. #include diff --git a/tests/queries/0_stateless/01380_nullable_state.reference b/tests/queries/0_stateless/01380_nullable_state.reference new file mode 100644 index 00000000000..f87ff0a3f1f --- /dev/null +++ b/tests/queries/0_stateless/01380_nullable_state.reference @@ -0,0 +1,64 @@ +0100012CCBC234 + +0100012CCBC234 +--- +0100012CCBC234 + +0100012CCBC234 +--- +0100012CCBC234 + +0100012CCBC234 +--- +0100012CCBC234 + +0100012CCBC234 +--- +0100012CCBC234 + +0100012CCBC234 +--- +0100012CCBC234 + +0100012CCBC234 +--- +1 + +1 +--- +0 1 +1 1 +2 1 +3 1 +4 1 + +0 1 +--- +0 1 +1 1 +2 1 +3 1 +4 1 + +0 1 +--- +0 [0] +1 [0] +2 [0] +3 [0] +4 [0] + +0 [0] +--- +0 [0] +1 [0] +2 [0] +3 [0] +4 [0] + +\N [0] +--- +0100012CCBC234 +--- +0100012CCBC234 +--- diff --git a/tests/queries/0_stateless/01380_nullable_state.sql b/tests/queries/0_stateless/01380_nullable_state.sql new file mode 100644 index 00000000000..6841a6ce636 --- /dev/null +++ b/tests/queries/0_stateless/01380_nullable_state.sql @@ -0,0 +1,26 @@ +SELECT hex(toString(uniqState(toNullable(1)))) WITH TOTALS; +SELECT '---'; +SELECT hex(toString(uniqState(x))) FROM (SELECT toNullable(1) AS x) WITH TOTALS; +SELECT '---'; +SELECT DISTINCT hex(toString(uniqState(x))) FROM (SELECT materialize(1) AS k, toNullable(1) AS x FROM numbers(1)) GROUP BY k WITH TOTALS ORDER BY k; +SELECT '---'; +SELECT DISTINCT hex(toString(uniqState(x))) FROM (SELECT materialize(1) AS k, toNullable(1) AS x FROM numbers(10)) GROUP BY k WITH TOTALS ORDER BY k; +SELECT '---'; +SELECT DISTINCT hex(toString(uniqState(x))) FROM (SELECT intDiv(number, 3) AS k, toNullable(1) AS x FROM numbers(10)) GROUP BY k WITH TOTALS ORDER BY k; +SELECT '---'; +SELECT DISTINCT hex(toString(uniqState(x))) FROM (SELECT intDiv(number, 3) AS k, toNullable(1) AS x FROM system.numbers LIMIT 100000) GROUP BY k WITH TOTALS ORDER BY k; +SELECT '---'; +SELECT DISTINCT arrayUniq(finalizeAggregation(groupArrayState(x))) FROM (SELECT intDiv(number, 3) AS k, toNullable(1) AS x FROM system.numbers LIMIT 100000) GROUP BY k WITH TOTALS ORDER BY k; +SELECT '---'; +SELECT k, finalizeAggregation(uniqState(x)) FROM (SELECT intDiv(number, 3) AS k, toNullable(1) AS x FROM system.numbers LIMIT 100000) GROUP BY k WITH TOTALS ORDER BY k LIMIT 5; +SELECT '---'; +SELECT k, finalizeAggregation(uniqState(x)) FROM (WITH toNullable(number = 3 ? 3 : 1) AS d SELECT intDiv(number, 3) AS k, number % d AS x FROM system.numbers LIMIT 100000) GROUP BY k WITH TOTALS ORDER BY k LIMIT 5; +SELECT '---'; +SELECT k, finalizeAggregation(quantilesTimingState(0.5)(x)) FROM (WITH toNullable(number = 3 ? 3 : 1) AS d SELECT intDiv(number, 3) AS k, number % d AS x FROM system.numbers LIMIT 100000) GROUP BY k WITH TOTALS ORDER BY k LIMIT 5; +SELECT '---'; +SELECT k, finalizeAggregation(quantilesTimingState(0.5)(x)) FROM (SELECT intDiv(number, if(number = 9223372036854775807, -2, if(number = 3, number = if(number = 1, NULL, 3), 1)) AS d) AS k, number % d AS x FROM system.numbers LIMIT 100000) GROUP BY k WITH TOTALS ORDER BY k ASC LIMIT 5; +SELECT '---'; +SELECT DISTINCT hex(toString(uniqState(x))) FROM (SELECT materialize(1) AS k, toNullable(1) AS x FROM numbers(1)) GROUP BY k WITH ROLLUP ORDER BY k; +SELECT '---'; +SELECT DISTINCT hex(toString(uniqState(x))) FROM (SELECT materialize(1) AS k, toNullable(1) AS x FROM numbers(1)) GROUP BY k WITH CUBE ORDER BY k; +SELECT '---';