diff --git a/dbms/src/Interpreters/ExpressionAnalyzer.cpp b/dbms/src/Interpreters/ExpressionAnalyzer.cpp index b825225e4a02a93586a15fbce68375c7d15f28ec..3c347d62a2804581d0438e9381e296ba07c771c2 100644 --- a/dbms/src/Interpreters/ExpressionAnalyzer.cpp +++ b/dbms/src/Interpreters/ExpressionAnalyzer.cpp @@ -211,13 +211,17 @@ void ExpressionAnalyzer::analyzeAggregation() /// constant expressions have non-null column pointer at this stage if (const auto is_constexpr = col.column) { - if (i < group_asts.size() - 1) - group_asts[i] = std::move(group_asts.back()); + /// but don't remove last key column if no aggregate functions, otherwise aggregation will not work + if (!aggregate_descriptions.empty() || group_asts.size() > 1) + { + if (i < group_asts.size() - 1) + group_asts[i] = std::move(group_asts.back()); - group_asts.pop_back(); - i -= 1; + group_asts.pop_back(); + i -= 1; - continue; + continue; + } } NameAndTypePair key{column_name, col.type}; @@ -781,7 +785,26 @@ void ExpressionAnalyzer::optimizeGroupBy() } if (group_exprs.empty()) - select_query->group_expression_list = nullptr; + { + /** Нельзя полностью убирать GROUP BY. Потому что если при этом даже агрегатных функций не было, то получится, что не будет агрегации. + * Вместо этого оставим GROUP BY const. + * Далее см. удаление констант в методе analyzeAggregation. + */ + + /// Нужно вставить константу, которая не является именем столбца таблицы. Такой случай редкий, но бывает. + UInt64 unused_column = 0; + String unused_column_name = toString(unused_column); + + while (columns.end() != std::find_if(columns.begin(), columns.end(), + [&unused_column_name](const NameAndTypePair & name_type) { return name_type.name == unused_column_name; })) + { + ++unused_column; + unused_column_name = toString(unused_column); + } + + select_query->group_expression_list = new ASTExpressionList; + select_query->group_expression_list->children.push_back(new ASTLiteral(StringRange(), UInt64(unused_column))); + } } diff --git a/dbms/tests/queries/0_stateless/00257_no_aggregates_and_constant_keys.reference b/dbms/tests/queries/0_stateless/00257_no_aggregates_and_constant_keys.reference new file mode 100644 index 0000000000000000000000000000000000000000..fc77ed8a2412b230cef31013fef7a7f375ea9a5c --- /dev/null +++ b/dbms/tests/queries/0_stateless/00257_no_aggregates_and_constant_keys.reference @@ -0,0 +1,29 @@ +40 +41 +2 42 +43 +11 +40 + +40 +41 + +41 +2 42 + +2 42 +43 + +43 +11 + +11 +11 + +11 +1 + +1 +2 + +2 diff --git a/dbms/tests/queries/0_stateless/00257_no_aggregates_and_constant_keys.sql b/dbms/tests/queries/0_stateless/00257_no_aggregates_and_constant_keys.sql new file mode 100644 index 0000000000000000000000000000000000000000..15f4536e18f70aa1615486c895180950504e8844 --- /dev/null +++ b/dbms/tests/queries/0_stateless/00257_no_aggregates_and_constant_keys.sql @@ -0,0 +1,15 @@ +select 40 as z from (select * from system.numbers limit 3) group by z; +select 41 as z from remote('127.0.0.{1,2}', system.one) group by z; +select count(), 42 AS z from remote('127.0.0.{1,2}', system.one) group by z; +select 43 AS z from remote('127.0.0.{1,2}', system.one) group by 42, 43, 44; +select 11 AS z from (SELECT 2 UNION ALL SELECT 3) group by 42, 43, 44; + +select 40 as z from (select * from system.numbers limit 3) group by z WITH TOTALS; +select 41 as z from remote('127.0.0.{1,2}', system.one) group by z WITH TOTALS; +select count(), 42 AS z from remote('127.0.0.{1,2}', system.one) group by z WITH TOTALS; +select 43 AS z from remote('127.0.0.{1,2}', system.one) group by 42, 43, 44 WITH TOTALS; +select 11 AS z from (SELECT 1 UNION ALL SELECT 2) group by 42, 43, 44 WITH TOTALS; +select 11 AS z from (SELECT 2 UNION ALL SELECT 3) group by 42, 43, 44 WITH TOTALS; + +SELECT count() WITH TOTALS; +SELECT count() FROM remote('127.0.0.{1,2}', system.one) WITH TOTALS;