diff --git a/dbms/src/Interpreters/ExpressionAnalyzer.cpp b/dbms/src/Interpreters/ExpressionAnalyzer.cpp index c02ee22684aa4ff1298c6e977d141ef259ee5f25..dc284fee3216f8143857c5eef94cd071b63e6d6d 100644 --- a/dbms/src/Interpreters/ExpressionAnalyzer.cpp +++ b/dbms/src/Interpreters/ExpressionAnalyzer.cpp @@ -886,8 +886,45 @@ static SharedPtr interpretSubquery( select_query->children.emplace_back(select_query->table); } else + { query = subquery->children.at(0); + /** В подзапросе могут быть указаны столбцы с одинаковыми именами. Например, SELECT x, x FROM t + * Это плохо, потому что результат такого запроса нельзя сохранить в таблицу, потому что в таблице не может быть одноимённых столбцов. + * Сохранение в таблицу требуется для GLOBAL-подзапросов. + * + * Чтобы избежать такой ситуации, будем переименовывать одинаковые столбцы. + */ + + std::set all_column_names; + std::set assigned_column_names; + + if (ASTSelectQuery * select = typeid_cast(query.get())) + { + for (auto & expr : select->select_expression_list->children) + all_column_names.insert(expr->getAliasOrColumnName()); + + for (auto & expr : select->select_expression_list->children) + { + auto name = expr->getAliasOrColumnName(); + + if (!assigned_column_names.insert(name).second) + { + size_t i = 1; + while (all_column_names.end() != all_column_names.find(name + "_" + toString(i))) + ++i; + + name = name + "_" + toString(i); + expr = expr->clone(); /// Отменяет склейку одинаковых выражений в дереве. + expr->setAlias(name); + + all_column_names.insert(name); + assigned_column_names.insert(name); + } + } + } + } + if (required_columns.empty()) return new InterpreterSelectQuery(query, subquery_context, QueryProcessingStage::Complete, subquery_depth + 1); else diff --git a/dbms/tests/queries/0_stateless/00217_global_subquery_columns_with_same_name.reference b/dbms/tests/queries/0_stateless/00217_global_subquery_columns_with_same_name.reference new file mode 100644 index 0000000000000000000000000000000000000000..7589f01b456a7cff3b4ea4af8a74b046b9d137e8 --- /dev/null +++ b/dbms/tests/queries/0_stateless/00217_global_subquery_columns_with_same_name.reference @@ -0,0 +1,2 @@ +42 1 +1 diff --git a/dbms/tests/queries/0_stateless/00217_global_subquery_columns_with_same_name.sql b/dbms/tests/queries/0_stateless/00217_global_subquery_columns_with_same_name.sql new file mode 100644 index 0000000000000000000000000000000000000000..327fee9a18d859483e1931be6c1cc1d60b7be5ea --- /dev/null +++ b/dbms/tests/queries/0_stateless/00217_global_subquery_columns_with_same_name.sql @@ -0,0 +1,2 @@ +SELECT k, a FROM (SELECT 42 AS k FROM remote('127.0.0.1', system.one)) GLOBAL ALL FULL OUTER JOIN (SELECT 42 AS k, 1 AS a, a) USING k; +SELECT 1 FROM remote('127.0.0.1', system.one) WHERE (1, 1) GLOBAL IN (SELECT 1 AS a, a);