diff --git a/src/Interpreters/ActionsDAG.cpp b/src/Interpreters/ActionsDAG.cpp index 2a594839c6a9..d5b5695b24c5 100644 --- a/src/Interpreters/ActionsDAG.cpp +++ b/src/Interpreters/ActionsDAG.cpp @@ -134,11 +134,11 @@ ActionsDAG::ActionsDAG(const NamesAndTypesList & inputs_) outputs.push_back(&addInput(input.name, input.type)); } -ActionsDAG::ActionsDAG(const ColumnsWithTypeAndName & inputs_) +ActionsDAG::ActionsDAG(const ColumnsWithTypeAndName & inputs_, bool duplicate_const_columns) { for (const auto & input : inputs_) { - if (input.column && isColumnConst(*input.column)) + if (input.column && isColumnConst(*input.column) && duplicate_const_columns) { addInput(input); diff --git a/src/Interpreters/ActionsDAG.h b/src/Interpreters/ActionsDAG.h index ee2b3fbf4f28..c73968d175b5 100644 --- a/src/Interpreters/ActionsDAG.h +++ b/src/Interpreters/ActionsDAG.h @@ -109,7 +109,7 @@ class ActionsDAG ActionsDAG & operator=(ActionsDAG &&) = default; ActionsDAG & operator=(const ActionsDAG &) = delete; explicit ActionsDAG(const NamesAndTypesList & inputs_); - explicit ActionsDAG(const ColumnsWithTypeAndName & inputs_); + explicit ActionsDAG(const ColumnsWithTypeAndName & inputs_, bool duplicate_const_columns = true); const Nodes & getNodes() const { return nodes; } static Nodes detachNodes(ActionsDAG && dag) { return std::move(dag.nodes); } diff --git a/src/Planner/PlannerExpressionAnalysis.cpp b/src/Planner/PlannerExpressionAnalysis.cpp index ed3f78193ee8..9f51d439795e 100644 --- a/src/Planner/PlannerExpressionAnalysis.cpp +++ b/src/Planner/PlannerExpressionAnalysis.cpp @@ -121,7 +121,9 @@ std::optional analyzeAggregation(const QueryTreeNodeP Names aggregation_keys; ActionsAndProjectInputsFlagPtr before_aggregation_actions = std::make_shared(); - before_aggregation_actions->dag = ActionsDAG(input_columns); + /// Here it is OK to materialize const columns: if column is used in GROUP BY, it may be expected to become non-const + /// See https://github.com/ClickHouse/ClickHouse/issues/70655 for example + before_aggregation_actions->dag = ActionsDAG(input_columns, false); before_aggregation_actions->dag.getOutputs().clear(); std::unordered_set before_aggregation_actions_output_node_names; diff --git a/tests/queries/0_stateless/00757_enum_defaults_const_analyzer.reference b/tests/queries/0_stateless/00757_enum_defaults_const_analyzer.reference index 6895acffed15..56ead34ad3b7 100644 --- a/tests/queries/0_stateless/00757_enum_defaults_const_analyzer.reference +++ b/tests/queries/0_stateless/00757_enum_defaults_const_analyzer.reference @@ -3,4 +3,4 @@ iphone 1 iphone 1 iphone 1 -iphone 1 +\N 1 diff --git a/tests/queries/0_stateless/03447_grouping_sets_analyzer_const_columns.reference b/tests/queries/0_stateless/03447_grouping_sets_analyzer_const_columns.reference new file mode 100644 index 000000000000..723208a70e1f --- /dev/null +++ b/tests/queries/0_stateless/03447_grouping_sets_analyzer_const_columns.reference @@ -0,0 +1,27 @@ +Const column in grouping set, analyzer on: +0 0 value 0 1 +0 0 value 1 1 +0 0 value 2 1 +0 0 value 3 1 +1 0 0 1 +1 0 1 1 +1 0 2 1 +1 0 3 1 +Non-const column in grouping set, analyzer on: +0 0 value 0 1 +0 0 value 1 1 +0 0 value 2 1 +0 0 value 3 1 +1 0 0 1 +1 0 1 1 +1 0 2 1 +1 0 3 1 +Const column in grouping set, analyzer off: +0 0 value 0 1 +0 0 value 1 1 +0 0 value 2 1 +0 0 value 3 1 +1 0 0 1 +1 0 1 1 +1 0 2 1 +1 0 3 1 diff --git a/tests/queries/0_stateless/03447_grouping_sets_analyzer_const_columns.sql b/tests/queries/0_stateless/03447_grouping_sets_analyzer_const_columns.sql new file mode 100644 index 000000000000..f12e5636bd3a --- /dev/null +++ b/tests/queries/0_stateless/03447_grouping_sets_analyzer_const_columns.sql @@ -0,0 +1,26 @@ +SET enable_analyzer=1; + +SELECT 'Const column in grouping set, analyzer on:'; + +SELECT grouping(key_a), grouping(key_b), key_a, key_b, count() FROM ( + SELECT 'value' as key_a, number as key_b FROM numbers(4) +) +GROUP BY GROUPING SETS((key_b), (key_a, key_b)) +ORDER BY (grouping(key_a), grouping(key_b), key_a, key_b); + +SELECT 'Non-const column in grouping set, analyzer on:'; + +SELECT grouping(key_a), grouping(key_b), key_a, key_b, count() FROM ( + SELECT materialize('value') as key_a, number as key_b FROM numbers(4) +) +GROUP BY GROUPING SETS((key_b), (key_a, key_b)) +ORDER BY (grouping(key_a), grouping(key_b), key_a, key_b); + +SELECT 'Const column in grouping set, analyzer off:'; + +SELECT grouping(key_a), grouping(key_b), key_a, key_b, count() FROM ( + SELECT 'value' as key_a, number as key_b FROM numbers(4) +) +GROUP BY GROUPING SETS((key_b), (key_a, key_b)) +ORDER BY (grouping(key_a), grouping(key_b), key_a, key_b) +SETTINGS allow_experimental_analyzer=0;